aboutsummaryrefslogtreecommitdiff
path: root/contrib/llvm-project/llvm/lib/Transforms/Utils/InlineFunction.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm-project/llvm/lib/Transforms/Utils/InlineFunction.cpp')
-rw-r--r--contrib/llvm-project/llvm/lib/Transforms/Utils/InlineFunction.cpp77
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();
}