diff options
Diffstat (limited to 'llvm/lib/Transforms/Utils/InlineFunction.cpp')
-rw-r--r-- | llvm/lib/Transforms/Utils/InlineFunction.cpp | 90 |
1 files changed, 16 insertions, 74 deletions
diff --git a/llvm/lib/Transforms/Utils/InlineFunction.cpp b/llvm/lib/Transforms/Utils/InlineFunction.cpp index 71ca527..55ad2b6d 100644 --- a/llvm/lib/Transforms/Utils/InlineFunction.cpp +++ b/llvm/lib/Transforms/Utils/InlineFunction.cpp @@ -34,7 +34,6 @@ #include "llvm/Analysis/VectorUtils.h" #include "llvm/IR/Argument.h" #include "llvm/IR/AttributeMask.h" -#include "llvm/IR/Attributes.h" #include "llvm/IR/BasicBlock.h" #include "llvm/IR/CFG.h" #include "llvm/IR/Constant.h" @@ -60,7 +59,6 @@ #include "llvm/IR/MDBuilder.h" #include "llvm/IR/Metadata.h" #include "llvm/IR/Module.h" -#include "llvm/IR/PatternMatch.h" #include "llvm/IR/ProfDataUtils.h" #include "llvm/IR/Type.h" #include "llvm/IR/User.h" @@ -1360,36 +1358,18 @@ static void AddParamAndFnBasicAttributes(const CallBase &CB, auto &Context = CalledFunction->getContext(); // Collect valid attributes for all params. - SmallVector<AttrBuilder> ValidObjParamAttrs, ValidExactParamAttrs; + SmallVector<AttrBuilder> ValidParamAttrs; bool HasAttrToPropagate = false; - // Attributes we can only propagate if the exact parameter is forwarded. - // We can propagate both poison generating and UB generating attributes - // without any extra checks. The only attribute that is tricky to propagate - // is `noundef` (skipped for now) as that can create new UB where previous - // behavior was just using a poison value. - static const Attribute::AttrKind ExactAttrsToPropagate[] = { - Attribute::Dereferenceable, Attribute::DereferenceableOrNull, - Attribute::NonNull, Attribute::Alignment, Attribute::Range}; - for (unsigned I = 0, E = CB.arg_size(); I < E; ++I) { - ValidObjParamAttrs.emplace_back(AttrBuilder{CB.getContext()}); - ValidExactParamAttrs.emplace_back(AttrBuilder{CB.getContext()}); + ValidParamAttrs.emplace_back(AttrBuilder{CB.getContext()}); // Access attributes can be propagated to any param with the same underlying // object as the argument. if (CB.paramHasAttr(I, Attribute::ReadNone)) - ValidObjParamAttrs.back().addAttribute(Attribute::ReadNone); + ValidParamAttrs.back().addAttribute(Attribute::ReadNone); if (CB.paramHasAttr(I, Attribute::ReadOnly)) - ValidObjParamAttrs.back().addAttribute(Attribute::ReadOnly); - - for (Attribute::AttrKind AK : ExactAttrsToPropagate) { - Attribute Attr = CB.getParamAttr(I, AK); - if (Attr.isValid()) - ValidExactParamAttrs.back().addAttribute(Attr); - } - - HasAttrToPropagate |= ValidObjParamAttrs.back().hasAttributes(); - HasAttrToPropagate |= ValidExactParamAttrs.back().hasAttributes(); + ValidParamAttrs.back().addAttribute(Attribute::ReadOnly); + HasAttrToPropagate |= ValidParamAttrs.back().hasAttributes(); } // Won't be able to propagate anything. @@ -1411,60 +1391,22 @@ static void AddParamAndFnBasicAttributes(const CallBase &CB, AttributeList AL = NewInnerCB->getAttributes(); for (unsigned I = 0, E = InnerCB->arg_size(); I < E; ++I) { - // It's unsound or requires special handling to propagate - // attributes to byval arguments. Even if CalledFunction - // doesn't e.g. write to the argument (readonly), the call to - // NewInnerCB may write to its by-value copy. - if (NewInnerCB->paramHasAttr(I, Attribute::ByVal)) + // Check if the underlying value for the parameter is an argument. + const Value *UnderlyingV = + getUnderlyingObject(InnerCB->getArgOperand(I)); + const Argument *Arg = dyn_cast<Argument>(UnderlyingV); + if (!Arg) continue; - // Don't bother propagating attrs to constants. - if (match(NewInnerCB->getArgOperand(I), - llvm::PatternMatch::m_ImmConstant())) + if (NewInnerCB->paramHasAttr(I, Attribute::ByVal)) + // It's unsound to propagate memory attributes to byval arguments. + // Even if CalledFunction doesn't e.g. write to the argument, + // the call to NewInnerCB may write to its by-value copy. continue; - // Check if the underlying value for the parameter is an argument. - const Argument *Arg = dyn_cast<Argument>(InnerCB->getArgOperand(I)); - unsigned ArgNo; - if (Arg) { - ArgNo = Arg->getArgNo(); - // For dereferenceable, dereferenceable_or_null, align, etc... - // we don't want to propagate if the existing param has the same - // attribute with "better" constraints. So remove from the - // new AL if the region of the existing param is larger than - // what we can propagate. - AttrBuilder NewAB{ - Context, AttributeSet::get(Context, ValidExactParamAttrs[ArgNo])}; - if (AL.getParamDereferenceableBytes(I) > - NewAB.getDereferenceableBytes()) - NewAB.removeAttribute(Attribute::Dereferenceable); - if (AL.getParamDereferenceableOrNullBytes(I) > - NewAB.getDereferenceableOrNullBytes()) - NewAB.removeAttribute(Attribute::DereferenceableOrNull); - if (AL.getParamAlignment(I).valueOrOne() > - NewAB.getAlignment().valueOrOne()) - NewAB.removeAttribute(Attribute::Alignment); - if (auto ExistingRange = AL.getParamRange(I)) { - if (auto NewRange = NewAB.getRange()) { - ConstantRange CombinedRange = - ExistingRange->intersectWith(*NewRange); - NewAB.removeAttribute(Attribute::Range); - NewAB.addRangeAttr(CombinedRange); - } - } - AL = AL.addParamAttributes(Context, I, NewAB); - } else { - // Check if the underlying value for the parameter is an argument. - const Value *UnderlyingV = - getUnderlyingObject(InnerCB->getArgOperand(I)); - Arg = dyn_cast<Argument>(UnderlyingV); - if (!Arg) - continue; - ArgNo = Arg->getArgNo(); - } - + unsigned ArgNo = Arg->getArgNo(); // If so, propagate its access attributes. - AL = AL.addParamAttributes(Context, I, ValidObjParamAttrs[ArgNo]); + AL = AL.addParamAttributes(Context, I, ValidParamAttrs[ArgNo]); // We can have conflicting attributes from the inner callsite and // to-be-inlined callsite. In that case, choose the most // restrictive. |