diff options
Diffstat (limited to 'contrib/llvm-project/llvm/lib/Transforms/Utils/InlineFunction.cpp')
-rw-r--r-- | contrib/llvm-project/llvm/lib/Transforms/Utils/InlineFunction.cpp | 77 |
1 files changed, 46 insertions, 31 deletions
diff --git a/contrib/llvm-project/llvm/lib/Transforms/Utils/InlineFunction.cpp b/contrib/llvm-project/llvm/lib/Transforms/Utils/InlineFunction.cpp index 923bcc781e47..2fb00f95b749 100644 --- a/contrib/llvm-project/llvm/lib/Transforms/Utils/InlineFunction.cpp +++ b/contrib/llvm-project/llvm/lib/Transforms/Utils/InlineFunction.cpp @@ -37,7 +37,6 @@ #include "llvm/IR/CFG.h" #include "llvm/IR/Constant.h" #include "llvm/IR/Constants.h" -#include "llvm/IR/DIBuilder.h" #include "llvm/IR/DataLayout.h" #include "llvm/IR/DebugInfo.h" #include "llvm/IR/DebugInfoMetadata.h" @@ -85,7 +84,7 @@ EnableNoAliasConversion("enable-noalias-to-md-conversion", cl::init(true), static cl::opt<bool> UseNoAliasIntrinsic("use-noalias-intrinsic-during-inlining", cl::Hidden, - cl::ZeroOrMore, cl::init(true), + cl::init(true), cl::desc("Use the llvm.experimental.noalias.scope.decl " "intrinsic during inlining.")); @@ -1044,12 +1043,10 @@ static void AddAliasScopeMetadata(CallBase &CB, ValueToValueMapTy &VMap, } for (Value *Arg : Call->args()) { - // We need to check the underlying objects of all arguments, not just - // the pointer arguments, because we might be passing pointers as - // integers, etc. - // However, if we know that the call only accesses pointer arguments, - // then we only need to check the pointer arguments. - if (IsArgMemOnlyCall && !Arg->getType()->isPointerTy()) + // Only care about pointer arguments. If a noalias argument is + // accessed through a non-pointer argument, it must be captured + // first (e.g. via ptrtoint), and we protect against captures below. + if (!Arg->getType()->isPointerTy()) continue; PtrArgs.push_back(Arg); @@ -1080,7 +1077,8 @@ static void AddAliasScopeMetadata(CallBase &CB, ValueToValueMapTy &VMap, // Figure out if we're derived from anything that is not a noalias // argument. - bool CanDeriveViaCapture = false, UsesAliasingPtr = false; + bool RequiresNoCaptureBefore = false, UsesAliasingPtr = false, + UsesUnknownObject = false; for (const Value *V : ObjSet) { // Is this value a constant that cannot be derived from any pointer // value (we need to exclude constant expressions, for example, that @@ -1101,19 +1099,28 @@ static void AddAliasScopeMetadata(CallBase &CB, ValueToValueMapTy &VMap, UsesAliasingPtr = true; } - // If this is not some identified function-local object (which cannot - // directly alias a noalias argument), or some other argument (which, - // by definition, also cannot alias a noalias argument), then we could - // alias a noalias argument that has been captured). - if (!isa<Argument>(V) && - !isIdentifiedFunctionLocal(const_cast<Value*>(V))) - CanDeriveViaCapture = true; + if (isEscapeSource(V)) { + // An escape source can only alias with a noalias argument if it has + // been captured beforehand. + RequiresNoCaptureBefore = true; + } else if (!isa<Argument>(V) && !isIdentifiedObject(V)) { + // If this is neither an escape source, nor some identified object + // (which cannot directly alias a noalias argument), nor some other + // argument (which, by definition, also cannot alias a noalias + // argument), conservatively do not make any assumptions. + UsesUnknownObject = true; + } } + // Nothing we can do if the used underlying object cannot be reliably + // determined. + if (UsesUnknownObject) + continue; + // A function call can always get captured noalias pointers (via other // parameters, globals, etc.). if (IsFuncCall && !IsArgMemOnlyCall) - CanDeriveViaCapture = true; + RequiresNoCaptureBefore = true; // First, we want to figure out all of the sets with which we definitely // don't alias. Iterate over all noalias set, and add those for which: @@ -1124,16 +1131,16 @@ static void AddAliasScopeMetadata(CallBase &CB, ValueToValueMapTy &VMap, // noalias arguments via other noalias arguments or globals, and so we // must always check for prior capture. for (const Argument *A : NoAliasArgs) { - if (!ObjSet.count(A) && (!CanDeriveViaCapture || - // It might be tempting to skip the - // PointerMayBeCapturedBefore check if - // A->hasNoCaptureAttr() is true, but this is - // incorrect because nocapture only guarantees - // that no copies outlive the function, not - // that the value cannot be locally captured. - !PointerMayBeCapturedBefore(A, - /* ReturnCaptures */ false, - /* StoreCaptures */ false, I, &DT))) + if (ObjSet.contains(A)) + continue; // May be based on a noalias argument. + + // It might be tempting to skip the PointerMayBeCapturedBefore check if + // A->hasNoCaptureAttr() is true, but this is incorrect because + // nocapture only guarantees that no copies outlive the function, not + // that the value cannot be locally captured. + if (!RequiresNoCaptureBefore || + !PointerMayBeCapturedBefore(A, /* ReturnCaptures */ false, + /* StoreCaptures */ false, I, &DT)) NoAliases.push_back(NewScopes[A]); } @@ -1422,7 +1429,8 @@ static Value *HandleByValArgument(Type *ByValType, Value *Arg, // If the byval had an alignment specified, we *must* use at least that // alignment, as it is required by the byval argument (and uses of the // pointer inside the callee). - Alignment = max(Alignment, MaybeAlign(ByValAlignment)); + if (ByValAlignment > 0) + Alignment = std::max(Alignment, Align(ByValAlignment)); Value *NewAlloca = new AllocaInst(ByValType, DL.getAllocaAddrSpace(), nullptr, Alignment, @@ -1601,7 +1609,7 @@ static void updateCallProfile(Function *Callee, const ValueToValueMapTy &VMap, return; auto CallSiteCount = PSI ? PSI->getProfileCount(TheCall, CallerBFI) : None; int64_t CallCount = - std::min(CallSiteCount.getValueOr(0), CalleeEntryCount.getCount()); + std::min(CallSiteCount.value_or(0), CalleeEntryCount.getCount()); updateProfileCallee(Callee, -CallCount, &VMap); } @@ -1609,7 +1617,7 @@ void llvm::updateProfileCallee( Function *Callee, int64_t EntryDelta, const ValueMap<const Value *, WeakTrackingVH> *VMap) { auto CalleeCount = Callee->getEntryCount(); - if (!CalleeCount.hasValue()) + if (!CalleeCount) return; const uint64_t PriorEntryCount = CalleeCount->getCount(); @@ -1789,6 +1797,13 @@ llvm::InlineResult llvm::InlineFunction(CallBase &CB, InlineFunctionInfo &IFI, BasicBlock *OrigBB = CB.getParent(); Function *Caller = OrigBB->getParent(); + // Do not inline strictfp function into non-strictfp one. It would require + // conversion of all FP operations in host function to constrained intrinsics. + if (CalledFunc->getAttributes().hasFnAttr(Attribute::StrictFP) && + !Caller->getAttributes().hasFnAttr(Attribute::StrictFP)) { + return InlineResult::failure("incompatible strictfp attributes"); + } + // GC poses two hazards to inlining, which only occur when the callee has GC: // 1. If the caller has no GC, then the callee's GC must be propagated to the // caller. @@ -2644,7 +2659,7 @@ llvm::InlineResult llvm::InlineFunction(CallBase &CB, InlineFunctionInfo &IFI, AssumptionCache *AC = IFI.GetAssumptionCache ? &IFI.GetAssumptionCache(*Caller) : nullptr; auto &DL = Caller->getParent()->getDataLayout(); - if (Value *V = SimplifyInstruction(PHI, {DL, nullptr, nullptr, AC})) { + if (Value *V = simplifyInstruction(PHI, {DL, nullptr, nullptr, AC})) { PHI->replaceAllUsesWith(V); PHI->eraseFromParent(); } |