From 32418db285b45d9c5db6a4c563d011026ec62212 Mon Sep 17 00:00:00 2001 From: Hal Finkel Date: Mon, 1 Sep 2014 09:01:39 +0000 Subject: [PATCH] Feed AA to the inliner and use AA->getModRefBehavior in AddAliasScopeMetadata This feeds AA through the IFI structure into the inliner so that AddAliasScopeMetadata can use AA->getModRefBehavior to figure out which functions only access their arguments (instead of just hard-coding some knowledge of memory intrinsics). Most of the information is only available from BasicAA; this is important for preserving alias scoping information for target-specific intrinsics when doing the noalias parameter attribute to metadata conversion. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@216866 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/Transforms/Utils/Cloning.h | 8 +++++-- lib/Transforms/IPO/InlineAlways.cpp | 2 ++ lib/Transforms/IPO/InlineSimple.cpp | 2 ++ lib/Transforms/IPO/Inliner.cpp | 5 ++++- lib/Transforms/Utils/InlineFunction.cpp | 30 +++++++++++++++---------- test/Transforms/Inline/noalias-calls.ll | 2 +- 6 files changed, 33 insertions(+), 16 deletions(-) diff --git a/include/llvm/Transforms/Utils/Cloning.h b/include/llvm/Transforms/Utils/Cloning.h index bdf50ddf5cc..989a849da00 100644 --- a/include/llvm/Transforms/Utils/Cloning.h +++ b/include/llvm/Transforms/Utils/Cloning.h @@ -43,6 +43,7 @@ class DataLayout; class Loop; class LoopInfo; class AllocaInst; +class AliasAnalysis; /// CloneModule - Return an exact copy of the specified module /// @@ -157,13 +158,16 @@ void CloneAndPruneFunctionInto(Function *NewFunc, const Function *OldFunc, /// InlineFunction call, and records the auxiliary results produced by it. class InlineFunctionInfo { public: - explicit InlineFunctionInfo(CallGraph *cg = nullptr, const DataLayout *DL = nullptr) - : CG(cg), DL(DL) {} + explicit InlineFunctionInfo(CallGraph *cg = nullptr, + const DataLayout *DL = nullptr, + AliasAnalysis *AA = nullptr) + : CG(cg), DL(DL), AA(AA) {} /// CG - If non-null, InlineFunction will update the callgraph to reflect the /// changes it makes. CallGraph *CG; const DataLayout *DL; + AliasAnalysis *AA; /// StaticAllocas - InlineFunction fills this in with all static allocas that /// get copied into the caller. diff --git a/lib/Transforms/IPO/InlineAlways.cpp b/lib/Transforms/IPO/InlineAlways.cpp index 624cb90c0d5..18c2540910f 100644 --- a/lib/Transforms/IPO/InlineAlways.cpp +++ b/lib/Transforms/IPO/InlineAlways.cpp @@ -14,6 +14,7 @@ #include "llvm/Transforms/IPO.h" #include "llvm/ADT/SmallPtrSet.h" +#include "llvm/Analysis/AliasAnalysis.h" #include "llvm/Analysis/CallGraph.h" #include "llvm/Analysis/InlineCost.h" #include "llvm/IR/CallSite.h" @@ -65,6 +66,7 @@ public: char AlwaysInliner::ID = 0; INITIALIZE_PASS_BEGIN(AlwaysInliner, "always-inline", "Inliner for always_inline functions", false, false) +INITIALIZE_AG_DEPENDENCY(AliasAnalysis) INITIALIZE_PASS_DEPENDENCY(CallGraphWrapperPass) INITIALIZE_PASS_DEPENDENCY(InlineCostAnalysis) INITIALIZE_PASS_END(AlwaysInliner, "always-inline", diff --git a/lib/Transforms/IPO/InlineSimple.cpp b/lib/Transforms/IPO/InlineSimple.cpp index d189756032b..b9b4895eaa8 100644 --- a/lib/Transforms/IPO/InlineSimple.cpp +++ b/lib/Transforms/IPO/InlineSimple.cpp @@ -12,6 +12,7 @@ //===----------------------------------------------------------------------===// #include "llvm/Transforms/IPO.h" +#include "llvm/Analysis/AliasAnalysis.h" #include "llvm/Analysis/CallGraph.h" #include "llvm/Analysis/InlineCost.h" #include "llvm/IR/CallSite.h" @@ -73,6 +74,7 @@ static int computeThresholdFromOptLevels(unsigned OptLevel, char SimpleInliner::ID = 0; INITIALIZE_PASS_BEGIN(SimpleInliner, "inline", "Function Integration/Inlining", false, false) +INITIALIZE_AG_DEPENDENCY(AliasAnalysis) INITIALIZE_PASS_DEPENDENCY(CallGraphWrapperPass) INITIALIZE_PASS_DEPENDENCY(InlineCostAnalysis) INITIALIZE_PASS_END(SimpleInliner, "inline", diff --git a/lib/Transforms/IPO/Inliner.cpp b/lib/Transforms/IPO/Inliner.cpp index a09387832df..3cb6479a10c 100644 --- a/lib/Transforms/IPO/Inliner.cpp +++ b/lib/Transforms/IPO/Inliner.cpp @@ -16,6 +16,7 @@ #include "llvm/Transforms/IPO/InlinerPass.h" #include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/Statistic.h" +#include "llvm/Analysis/AliasAnalysis.h" #include "llvm/Analysis/CallGraph.h" #include "llvm/Analysis/InlineCost.h" #include "llvm/IR/CallSite.h" @@ -74,6 +75,7 @@ Inliner::Inliner(char &ID, int Threshold, bool InsertLifetime) /// the call graph. If the derived class implements this method, it should /// always explicitly call the implementation here. void Inliner::getAnalysisUsage(AnalysisUsage &AU) const { + AU.addRequired(); CallGraphSCCPass::getAnalysisUsage(AU); } @@ -442,6 +444,7 @@ bool Inliner::runOnSCC(CallGraphSCC &SCC) { DataLayoutPass *DLP = getAnalysisIfAvailable(); const DataLayout *DL = DLP ? &DLP->getDataLayout() : nullptr; const TargetLibraryInfo *TLI = getAnalysisIfAvailable(); + AliasAnalysis *AA = &getAnalysis(); SmallPtrSet SCCFunctions; DEBUG(dbgs() << "Inliner visiting SCC:"); @@ -500,7 +503,7 @@ bool Inliner::runOnSCC(CallGraphSCC &SCC) { InlinedArrayAllocasTy InlinedArrayAllocas; - InlineFunctionInfo InlineInfo(&CG, DL); + InlineFunctionInfo InlineInfo(&CG, DL, AA); // Now that we have all of the call sites, loop over them and inline them if // it looks profitable to do so. diff --git a/lib/Transforms/Utils/InlineFunction.cpp b/lib/Transforms/Utils/InlineFunction.cpp index d88554189d1..f2930dcd61d 100644 --- a/lib/Transforms/Utils/InlineFunction.cpp +++ b/lib/Transforms/Utils/InlineFunction.cpp @@ -394,7 +394,7 @@ static void CloneAliasScopeMetadata(CallSite CS, ValueToValueMapTy &VMap) { /// parameters with noalias metadata specifying the new scope, and tag all /// non-derived loads, stores and memory intrinsics with the new alias scopes. static void AddAliasScopeMetadata(CallSite CS, ValueToValueMapTy &VMap, - const DataLayout *DL) { + const DataLayout *DL, AliasAnalysis *AA) { if (!EnableNoAliasConversion) return; @@ -458,6 +458,7 @@ static void AddAliasScopeMetadata(CallSite CS, ValueToValueMapTy &VMap, if (!NI) continue; + bool IsArgMemOnlyCall = false, IsFuncCall = false; SmallVector PtrArgs; if (const LoadInst *LI = dyn_cast(I)) @@ -477,22 +478,27 @@ static void AddAliasScopeMetadata(CallSite CS, ValueToValueMapTy &VMap, if (ICS.doesNotAccessMemory()) continue; + IsFuncCall = true; + if (AA) { + AliasAnalysis::ModRefBehavior MRB = AA->getModRefBehavior(ICS); + if (MRB == AliasAnalysis::OnlyAccessesArgumentPointees || + MRB == AliasAnalysis::OnlyReadsArgumentPointees) + IsArgMemOnlyCall = true; + } + for (ImmutableCallSite::arg_iterator AI = ICS.arg_begin(), - AE = ICS.arg_end(); AI != AE; ++AI) + AE = ICS.arg_end(); AI != AE; ++AI) { // We need to check the underlying objects of all arguments, not just // the pointer arguments, because we might be passing pointers as // integers, etc. - // FIXME: If we know that the call only accesses pointer arguments, + // However, if we know that the call only accesses pointer arguments, // then we only need to check the pointer arguments. - PtrArgs.push_back(*AI); - } + if (IsArgMemOnlyCall && !(*AI)->getType()->isPointerTy()) + continue; - bool IsFuncCall = isa(I) || isa(I); - // FIXME: We should have a way to access the - // IntrReadArgMem/IntrReadWriteArgMem properties of intrinsics, and we - // should have a way to determine that for regular functions too. For - // now, just do this for the memory intrinsics we understand. - bool IsArgMemOnlyCall = isa(I); + PtrArgs.push_back(*AI); + } + } // If we found no pointers, then this instruction is not suitable for // pairing with an instruction to receive aliasing metadata. @@ -975,7 +981,7 @@ bool llvm::InlineFunction(CallSite CS, InlineFunctionInfo &IFI, CloneAliasScopeMetadata(CS, VMap); // Add noalias metadata if necessary. - AddAliasScopeMetadata(CS, VMap, IFI.DL); + AddAliasScopeMetadata(CS, VMap, IFI.DL, IFI.AA); } // If there are any alloca instructions in the block that used to be the entry diff --git a/test/Transforms/Inline/noalias-calls.ll b/test/Transforms/Inline/noalias-calls.ll index 65b2f6e39cc..13408e4f6e9 100644 --- a/test/Transforms/Inline/noalias-calls.ll +++ b/test/Transforms/Inline/noalias-calls.ll @@ -1,4 +1,4 @@ -; RUN: opt -inline -enable-noalias-to-md-conversion -S < %s | FileCheck %s +; RUN: opt -basicaa -inline -enable-noalias-to-md-conversion -S < %s | FileCheck %s target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128" target triple = "x86_64-unknown-linux-gnu"