diff options
Diffstat (limited to 'lib/Analysis')
-rw-r--r-- | lib/Analysis/AliasAnalysisCounter.cpp | 14 | ||||
-rw-r--r-- | lib/Analysis/AliasDebugger.cpp | 10 | ||||
-rw-r--r-- | lib/Analysis/BasicAliasAnalysis.cpp | 20 | ||||
-rw-r--r-- | lib/Analysis/DebugInfo.cpp | 60 | ||||
-rw-r--r-- | lib/Analysis/DomPrinter.cpp | 74 | ||||
-rw-r--r-- | lib/Analysis/IPA/Andersens.cpp | 10 | ||||
-rw-r--r-- | lib/Analysis/IPA/CallGraph.cpp | 12 | ||||
-rw-r--r-- | lib/Analysis/IPA/CallGraphSCCPass.cpp | 57 | ||||
-rw-r--r-- | lib/Analysis/IPA/GlobalsModRef.cpp | 10 | ||||
-rw-r--r-- | lib/Analysis/IPA/Makefile | 2 | ||||
-rw-r--r-- | lib/Analysis/IVUsers.cpp | 19 | ||||
-rw-r--r-- | lib/Analysis/LoopPass.cpp | 45 | ||||
-rw-r--r-- | lib/Analysis/Makefile | 1 | ||||
-rw-r--r-- | lib/Analysis/ProfileEstimatorPass.cpp | 10 | ||||
-rw-r--r-- | lib/Analysis/ProfileInfo.cpp | 14 | ||||
-rw-r--r-- | lib/Analysis/ProfileInfoLoaderPass.cpp | 10 | ||||
-rw-r--r-- | lib/Analysis/ScalarEvolution.cpp | 212 | ||||
-rw-r--r-- | lib/Analysis/ScalarEvolutionAliasAnalysis.cpp | 10 | ||||
-rw-r--r-- | lib/Analysis/ScalarEvolutionExpander.cpp | 238 |
19 files changed, 595 insertions, 233 deletions
diff --git a/lib/Analysis/AliasAnalysisCounter.cpp b/lib/Analysis/AliasAnalysisCounter.cpp index ae28b55..761cd46 100644 --- a/lib/Analysis/AliasAnalysisCounter.cpp +++ b/lib/Analysis/AliasAnalysisCounter.cpp @@ -31,7 +31,6 @@ namespace { class AliasAnalysisCounter : public ModulePass, public AliasAnalysis { unsigned No, May, Must; unsigned NoMR, JustRef, JustMod, MR; - const char *Name; Module *M; public: static char ID; // Class identification, replacement for typeinfo @@ -49,7 +48,7 @@ namespace { unsigned MRSum = NoMR+JustRef+JustMod+MR; if (AASum + MRSum) { // Print a report if any counted queries occurred... errs() << "\n===== Alias Analysis Counter Report =====\n" - << " Analysis counted: " << Name << "\n" + << " Analysis counted:\n" << " " << AASum << " Total Alias Queries Performed\n"; if (AASum) { printLine("no alias", No, AASum); @@ -75,7 +74,6 @@ namespace { bool runOnModule(Module &M) { this->M = &M; InitializeAliasAnalysis(this); - Name = dynamic_cast<Pass*>(&getAnalysis<AliasAnalysis>())->getPassName(); return false; } @@ -85,6 +83,16 @@ namespace { AU.setPreservesAll(); } + /// getAdjustedAnalysisPointer - This method is used when a pass implements + /// an analysis interface through multiple inheritance. If needed, it + /// should override this to adjust the this pointer as needed for the + /// specified pass info. + virtual void *getAdjustedAnalysisPointer(const PassInfo *PI) { + if (PI->isPassID(&AliasAnalysis::ID)) + return (AliasAnalysis*)this; + return this; + } + // FIXME: We could count these too... bool pointsToConstantMemory(const Value *P) { return getAnalysis<AliasAnalysis>().pointsToConstantMemory(P); diff --git a/lib/Analysis/AliasDebugger.cpp b/lib/Analysis/AliasDebugger.cpp index 6868e3f..88c2875 100644 --- a/lib/Analysis/AliasDebugger.cpp +++ b/lib/Analysis/AliasDebugger.cpp @@ -71,6 +71,16 @@ namespace { AU.setPreservesAll(); // Does not transform code } + /// getAdjustedAnalysisPointer - This method is used when a pass implements + /// an analysis interface through multiple inheritance. If needed, it + /// should override this to adjust the this pointer as needed for the + /// specified pass info. + virtual void *getAdjustedAnalysisPointer(const PassInfo *PI) { + if (PI->isPassID(&AliasAnalysis::ID)) + return (AliasAnalysis*)this; + return this; + } + //------------------------------------------------ // Implement the AliasAnalysis API // diff --git a/lib/Analysis/BasicAliasAnalysis.cpp b/lib/Analysis/BasicAliasAnalysis.cpp index b2983c7..36b831c 100644 --- a/lib/Analysis/BasicAliasAnalysis.cpp +++ b/lib/Analysis/BasicAliasAnalysis.cpp @@ -153,6 +153,16 @@ namespace { virtual void deleteValue(Value *V) {} virtual void copyValue(Value *From, Value *To) {} + + /// getAdjustedAnalysisPointer - This method is used when a pass implements + /// an analysis interface through multiple inheritance. If needed, it should + /// override this to adjust the this pointer as needed for the specified pass + /// info. + virtual void *getAdjustedAnalysisPointer(const PassInfo *PI) { + if (PI->isPassID(&AliasAnalysis::ID)) + return (AliasAnalysis*)this; + return this; + } }; } // End of anonymous namespace @@ -192,6 +202,16 @@ namespace { /// global) or not. bool pointsToConstantMemory(const Value *P); + /// getAdjustedAnalysisPointer - This method is used when a pass implements + /// an analysis interface through multiple inheritance. If needed, it should + /// override this to adjust the this pointer as needed for the specified pass + /// info. + virtual void *getAdjustedAnalysisPointer(const PassInfo *PI) { + if (PI->isPassID(&AliasAnalysis::ID)) + return (AliasAnalysis*)this; + return this; + } + private: // VisitedPHIs - Track PHI nodes visited by a aliasCheck() call. SmallPtrSet<const Value*, 16> VisitedPHIs; diff --git a/lib/Analysis/DebugInfo.cpp b/lib/Analysis/DebugInfo.cpp index 59ba807..4ba837a 100644 --- a/lib/Analysis/DebugInfo.cpp +++ b/lib/Analysis/DebugInfo.cpp @@ -599,7 +599,7 @@ void DIVariable::dump() const { //===----------------------------------------------------------------------===// DIFactory::DIFactory(Module &m) - : M(m), VMContext(M.getContext()), DeclareFn(0) {} + : M(m), VMContext(M.getContext()), DeclareFn(0), ValueFn(0) {} Constant *DIFactory::GetTagConstant(unsigned TAG) { assert((TAG & LLVMDebugVersionMask) == 0 && @@ -854,7 +854,7 @@ DISubprogram DIFactory::CreateSubprogram(DIDescriptor Context, StringRef DisplayName, StringRef LinkageName, DICompileUnit CompileUnit, - unsigned LineNo, DIType Type, + unsigned LineNo, DIType Ty, bool isLocalToUnit, bool isDefinition, unsigned VK, unsigned VIndex, @@ -869,7 +869,7 @@ DISubprogram DIFactory::CreateSubprogram(DIDescriptor Context, MDString::get(VMContext, LinkageName), CompileUnit.getNode(), ConstantInt::get(Type::getInt32Ty(VMContext), LineNo), - Type.getNode(), + Ty.getNode(), ConstantInt::get(Type::getInt1Ty(VMContext), isLocalToUnit), ConstantInt::get(Type::getInt1Ty(VMContext), isDefinition), ConstantInt::get(Type::getInt32Ty(VMContext), (unsigned)VK), @@ -911,7 +911,7 @@ DIFactory::CreateGlobalVariable(DIDescriptor Context, StringRef Name, StringRef DisplayName, StringRef LinkageName, DICompileUnit CompileUnit, - unsigned LineNo, DIType Type,bool isLocalToUnit, + unsigned LineNo, DIType Ty,bool isLocalToUnit, bool isDefinition, llvm::GlobalVariable *Val) { Value *Elts[] = { GetTagConstant(dwarf::DW_TAG_variable), @@ -922,7 +922,7 @@ DIFactory::CreateGlobalVariable(DIDescriptor Context, StringRef Name, MDString::get(VMContext, LinkageName), CompileUnit.getNode(), ConstantInt::get(Type::getInt32Ty(VMContext), LineNo), - Type.getNode(), + Ty.getNode(), ConstantInt::get(Type::getInt1Ty(VMContext), isLocalToUnit), ConstantInt::get(Type::getInt1Ty(VMContext), isDefinition), Val @@ -943,14 +943,14 @@ DIFactory::CreateGlobalVariable(DIDescriptor Context, StringRef Name, DIVariable DIFactory::CreateVariable(unsigned Tag, DIDescriptor Context, StringRef Name, DICompileUnit CompileUnit, unsigned LineNo, - DIType Type) { + DIType Ty) { Value *Elts[] = { GetTagConstant(Tag), Context.getNode(), MDString::get(VMContext, Name), CompileUnit.getNode(), ConstantInt::get(Type::getInt32Ty(VMContext), LineNo), - Type.getNode(), + Ty.getNode(), }; return DIVariable(MDNode::get(VMContext, &Elts[0], 6)); } @@ -962,14 +962,15 @@ DIVariable DIFactory::CreateComplexVariable(unsigned Tag, DIDescriptor Context, const std::string &Name, DICompileUnit CompileUnit, unsigned LineNo, - DIType Type, SmallVector<Value *, 9> &addr) { + DIType Ty, + SmallVector<Value *, 9> &addr) { SmallVector<Value *, 9> Elts; Elts.push_back(GetTagConstant(Tag)); Elts.push_back(Context.getNode()); Elts.push_back(MDString::get(VMContext, Name)); Elts.push_back(CompileUnit.getNode()); Elts.push_back(ConstantInt::get(Type::getInt32Ty(VMContext), LineNo)); - Elts.push_back(Type.getNode()); + Elts.push_back(Ty.getNode()); Elts.insert(Elts.end(), addr.begin(), addr.end()); return DIVariable(MDNode::get(VMContext, &Elts[0], 6+addr.size())); @@ -1035,8 +1036,8 @@ Instruction *DIFactory::InsertDeclare(Value *Storage, DIVariable D, if (!DeclareFn) DeclareFn = Intrinsic::getDeclaration(&M, Intrinsic::dbg_declare); - Value *Elts[] = { Storage }; - Value *Args[] = { MDNode::get(Storage->getContext(), Elts, 1), D.getNode() }; + Value *Args[] = { MDNode::get(Storage->getContext(), &Storage, 1), + D.getNode() }; return CallInst::Create(DeclareFn, Args, Args+2, "", InsertBefore); } @@ -1046,8 +1047,8 @@ Instruction *DIFactory::InsertDeclare(Value *Storage, DIVariable D, if (!DeclareFn) DeclareFn = Intrinsic::getDeclaration(&M, Intrinsic::dbg_declare); - Value *Elts[] = { Storage }; - Value *Args[] = { MDNode::get(Storage->getContext(), Elts, 1), D.getNode() }; + Value *Args[] = { MDNode::get(Storage->getContext(), &Storage, 1), + D.getNode() }; return CallInst::Create(DeclareFn, Args, Args+2, "", InsertAtEnd); } @@ -1059,8 +1060,7 @@ Instruction *DIFactory::InsertDbgValueIntrinsic(Value *V, uint64_t Offset, if (!ValueFn) ValueFn = Intrinsic::getDeclaration(&M, Intrinsic::dbg_value); - Value *Elts[] = { V }; - Value *Args[] = { MDNode::get(V->getContext(), Elts, 1), + Value *Args[] = { MDNode::get(V->getContext(), &V, 1), ConstantInt::get(Type::getInt64Ty(V->getContext()), Offset), D.getNode() }; return CallInst::Create(ValueFn, Args, Args+3, "", InsertBefore); @@ -1074,8 +1074,7 @@ Instruction *DIFactory::InsertDbgValueIntrinsic(Value *V, uint64_t Offset, if (!ValueFn) ValueFn = Intrinsic::getDeclaration(&M, Intrinsic::dbg_value); - Value *Elts[] = { V }; - Value *Args[] = { MDNode::get(V->getContext(), Elts, 1), + Value *Args[] = { MDNode::get(V->getContext(), &V, 1), ConstantInt::get(Type::getInt64Ty(V->getContext()), Offset), D.getNode() }; return CallInst::Create(ValueFn, Args, Args+3, "", InsertAtEnd); @@ -1139,9 +1138,9 @@ void DebugInfoFinder::processType(DIType DT) { if (!DA.isNull()) for (unsigned i = 0, e = DA.getNumElements(); i != e; ++i) { DIDescriptor D = DA.getElement(i); - DIType TypeE = DIType(D.getNode()); - if (!TypeE.isNull()) - processType(TypeE); + DIType TyE = DIType(D.getNode()); + if (!TyE.isNull()) + processType(TyE); else processSubprogram(DISubprogram(D.getNode())); } @@ -1234,7 +1233,8 @@ bool DebugInfoFinder::addSubprogram(DISubprogram SP) { return true; } -Value *llvm::findDbgGlobalDeclare(GlobalVariable *V) { +/// Find the debug info descriptor corresponding to this global variable. +static Value *findDbgGlobalDeclare(GlobalVariable *V) { const Module *M = V->getParent(); NamedMDNode *NMD = M->getNamedMetadata("llvm.dbg.gv"); if (!NMD) @@ -1252,7 +1252,7 @@ Value *llvm::findDbgGlobalDeclare(GlobalVariable *V) { /// Finds the llvm.dbg.declare intrinsic corresponding to this value if any. /// It looks through pointer casts too. -const DbgDeclareInst *llvm::findDbgDeclare(const Value *V) { +static const DbgDeclareInst *findDbgDeclare(const Value *V) { V = V->stripPointerCasts(); if (!isa<Instruction>(V) && !isa<Argument>(V)) @@ -1320,23 +1320,15 @@ bool llvm::getLocationInfo(const Value *V, std::string &DisplayName, /// from DILocation. DebugLoc llvm::ExtractDebugLocation(DILocation &Loc, DebugLocTracker &DebugLocInfo) { - DebugLoc DL; - MDNode *Context = Loc.getScope().getNode(); - MDNode *InlinedLoc = NULL; - if (!Loc.getOrigLocation().isNull()) - InlinedLoc = Loc.getOrigLocation().getNode(); - // If this location is already tracked then use it. - DebugLocTuple Tuple(Context, InlinedLoc, Loc.getLineNumber(), - Loc.getColumnNumber()); - DenseMap<DebugLocTuple, unsigned>::iterator II - = DebugLocInfo.DebugIdMap.find(Tuple); + DenseMap<MDNode *, unsigned>::iterator II + = DebugLocInfo.DebugIdMap.find(Loc.getNode()); if (II != DebugLocInfo.DebugIdMap.end()) return DebugLoc::get(II->second); // Add a new location entry. unsigned Id = DebugLocInfo.DebugLocations.size(); - DebugLocInfo.DebugLocations.push_back(Tuple); - DebugLocInfo.DebugIdMap[Tuple] = Id; + DebugLocInfo.DebugLocations.push_back(Loc.getNode()); + DebugLocInfo.DebugIdMap[Loc.getNode()] = Id; return DebugLoc::get(Id); } diff --git a/lib/Analysis/DomPrinter.cpp b/lib/Analysis/DomPrinter.cpp index 32b8994..3af687a 100644 --- a/lib/Analysis/DomPrinter.cpp +++ b/lib/Analysis/DomPrinter.cpp @@ -19,10 +19,9 @@ //===----------------------------------------------------------------------===// #include "llvm/Analysis/DomPrinter.h" -#include "llvm/Pass.h" -#include "llvm/Function.h" -#include "llvm/Analysis/CFGPrinter.h" + #include "llvm/Analysis/Dominators.h" +#include "llvm/Analysis/DOTGraphTraitsPass.h" #include "llvm/Analysis/PostDominators.h" using namespace llvm; @@ -110,29 +109,29 @@ struct GenericGraphViewer : public FunctionPass { }; struct DomViewer - : public GenericGraphViewer<DominatorTree, false> { + : public DOTGraphTraitsViewer<DominatorTree, false> { static char ID; - DomViewer() : GenericGraphViewer<DominatorTree, false>("dom", &ID){} + DomViewer() : DOTGraphTraitsViewer<DominatorTree, false>("dom", &ID){} }; struct DomOnlyViewer - : public GenericGraphViewer<DominatorTree, true> { + : public DOTGraphTraitsViewer<DominatorTree, true> { static char ID; - DomOnlyViewer() : GenericGraphViewer<DominatorTree, true>("domonly", &ID){} + DomOnlyViewer() : DOTGraphTraitsViewer<DominatorTree, true>("domonly", &ID){} }; struct PostDomViewer - : public GenericGraphViewer<PostDominatorTree, false> { + : public DOTGraphTraitsViewer<PostDominatorTree, false> { static char ID; PostDomViewer() : - GenericGraphViewer<PostDominatorTree, false>("postdom", &ID){} + DOTGraphTraitsViewer<PostDominatorTree, false>("postdom", &ID){} }; struct PostDomOnlyViewer - : public GenericGraphViewer<PostDominatorTree, true> { + : public DOTGraphTraitsViewer<PostDominatorTree, true> { static char ID; PostDomOnlyViewer() : - GenericGraphViewer<PostDominatorTree, true>("postdomonly", &ID){} + DOTGraphTraitsViewer<PostDominatorTree, true>("postdomonly", &ID){} }; } // end anonymous namespace @@ -155,67 +154,30 @@ RegisterPass<PostDomOnlyViewer> D("view-postdom-only", "(with no function bodies)"); namespace { -template <class Analysis, bool OnlyBBS> -struct GenericGraphPrinter : public FunctionPass { - - std::string Name; - - GenericGraphPrinter(std::string GraphName, const void *ID) - : FunctionPass(ID) { - Name = GraphName; - } - - virtual bool runOnFunction(Function &F) { - Analysis *Graph; - std::string Filename = Name + "." + F.getNameStr() + ".dot"; - errs() << "Writing '" << Filename << "'..."; - - std::string ErrorInfo; - raw_fd_ostream File(Filename.c_str(), ErrorInfo); - Graph = &getAnalysis<Analysis>(); - - std::string Title, GraphName; - GraphName = DOTGraphTraits<Analysis*>::getGraphName(Graph); - Title = GraphName + " for '" + F.getNameStr() + "' function"; - - if (ErrorInfo.empty()) - WriteGraph(File, Graph, OnlyBBS, Name, Title); - else - errs() << " error opening file for writing!"; - errs() << "\n"; - return false; - } - - virtual void getAnalysisUsage(AnalysisUsage &AU) const { - AU.setPreservesAll(); - AU.addRequired<Analysis>(); - } -}; - struct DomPrinter - : public GenericGraphPrinter<DominatorTree, false> { + : public DOTGraphTraitsPrinter<DominatorTree, false> { static char ID; - DomPrinter() : GenericGraphPrinter<DominatorTree, false>("dom", &ID) {} + DomPrinter() : DOTGraphTraitsPrinter<DominatorTree, false>("dom", &ID) {} }; struct DomOnlyPrinter - : public GenericGraphPrinter<DominatorTree, true> { + : public DOTGraphTraitsPrinter<DominatorTree, true> { static char ID; - DomOnlyPrinter() : GenericGraphPrinter<DominatorTree, true>("domonly", &ID) {} + DomOnlyPrinter() : DOTGraphTraitsPrinter<DominatorTree, true>("domonly", &ID) {} }; struct PostDomPrinter - : public GenericGraphPrinter<PostDominatorTree, false> { + : public DOTGraphTraitsPrinter<PostDominatorTree, false> { static char ID; PostDomPrinter() : - GenericGraphPrinter<PostDominatorTree, false>("postdom", &ID) {} + DOTGraphTraitsPrinter<PostDominatorTree, false>("postdom", &ID) {} }; struct PostDomOnlyPrinter - : public GenericGraphPrinter<PostDominatorTree, true> { + : public DOTGraphTraitsPrinter<PostDominatorTree, true> { static char ID; PostDomOnlyPrinter() : - GenericGraphPrinter<PostDominatorTree, true>("postdomonly", &ID) {} + DOTGraphTraitsPrinter<PostDominatorTree, true>("postdomonly", &ID) {} }; } // end anonymous namespace diff --git a/lib/Analysis/IPA/Andersens.cpp b/lib/Analysis/IPA/Andersens.cpp index 28c66af..4180206 100644 --- a/lib/Analysis/IPA/Andersens.cpp +++ b/lib/Analysis/IPA/Andersens.cpp @@ -475,6 +475,16 @@ namespace { AU.setPreservesAll(); // Does not transform code } + /// getAdjustedAnalysisPointer - This method is used when a pass implements + /// an analysis interface through multiple inheritance. If needed, it + /// should override this to adjust the this pointer as needed for the + /// specified pass info. + virtual void *getAdjustedAnalysisPointer(const PassInfo *PI) { + if (PI->isPassID(&AliasAnalysis::ID)) + return (AliasAnalysis*)this; + return this; + } + //------------------------------------------------ // Implement the AliasAnalysis API // diff --git a/lib/Analysis/IPA/CallGraph.cpp b/lib/Analysis/IPA/CallGraph.cpp index a826177..8c43aa1 100644 --- a/lib/Analysis/IPA/CallGraph.cpp +++ b/lib/Analysis/IPA/CallGraph.cpp @@ -26,7 +26,7 @@ namespace { //===----------------------------------------------------------------------===// // BasicCallGraph class definition // -class BasicCallGraph : public CallGraph, public ModulePass { +class BasicCallGraph : public ModulePass, public CallGraph { // Root is root of the call graph, or the external node if a 'main' function // couldn't be found. // @@ -82,6 +82,16 @@ public: destroy(); } + /// getAdjustedAnalysisPointer - This method is used when a pass implements + /// an analysis interface through multiple inheritance. If needed, it should + /// override this to adjust the this pointer as needed for the specified pass + /// info. + virtual void *getAdjustedAnalysisPointer(const PassInfo *PI) { + if (PI->isPassID(&CallGraph::ID)) + return (CallGraph*)this; + return this; + } + CallGraphNode* getExternalCallingNode() const { return ExternalCallingNode; } CallGraphNode* getCallsExternalNode() const { return CallsExternalNode; } diff --git a/lib/Analysis/IPA/CallGraphSCCPass.cpp b/lib/Analysis/IPA/CallGraphSCCPass.cpp index 5504b9b..0e333d1 100644 --- a/lib/Analysis/IPA/CallGraphSCCPass.cpp +++ b/lib/Analysis/IPA/CallGraphSCCPass.cpp @@ -57,6 +57,9 @@ public: return "CallGraph Pass Manager"; } + virtual PMDataManager *getAsPMDataManager() { return this; } + virtual Pass *getAsPass() { return this; } + // Print passes managed by this manager void dumpPassStructure(unsigned Offset) { errs().indent(Offset*2) << "Call Graph SCC Pass Manager\n"; @@ -90,7 +93,10 @@ char CGPassManager::ID = 0; bool CGPassManager::RunPassOnSCC(Pass *P, std::vector<CallGraphNode*> &CurSCC, CallGraph &CG, bool &CallGraphUpToDate) { bool Changed = false; - if (CallGraphSCCPass *CGSP = dynamic_cast<CallGraphSCCPass*>(P)) { + PMDataManager *PM = P->getAsPMDataManager(); + + if (PM == 0) { + CallGraphSCCPass *CGSP = (CallGraphSCCPass*)P; if (!CallGraphUpToDate) { RefreshCallGraph(CurSCC, CG, false); CallGraphUpToDate = true; @@ -110,8 +116,10 @@ bool CGPassManager::RunPassOnSCC(Pass *P, std::vector<CallGraphNode*> &CurSCC, return Changed; } - FPPassManager *FPP = dynamic_cast<FPPassManager *>(P); - assert(FPP && "Invalid CGPassManager member"); + + assert(PM->getPassManagerType() == PMT_FunctionPassManager && + "Invalid CGPassManager member"); + FPPassManager *FPP = (FPPassManager*)P; // Run pass P on all functions in the current SCC. for (unsigned i = 0, e = CurSCC.size(); i != e; ++i) { @@ -360,14 +368,13 @@ bool CGPassManager::runOnModule(Module &M) { /// Initialize CG bool CGPassManager::doInitialization(CallGraph &CG) { bool Changed = false; - for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index) { - Pass *P = getContainedPass(Index); - if (CallGraphSCCPass *CGSP = dynamic_cast<CallGraphSCCPass *>(P)) { - Changed |= CGSP->doInitialization(CG); + for (unsigned i = 0, e = getNumContainedPasses(); i != e; ++i) { + if (PMDataManager *PM = getContainedPass(i)->getAsPMDataManager()) { + assert(PM->getPassManagerType() == PMT_FunctionPassManager && + "Invalid CGPassManager member"); + Changed |= ((FPPassManager*)PM)->doInitialization(CG.getModule()); } else { - FPPassManager *FP = dynamic_cast<FPPassManager *>(P); - assert (FP && "Invalid CGPassManager member"); - Changed |= FP->doInitialization(CG.getModule()); + Changed |= ((CallGraphSCCPass*)getContainedPass(i))->doInitialization(CG); } } return Changed; @@ -376,14 +383,13 @@ bool CGPassManager::doInitialization(CallGraph &CG) { /// Finalize CG bool CGPassManager::doFinalization(CallGraph &CG) { bool Changed = false; - for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index) { - Pass *P = getContainedPass(Index); - if (CallGraphSCCPass *CGSP = dynamic_cast<CallGraphSCCPass *>(P)) { - Changed |= CGSP->doFinalization(CG); + for (unsigned i = 0, e = getNumContainedPasses(); i != e; ++i) { + if (PMDataManager *PM = getContainedPass(i)->getAsPMDataManager()) { + assert(PM->getPassManagerType() == PMT_FunctionPassManager && + "Invalid CGPassManager member"); + Changed |= ((FPPassManager*)PM)->doFinalization(CG.getModule()); } else { - FPPassManager *FP = dynamic_cast<FPPassManager *>(P); - assert (FP && "Invalid CGPassManager member"); - Changed |= FP->doFinalization(CG.getModule()); + Changed |= ((CallGraphSCCPass*)getContainedPass(i))->doFinalization(CG); } } return Changed; @@ -397,13 +403,14 @@ void CallGraphSCCPass::assignPassManager(PMStack &PMS, PMS.top()->getPassManagerType() > PMT_CallGraphPassManager) PMS.pop(); - assert (!PMS.empty() && "Unable to handle Call Graph Pass"); - CGPassManager *CGP = dynamic_cast<CGPassManager *>(PMS.top()); - - // Create new Call Graph SCC Pass Manager if it does not exist. - if (!CGP) { - - assert (!PMS.empty() && "Unable to create Call Graph Pass Manager"); + assert(!PMS.empty() && "Unable to handle Call Graph Pass"); + CGPassManager *CGP; + + if (PMS.top()->getPassManagerType() == PMT_CallGraphPassManager) + CGP = (CGPassManager*)PMS.top(); + else { + // Create new Call Graph SCC Pass Manager if it does not exist. + assert(!PMS.empty() && "Unable to create Call Graph Pass Manager"); PMDataManager *PMD = PMS.top(); // [1] Create new Call Graph Pass Manager @@ -415,7 +422,7 @@ void CallGraphSCCPass::assignPassManager(PMStack &PMS, // [3] Assign manager to manage this new manager. This may create // and push new managers into PMS - Pass *P = dynamic_cast<Pass *>(CGP); + Pass *P = CGP; TPM->schedulePass(P); // [4] Push new manager into PMS diff --git a/lib/Analysis/IPA/GlobalsModRef.cpp b/lib/Analysis/IPA/GlobalsModRef.cpp index a979a99..e803a48 100644 --- a/lib/Analysis/IPA/GlobalsModRef.cpp +++ b/lib/Analysis/IPA/GlobalsModRef.cpp @@ -145,6 +145,16 @@ namespace { virtual void deleteValue(Value *V); virtual void copyValue(Value *From, Value *To); + /// getAdjustedAnalysisPointer - This method is used when a pass implements + /// an analysis interface through multiple inheritance. If needed, it + /// should override this to adjust the this pointer as needed for the + /// specified pass info. + virtual void *getAdjustedAnalysisPointer(const PassInfo *PI) { + if (PI->isPassID(&AliasAnalysis::ID)) + return (AliasAnalysis*)this; + return this; + } + private: /// getFunctionInfo - Return the function info for the function, or null if /// we don't have anything useful to say about it. diff --git a/lib/Analysis/IPA/Makefile b/lib/Analysis/IPA/Makefile index adacb16..da719ba 100644 --- a/lib/Analysis/IPA/Makefile +++ b/lib/Analysis/IPA/Makefile @@ -10,5 +10,7 @@ LEVEL = ../../.. LIBRARYNAME = LLVMipa BUILD_ARCHIVE = 1 +CXXFLAGS = -fno-rtti + include $(LEVEL)/Makefile.common diff --git a/lib/Analysis/IVUsers.cpp b/lib/Analysis/IVUsers.cpp index 26c0c9e..38611cc 100644 --- a/lib/Analysis/IVUsers.cpp +++ b/lib/Analysis/IVUsers.cpp @@ -324,12 +324,19 @@ const SCEV *IVUsers::getReplacementExpr(const IVStrideUse &U) const { // the actual replacement value. if (U.isUseOfPostIncrementedValue()) RetVal = SE->getAddExpr(RetVal, U.getParent()->Stride); - // Evaluate the expression out of the loop, if possible. - if (!L->contains(U.getUser())) { - const SCEV *ExitVal = SE->getSCEVAtScope(RetVal, L->getParentLoop()); - if (ExitVal->isLoopInvariant(L)) - RetVal = ExitVal; - } + return RetVal; +} + +/// getCanonicalExpr - Return a SCEV expression which computes the +/// value of the SCEV of the given IVStrideUse, ignoring the +/// isUseOfPostIncrementedValue flag. +const SCEV *IVUsers::getCanonicalExpr(const IVStrideUse &U) const { + // Start with zero. + const SCEV *RetVal = SE->getIntegerSCEV(0, U.getParent()->Stride->getType()); + // Create the basic add recurrence. + RetVal = SE->getAddRecExpr(RetVal, U.getParent()->Stride, L); + // Add the offset in a separate step, because it may be loop-variant. + RetVal = SE->getAddExpr(RetVal, U.getOffset()); return RetVal; } diff --git a/lib/Analysis/LoopPass.cpp b/lib/Analysis/LoopPass.cpp index 43463cd..2d613f6 100644 --- a/lib/Analysis/LoopPass.cpp +++ b/lib/Analysis/LoopPass.cpp @@ -147,8 +147,7 @@ void LPPassManager::redoLoop(Loop *L) { void LPPassManager::cloneBasicBlockSimpleAnalysis(BasicBlock *From, BasicBlock *To, Loop *L) { for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index) { - Pass *P = getContainedPass(Index); - LoopPass *LP = dynamic_cast<LoopPass *>(P); + LoopPass *LP = (LoopPass *)getContainedPass(Index); LP->cloneBasicBlockAnalysis(From, To, L); } } @@ -163,8 +162,7 @@ void LPPassManager::deleteSimpleAnalysisValue(Value *V, Loop *L) { } } for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index) { - Pass *P = getContainedPass(Index); - LoopPass *LP = dynamic_cast<LoopPass *>(P); + LoopPass *LP = (LoopPass *)getContainedPass(Index); LP->deleteAnalysisValue(V, L); } } @@ -206,10 +204,8 @@ bool LPPassManager::runOnFunction(Function &F) { I != E; ++I) { Loop *L = *I; for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index) { - Pass *P = getContainedPass(Index); - LoopPass *LP = dynamic_cast<LoopPass *>(P); - if (LP) - Changed |= LP->doInitialization(L, *this); + LoopPass *P = (LoopPass*)getContainedPass(Index); + Changed |= P->doInitialization(L, *this); } } @@ -222,7 +218,7 @@ bool LPPassManager::runOnFunction(Function &F) { // Run all passes on the current Loop. for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index) { - Pass *P = getContainedPass(Index); + LoopPass *P = (LoopPass*)getContainedPass(Index); dumpPassInfo(P, EXECUTION_MSG, ON_LOOP_MSG, CurrentLoop->getHeader()->getNameStr()); @@ -230,12 +226,10 @@ bool LPPassManager::runOnFunction(Function &F) { initializeAnalysisImpl(P); - LoopPass *LP = dynamic_cast<LoopPass *>(P); - assert(LP && "Invalid LPPassManager member"); { - PassManagerPrettyStackEntry X(LP, *CurrentLoop->getHeader()); + PassManagerPrettyStackEntry X(P, *CurrentLoop->getHeader()); Timer *T = StartPassTimer(P); - Changed |= LP->runOnLoop(CurrentLoop, *this); + Changed |= P->runOnLoop(CurrentLoop, *this); StopPassTimer(P, T); } @@ -256,7 +250,7 @@ bool LPPassManager::runOnFunction(Function &F) { StopPassTimer(LI, T); // Then call the regular verifyAnalysis functions. - verifyPreservedAnalysis(LP); + verifyPreservedAnalysis(P); } removeNotPreservedAnalysis(P); @@ -289,10 +283,8 @@ bool LPPassManager::runOnFunction(Function &F) { // Finalization for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index) { - Pass *P = getContainedPass(Index); - LoopPass *LP = dynamic_cast <LoopPass *>(P); - if (LP) - Changed |= LP->doFinalization(); + LoopPass *P = (LoopPass *)getContainedPass(Index); + Changed |= P->doFinalization(); } return Changed; @@ -325,12 +317,11 @@ void LoopPass::preparePassManager(PMStack &PMS) { PMS.top()->getPassManagerType() > PMT_LoopPassManager) PMS.pop(); - LPPassManager *LPPM = dynamic_cast<LPPassManager *>(PMS.top()); - // If this pass is destroying high level information that is used // by other passes that are managed by LPM then do not insert // this pass in current LPM. Use new LPPassManager. - if (LPPM && !LPPM->preserveHigherLevelAnalysis(this)) + if (PMS.top()->getPassManagerType() == PMT_LoopPassManager && + !PMS.top()->preserveHigherLevelAnalysis(this)) PMS.pop(); } @@ -342,11 +333,11 @@ void LoopPass::assignPassManager(PMStack &PMS, PMS.top()->getPassManagerType() > PMT_LoopPassManager) PMS.pop(); - LPPassManager *LPPM = dynamic_cast<LPPassManager *>(PMS.top()); - - // Create new Loop Pass Manager if it does not exist. - if (!LPPM) { - + LPPassManager *LPPM; + if (PMS.top()->getPassManagerType() == PMT_LoopPassManager) + LPPM = (LPPassManager*)PMS.top(); + else { + // Create new Loop Pass Manager if it does not exist. assert (!PMS.empty() && "Unable to create Loop Pass Manager"); PMDataManager *PMD = PMS.top(); @@ -360,7 +351,7 @@ void LoopPass::assignPassManager(PMStack &PMS, // [3] Assign manager to manage this new manager. This may create // and push new managers into PMS - Pass *P = dynamic_cast<Pass *>(LPPM); + Pass *P = LPPM->getAsPass(); TPM->schedulePass(P); // [4] Push new manager into PMS diff --git a/lib/Analysis/Makefile b/lib/Analysis/Makefile index 4af6d35..f61b8aa 100644 --- a/lib/Analysis/Makefile +++ b/lib/Analysis/Makefile @@ -11,6 +11,7 @@ LEVEL = ../.. LIBRARYNAME = LLVMAnalysis DIRS = IPA BUILD_ARCHIVE = 1 +CXXFLAGS = -fno-rtti include $(LEVEL)/Makefile.common diff --git a/lib/Analysis/ProfileEstimatorPass.cpp b/lib/Analysis/ProfileEstimatorPass.cpp index cf9311a..bce6b31 100644 --- a/lib/Analysis/ProfileEstimatorPass.cpp +++ b/lib/Analysis/ProfileEstimatorPass.cpp @@ -55,6 +55,16 @@ namespace { /// run - Estimate the profile information from the specified file. virtual bool runOnFunction(Function &F); + /// getAdjustedAnalysisPointer - This method is used when a pass implements + /// an analysis interface through multiple inheritance. If needed, it + /// should override this to adjust the this pointer as needed for the + /// specified pass info. + virtual void *getAdjustedAnalysisPointer(const PassInfo *PI) { + if (PI->isPassID(&ProfileInfo::ID)) + return (ProfileInfo*)this; + return this; + } + virtual void recurseBasicBlock(BasicBlock *BB); void inline printEdgeWeight(Edge); diff --git a/lib/Analysis/ProfileInfo.cpp b/lib/Analysis/ProfileInfo.cpp index afd86b1..85531be 100644 --- a/lib/Analysis/ProfileInfo.cpp +++ b/lib/Analysis/ProfileInfo.cpp @@ -1079,6 +1079,20 @@ namespace { struct NoProfileInfo : public ImmutablePass, public ProfileInfo { static char ID; // Class identification, replacement for typeinfo NoProfileInfo() : ImmutablePass(&ID) {} + + /// getAdjustedAnalysisPointer - This method is used when a pass implements + /// an analysis interface through multiple inheritance. If needed, it + /// should override this to adjust the this pointer as needed for the + /// specified pass info. + virtual void *getAdjustedAnalysisPointer(const PassInfo *PI) { + if (PI->isPassID(&ProfileInfo::ID)) + return (ProfileInfo*)this; + return this; + } + + virtual const char *getPassName() const { + return "NoProfileInfo"; + } }; } // End of anonymous namespace diff --git a/lib/Analysis/ProfileInfoLoaderPass.cpp b/lib/Analysis/ProfileInfoLoaderPass.cpp index d8c511f..ac9ed52 100644 --- a/lib/Analysis/ProfileInfoLoaderPass.cpp +++ b/lib/Analysis/ProfileInfoLoaderPass.cpp @@ -63,6 +63,16 @@ namespace { virtual void readEdgeOrRemember(Edge, Edge&, unsigned &, double &); virtual void readEdge(ProfileInfo::Edge, std::vector<unsigned>&); + /// getAdjustedAnalysisPointer - This method is used when a pass implements + /// an analysis interface through multiple inheritance. If needed, it + /// should override this to adjust the this pointer as needed for the + /// specified pass info. + virtual void *getAdjustedAnalysisPointer(const PassInfo *PI) { + if (PI->isPassID(&ProfileInfo::ID)) + return (ProfileInfo*)this; + return this; + } + /// run - Load the profile information from the specified file. virtual bool runOnModule(Module &M); }; diff --git a/lib/Analysis/ScalarEvolution.cpp b/lib/Analysis/ScalarEvolution.cpp index 4d85ce4..2f44913 100644 --- a/lib/Analysis/ScalarEvolution.cpp +++ b/lib/Analysis/ScalarEvolution.cpp @@ -1089,6 +1089,15 @@ const SCEV *ScalarEvolution::getAnyExtendExpr(const SCEV *Op, if (!isa<SCEVSignExtendExpr>(SExt)) return SExt; + // Force the cast to be folded into the operands of an addrec. + if (const SCEVAddRecExpr *AR = dyn_cast<SCEVAddRecExpr>(Op)) { + SmallVector<const SCEV *, 4> Ops; + for (SCEVAddRecExpr::op_iterator I = AR->op_begin(), E = AR->op_end(); + I != E; ++I) + Ops.push_back(getAnyExtendExpr(*I, Ty)); + return getAddRecExpr(Ops, AR->getLoop()); + } + // If the expression is obviously signed, use the sext cast value. if (isa<SCEVSMaxExpr>(Op)) return SExt; @@ -1204,6 +1213,17 @@ const SCEV *ScalarEvolution::getAddExpr(SmallVectorImpl<const SCEV *> &Ops, "SCEVAddExpr operand types don't match!"); #endif + // If HasNSW is true and all the operands are non-negative, infer HasNUW. + if (!HasNUW && HasNSW) { + bool All = true; + for (unsigned i = 0, e = Ops.size(); i != e; ++i) + if (!isKnownNonNegative(Ops[i])) { + All = false; + break; + } + if (All) HasNUW = true; + } + // Sort by complexity, this groups all similar expression types together. GroupByComplexity(Ops, LI); @@ -1521,21 +1541,24 @@ const SCEV *ScalarEvolution::getAddExpr(SmallVectorImpl<const SCEV *> &Ops, for (unsigned i = 0, e = Ops.size(); i != e; ++i) ID.AddPointer(Ops[i]); void *IP = 0; - if (const SCEV *S = UniqueSCEVs.FindNodeOrInsertPos(ID, IP)) return S; - SCEVAddExpr *S = SCEVAllocator.Allocate<SCEVAddExpr>(); - new (S) SCEVAddExpr(ID, Ops); - UniqueSCEVs.InsertNode(S, IP); + SCEVAddExpr *S = + static_cast<SCEVAddExpr *>(UniqueSCEVs.FindNodeOrInsertPos(ID, IP)); + if (!S) { + S = SCEVAllocator.Allocate<SCEVAddExpr>(); + new (S) SCEVAddExpr(ID, Ops); + UniqueSCEVs.InsertNode(S, IP); + } if (HasNUW) S->setHasNoUnsignedWrap(true); if (HasNSW) S->setHasNoSignedWrap(true); return S; } - /// getMulExpr - Get a canonical multiply expression, or something simpler if /// possible. const SCEV *ScalarEvolution::getMulExpr(SmallVectorImpl<const SCEV *> &Ops, bool HasNUW, bool HasNSW) { assert(!Ops.empty() && "Cannot get empty mul!"); + if (Ops.size() == 1) return Ops[0]; #ifndef NDEBUG for (unsigned i = 1, e = Ops.size(); i != e; ++i) assert(getEffectiveSCEVType(Ops[i]->getType()) == @@ -1543,6 +1566,17 @@ const SCEV *ScalarEvolution::getMulExpr(SmallVectorImpl<const SCEV *> &Ops, "SCEVMulExpr operand types don't match!"); #endif + // If HasNSW is true and all the operands are non-negative, infer HasNUW. + if (!HasNUW && HasNSW) { + bool All = true; + for (unsigned i = 0, e = Ops.size(); i != e; ++i) + if (!isKnownNonNegative(Ops[i])) { + All = false; + break; + } + if (All) HasNUW = true; + } + // Sort by complexity, this groups all similar expression types together. GroupByComplexity(Ops, LI); @@ -1558,7 +1592,6 @@ const SCEV *ScalarEvolution::getMulExpr(SmallVectorImpl<const SCEV *> &Ops, return getAddExpr(getMulExpr(LHSC, Add->getOperand(0)), getMulExpr(LHSC, Add->getOperand(1))); - ++Idx; while (const SCEVConstant *RHSC = dyn_cast<SCEVConstant>(Ops[Idx])) { // We found two constants, fold them together! @@ -1578,6 +1611,22 @@ const SCEV *ScalarEvolution::getMulExpr(SmallVectorImpl<const SCEV *> &Ops, } else if (cast<SCEVConstant>(Ops[0])->getValue()->isZero()) { // If we have a multiply of zero, it will always be zero. return Ops[0]; + } else if (Ops[0]->isAllOnesValue()) { + // If we have a mul by -1 of an add, try distributing the -1 among the + // add operands. + if (Ops.size() == 2) + if (const SCEVAddExpr *Add = dyn_cast<SCEVAddExpr>(Ops[1])) { + SmallVector<const SCEV *, 4> NewOps; + bool AnyFolded = false; + for (SCEVAddRecExpr::op_iterator I = Add->op_begin(), E = Add->op_end(); + I != E; ++I) { + const SCEV *Mul = getMulExpr(Ops[0], *I); + if (!isa<SCEVMulExpr>(Mul)) AnyFolded = true; + NewOps.push_back(Mul); + } + if (AnyFolded) + return getAddExpr(NewOps); + } } } @@ -1644,7 +1693,9 @@ const SCEV *ScalarEvolution::getMulExpr(SmallVectorImpl<const SCEV *> &Ops, // It's tempting to propagate the NSW flag here, but nsw multiplication // is not associative so this isn't necessarily safe. - const SCEV *NewRec = getAddRecExpr(NewOps, AddRec->getLoop()); + const SCEV *NewRec = getAddRecExpr(NewOps, AddRec->getLoop(), + HasNUW && AddRec->hasNoUnsignedWrap(), + /*HasNSW=*/false); // If all of the other operands were loop invariant, we are done. if (Ops.size() == 1) return NewRec; @@ -1698,10 +1749,13 @@ const SCEV *ScalarEvolution::getMulExpr(SmallVectorImpl<const SCEV *> &Ops, for (unsigned i = 0, e = Ops.size(); i != e; ++i) ID.AddPointer(Ops[i]); void *IP = 0; - if (const SCEV *S = UniqueSCEVs.FindNodeOrInsertPos(ID, IP)) return S; - SCEVMulExpr *S = SCEVAllocator.Allocate<SCEVMulExpr>(); - new (S) SCEVMulExpr(ID, Ops); - UniqueSCEVs.InsertNode(S, IP); + SCEVMulExpr *S = + static_cast<SCEVMulExpr *>(UniqueSCEVs.FindNodeOrInsertPos(ID, IP)); + if (!S) { + S = SCEVAllocator.Allocate<SCEVMulExpr>(); + new (S) SCEVMulExpr(ID, Ops); + UniqueSCEVs.InsertNode(S, IP); + } if (HasNUW) S->setHasNoUnsignedWrap(true); if (HasNSW) S->setHasNoSignedWrap(true); return S; @@ -1844,10 +1898,24 @@ ScalarEvolution::getAddRecExpr(SmallVectorImpl<const SCEV *> &Operands, return getAddRecExpr(Operands, L, HasNUW, HasNSW); // {X,+,0} --> X } + // If HasNSW is true and all the operands are non-negative, infer HasNUW. + if (!HasNUW && HasNSW) { + bool All = true; + for (unsigned i = 0, e = Operands.size(); i != e; ++i) + if (!isKnownNonNegative(Operands[i])) { + All = false; + break; + } + if (All) HasNUW = true; + } + // Canonicalize nested AddRecs in by nesting them in order of loop depth. if (const SCEVAddRecExpr *NestedAR = dyn_cast<SCEVAddRecExpr>(Operands[0])) { const Loop *NestedLoop = NestedAR->getLoop(); - if (L->getLoopDepth() < NestedLoop->getLoopDepth()) { + if (L->contains(NestedLoop->getHeader()) ? + (L->getLoopDepth() < NestedLoop->getLoopDepth()) : + (!NestedLoop->contains(L->getHeader()) && + DT->dominates(L->getHeader(), NestedLoop->getHeader()))) { SmallVector<const SCEV *, 4> NestedOperands(NestedAR->op_begin(), NestedAR->op_end()); Operands[0] = NestedAR->getStart(); @@ -1877,6 +1945,8 @@ ScalarEvolution::getAddRecExpr(SmallVectorImpl<const SCEV *> &Operands, } } + // Okay, it looks like we really DO need an addrec expr. Check to see if we + // already have one, otherwise create a new one. FoldingSetNodeID ID; ID.AddInteger(scAddRecExpr); ID.AddInteger(Operands.size()); @@ -1884,10 +1954,13 @@ ScalarEvolution::getAddRecExpr(SmallVectorImpl<const SCEV *> &Operands, ID.AddPointer(Operands[i]); ID.AddPointer(L); void *IP = 0; - if (const SCEV *S = UniqueSCEVs.FindNodeOrInsertPos(ID, IP)) return S; - SCEVAddRecExpr *S = SCEVAllocator.Allocate<SCEVAddRecExpr>(); - new (S) SCEVAddRecExpr(ID, Operands, L); - UniqueSCEVs.InsertNode(S, IP); + SCEVAddRecExpr *S = + static_cast<SCEVAddRecExpr *>(UniqueSCEVs.FindNodeOrInsertPos(ID, IP)); + if (!S) { + S = SCEVAllocator.Allocate<SCEVAddRecExpr>(); + new (S) SCEVAddRecExpr(ID, Operands, L); + UniqueSCEVs.InsertNode(S, IP); + } if (HasNUW) S->setHasNoUnsignedWrap(true); if (HasNSW) S->setHasNoSignedWrap(true); return S; @@ -2525,31 +2598,28 @@ const SCEV *ScalarEvolution::createNodeForPHI(PHINode *PN) { if (Accum->isLoopInvariant(L) || (isa<SCEVAddRecExpr>(Accum) && cast<SCEVAddRecExpr>(Accum)->getLoop() == L)) { + bool HasNUW = false; + bool HasNSW = false; + + // If the increment doesn't overflow, then neither the addrec nor + // the post-increment will overflow. + if (const AddOperator *OBO = dyn_cast<AddOperator>(BEValueV)) { + if (OBO->hasNoUnsignedWrap()) + HasNUW = true; + if (OBO->hasNoSignedWrap()) + HasNSW = true; + } + const SCEV *StartVal = getSCEV(PN->getIncomingValue(IncomingEdge)); - const SCEVAddRecExpr *PHISCEV = - cast<SCEVAddRecExpr>(getAddRecExpr(StartVal, Accum, L)); - - // If the increment doesn't overflow, then neither the addrec nor the - // post-increment will overflow. - if (const AddOperator *OBO = dyn_cast<AddOperator>(BEValueV)) - if (OBO->getOperand(0) == PN && - getSCEV(OBO->getOperand(1)) == - PHISCEV->getStepRecurrence(*this)) { - const SCEVAddRecExpr *PostInc = PHISCEV->getPostIncExpr(*this); - if (OBO->hasNoUnsignedWrap()) { - const_cast<SCEVAddRecExpr *>(PHISCEV) - ->setHasNoUnsignedWrap(true); - const_cast<SCEVAddRecExpr *>(PostInc) - ->setHasNoUnsignedWrap(true); - } - if (OBO->hasNoSignedWrap()) { - const_cast<SCEVAddRecExpr *>(PHISCEV) - ->setHasNoSignedWrap(true); - const_cast<SCEVAddRecExpr *>(PostInc) - ->setHasNoSignedWrap(true); - } - } + const SCEV *PHISCEV = + getAddRecExpr(StartVal, Accum, L, HasNUW, HasNSW); + + // Since the no-wrap flags are on the increment, they apply to the + // post-incremented value as well. + if (Accum->isLoopInvariant(L)) + (void)getAddRecExpr(getAddExpr(StartVal, Accum), + Accum, L, HasNUW, HasNSW); // Okay, for the entire analysis of this edge we assumed the PHI // to be symbolic. We now need to go back and purge all of the @@ -2781,26 +2851,29 @@ ScalarEvolution::getUnsignedRange(const SCEV *S) { if (const SCEVAddRecExpr *AddRec = dyn_cast<SCEVAddRecExpr>(S)) { const SCEV *T = getBackedgeTakenCount(AddRec->getLoop()); const SCEVConstant *Trip = dyn_cast<SCEVConstant>(T); - if (!Trip) return FullSet; + ConstantRange ConservativeResult = FullSet; + + // If there's no unsigned wrap, the value will never be less than its + // initial value. + if (AddRec->hasNoUnsignedWrap()) + if (const SCEVConstant *C = dyn_cast<SCEVConstant>(AddRec->getStart())) + ConservativeResult = + ConstantRange(C->getValue()->getValue(), + APInt(getTypeSizeInBits(C->getType()), 0)); // TODO: non-affine addrec - if (AddRec->isAffine()) { + if (Trip && AddRec->isAffine()) { const Type *Ty = AddRec->getType(); const SCEV *MaxBECount = getMaxBackedgeTakenCount(AddRec->getLoop()); if (getTypeSizeInBits(MaxBECount->getType()) <= getTypeSizeInBits(Ty)) { MaxBECount = getNoopOrZeroExtend(MaxBECount, Ty); const SCEV *Start = AddRec->getStart(); - const SCEV *Step = AddRec->getStepRecurrence(*this); const SCEV *End = AddRec->evaluateAtIteration(MaxBECount, *this); // Check for overflow. - // TODO: This is very conservative. - if (!(Step->isOne() && - isKnownPredicate(ICmpInst::ICMP_ULT, Start, End)) && - !(Step->isAllOnesValue() && - isKnownPredicate(ICmpInst::ICMP_UGT, Start, End))) - return FullSet; + if (!AddRec->hasNoUnsignedWrap()) + return ConservativeResult; ConstantRange StartRange = getUnsignedRange(Start); ConstantRange EndRange = getUnsignedRange(End); @@ -2809,10 +2882,12 @@ ScalarEvolution::getUnsignedRange(const SCEV *S) { APInt Max = APIntOps::umax(StartRange.getUnsignedMax(), EndRange.getUnsignedMax()); if (Min.isMinValue() && Max.isMaxValue()) - return FullSet; + return ConservativeResult; return ConstantRange(Min, Max+1); } } + + return ConservativeResult; } if (const SCEVUnknown *U = dyn_cast<SCEVUnknown>(S)) { @@ -2891,26 +2966,39 @@ ScalarEvolution::getSignedRange(const SCEV *S) { if (const SCEVAddRecExpr *AddRec = dyn_cast<SCEVAddRecExpr>(S)) { const SCEV *T = getBackedgeTakenCount(AddRec->getLoop()); const SCEVConstant *Trip = dyn_cast<SCEVConstant>(T); - if (!Trip) return FullSet; + ConstantRange ConservativeResult = FullSet; + + // If there's no signed wrap, and all the operands have the same sign or + // zero, the value won't ever change sign. + if (AddRec->hasNoSignedWrap()) { + bool AllNonNeg = true; + bool AllNonPos = true; + for (unsigned i = 0, e = AddRec->getNumOperands(); i != e; ++i) { + if (!isKnownNonNegative(AddRec->getOperand(i))) AllNonNeg = false; + if (!isKnownNonPositive(AddRec->getOperand(i))) AllNonPos = false; + } + unsigned BitWidth = getTypeSizeInBits(AddRec->getType()); + if (AllNonNeg) + ConservativeResult = ConstantRange(APInt(BitWidth, 0), + APInt::getSignedMinValue(BitWidth)); + else if (AllNonPos) + ConservativeResult = ConstantRange(APInt::getSignedMinValue(BitWidth), + APInt(BitWidth, 1)); + } // TODO: non-affine addrec - if (AddRec->isAffine()) { + if (Trip && AddRec->isAffine()) { const Type *Ty = AddRec->getType(); const SCEV *MaxBECount = getMaxBackedgeTakenCount(AddRec->getLoop()); if (getTypeSizeInBits(MaxBECount->getType()) <= getTypeSizeInBits(Ty)) { MaxBECount = getNoopOrZeroExtend(MaxBECount, Ty); const SCEV *Start = AddRec->getStart(); - const SCEV *Step = AddRec->getStepRecurrence(*this); const SCEV *End = AddRec->evaluateAtIteration(MaxBECount, *this); // Check for overflow. - // TODO: This is very conservative. - if (!(Step->isOne() && - isKnownPredicate(ICmpInst::ICMP_SLT, Start, End)) && - !(Step->isAllOnesValue() && - isKnownPredicate(ICmpInst::ICMP_SGT, Start, End))) - return FullSet; + if (!AddRec->hasNoSignedWrap()) + return ConservativeResult; ConstantRange StartRange = getSignedRange(Start); ConstantRange EndRange = getSignedRange(End); @@ -2919,15 +3007,19 @@ ScalarEvolution::getSignedRange(const SCEV *S) { APInt Max = APIntOps::smax(StartRange.getSignedMax(), EndRange.getSignedMax()); if (Min.isMinSignedValue() && Max.isMaxSignedValue()) - return FullSet; + return ConservativeResult; return ConstantRange(Min, Max+1); } } + + return ConservativeResult; } if (const SCEVUnknown *U = dyn_cast<SCEVUnknown>(S)) { // For a SCEVUnknown, ask ValueTracking. unsigned BitWidth = getTypeSizeInBits(U->getType()); + if (!U->getValue()->getType()->isInteger() && !TD) + return FullSet; unsigned NS = ComputeNumSignBits(U->getValue(), TD); if (NS == 1) return FullSet; @@ -5167,6 +5259,7 @@ ScalarEvolution::ScalarEvolution() bool ScalarEvolution::runOnFunction(Function &F) { this->F = &F; LI = &getAnalysis<LoopInfo>(); + DT = &getAnalysis<DominatorTree>(); TD = getAnalysisIfAvailable<TargetData>(); return false; } @@ -5183,6 +5276,7 @@ void ScalarEvolution::releaseMemory() { void ScalarEvolution::getAnalysisUsage(AnalysisUsage &AU) const { AU.setPreservesAll(); AU.addRequiredTransitive<LoopInfo>(); + AU.addRequiredTransitive<DominatorTree>(); } bool ScalarEvolution::hasLoopInvariantBackedgeTakenCount(const Loop *L) { diff --git a/lib/Analysis/ScalarEvolutionAliasAnalysis.cpp b/lib/Analysis/ScalarEvolutionAliasAnalysis.cpp index ef0e97b..498c4a8 100644 --- a/lib/Analysis/ScalarEvolutionAliasAnalysis.cpp +++ b/lib/Analysis/ScalarEvolutionAliasAnalysis.cpp @@ -32,6 +32,16 @@ namespace { static char ID; // Class identification, replacement for typeinfo ScalarEvolutionAliasAnalysis() : FunctionPass(&ID), SE(0) {} + /// getAdjustedAnalysisPointer - This method is used when a pass implements + /// an analysis interface through multiple inheritance. If needed, it + /// should override this to adjust the this pointer as needed for the + /// specified pass info. + virtual void *getAdjustedAnalysisPointer(const PassInfo *PI) { + if (PI->isPassID(&AliasAnalysis::ID)) + return (AliasAnalysis*)this; + return this; + } + private: virtual void getAnalysisUsage(AnalysisUsage &AU) const; virtual bool runOnFunction(Function &F); diff --git a/lib/Analysis/ScalarEvolutionExpander.cpp b/lib/Analysis/ScalarEvolutionExpander.cpp index 7157d47..a72f58f 100644 --- a/lib/Analysis/ScalarEvolutionExpander.cpp +++ b/lib/Analysis/ScalarEvolutionExpander.cpp @@ -81,7 +81,7 @@ Value *SCEVExpander::InsertNoopCastOfTo(Value *V, const Type *Ty) { Instruction *I = CastInst::Create(Op, V, Ty, V->getName(), A->getParent()->getEntryBlock().begin()); - InsertedValues.insert(I); + rememberInstruction(I); return I; } @@ -98,14 +98,16 @@ Value *SCEVExpander::InsertNoopCastOfTo(Value *V, const Type *Ty) { It = cast<InvokeInst>(I)->getNormalDest()->begin(); while (isa<PHINode>(It)) ++It; if (It != BasicBlock::iterator(CI)) { - // Recreate the cast at the beginning of the entry block. + // Recreate the cast after the user. // The old cast is left in place in case it is being used // as an insert point. Instruction *NewCI = CastInst::Create(Op, V, Ty, "", It); NewCI->takeName(CI); CI->replaceAllUsesWith(NewCI); + rememberInstruction(NewCI); return NewCI; } + rememberInstruction(CI); return CI; } } @@ -114,7 +116,7 @@ Value *SCEVExpander::InsertNoopCastOfTo(Value *V, const Type *Ty) { IP = II->getNormalDest()->begin(); while (isa<PHINode>(IP)) ++IP; Instruction *CI = CastInst::Create(Op, V, Ty, V->getName(), IP); - InsertedValues.insert(CI); + rememberInstruction(CI); return CI; } @@ -144,7 +146,7 @@ Value *SCEVExpander::InsertBinop(Instruction::BinaryOps Opcode, // If we haven't found this binop, insert it. Value *BO = Builder.CreateBinOp(Opcode, LHS, RHS, "tmp"); - InsertedValues.insert(BO); + rememberInstruction(BO); return BO; } @@ -323,7 +325,7 @@ static void SplitAddRecs(SmallVectorImpl<const SCEV *> &Ops, /// http://llvm.org/docs/LangRef.html#pointeraliasing /// for details. /// -/// Design note: The correctness of using getelmeentptr here depends on +/// Design note: The correctness of using getelementptr here depends on /// ScalarEvolution not recognizing inttoptr and ptrtoint operators, as /// they may introduce pointer arithmetic which may not be safely converted /// into getelementptr. @@ -491,22 +493,39 @@ Value *SCEVExpander::expandAddToGEP(const SCEV *const *op_begin, // Emit a GEP. Value *GEP = Builder.CreateGEP(V, Idx, "uglygep"); - InsertedValues.insert(GEP); + rememberInstruction(GEP); return GEP; } // Insert a pretty getelementptr. Note that this GEP is not marked inbounds, // because ScalarEvolution may have changed the address arithmetic to // compute a value which is beyond the end of the allocated object. - Value *GEP = Builder.CreateGEP(V, + Value *Casted = V; + if (V->getType() != PTy) + Casted = InsertNoopCastOfTo(Casted, PTy); + Value *GEP = Builder.CreateGEP(Casted, GepIndices.begin(), GepIndices.end(), "scevgep"); Ops.push_back(SE.getUnknown(GEP)); - InsertedValues.insert(GEP); + rememberInstruction(GEP); return expand(SE.getAddExpr(Ops)); } +/// isNonConstantNegative - Return true if the specified scev is negated, but +/// not a constant. +static bool isNonConstantNegative(const SCEV *F) { + const SCEVMulExpr *Mul = dyn_cast<SCEVMulExpr>(F); + if (!Mul) return false; + + // If there is a constant factor, it will be first. + const SCEVConstant *SC = dyn_cast<SCEVConstant>(Mul->getOperand(0)); + if (!SC) return false; + + // Return true if the value is negative, this matches things like (-42 * V). + return SC->getValue()->getValue().isNegative(); +} + Value *SCEVExpander::visitAddExpr(const SCEVAddExpr *S) { int NumOperands = S->getNumOperands(); const Type *Ty = SE.getEffectiveSCEVType(S->getType()); @@ -539,8 +558,14 @@ Value *SCEVExpander::visitAddExpr(const SCEVAddExpr *S) { // Emit a bunch of add instructions for (int i = NumOperands-1; i >= 0; --i) { if (i == PIdx) continue; - Value *W = expandCodeFor(S->getOperand(i), Ty); - V = InsertBinop(Instruction::Add, V, W); + const SCEV *Op = S->getOperand(i); + if (isNonConstantNegative(Op)) { + Value *W = expandCodeFor(SE.getNegativeSCEV(Op), Ty); + V = InsertBinop(Instruction::Sub, V, W); + } else { + Value *W = expandCodeFor(Op, Ty); + V = InsertBinop(Instruction::Add, V, W); + } } return V; } @@ -603,7 +628,175 @@ static void ExposePointerBase(const SCEV *&Base, const SCEV *&Rest, } } +/// getAddRecExprPHILiterally - Helper for expandAddRecExprLiterally. Expand +/// the base addrec, which is the addrec without any non-loop-dominating +/// values, and return the PHI. +PHINode * +SCEVExpander::getAddRecExprPHILiterally(const SCEVAddRecExpr *Normalized, + const Loop *L, + const Type *ExpandTy, + const Type *IntTy) { + // Reuse a previously-inserted PHI, if present. + for (BasicBlock::iterator I = L->getHeader()->begin(); + PHINode *PN = dyn_cast<PHINode>(I); ++I) + if (isInsertedInstruction(PN) && SE.getSCEV(PN) == Normalized) + return PN; + + // Save the original insertion point so we can restore it when we're done. + BasicBlock *SaveInsertBB = Builder.GetInsertBlock(); + BasicBlock::iterator SaveInsertPt = Builder.GetInsertPoint(); + + // Expand code for the start value. + Value *StartV = expandCodeFor(Normalized->getStart(), ExpandTy, + L->getHeader()->begin()); + + // Expand code for the step value. Insert instructions right before the + // terminator corresponding to the back-edge. Do this before creating the PHI + // so that PHI reuse code doesn't see an incomplete PHI. If the stride is + // negative, insert a sub instead of an add for the increment (unless it's a + // constant, because subtracts of constants are canonicalized to adds). + const SCEV *Step = Normalized->getStepRecurrence(SE); + bool isPointer = isa<PointerType>(ExpandTy); + bool isNegative = !isPointer && isNonConstantNegative(Step); + if (isNegative) + Step = SE.getNegativeSCEV(Step); + Value *StepV = expandCodeFor(Step, IntTy, L->getHeader()->begin()); + + // Create the PHI. + Builder.SetInsertPoint(L->getHeader(), L->getHeader()->begin()); + PHINode *PN = Builder.CreatePHI(ExpandTy, "lsr.iv"); + rememberInstruction(PN); + + // Create the step instructions and populate the PHI. + BasicBlock *Header = L->getHeader(); + for (pred_iterator HPI = pred_begin(Header), HPE = pred_end(Header); + HPI != HPE; ++HPI) { + BasicBlock *Pred = *HPI; + + // Add a start value. + if (!L->contains(Pred)) { + PN->addIncoming(StartV, Pred); + continue; + } + + // Create a step value and add it to the PHI. If IVIncInsertLoop is + // non-null and equal to the addrec's loop, insert the instructions + // at IVIncInsertPos. + Instruction *InsertPos = L == IVIncInsertLoop ? + IVIncInsertPos : Pred->getTerminator(); + Builder.SetInsertPoint(InsertPos->getParent(), InsertPos); + Value *IncV; + // If the PHI is a pointer, use a GEP, otherwise use an add or sub. + if (isPointer) { + const PointerType *GEPPtrTy = cast<PointerType>(ExpandTy); + // If the step isn't constant, don't use an implicitly scaled GEP, because + // that would require a multiply inside the loop. + if (!isa<ConstantInt>(StepV)) + GEPPtrTy = PointerType::get(Type::getInt1Ty(SE.getContext()), + GEPPtrTy->getAddressSpace()); + const SCEV *const StepArray[1] = { SE.getSCEV(StepV) }; + IncV = expandAddToGEP(StepArray, StepArray+1, GEPPtrTy, IntTy, PN); + if (IncV->getType() != PN->getType()) { + IncV = Builder.CreateBitCast(IncV, PN->getType(), "tmp"); + rememberInstruction(IncV); + } + } else { + IncV = isNegative ? + Builder.CreateSub(PN, StepV, "lsr.iv.next") : + Builder.CreateAdd(PN, StepV, "lsr.iv.next"); + rememberInstruction(IncV); + } + PN->addIncoming(IncV, Pred); + } + + // Restore the original insert point. + if (SaveInsertBB) + Builder.SetInsertPoint(SaveInsertBB, SaveInsertPt); + + // Remember this PHI, even in post-inc mode. + InsertedValues.insert(PN); + + return PN; +} + +Value *SCEVExpander::expandAddRecExprLiterally(const SCEVAddRecExpr *S) { + const Type *STy = S->getType(); + const Type *IntTy = SE.getEffectiveSCEVType(STy); + const Loop *L = S->getLoop(); + + // Determine a normalized form of this expression, which is the expression + // before any post-inc adjustment is made. + const SCEVAddRecExpr *Normalized = S; + if (L == PostIncLoop) { + const SCEV *Step = S->getStepRecurrence(SE); + Normalized = cast<SCEVAddRecExpr>(SE.getMinusSCEV(S, Step)); + } + + // Strip off any non-loop-dominating component from the addrec start. + const SCEV *Start = Normalized->getStart(); + const SCEV *PostLoopOffset = 0; + if (!Start->properlyDominates(L->getHeader(), SE.DT)) { + PostLoopOffset = Start; + Start = SE.getIntegerSCEV(0, Normalized->getType()); + Normalized = + cast<SCEVAddRecExpr>(SE.getAddRecExpr(Start, + Normalized->getStepRecurrence(SE), + Normalized->getLoop())); + } + + // Strip off any non-loop-dominating component from the addrec step. + const SCEV *Step = Normalized->getStepRecurrence(SE); + const SCEV *PostLoopScale = 0; + if (!Step->hasComputableLoopEvolution(L) && + !Step->dominates(L->getHeader(), SE.DT)) { + PostLoopScale = Step; + Step = SE.getIntegerSCEV(1, Normalized->getType()); + Normalized = + cast<SCEVAddRecExpr>(SE.getAddRecExpr(Start, Step, + Normalized->getLoop())); + } + + // Expand the core addrec. If we need post-loop scaling, force it to + // expand to an integer type to avoid the need for additional casting. + const Type *ExpandTy = PostLoopScale ? IntTy : STy; + PHINode *PN = getAddRecExprPHILiterally(Normalized, L, ExpandTy, IntTy); + + // Accomodate post-inc mode, if necessary. + Value *Result; + if (L != PostIncLoop) + Result = PN; + else { + // In PostInc mode, use the post-incremented value. + BasicBlock *LatchBlock = L->getLoopLatch(); + assert(LatchBlock && "PostInc mode requires a unique loop latch!"); + Result = PN->getIncomingValueForBlock(LatchBlock); + } + + // Re-apply any non-loop-dominating scale. + if (PostLoopScale) { + Result = Builder.CreateMul(Result, + expandCodeFor(PostLoopScale, IntTy)); + rememberInstruction(Result); + } + + // Re-apply any non-loop-dominating offset. + if (PostLoopOffset) { + if (const PointerType *PTy = dyn_cast<PointerType>(ExpandTy)) { + const SCEV *const OffsetArray[1] = { PostLoopOffset }; + Result = expandAddToGEP(OffsetArray, OffsetArray+1, PTy, IntTy, Result); + } else { + Result = Builder.CreateAdd(Result, + expandCodeFor(PostLoopOffset, IntTy)); + rememberInstruction(Result); + } + } + + return Result; +} + Value *SCEVExpander::visitAddRecExpr(const SCEVAddRecExpr *S) { + if (!CanonicalMode) return expandAddRecExprLiterally(S); + const Type *Ty = SE.getEffectiveSCEVType(S->getType()); const Loop *L = S->getLoop(); @@ -681,17 +874,17 @@ Value *SCEVExpander::visitAddRecExpr(const SCEVAddRecExpr *S) { // specified loop. BasicBlock *Header = L->getHeader(); PHINode *PN = PHINode::Create(Ty, "indvar", Header->begin()); - InsertedValues.insert(PN); + rememberInstruction(PN); Constant *One = ConstantInt::get(Ty, 1); for (pred_iterator HPI = pred_begin(Header), HPE = pred_end(Header); HPI != HPE; ++HPI) if (L->contains(*HPI)) { - // Insert a unit add instruction right before the terminator corresponding - // to the back-edge. + // Insert a unit add instruction right before the terminator + // corresponding to the back-edge. Instruction *Add = BinaryOperator::CreateAdd(PN, One, "indvar.next", (*HPI)->getTerminator()); - InsertedValues.insert(Add); + rememberInstruction(Add); PN->addIncoming(Add, *HPI); } else { PN->addIncoming(Constant::getNullValue(Ty), *HPI); @@ -738,7 +931,7 @@ Value *SCEVExpander::visitTruncateExpr(const SCEVTruncateExpr *S) { Value *V = expandCodeFor(S->getOperand(), SE.getEffectiveSCEVType(S->getOperand()->getType())); Value *I = Builder.CreateTrunc(V, Ty, "tmp"); - InsertedValues.insert(I); + rememberInstruction(I); return I; } @@ -747,7 +940,7 @@ Value *SCEVExpander::visitZeroExtendExpr(const SCEVZeroExtendExpr *S) { Value *V = expandCodeFor(S->getOperand(), SE.getEffectiveSCEVType(S->getOperand()->getType())); Value *I = Builder.CreateZExt(V, Ty, "tmp"); - InsertedValues.insert(I); + rememberInstruction(I); return I; } @@ -756,7 +949,7 @@ Value *SCEVExpander::visitSignExtendExpr(const SCEVSignExtendExpr *S) { Value *V = expandCodeFor(S->getOperand(), SE.getEffectiveSCEVType(S->getOperand()->getType())); Value *I = Builder.CreateSExt(V, Ty, "tmp"); - InsertedValues.insert(I); + rememberInstruction(I); return I; } @@ -772,9 +965,9 @@ Value *SCEVExpander::visitSMaxExpr(const SCEVSMaxExpr *S) { } Value *RHS = expandCodeFor(S->getOperand(i), Ty); Value *ICmp = Builder.CreateICmpSGT(LHS, RHS, "tmp"); - InsertedValues.insert(ICmp); + rememberInstruction(ICmp); Value *Sel = Builder.CreateSelect(ICmp, LHS, RHS, "smax"); - InsertedValues.insert(Sel); + rememberInstruction(Sel); LHS = Sel; } // In the case of mixed integer and pointer types, cast the @@ -796,9 +989,9 @@ Value *SCEVExpander::visitUMaxExpr(const SCEVUMaxExpr *S) { } Value *RHS = expandCodeFor(S->getOperand(i), Ty); Value *ICmp = Builder.CreateICmpUGT(LHS, RHS, "tmp"); - InsertedValues.insert(ICmp); + rememberInstruction(ICmp); Value *Sel = Builder.CreateSelect(ICmp, LHS, RHS, "umax"); - InsertedValues.insert(Sel); + rememberInstruction(Sel); LHS = Sel; } // In the case of mixed integer and pointer types, cast the @@ -863,7 +1056,8 @@ Value *SCEVExpander::expand(const SCEV *S) { Value *V = visit(S); // Remember the expanded value for this SCEV at this location. - InsertedExpressions[std::make_pair(S, InsertPt)] = V; + if (!PostIncLoop) + InsertedExpressions[std::make_pair(S, InsertPt)] = V; Builder.SetInsertPoint(SaveInsertBB, SaveInsertPt); return V; |