diff options
Diffstat (limited to 'llvm/lib/Transforms/IPO/ArgumentPromotion.cpp')
-rw-r--r-- | llvm/lib/Transforms/IPO/ArgumentPromotion.cpp | 35 |
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. |