summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Transforms/IPO/ArgumentPromotion.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/Transforms/IPO/ArgumentPromotion.cpp')
-rw-r--r--llvm/lib/Transforms/IPO/ArgumentPromotion.cpp35
1 files changed, 31 insertions, 4 deletions
diff --git a/llvm/lib/Transforms/IPO/ArgumentPromotion.cpp b/llvm/lib/Transforms/IPO/ArgumentPromotion.cpp
index 517a9c082a4..4663de0b049 100644
--- a/llvm/lib/Transforms/IPO/ArgumentPromotion.cpp
+++ b/llvm/lib/Transforms/IPO/ArgumentPromotion.cpp
@@ -49,6 +49,7 @@
#include "llvm/Analysis/Loads.h"
#include "llvm/Analysis/MemoryLocation.h"
#include "llvm/Analysis/TargetLibraryInfo.h"
+#include "llvm/Analysis/TargetTransformInfo.h"
#include "llvm/IR/Argument.h"
#include "llvm/IR/Attributes.h"
#include "llvm/IR/BasicBlock.h"
@@ -809,6 +810,21 @@ static bool canPaddingBeAccessed(Argument *arg) {
return false;
}
+static bool areFunctionArgsABICompatible(
+ const Function &F, const TargetTransformInfo &TTI,
+ SmallPtrSetImpl<Argument *> &ArgsToPromote,
+ SmallPtrSetImpl<Argument *> &ByValArgsToTransform) {
+ for (const Use &U : F.uses()) {
+ CallSite CS(U.getUser());
+ const Function *Caller = CS.getCaller();
+ const Function *Callee = CS.getCalledFunction();
+ if (!TTI.areFunctionArgsABICompatible(Caller, Callee, ArgsToPromote) ||
+ !TTI.areFunctionArgsABICompatible(Caller, Callee, ByValArgsToTransform))
+ return false;
+ }
+ return true;
+}
+
/// PromoteArguments - This method checks the specified function to see if there
/// are any promotable arguments and if it is safe to promote the function (for
/// example, all callers are direct). If safe to promote some arguments, it
@@ -817,7 +833,8 @@ static Function *
promoteArguments(Function *F, function_ref<AAResults &(Function &F)> AARGetter,
unsigned MaxElements,
Optional<function_ref<void(CallSite OldCS, CallSite NewCS)>>
- ReplaceCallSite) {
+ ReplaceCallSite,
+ const TargetTransformInfo &TTI) {
// Don't perform argument promotion for naked functions; otherwise we can end
// up removing parameters that are seemingly 'not used' as they are referred
// to in the assembly.
@@ -846,7 +863,7 @@ promoteArguments(Function *F, function_ref<AAResults &(Function &F)> AARGetter,
// Second check: make sure that all callers are direct callers. We can't
// transform functions that have indirect callers. Also see if the function
- // is self-recursive.
+ // is self-recursive and check that target features are compatible.
bool isSelfRecursive = false;
for (Use &U : F->uses()) {
CallSite CS(U.getUser());
@@ -955,6 +972,10 @@ promoteArguments(Function *F, function_ref<AAResults &(Function &F)> AARGetter,
if (ArgsToPromote.empty() && ByValArgsToTransform.empty())
return nullptr;
+ if (!areFunctionArgsABICompatible(*F, TTI, ArgsToPromote,
+ ByValArgsToTransform))
+ return nullptr;
+
return doPromotion(F, ArgsToPromote, ByValArgsToTransform, ReplaceCallSite);
}
@@ -980,7 +1001,9 @@ PreservedAnalyses ArgumentPromotionPass::run(LazyCallGraph::SCC &C,
return FAM.getResult<AAManager>(F);
};
- Function *NewF = promoteArguments(&OldF, AARGetter, MaxElements, None);
+ const TargetTransformInfo &TTI = FAM.getResult<TargetIRAnalysis>(OldF);
+ Function *NewF =
+ promoteArguments(&OldF, AARGetter, MaxElements, None, TTI);
if (!NewF)
continue;
LocalChange = true;
@@ -1018,6 +1041,7 @@ struct ArgPromotion : public CallGraphSCCPass {
void getAnalysisUsage(AnalysisUsage &AU) const override {
AU.addRequired<AssumptionCacheTracker>();
AU.addRequired<TargetLibraryInfoWrapperPass>();
+ AU.addRequired<TargetTransformInfoWrapperPass>();
getAAResultsAnalysisUsage(AU);
CallGraphSCCPass::getAnalysisUsage(AU);
}
@@ -1043,6 +1067,7 @@ INITIALIZE_PASS_BEGIN(ArgPromotion, "argpromotion",
INITIALIZE_PASS_DEPENDENCY(AssumptionCacheTracker)
INITIALIZE_PASS_DEPENDENCY(CallGraphWrapperPass)
INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfoWrapperPass)
+INITIALIZE_PASS_DEPENDENCY(TargetTransformInfoWrapperPass)
INITIALIZE_PASS_END(ArgPromotion, "argpromotion",
"Promote 'by reference' arguments to scalars", false, false)
@@ -1079,8 +1104,10 @@ bool ArgPromotion::runOnSCC(CallGraphSCC &SCC) {
CallerNode->replaceCallEdge(OldCS, NewCS, NewCalleeNode);
};
+ const TargetTransformInfo &TTI =
+ getAnalysis<TargetTransformInfoWrapperPass>().getTTI(*OldF);
if (Function *NewF = promoteArguments(OldF, AARGetter, MaxElements,
- {ReplaceCallSite})) {
+ {ReplaceCallSite}, TTI)) {
LocalChange = true;
// Update the call graph for the newly promoted function.
OpenPOWER on IntegriCloud