summaryrefslogtreecommitdiffstats
path: root/lib/Analysis
diff options
context:
space:
mode:
authorrdivacky <rdivacky@FreeBSD.org>2010-01-23 11:09:33 +0000
committerrdivacky <rdivacky@FreeBSD.org>2010-01-23 11:09:33 +0000
commit3fd58f91dd318518f7daa4ba64c0aaf31799d89b (patch)
tree74eecbae571601ec6a626a53374b1eddc7b164a5 /lib/Analysis
parent3fba7d16b41dfbefe3b1be6bc0ab94c017728f79 (diff)
downloadFreeBSD-src-3fd58f91dd318518f7daa4ba64c0aaf31799d89b.zip
FreeBSD-src-3fd58f91dd318518f7daa4ba64c0aaf31799d89b.tar.gz
Update LLVM to r94309.
Diffstat (limited to 'lib/Analysis')
-rw-r--r--lib/Analysis/AliasAnalysisCounter.cpp14
-rw-r--r--lib/Analysis/AliasDebugger.cpp10
-rw-r--r--lib/Analysis/BasicAliasAnalysis.cpp20
-rw-r--r--lib/Analysis/DebugInfo.cpp60
-rw-r--r--lib/Analysis/DomPrinter.cpp74
-rw-r--r--lib/Analysis/IPA/Andersens.cpp10
-rw-r--r--lib/Analysis/IPA/CallGraph.cpp12
-rw-r--r--lib/Analysis/IPA/CallGraphSCCPass.cpp57
-rw-r--r--lib/Analysis/IPA/GlobalsModRef.cpp10
-rw-r--r--lib/Analysis/IPA/Makefile2
-rw-r--r--lib/Analysis/IVUsers.cpp19
-rw-r--r--lib/Analysis/LoopPass.cpp45
-rw-r--r--lib/Analysis/Makefile1
-rw-r--r--lib/Analysis/ProfileEstimatorPass.cpp10
-rw-r--r--lib/Analysis/ProfileInfo.cpp14
-rw-r--r--lib/Analysis/ProfileInfoLoaderPass.cpp10
-rw-r--r--lib/Analysis/ScalarEvolution.cpp212
-rw-r--r--lib/Analysis/ScalarEvolutionAliasAnalysis.cpp10
-rw-r--r--lib/Analysis/ScalarEvolutionExpander.cpp238
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;
OpenPOWER on IntegriCloud