diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2015-01-18 16:17:27 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2015-01-18 16:17:27 +0000 |
commit | 67c32a98315f785a9ec9d531c1f571a0196c7463 (patch) | |
tree | 4abb9cbeecc7901726dd0b4a37369596c852e9ef /lib/Analysis/IPA | |
parent | 9f61947910e6ab40de38e6b4034751ef1513200f (diff) |
Diffstat (limited to 'lib/Analysis/IPA')
-rw-r--r-- | lib/Analysis/IPA/CMakeLists.txt | 1 | ||||
-rw-r--r-- | lib/Analysis/IPA/CallGraph.cpp | 3 | ||||
-rw-r--r-- | lib/Analysis/IPA/CallGraphSCCPass.cpp | 11 | ||||
-rw-r--r-- | lib/Analysis/IPA/FindUsedTypes.cpp | 100 | ||||
-rw-r--r-- | lib/Analysis/IPA/IPA.cpp | 1 | ||||
-rw-r--r-- | lib/Analysis/IPA/InlineCost.cpp | 36 |
6 files changed, 37 insertions, 115 deletions
diff --git a/lib/Analysis/IPA/CMakeLists.txt b/lib/Analysis/IPA/CMakeLists.txt index 67b413577980..6095136d60a1 100644 --- a/lib/Analysis/IPA/CMakeLists.txt +++ b/lib/Analysis/IPA/CMakeLists.txt @@ -2,7 +2,6 @@ add_llvm_library(LLVMipa CallGraph.cpp CallGraphSCCPass.cpp CallPrinter.cpp - FindUsedTypes.cpp GlobalsModRef.cpp IPA.cpp InlineCost.cpp diff --git a/lib/Analysis/IPA/CallGraph.cpp b/lib/Analysis/IPA/CallGraph.cpp index dfabb0ad063d..67cf7f86e072 100644 --- a/lib/Analysis/IPA/CallGraph.cpp +++ b/lib/Analysis/IPA/CallGraph.cpp @@ -282,6 +282,3 @@ void CallGraphWrapperPass::print(raw_ostream &OS, const Module *) const { #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) void CallGraphWrapperPass::dump() const { print(dbgs(), nullptr); } #endif - -// Enuse that users of CallGraph.h also link with this file -DEFINING_FILE_FOR(CallGraph) diff --git a/lib/Analysis/IPA/CallGraphSCCPass.cpp b/lib/Analysis/IPA/CallGraphSCCPass.cpp index c27edbfa2ff5..ded1de79a124 100644 --- a/lib/Analysis/IPA/CallGraphSCCPass.cpp +++ b/lib/Analysis/IPA/CallGraphSCCPass.cpp @@ -21,8 +21,8 @@ #include "llvm/Analysis/CallGraph.h" #include "llvm/IR/Function.h" #include "llvm/IR/IntrinsicInst.h" -#include "llvm/IR/LegacyPassManagers.h" #include "llvm/IR/LLVMContext.h" +#include "llvm/IR/LegacyPassManagers.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/Debug.h" #include "llvm/Support/Timer.h" @@ -243,7 +243,14 @@ bool CGPassManager::RefreshCallGraph(CallGraphSCC &CurSCC, assert(!CallSites.count(I->first) && "Call site occurs in node multiple times"); - CallSites.insert(std::make_pair(I->first, I->second)); + + CallSite CS(I->first); + if (CS) { + Function *Callee = CS.getCalledFunction(); + // Ignore intrinsics because they're not really function calls. + if (!Callee || !(Callee->isIntrinsic())) + CallSites.insert(std::make_pair(I->first, I->second)); + } ++I; } diff --git a/lib/Analysis/IPA/FindUsedTypes.cpp b/lib/Analysis/IPA/FindUsedTypes.cpp deleted file mode 100644 index b37344b044ce..000000000000 --- a/lib/Analysis/IPA/FindUsedTypes.cpp +++ /dev/null @@ -1,100 +0,0 @@ -//===- FindUsedTypes.cpp - Find all Types used by a module ----------------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This pass is used to seek out all of the types in use by the program. Note -// that this analysis explicitly does not include types only used by the symbol -// table. -// -//===----------------------------------------------------------------------===// - -#include "llvm/Analysis/FindUsedTypes.h" -#include "llvm/IR/Constants.h" -#include "llvm/IR/DerivedTypes.h" -#include "llvm/IR/InstIterator.h" -#include "llvm/IR/Module.h" -#include "llvm/Support/raw_ostream.h" -using namespace llvm; - -char FindUsedTypes::ID = 0; -INITIALIZE_PASS(FindUsedTypes, "print-used-types", - "Find Used Types", false, true) - -// IncorporateType - Incorporate one type and all of its subtypes into the -// collection of used types. -// -void FindUsedTypes::IncorporateType(Type *Ty) { - // If ty doesn't already exist in the used types map, add it now, otherwise - // return. - if (!UsedTypes.insert(Ty)) return; // Already contain Ty. - - // Make sure to add any types this type references now. - // - for (Type::subtype_iterator I = Ty->subtype_begin(), E = Ty->subtype_end(); - I != E; ++I) - IncorporateType(*I); -} - -void FindUsedTypes::IncorporateValue(const Value *V) { - IncorporateType(V->getType()); - - // If this is a constant, it could be using other types... - if (const Constant *C = dyn_cast<Constant>(V)) { - if (!isa<GlobalValue>(C)) - for (User::const_op_iterator OI = C->op_begin(), OE = C->op_end(); - OI != OE; ++OI) - IncorporateValue(*OI); - } -} - - -// run - This incorporates all types used by the specified module -// -bool FindUsedTypes::runOnModule(Module &m) { - UsedTypes.clear(); // reset if run multiple times... - - // Loop over global variables, incorporating their types - for (Module::const_global_iterator I = m.global_begin(), E = m.global_end(); - I != E; ++I) { - IncorporateType(I->getType()); - if (I->hasInitializer()) - IncorporateValue(I->getInitializer()); - } - - for (Module::iterator MI = m.begin(), ME = m.end(); MI != ME; ++MI) { - IncorporateType(MI->getType()); - const Function &F = *MI; - - // Loop over all of the instructions in the function, adding their return - // type as well as the types of their operands. - // - for (const_inst_iterator II = inst_begin(F), IE = inst_end(F); - II != IE; ++II) { - const Instruction &I = *II; - - IncorporateType(I.getType()); // Incorporate the type of the instruction - for (User::const_op_iterator OI = I.op_begin(), OE = I.op_end(); - OI != OE; ++OI) - IncorporateValue(*OI); // Insert inst operand types as well - } - } - - return false; -} - -// Print the types found in the module. If the optional Module parameter is -// passed in, then the types are printed symbolically if possible, using the -// symbol table from the module. -// -void FindUsedTypes::print(raw_ostream &OS, const Module *M) const { - OS << "Types in use by this module:\n"; - for (SetVector<Type *>::const_iterator I = UsedTypes.begin(), - E = UsedTypes.end(); I != E; ++I) { - OS << " " << **I << '\n'; - } -} diff --git a/lib/Analysis/IPA/IPA.cpp b/lib/Analysis/IPA/IPA.cpp index b26c052de67e..806bfb81b6d5 100644 --- a/lib/Analysis/IPA/IPA.cpp +++ b/lib/Analysis/IPA/IPA.cpp @@ -22,7 +22,6 @@ void llvm::initializeIPA(PassRegistry &Registry) { initializeCallGraphWrapperPassPass(Registry); initializeCallGraphPrinterPass(Registry); initializeCallGraphViewerPass(Registry); - initializeFindUsedTypesPass(Registry); initializeGlobalsModRefPass(Registry); } diff --git a/lib/Analysis/IPA/InlineCost.cpp b/lib/Analysis/IPA/InlineCost.cpp index 8807529cabac..58ac5d33409e 100644 --- a/lib/Analysis/IPA/InlineCost.cpp +++ b/lib/Analysis/IPA/InlineCost.cpp @@ -17,6 +17,8 @@ #include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/Statistic.h" +#include "llvm/Analysis/AssumptionCache.h" +#include "llvm/Analysis/CodeMetrics.h" #include "llvm/Analysis/ConstantFolding.h" #include "llvm/Analysis/InstructionSimplify.h" #include "llvm/Analysis/TargetTransformInfo.h" @@ -49,6 +51,9 @@ class CallAnalyzer : public InstVisitor<CallAnalyzer, bool> { /// The TargetTransformInfo available for this compilation. const TargetTransformInfo &TTI; + /// The cache of @llvm.assume intrinsics. + AssumptionCache &AC; + // The called function. Function &F; @@ -104,7 +109,7 @@ class CallAnalyzer : public InstVisitor<CallAnalyzer, bool> { ConstantInt *stripAndComputeInBoundsConstantOffsets(Value *&V); // Custom analysis routines. - bool analyzeBlock(BasicBlock *BB); + bool analyzeBlock(BasicBlock *BB, SmallPtrSetImpl<const Value *> &EphValues); // Disable several entry points to the visitor so we don't accidentally use // them by declaring but not defining them here. @@ -141,8 +146,8 @@ class CallAnalyzer : public InstVisitor<CallAnalyzer, bool> { public: CallAnalyzer(const DataLayout *DL, const TargetTransformInfo &TTI, - Function &Callee, int Threshold) - : DL(DL), TTI(TTI), F(Callee), Threshold(Threshold), Cost(0), + AssumptionCache &AC, Function &Callee, int Threshold) + : DL(DL), TTI(TTI), AC(AC), F(Callee), Threshold(Threshold), Cost(0), IsCallerRecursive(false), IsRecursiveCall(false), ExposesReturnsTwice(false), HasDynamicAlloca(false), ContainsNoDuplicateCall(false), HasReturn(false), HasIndirectBr(false), @@ -778,7 +783,7 @@ bool CallAnalyzer::visitCallSite(CallSite CS) { // during devirtualization and so we want to give it a hefty bonus for // inlining, but cap that bonus in the event that inlining wouldn't pan // out. Pretend to inline the function, with a custom threshold. - CallAnalyzer CA(DL, TTI, *F, InlineConstants::IndirectCallThreshold); + CallAnalyzer CA(DL, TTI, AC, *F, InlineConstants::IndirectCallThreshold); if (CA.analyzeCall(CS)) { // We were able to inline the indirect call! Subtract the cost from the // bonus we want to apply, but don't go below zero. @@ -881,7 +886,8 @@ bool CallAnalyzer::visitInstruction(Instruction &I) { /// aborts early if the threshold has been exceeded or an impossible to inline /// construct has been detected. It returns false if inlining is no longer /// viable, and true if inlining remains viable. -bool CallAnalyzer::analyzeBlock(BasicBlock *BB) { +bool CallAnalyzer::analyzeBlock(BasicBlock *BB, + SmallPtrSetImpl<const Value *> &EphValues) { for (BasicBlock::iterator I = BB->begin(), E = BB->end(); I != E; ++I) { // FIXME: Currently, the number of instructions in a function regardless of // our ability to simplify them during inline to constants or dead code, @@ -893,6 +899,10 @@ bool CallAnalyzer::analyzeBlock(BasicBlock *BB) { if (isa<DbgInfoIntrinsic>(I)) continue; + // Skip ephemeral values. + if (EphValues.count(I)) + continue; + ++NumInstructions; if (isa<ExtractElementInst>(I) || I->getType()->isVectorTy()) ++NumVectorInstructions; @@ -967,7 +977,7 @@ ConstantInt *CallAnalyzer::stripAndComputeInBoundsConstantOffsets(Value *&V) { break; } assert(V->getType()->isPointerTy() && "Unexpected operand type!"); - } while (Visited.insert(V)); + } while (Visited.insert(V).second); Type *IntPtrTy = DL->getIntPtrType(V->getContext()); return cast<ConstantInt>(ConstantInt::get(IntPtrTy, Offset)); @@ -1096,6 +1106,12 @@ bool CallAnalyzer::analyzeCall(CallSite CS) { NumConstantOffsetPtrArgs = ConstantOffsetPtrs.size(); NumAllocaArgs = SROAArgValues.size(); + // FIXME: If a caller has multiple calls to a callee, we end up recomputing + // the ephemeral values multiple times (and they're completely determined by + // the callee, so this is purely duplicate work). + SmallPtrSet<const Value *, 32> EphValues; + CodeMetrics::collectEphemeralValues(&F, &AC, EphValues); + // The worklist of live basic blocks in the callee *after* inlining. We avoid // adding basic blocks of the callee which can be proven to be dead for this // particular call site in order to get more accurate cost estimates. This @@ -1129,7 +1145,7 @@ bool CallAnalyzer::analyzeCall(CallSite CS) { // Analyze the cost of this block. If we blow through the threshold, this // returns false, and we can bail on out. - if (!analyzeBlock(BB)) { + if (!analyzeBlock(BB, EphValues)) { if (IsRecursiveCall || ExposesReturnsTwice || HasDynamicAlloca || HasIndirectBr) return false; @@ -1217,6 +1233,7 @@ void CallAnalyzer::dump() { INITIALIZE_PASS_BEGIN(InlineCostAnalysis, "inline-cost", "Inline Cost Analysis", true, true) INITIALIZE_AG_DEPENDENCY(TargetTransformInfo) +INITIALIZE_PASS_DEPENDENCY(AssumptionCacheTracker) INITIALIZE_PASS_END(InlineCostAnalysis, "inline-cost", "Inline Cost Analysis", true, true) @@ -1228,12 +1245,14 @@ InlineCostAnalysis::~InlineCostAnalysis() {} void InlineCostAnalysis::getAnalysisUsage(AnalysisUsage &AU) const { AU.setPreservesAll(); + AU.addRequired<AssumptionCacheTracker>(); AU.addRequired<TargetTransformInfo>(); CallGraphSCCPass::getAnalysisUsage(AU); } bool InlineCostAnalysis::runOnSCC(CallGraphSCC &SCC) { TTI = &getAnalysis<TargetTransformInfo>(); + ACT = &getAnalysis<AssumptionCacheTracker>(); return false; } @@ -1290,7 +1309,8 @@ InlineCost InlineCostAnalysis::getInlineCost(CallSite CS, Function *Callee, DEBUG(llvm::dbgs() << " Analyzing call of " << Callee->getName() << "...\n"); - CallAnalyzer CA(Callee->getDataLayout(), *TTI, *Callee, Threshold); + CallAnalyzer CA(Callee->getDataLayout(), *TTI, + ACT->getAssumptionCache(*Callee), *Callee, Threshold); bool ShouldInline = CA.analyzeCall(CS); DEBUG(CA.dump()); |