It's not necessary to do rounding for alloca operations when the requested
alignment is equal to the stack alignment.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@40004 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Analysis/AliasAnalysis.cpp b/lib/Analysis/AliasAnalysis.cpp
new file mode 100644
index 0000000..5ae2342
--- /dev/null
+++ b/lib/Analysis/AliasAnalysis.cpp
@@ -0,0 +1,191 @@
+//===- AliasAnalysis.cpp - Generic Alias Analysis Interface Implementation -==//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the generic AliasAnalysis interface which is used as the
+// common interface used by all clients and implementations of alias analysis.
+//
+// This file also implements the default version of the AliasAnalysis interface
+// that is to be used when no other implementation is specified. This does some
+// simple tests that detect obvious cases: two different global pointers cannot
+// alias, a global cannot alias a malloc, two different mallocs cannot alias,
+// etc.
+//
+// This alias analysis implementation really isn't very good for anything, but
+// it is very fast, and makes a nice clean default implementation. Because it
+// handles lots of little corner cases, other, more complex, alias analysis
+// implementations may choose to rely on this pass to resolve these simple and
+// easy cases.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Analysis/AliasAnalysis.h"
+#include "llvm/Pass.h"
+#include "llvm/BasicBlock.h"
+#include "llvm/Instructions.h"
+#include "llvm/Type.h"
+#include "llvm/Target/TargetData.h"
+using namespace llvm;
+
+// Register the AliasAnalysis interface, providing a nice name to refer to.
+namespace {
+ RegisterAnalysisGroup<AliasAnalysis> Z("Alias Analysis");
+}
+char AliasAnalysis::ID = 0;
+
+//===----------------------------------------------------------------------===//
+// Default chaining methods
+//===----------------------------------------------------------------------===//
+
+AliasAnalysis::AliasResult
+AliasAnalysis::alias(const Value *V1, unsigned V1Size,
+ const Value *V2, unsigned V2Size) {
+ assert(AA && "AA didn't call InitializeAliasAnalysis in its run method!");
+ return AA->alias(V1, V1Size, V2, V2Size);
+}
+
+void AliasAnalysis::getMustAliases(Value *P, std::vector<Value*> &RetVals) {
+ assert(AA && "AA didn't call InitializeAliasAnalysis in its run method!");
+ return AA->getMustAliases(P, RetVals);
+}
+
+bool AliasAnalysis::pointsToConstantMemory(const Value *P) {
+ assert(AA && "AA didn't call InitializeAliasAnalysis in its run method!");
+ return AA->pointsToConstantMemory(P);
+}
+
+AliasAnalysis::ModRefBehavior
+AliasAnalysis::getModRefBehavior(Function *F, CallSite CS,
+ std::vector<PointerAccessInfo> *Info) {
+ assert(AA && "AA didn't call InitializeAliasAnalysis in its run method!");
+ return AA->getModRefBehavior(F, CS, Info);
+}
+
+bool AliasAnalysis::hasNoModRefInfoForCalls() const {
+ assert(AA && "AA didn't call InitializeAliasAnalysis in its run method!");
+ return AA->hasNoModRefInfoForCalls();
+}
+
+void AliasAnalysis::deleteValue(Value *V) {
+ assert(AA && "AA didn't call InitializeAliasAnalysis in its run method!");
+ AA->deleteValue(V);
+}
+
+void AliasAnalysis::copyValue(Value *From, Value *To) {
+ assert(AA && "AA didn't call InitializeAliasAnalysis in its run method!");
+ AA->copyValue(From, To);
+}
+
+AliasAnalysis::ModRefResult
+AliasAnalysis::getModRefInfo(CallSite CS1, CallSite CS2) {
+ // FIXME: we can do better.
+ assert(AA && "AA didn't call InitializeAliasAnalysis in its run method!");
+ return AA->getModRefInfo(CS1, CS2);
+}
+
+
+//===----------------------------------------------------------------------===//
+// AliasAnalysis non-virtual helper method implementation
+//===----------------------------------------------------------------------===//
+
+AliasAnalysis::ModRefResult
+AliasAnalysis::getModRefInfo(LoadInst *L, Value *P, unsigned Size) {
+ return alias(L->getOperand(0), TD->getTypeSize(L->getType()),
+ P, Size) ? Ref : NoModRef;
+}
+
+AliasAnalysis::ModRefResult
+AliasAnalysis::getModRefInfo(StoreInst *S, Value *P, unsigned Size) {
+ // If the stored address cannot alias the pointer in question, then the
+ // pointer cannot be modified by the store.
+ if (!alias(S->getOperand(1), TD->getTypeSize(S->getOperand(0)->getType()),
+ P, Size))
+ return NoModRef;
+
+ // If the pointer is a pointer to constant memory, then it could not have been
+ // modified by this store.
+ return pointsToConstantMemory(P) ? NoModRef : Mod;
+}
+
+AliasAnalysis::ModRefResult
+AliasAnalysis::getModRefInfo(CallSite CS, Value *P, unsigned Size) {
+ ModRefResult Mask = ModRef;
+ if (Function *F = CS.getCalledFunction()) {
+ ModRefBehavior MRB = getModRefBehavior(F, CallSite());
+ if (MRB == OnlyReadsMemory)
+ Mask = Ref;
+ else if (MRB == DoesNotAccessMemory)
+ return NoModRef;
+ }
+
+ if (!AA) return Mask;
+
+ // If P points to a constant memory location, the call definitely could not
+ // modify the memory location.
+ if ((Mask & Mod) && AA->pointsToConstantMemory(P))
+ Mask = ModRefResult(Mask & ~Mod);
+
+ return ModRefResult(Mask & AA->getModRefInfo(CS, P, Size));
+}
+
+// AliasAnalysis destructor: DO NOT move this to the header file for
+// AliasAnalysis or else clients of the AliasAnalysis class may not depend on
+// the AliasAnalysis.o file in the current .a file, causing alias analysis
+// support to not be included in the tool correctly!
+//
+AliasAnalysis::~AliasAnalysis() {}
+
+/// setTargetData - Subclasses must call this method to initialize the
+/// AliasAnalysis interface before any other methods are called.
+///
+void AliasAnalysis::InitializeAliasAnalysis(Pass *P) {
+ TD = &P->getAnalysis<TargetData>();
+ AA = &P->getAnalysis<AliasAnalysis>();
+}
+
+// getAnalysisUsage - All alias analysis implementations should invoke this
+// directly (using AliasAnalysis::getAnalysisUsage(AU)) to make sure that
+// TargetData is required by the pass.
+void AliasAnalysis::getAnalysisUsage(AnalysisUsage &AU) const {
+ AU.addRequired<TargetData>(); // All AA's need TargetData.
+ AU.addRequired<AliasAnalysis>(); // All AA's chain
+}
+
+/// canBasicBlockModify - Return true if it is possible for execution of the
+/// specified basic block to modify the value pointed to by Ptr.
+///
+bool AliasAnalysis::canBasicBlockModify(const BasicBlock &BB,
+ const Value *Ptr, unsigned Size) {
+ return canInstructionRangeModify(BB.front(), BB.back(), Ptr, Size);
+}
+
+/// canInstructionRangeModify - Return true if it is possible for the execution
+/// of the specified instructions to modify the value pointed to by Ptr. The
+/// instructions to consider are all of the instructions in the range of [I1,I2]
+/// INCLUSIVE. I1 and I2 must be in the same basic block.
+///
+bool AliasAnalysis::canInstructionRangeModify(const Instruction &I1,
+ const Instruction &I2,
+ const Value *Ptr, unsigned Size) {
+ assert(I1.getParent() == I2.getParent() &&
+ "Instructions not in same basic block!");
+ BasicBlock::iterator I = const_cast<Instruction*>(&I1);
+ BasicBlock::iterator E = const_cast<Instruction*>(&I2);
+ ++E; // Convert from inclusive to exclusive range.
+
+ for (; I != E; ++I) // Check every instruction in range
+ if (getModRefInfo(I, const_cast<Value*>(Ptr), Size) & Mod)
+ return true;
+ return false;
+}
+
+// Because of the way .a files work, we must force the BasicAA implementation to
+// be pulled in if the AliasAnalysis classes are pulled in. Otherwise we run
+// the risk of AliasAnalysis being used, but the default implementation not
+// being linked into the tool that uses it.
+DEFINING_FILE_FOR(AliasAnalysis)
diff --git a/lib/Analysis/AliasAnalysisCounter.cpp b/lib/Analysis/AliasAnalysisCounter.cpp
new file mode 100644
index 0000000..eea2c99
--- /dev/null
+++ b/lib/Analysis/AliasAnalysisCounter.cpp
@@ -0,0 +1,165 @@
+//===- AliasAnalysisCounter.cpp - Alias Analysis Query Counter ------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements a pass which can be used to count how many alias queries
+// are being made and how the alias analysis implementation being used responds.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Analysis/Passes.h"
+#include "llvm/Pass.h"
+#include "llvm/Analysis/AliasAnalysis.h"
+#include "llvm/Assembly/Writer.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/Compiler.h"
+#include "llvm/Support/Streams.h"
+using namespace llvm;
+
+namespace {
+ cl::opt<bool>
+ PrintAll("count-aa-print-all-queries", cl::ReallyHidden);
+ cl::opt<bool>
+ PrintAllFailures("count-aa-print-all-failed-queries", cl::ReallyHidden);
+
+ class VISIBILITY_HIDDEN 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
+ AliasAnalysisCounter() : ModulePass((intptr_t) &ID) {
+ No = May = Must = 0;
+ NoMR = JustRef = JustMod = MR = 0;
+ }
+
+ void printLine(const char *Desc, unsigned Val, unsigned Sum) {
+ cerr << " " << Val << " " << Desc << " responses ("
+ << Val*100/Sum << "%)\n";
+ }
+ ~AliasAnalysisCounter() {
+ unsigned AASum = No+May+Must;
+ unsigned MRSum = NoMR+JustRef+JustMod+MR;
+ if (AASum + MRSum) { // Print a report if any counted queries occurred...
+ cerr << "\n===== Alias Analysis Counter Report =====\n"
+ << " Analysis counted: " << Name << "\n"
+ << " " << AASum << " Total Alias Queries Performed\n";
+ if (AASum) {
+ printLine("no alias", No, AASum);
+ printLine("may alias", May, AASum);
+ printLine("must alias", Must, AASum);
+ cerr << " Alias Analysis Counter Summary: " << No*100/AASum << "%/"
+ << May*100/AASum << "%/" << Must*100/AASum<<"%\n\n";
+ }
+
+ cerr << " " << MRSum << " Total Mod/Ref Queries Performed\n";
+ if (MRSum) {
+ printLine("no mod/ref", NoMR, MRSum);
+ printLine("ref", JustRef, MRSum);
+ printLine("mod", JustMod, MRSum);
+ printLine("mod/ref", MR, MRSum);
+ cerr << " Mod/Ref Analysis Counter Summary: " <<NoMR*100/MRSum<< "%/"
+ << JustRef*100/MRSum << "%/" << JustMod*100/MRSum << "%/"
+ << MR*100/MRSum <<"%\n\n";
+ }
+ }
+ }
+
+ bool runOnModule(Module &M) {
+ this->M = &M;
+ InitializeAliasAnalysis(this);
+ Name = dynamic_cast<Pass*>(&getAnalysis<AliasAnalysis>())->getPassName();
+ return false;
+ }
+
+ virtual void getAnalysisUsage(AnalysisUsage &AU) const {
+ AliasAnalysis::getAnalysisUsage(AU);
+ AU.addRequired<AliasAnalysis>();
+ AU.setPreservesAll();
+ }
+
+ // FIXME: We could count these too...
+ bool pointsToConstantMemory(const Value *P) {
+ return getAnalysis<AliasAnalysis>().pointsToConstantMemory(P);
+ }
+ bool doesNotAccessMemory(Function *F) {
+ return getAnalysis<AliasAnalysis>().doesNotAccessMemory(F);
+ }
+ bool onlyReadsMemory(Function *F) {
+ return getAnalysis<AliasAnalysis>().onlyReadsMemory(F);
+ }
+
+
+ // Forwarding functions: just delegate to a real AA implementation, counting
+ // the number of responses...
+ AliasResult alias(const Value *V1, unsigned V1Size,
+ const Value *V2, unsigned V2Size);
+
+ ModRefResult getModRefInfo(CallSite CS, Value *P, unsigned Size);
+ ModRefResult getModRefInfo(CallSite CS1, CallSite CS2) {
+ return AliasAnalysis::getModRefInfo(CS1,CS2);
+ }
+ };
+
+ char AliasAnalysisCounter::ID = 0;
+ RegisterPass<AliasAnalysisCounter>
+ X("count-aa", "Count Alias Analysis Query Responses");
+ RegisterAnalysisGroup<AliasAnalysis> Y(X);
+}
+
+ModulePass *llvm::createAliasAnalysisCounterPass() {
+ return new AliasAnalysisCounter();
+}
+
+AliasAnalysis::AliasResult
+AliasAnalysisCounter::alias(const Value *V1, unsigned V1Size,
+ const Value *V2, unsigned V2Size) {
+ AliasResult R = getAnalysis<AliasAnalysis>().alias(V1, V1Size, V2, V2Size);
+
+ const char *AliasString;
+ switch (R) {
+ default: assert(0 && "Unknown alias type!");
+ case NoAlias: No++; AliasString = "No alias"; break;
+ case MayAlias: May++; AliasString = "May alias"; break;
+ case MustAlias: Must++; AliasString = "Must alias"; break;
+ }
+
+ if (PrintAll || (PrintAllFailures && R == MayAlias)) {
+ cerr << AliasString << ":\t";
+ cerr << "[" << V1Size << "B] ";
+ WriteAsOperand(*cerr.stream(), V1, true, M) << ", ";
+ cerr << "[" << V2Size << "B] ";
+ WriteAsOperand(*cerr.stream(), V2, true, M) << "\n";
+ }
+
+ return R;
+}
+
+AliasAnalysis::ModRefResult
+AliasAnalysisCounter::getModRefInfo(CallSite CS, Value *P, unsigned Size) {
+ ModRefResult R = getAnalysis<AliasAnalysis>().getModRefInfo(CS, P, Size);
+
+ const char *MRString;
+ switch (R) {
+ default: assert(0 && "Unknown mod/ref type!");
+ case NoModRef: NoMR++; MRString = "NoModRef"; break;
+ case Ref: JustRef++; MRString = "JustRef"; break;
+ case Mod: JustMod++; MRString = "JustMod"; break;
+ case ModRef: MR++; MRString = "ModRef"; break;
+ }
+
+ if (PrintAll || (PrintAllFailures && R == ModRef)) {
+ cerr << MRString << ": Ptr: ";
+ cerr << "[" << Size << "B] ";
+ WriteAsOperand(*cerr.stream(), P, true, M);
+ cerr << "\t<->" << *CS.getInstruction();
+ }
+ return R;
+}
diff --git a/lib/Analysis/AliasAnalysisEvaluator.cpp b/lib/Analysis/AliasAnalysisEvaluator.cpp
new file mode 100644
index 0000000..30965c2
--- /dev/null
+++ b/lib/Analysis/AliasAnalysisEvaluator.cpp
@@ -0,0 +1,239 @@
+//===- AliasAnalysisEvaluator.cpp - Alias Analysis Accuracy Evaluator -----===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements a simple N^2 alias analysis accuracy evaluator.
+// Basically, for each function in the program, it simply queries to see how the
+// alias analysis implementation answers alias queries between each pair of
+// pointers in the function.
+//
+// This is inspired and adapted from code by: Naveen Neelakantam, Francesco
+// Spadini, and Wojciech Stryjewski.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Constants.h"
+#include "llvm/DerivedTypes.h"
+#include "llvm/Function.h"
+#include "llvm/Instructions.h"
+#include "llvm/Pass.h"
+#include "llvm/Analysis/Passes.h"
+#include "llvm/Analysis/AliasAnalysis.h"
+#include "llvm/Assembly/Writer.h"
+#include "llvm/Target/TargetData.h"
+#include "llvm/Support/InstIterator.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/Compiler.h"
+#include "llvm/Support/Streams.h"
+#include <set>
+using namespace llvm;
+
+namespace {
+ cl::opt<bool> PrintAll("print-all-alias-modref-info", cl::ReallyHidden);
+
+ cl::opt<bool> PrintNoAlias("print-no-aliases", cl::ReallyHidden);
+ cl::opt<bool> PrintMayAlias("print-may-aliases", cl::ReallyHidden);
+ cl::opt<bool> PrintMustAlias("print-must-aliases", cl::ReallyHidden);
+
+ cl::opt<bool> PrintNoModRef("print-no-modref", cl::ReallyHidden);
+ cl::opt<bool> PrintMod("print-mod", cl::ReallyHidden);
+ cl::opt<bool> PrintRef("print-ref", cl::ReallyHidden);
+ cl::opt<bool> PrintModRef("print-modref", cl::ReallyHidden);
+
+ class VISIBILITY_HIDDEN AAEval : public FunctionPass {
+ unsigned NoAlias, MayAlias, MustAlias;
+ unsigned NoModRef, Mod, Ref, ModRef;
+
+ public:
+ static char ID; // Pass identification, replacement for typeid
+ AAEval() : FunctionPass((intptr_t)&ID) {}
+
+ virtual void getAnalysisUsage(AnalysisUsage &AU) const {
+ AU.addRequired<AliasAnalysis>();
+ AU.setPreservesAll();
+ }
+
+ bool doInitialization(Module &M) {
+ NoAlias = MayAlias = MustAlias = 0;
+ NoModRef = Mod = Ref = ModRef = 0;
+
+ if (PrintAll) {
+ PrintNoAlias = PrintMayAlias = PrintMustAlias = true;
+ PrintNoModRef = PrintMod = PrintRef = PrintModRef = true;
+ }
+ return false;
+ }
+
+ bool runOnFunction(Function &F);
+ bool doFinalization(Module &M);
+ };
+
+ char AAEval::ID = 0;
+ RegisterPass<AAEval>
+ X("aa-eval", "Exhaustive Alias Analysis Precision Evaluator");
+}
+
+FunctionPass *llvm::createAAEvalPass() { return new AAEval(); }
+
+static inline void PrintResults(const char *Msg, bool P, Value *V1, Value *V2,
+ Module *M) {
+ if (P) {
+ cerr << " " << Msg << ":\t";
+ WriteAsOperand(*cerr.stream(), V1, true, M) << ", ";
+ WriteAsOperand(*cerr.stream(), V2, true, M) << "\n";
+ }
+}
+
+static inline void
+PrintModRefResults(const char *Msg, bool P, Instruction *I, Value *Ptr,
+ Module *M) {
+ if (P) {
+ cerr << " " << Msg << ": Ptr: ";
+ WriteAsOperand(*cerr.stream(), Ptr, true, M);
+ cerr << "\t<->" << *I;
+ }
+}
+
+bool AAEval::runOnFunction(Function &F) {
+ AliasAnalysis &AA = getAnalysis<AliasAnalysis>();
+
+ const TargetData &TD = AA.getTargetData();
+
+ std::set<Value *> Pointers;
+ std::set<CallSite> CallSites;
+
+ for (Function::arg_iterator I = F.arg_begin(), E = F.arg_end(); I != E; ++I)
+ if (isa<PointerType>(I->getType())) // Add all pointer arguments
+ Pointers.insert(I);
+
+ for (inst_iterator I = inst_begin(F), E = inst_end(F); I != E; ++I) {
+ if (isa<PointerType>(I->getType())) // Add all pointer instructions
+ Pointers.insert(&*I);
+ Instruction &Inst = *I;
+ User::op_iterator OI = Inst.op_begin();
+ if ((isa<InvokeInst>(Inst) || isa<CallInst>(Inst)) &&
+ isa<Function>(Inst.getOperand(0)))
+ ++OI; // Skip actual functions for direct function calls.
+ for (; OI != Inst.op_end(); ++OI)
+ if (isa<PointerType>((*OI)->getType()) && !isa<ConstantPointerNull>(*OI))
+ Pointers.insert(*OI);
+
+ CallSite CS = CallSite::get(&*I);
+ if (CS.getInstruction()) CallSites.insert(CS);
+ }
+
+ if (PrintNoAlias || PrintMayAlias || PrintMustAlias ||
+ PrintNoModRef || PrintMod || PrintRef || PrintModRef)
+ cerr << "Function: " << F.getName() << ": " << Pointers.size()
+ << " pointers, " << CallSites.size() << " call sites\n";
+
+ // iterate over the worklist, and run the full (n^2)/2 disambiguations
+ for (std::set<Value *>::iterator I1 = Pointers.begin(), E = Pointers.end();
+ I1 != E; ++I1) {
+ unsigned I1Size = 0;
+ const Type *I1ElTy = cast<PointerType>((*I1)->getType())->getElementType();
+ if (I1ElTy->isSized()) I1Size = TD.getTypeSize(I1ElTy);
+
+ for (std::set<Value *>::iterator I2 = Pointers.begin(); I2 != I1; ++I2) {
+ unsigned I2Size = 0;
+ const Type *I2ElTy =cast<PointerType>((*I2)->getType())->getElementType();
+ if (I2ElTy->isSized()) I2Size = TD.getTypeSize(I2ElTy);
+
+ switch (AA.alias(*I1, I1Size, *I2, I2Size)) {
+ case AliasAnalysis::NoAlias:
+ PrintResults("NoAlias", PrintNoAlias, *I1, *I2, F.getParent());
+ ++NoAlias; break;
+ case AliasAnalysis::MayAlias:
+ PrintResults("MayAlias", PrintMayAlias, *I1, *I2, F.getParent());
+ ++MayAlias; break;
+ case AliasAnalysis::MustAlias:
+ PrintResults("MustAlias", PrintMustAlias, *I1, *I2, F.getParent());
+ ++MustAlias; break;
+ default:
+ cerr << "Unknown alias query result!\n";
+ }
+ }
+ }
+
+ // Mod/ref alias analysis: compare all pairs of calls and values
+ for (std::set<CallSite>::iterator C = CallSites.begin(),
+ Ce = CallSites.end(); C != Ce; ++C) {
+ Instruction *I = C->getInstruction();
+
+ for (std::set<Value *>::iterator V = Pointers.begin(), Ve = Pointers.end();
+ V != Ve; ++V) {
+ unsigned Size = 0;
+ const Type *ElTy = cast<PointerType>((*V)->getType())->getElementType();
+ if (ElTy->isSized()) Size = TD.getTypeSize(ElTy);
+
+ switch (AA.getModRefInfo(*C, *V, Size)) {
+ case AliasAnalysis::NoModRef:
+ PrintModRefResults("NoModRef", PrintNoModRef, I, *V, F.getParent());
+ ++NoModRef; break;
+ case AliasAnalysis::Mod:
+ PrintModRefResults(" Mod", PrintMod, I, *V, F.getParent());
+ ++Mod; break;
+ case AliasAnalysis::Ref:
+ PrintModRefResults(" Ref", PrintRef, I, *V, F.getParent());
+ ++Ref; break;
+ case AliasAnalysis::ModRef:
+ PrintModRefResults(" ModRef", PrintModRef, I, *V, F.getParent());
+ ++ModRef; break;
+ default:
+ cerr << "Unknown alias query result!\n";
+ }
+ }
+ }
+
+ return false;
+}
+
+static void PrintPercent(unsigned Num, unsigned Sum) {
+ cerr << "(" << Num*100ULL/Sum << "."
+ << ((Num*1000ULL/Sum) % 10) << "%)\n";
+}
+
+bool AAEval::doFinalization(Module &M) {
+ unsigned AliasSum = NoAlias + MayAlias + MustAlias;
+ cerr << "===== Alias Analysis Evaluator Report =====\n";
+ if (AliasSum == 0) {
+ cerr << " Alias Analysis Evaluator Summary: No pointers!\n";
+ } else {
+ cerr << " " << AliasSum << " Total Alias Queries Performed\n";
+ cerr << " " << NoAlias << " no alias responses ";
+ PrintPercent(NoAlias, AliasSum);
+ cerr << " " << MayAlias << " may alias responses ";
+ PrintPercent(MayAlias, AliasSum);
+ cerr << " " << MustAlias << " must alias responses ";
+ PrintPercent(MustAlias, AliasSum);
+ cerr << " Alias Analysis Evaluator Pointer Alias Summary: "
+ << NoAlias*100/AliasSum << "%/" << MayAlias*100/AliasSum << "%/"
+ << MustAlias*100/AliasSum << "%\n";
+ }
+
+ // Display the summary for mod/ref analysis
+ unsigned ModRefSum = NoModRef + Mod + Ref + ModRef;
+ if (ModRefSum == 0) {
+ cerr << " Alias Analysis Mod/Ref Evaluator Summary: no mod/ref!\n";
+ } else {
+ cerr << " " << ModRefSum << " Total ModRef Queries Performed\n";
+ cerr << " " << NoModRef << " no mod/ref responses ";
+ PrintPercent(NoModRef, ModRefSum);
+ cerr << " " << Mod << " mod responses ";
+ PrintPercent(Mod, ModRefSum);
+ cerr << " " << Ref << " ref responses ";
+ PrintPercent(Ref, ModRefSum);
+ cerr << " " << ModRef << " mod & ref responses ";
+ PrintPercent(ModRef, ModRefSum);
+ cerr << " Alias Analysis Evaluator Mod/Ref Summary: "
+ << NoModRef*100/ModRefSum << "%/" << Mod*100/ModRefSum << "%/"
+ << Ref*100/ModRefSum << "%/" << ModRef*100/ModRefSum << "%\n";
+ }
+
+ return false;
+}
diff --git a/lib/Analysis/AliasDebugger.cpp b/lib/Analysis/AliasDebugger.cpp
new file mode 100644
index 0000000..bbb7acf
--- /dev/null
+++ b/lib/Analysis/AliasDebugger.cpp
@@ -0,0 +1,131 @@
+//===- AliasDebugger.cpp - Simple Alias Analysis Use Checker --------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by Andrew Lenharth and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This simple pass checks alias analysis users to ensure that if they
+// create a new value, they do not query AA without informing it of the value.
+// It acts as a shim over any other AA pass you want.
+//
+// Yes keeping track of every value in the program is expensive, but this is
+// a debugging pass.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Analysis/Passes.h"
+#include "llvm/Module.h"
+#include "llvm/Pass.h"
+#include "llvm/Instructions.h"
+#include "llvm/Constants.h"
+#include "llvm/DerivedTypes.h"
+#include "llvm/Analysis/AliasAnalysis.h"
+#include "llvm/Support/Compiler.h"
+#include <set>
+using namespace llvm;
+
+namespace {
+
+ class VISIBILITY_HIDDEN AliasDebugger
+ : public ModulePass, public AliasAnalysis {
+
+ //What we do is simple. Keep track of every value the AA could
+ //know about, and verify that queries are one of those.
+ //A query to a value that didn't exist when the AA was created
+ //means someone forgot to update the AA when creating new values
+
+ std::set<const Value*> Vals;
+
+ public:
+ static char ID; // Class identification, replacement for typeinfo
+ AliasDebugger() : ModulePass((intptr_t)&ID) {}
+
+ bool runOnModule(Module &M) {
+ InitializeAliasAnalysis(this); // set up super class
+
+ for(Module::global_iterator I = M.global_begin(),
+ E = M.global_end(); I != E; ++I)
+ Vals.insert(&*I);
+
+ for(Module::iterator I = M.begin(),
+ E = M.end(); I != E; ++I){
+ Vals.insert(&*I);
+ if(!I->isDeclaration()) {
+ for (Function::arg_iterator AI = I->arg_begin(), AE = I->arg_end();
+ AI != AE; ++AI)
+ Vals.insert(&*AI);
+ for (Function::const_iterator FI = I->begin(), FE = I->end();
+ FI != FE; ++FI)
+ for (BasicBlock::const_iterator BI = FI->begin(), BE = FI->end();
+ BI != BE; ++BI)
+ Vals.insert(&*BI);
+ }
+
+ }
+ return false;
+ }
+
+ virtual void getAnalysisUsage(AnalysisUsage &AU) const {
+ AliasAnalysis::getAnalysisUsage(AU);
+ AU.setPreservesAll(); // Does not transform code
+ }
+
+ //------------------------------------------------
+ // Implement the AliasAnalysis API
+ //
+ AliasResult alias(const Value *V1, unsigned V1Size,
+ const Value *V2, unsigned V2Size) {
+ assert(Vals.find(V1) != Vals.end() && "Never seen value in AA before");
+ assert(Vals.find(V2) != Vals.end() && "Never seen value in AA before");
+ return AliasAnalysis::alias(V1, V1Size, V2, V2Size);
+ }
+
+ ModRefResult getModRefInfo(CallSite CS, Value *P, unsigned Size) {
+ assert(Vals.find(P) != Vals.end() && "Never seen value in AA before");
+ return AliasAnalysis::getModRefInfo(CS, P, Size);
+ }
+
+ ModRefResult getModRefInfo(CallSite CS1, CallSite CS2) {
+ return AliasAnalysis::getModRefInfo(CS1,CS2);
+ }
+
+ void getMustAliases(Value *P, std::vector<Value*> &RetVals) {
+ assert(Vals.find(P) != Vals.end() && "Never seen value in AA before");
+ return AliasAnalysis::getMustAliases(P, RetVals);
+ }
+
+ bool pointsToConstantMemory(const Value *P) {
+ assert(Vals.find(P) != Vals.end() && "Never seen value in AA before");
+ return AliasAnalysis::pointsToConstantMemory(P);
+ }
+
+ /// getModRefBehavior - Return the behavior of the specified function if
+ /// called from the specified call site. The call site may be null in which
+ /// case the most generic behavior of this function should be returned.
+ virtual ModRefBehavior getModRefBehavior(Function *F, CallSite CS,
+ std::vector<PointerAccessInfo> *Info) {
+ assert(Vals.find(F) != Vals.end() && "Never seen value in AA before");
+ return AliasAnalysis::getModRefBehavior(F, CS, Info);
+ }
+
+ virtual void deleteValue(Value *V) {
+ assert(Vals.find(V) != Vals.end() && "Never seen value in AA before");
+ AliasAnalysis::deleteValue(V);
+ }
+ virtual void copyValue(Value *From, Value *To) {
+ Vals.insert(To);
+ AliasAnalysis::copyValue(From, To);
+ }
+
+ };
+
+ char AliasDebugger::ID = 0;
+ RegisterPass<AliasDebugger> X("debug-aa", "AA use debugger");
+ RegisterAnalysisGroup<AliasAnalysis> Y(X);
+}
+
+Pass *llvm::createAliasDebugger() { return new AliasDebugger(); }
+
diff --git a/lib/Analysis/AliasSetTracker.cpp b/lib/Analysis/AliasSetTracker.cpp
new file mode 100644
index 0000000..0397af7
--- /dev/null
+++ b/lib/Analysis/AliasSetTracker.cpp
@@ -0,0 +1,580 @@
+//===- AliasSetTracker.cpp - Alias Sets Tracker implementation-------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the AliasSetTracker and AliasSet classes.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Analysis/AliasSetTracker.h"
+#include "llvm/Analysis/AliasAnalysis.h"
+#include "llvm/Instructions.h"
+#include "llvm/Pass.h"
+#include "llvm/Type.h"
+#include "llvm/Target/TargetData.h"
+#include "llvm/Assembly/Writer.h"
+#include "llvm/Support/Compiler.h"
+#include "llvm/Support/InstIterator.h"
+#include "llvm/Support/Streams.h"
+using namespace llvm;
+
+/// mergeSetIn - Merge the specified alias set into this alias set.
+///
+void AliasSet::mergeSetIn(AliasSet &AS, AliasSetTracker &AST) {
+ assert(!AS.Forward && "Alias set is already forwarding!");
+ assert(!Forward && "This set is a forwarding set!!");
+
+ // Update the alias and access types of this set...
+ AccessTy |= AS.AccessTy;
+ AliasTy |= AS.AliasTy;
+
+ if (AliasTy == MustAlias) {
+ // Check that these two merged sets really are must aliases. Since both
+ // used to be must-alias sets, we can just check any pointer from each set
+ // for aliasing.
+ AliasAnalysis &AA = AST.getAliasAnalysis();
+ HashNodePair *L = getSomePointer();
+ HashNodePair *R = AS.getSomePointer();
+
+ // If the pointers are not a must-alias pair, this set becomes a may alias.
+ if (AA.alias(L->first, L->second.getSize(), R->first, R->second.getSize())
+ != AliasAnalysis::MustAlias)
+ AliasTy = MayAlias;
+ }
+
+ if (CallSites.empty()) { // Merge call sites...
+ if (!AS.CallSites.empty())
+ std::swap(CallSites, AS.CallSites);
+ } else if (!AS.CallSites.empty()) {
+ CallSites.insert(CallSites.end(), AS.CallSites.begin(), AS.CallSites.end());
+ AS.CallSites.clear();
+ }
+
+ AS.Forward = this; // Forward across AS now...
+ addRef(); // AS is now pointing to us...
+
+ // Merge the list of constituent pointers...
+ if (AS.PtrList) {
+ *PtrListEnd = AS.PtrList;
+ AS.PtrList->second.setPrevInList(PtrListEnd);
+ PtrListEnd = AS.PtrListEnd;
+
+ AS.PtrList = 0;
+ AS.PtrListEnd = &AS.PtrList;
+ assert(*AS.PtrListEnd == 0 && "End of list is not null?");
+ }
+}
+
+void AliasSetTracker::removeAliasSet(AliasSet *AS) {
+ if (AliasSet *Fwd = AS->Forward) {
+ Fwd->dropRef(*this);
+ AS->Forward = 0;
+ }
+ AliasSets.erase(AS);
+}
+
+void AliasSet::removeFromTracker(AliasSetTracker &AST) {
+ assert(RefCount == 0 && "Cannot remove non-dead alias set from tracker!");
+ AST.removeAliasSet(this);
+}
+
+void AliasSet::addPointer(AliasSetTracker &AST, HashNodePair &Entry,
+ unsigned Size, bool KnownMustAlias) {
+ assert(!Entry.second.hasAliasSet() && "Entry already in set!");
+
+ // Check to see if we have to downgrade to _may_ alias.
+ if (isMustAlias() && !KnownMustAlias)
+ if (HashNodePair *P = getSomePointer()) {
+ AliasAnalysis &AA = AST.getAliasAnalysis();
+ AliasAnalysis::AliasResult Result =
+ AA.alias(P->first, P->second.getSize(), Entry.first, Size);
+ if (Result == AliasAnalysis::MayAlias)
+ AliasTy = MayAlias;
+ else // First entry of must alias must have maximum size!
+ P->second.updateSize(Size);
+ assert(Result != AliasAnalysis::NoAlias && "Cannot be part of must set!");
+ }
+
+ Entry.second.setAliasSet(this);
+ Entry.second.updateSize(Size);
+
+ // Add it to the end of the list...
+ assert(*PtrListEnd == 0 && "End of list is not null?");
+ *PtrListEnd = &Entry;
+ PtrListEnd = Entry.second.setPrevInList(PtrListEnd);
+ assert(*PtrListEnd == 0 && "End of list is not null?");
+ addRef(); // Entry points to alias set...
+}
+
+void AliasSet::addCallSite(CallSite CS, AliasAnalysis &AA) {
+ CallSites.push_back(CS);
+
+ if (Function *F = CS.getCalledFunction()) {
+ AliasAnalysis::ModRefBehavior Behavior = AA.getModRefBehavior(F, CS);
+ if (Behavior == AliasAnalysis::DoesNotAccessMemory)
+ return;
+ else if (Behavior == AliasAnalysis::OnlyReadsMemory) {
+ AliasTy = MayAlias;
+ AccessTy |= Refs;
+ return;
+ }
+ }
+
+ // FIXME: This should use mod/ref information to make this not suck so bad
+ AliasTy = MayAlias;
+ AccessTy = ModRef;
+}
+
+/// aliasesPointer - Return true if the specified pointer "may" (or must)
+/// alias one of the members in the set.
+///
+bool AliasSet::aliasesPointer(const Value *Ptr, unsigned Size,
+ AliasAnalysis &AA) const {
+ if (AliasTy == MustAlias) {
+ assert(CallSites.empty() && "Illegal must alias set!");
+
+ // If this is a set of MustAliases, only check to see if the pointer aliases
+ // SOME value in the set...
+ HashNodePair *SomePtr = getSomePointer();
+ assert(SomePtr && "Empty must-alias set??");
+ return AA.alias(SomePtr->first, SomePtr->second.getSize(), Ptr, Size);
+ }
+
+ // If this is a may-alias set, we have to check all of the pointers in the set
+ // to be sure it doesn't alias the set...
+ for (iterator I = begin(), E = end(); I != E; ++I)
+ if (AA.alias(Ptr, Size, I.getPointer(), I.getSize()))
+ return true;
+
+ // Check the call sites list and invoke list...
+ if (!CallSites.empty()) {
+ if (AA.hasNoModRefInfoForCalls())
+ return true;
+
+ for (unsigned i = 0, e = CallSites.size(); i != e; ++i)
+ if (AA.getModRefInfo(CallSites[i], const_cast<Value*>(Ptr), Size)
+ != AliasAnalysis::NoModRef)
+ return true;
+ }
+
+ return false;
+}
+
+bool AliasSet::aliasesCallSite(CallSite CS, AliasAnalysis &AA) const {
+ if (Function *F = CS.getCalledFunction())
+ if (AA.doesNotAccessMemory(F))
+ return false;
+
+ if (AA.hasNoModRefInfoForCalls())
+ return true;
+
+ for (unsigned i = 0, e = CallSites.size(); i != e; ++i)
+ if (AA.getModRefInfo(CallSites[i], CS) != AliasAnalysis::NoModRef ||
+ AA.getModRefInfo(CS, CallSites[i]) != AliasAnalysis::NoModRef)
+ return true;
+
+ for (iterator I = begin(), E = end(); I != E; ++I)
+ if (AA.getModRefInfo(CS, I.getPointer(), I.getSize()) !=
+ AliasAnalysis::NoModRef)
+ return true;
+
+ return false;
+}
+
+
+/// findAliasSetForPointer - Given a pointer, find the one alias set to put the
+/// instruction referring to the pointer into. If there are multiple alias sets
+/// that may alias the pointer, merge them together and return the unified set.
+///
+AliasSet *AliasSetTracker::findAliasSetForPointer(const Value *Ptr,
+ unsigned Size) {
+ AliasSet *FoundSet = 0;
+ for (iterator I = begin(), E = end(); I != E; ++I)
+ if (!I->Forward && I->aliasesPointer(Ptr, Size, AA)) {
+ if (FoundSet == 0) { // If this is the first alias set ptr can go into.
+ FoundSet = I; // Remember it.
+ } else { // Otherwise, we must merge the sets.
+ FoundSet->mergeSetIn(*I, *this); // Merge in contents.
+ }
+ }
+
+ return FoundSet;
+}
+
+/// containsPointer - Return true if the specified location is represented by
+/// this alias set, false otherwise. This does not modify the AST object or
+/// alias sets.
+bool AliasSetTracker::containsPointer(Value *Ptr, unsigned Size) const {
+ for (const_iterator I = begin(), E = end(); I != E; ++I)
+ if (!I->Forward && I->aliasesPointer(Ptr, Size, AA))
+ return true;
+ return false;
+}
+
+
+
+AliasSet *AliasSetTracker::findAliasSetForCallSite(CallSite CS) {
+ AliasSet *FoundSet = 0;
+ for (iterator I = begin(), E = end(); I != E; ++I)
+ if (!I->Forward && I->aliasesCallSite(CS, AA)) {
+ if (FoundSet == 0) { // If this is the first alias set ptr can go into.
+ FoundSet = I; // Remember it.
+ } else if (!I->Forward) { // Otherwise, we must merge the sets.
+ FoundSet->mergeSetIn(*I, *this); // Merge in contents.
+ }
+ }
+
+ return FoundSet;
+}
+
+
+
+
+/// getAliasSetForPointer - Return the alias set that the specified pointer
+/// lives in...
+AliasSet &AliasSetTracker::getAliasSetForPointer(Value *Pointer, unsigned Size,
+ bool *New) {
+ AliasSet::HashNodePair &Entry = getEntryFor(Pointer);
+
+ // Check to see if the pointer is already known...
+ if (Entry.second.hasAliasSet()) {
+ Entry.second.updateSize(Size);
+ // Return the set!
+ return *Entry.second.getAliasSet(*this)->getForwardedTarget(*this);
+ } else if (AliasSet *AS = findAliasSetForPointer(Pointer, Size)) {
+ // Add it to the alias set it aliases...
+ AS->addPointer(*this, Entry, Size);
+ return *AS;
+ } else {
+ if (New) *New = true;
+ // Otherwise create a new alias set to hold the loaded pointer...
+ AliasSets.push_back(new AliasSet());
+ AliasSets.back().addPointer(*this, Entry, Size);
+ return AliasSets.back();
+ }
+}
+
+bool AliasSetTracker::add(Value *Ptr, unsigned Size) {
+ bool NewPtr;
+ addPointer(Ptr, Size, AliasSet::NoModRef, NewPtr);
+ return NewPtr;
+}
+
+
+bool AliasSetTracker::add(LoadInst *LI) {
+ bool NewPtr;
+ AliasSet &AS = addPointer(LI->getOperand(0),
+ AA.getTargetData().getTypeSize(LI->getType()),
+ AliasSet::Refs, NewPtr);
+ if (LI->isVolatile()) AS.setVolatile();
+ return NewPtr;
+}
+
+bool AliasSetTracker::add(StoreInst *SI) {
+ bool NewPtr;
+ Value *Val = SI->getOperand(0);
+ AliasSet &AS = addPointer(SI->getOperand(1),
+ AA.getTargetData().getTypeSize(Val->getType()),
+ AliasSet::Mods, NewPtr);
+ if (SI->isVolatile()) AS.setVolatile();
+ return NewPtr;
+}
+
+bool AliasSetTracker::add(FreeInst *FI) {
+ bool NewPtr;
+ AliasSet &AS = addPointer(FI->getOperand(0), ~0,
+ AliasSet::Mods, NewPtr);
+
+ // Free operations are volatile ops (cannot be moved).
+ AS.setVolatile();
+ return NewPtr;
+}
+
+
+bool AliasSetTracker::add(CallSite CS) {
+ if (Function *F = CS.getCalledFunction())
+ if (AA.doesNotAccessMemory(F))
+ return true; // doesn't alias anything
+
+ AliasSet *AS = findAliasSetForCallSite(CS);
+ if (!AS) {
+ AliasSets.push_back(new AliasSet());
+ AS = &AliasSets.back();
+ AS->addCallSite(CS, AA);
+ return true;
+ } else {
+ AS->addCallSite(CS, AA);
+ return false;
+ }
+}
+
+bool AliasSetTracker::add(Instruction *I) {
+ // Dispatch to one of the other add methods...
+ if (LoadInst *LI = dyn_cast<LoadInst>(I))
+ return add(LI);
+ else if (StoreInst *SI = dyn_cast<StoreInst>(I))
+ return add(SI);
+ else if (CallInst *CI = dyn_cast<CallInst>(I))
+ return add(CI);
+ else if (InvokeInst *II = dyn_cast<InvokeInst>(I))
+ return add(II);
+ else if (FreeInst *FI = dyn_cast<FreeInst>(I))
+ return add(FI);
+ return true;
+}
+
+void AliasSetTracker::add(BasicBlock &BB) {
+ for (BasicBlock::iterator I = BB.begin(), E = BB.end(); I != E; ++I)
+ add(I);
+}
+
+void AliasSetTracker::add(const AliasSetTracker &AST) {
+ assert(&AA == &AST.AA &&
+ "Merging AliasSetTracker objects with different Alias Analyses!");
+
+ // Loop over all of the alias sets in AST, adding the pointers contained
+ // therein into the current alias sets. This can cause alias sets to be
+ // merged together in the current AST.
+ for (const_iterator I = AST.begin(), E = AST.end(); I != E; ++I)
+ if (!I->Forward) { // Ignore forwarding alias sets
+ AliasSet &AS = const_cast<AliasSet&>(*I);
+
+ // If there are any call sites in the alias set, add them to this AST.
+ for (unsigned i = 0, e = AS.CallSites.size(); i != e; ++i)
+ add(AS.CallSites[i]);
+
+ // Loop over all of the pointers in this alias set...
+ AliasSet::iterator I = AS.begin(), E = AS.end();
+ bool X;
+ for (; I != E; ++I) {
+ AliasSet &NewAS = addPointer(I.getPointer(), I.getSize(),
+ (AliasSet::AccessType)AS.AccessTy, X);
+ if (AS.isVolatile()) NewAS.setVolatile();
+ }
+ }
+}
+
+/// remove - Remove the specified (potentially non-empty) alias set from the
+/// tracker.
+void AliasSetTracker::remove(AliasSet &AS) {
+ // Drop all call sites.
+ AS.CallSites.clear();
+
+ // Clear the alias set.
+ unsigned NumRefs = 0;
+ while (!AS.empty()) {
+ AliasSet::HashNodePair *P = AS.PtrList;
+
+ // Unlink from the list of values.
+ P->second.removeFromList();
+
+ // Remember how many references need to be dropped.
+ ++NumRefs;
+
+ // Finally, remove the entry.
+ Value *Remove = P->first; // Take a copy because it is invalid to pass
+ PointerMap.erase(Remove); // a reference to the data being erased.
+ }
+
+ // Stop using the alias set, removing it.
+ AS.RefCount -= NumRefs;
+ if (AS.RefCount == 0)
+ AS.removeFromTracker(*this);
+}
+
+bool AliasSetTracker::remove(Value *Ptr, unsigned Size) {
+ AliasSet *AS = findAliasSetForPointer(Ptr, Size);
+ if (!AS) return false;
+ remove(*AS);
+ return true;
+}
+
+bool AliasSetTracker::remove(LoadInst *LI) {
+ unsigned Size = AA.getTargetData().getTypeSize(LI->getType());
+ AliasSet *AS = findAliasSetForPointer(LI->getOperand(0), Size);
+ if (!AS) return false;
+ remove(*AS);
+ return true;
+}
+
+bool AliasSetTracker::remove(StoreInst *SI) {
+ unsigned Size = AA.getTargetData().getTypeSize(SI->getOperand(0)->getType());
+ AliasSet *AS = findAliasSetForPointer(SI->getOperand(1), Size);
+ if (!AS) return false;
+ remove(*AS);
+ return true;
+}
+
+bool AliasSetTracker::remove(FreeInst *FI) {
+ AliasSet *AS = findAliasSetForPointer(FI->getOperand(0), ~0);
+ if (!AS) return false;
+ remove(*AS);
+ return true;
+}
+
+bool AliasSetTracker::remove(CallSite CS) {
+ if (Function *F = CS.getCalledFunction())
+ if (AA.doesNotAccessMemory(F))
+ return false; // doesn't alias anything
+
+ AliasSet *AS = findAliasSetForCallSite(CS);
+ if (!AS) return false;
+ remove(*AS);
+ return true;
+}
+
+bool AliasSetTracker::remove(Instruction *I) {
+ // Dispatch to one of the other remove methods...
+ if (LoadInst *LI = dyn_cast<LoadInst>(I))
+ return remove(LI);
+ else if (StoreInst *SI = dyn_cast<StoreInst>(I))
+ return remove(SI);
+ else if (CallInst *CI = dyn_cast<CallInst>(I))
+ return remove(CI);
+ else if (FreeInst *FI = dyn_cast<FreeInst>(I))
+ return remove(FI);
+ return true;
+}
+
+
+// deleteValue method - This method is used to remove a pointer value from the
+// AliasSetTracker entirely. It should be used when an instruction is deleted
+// from the program to update the AST. If you don't use this, you would have
+// dangling pointers to deleted instructions.
+//
+void AliasSetTracker::deleteValue(Value *PtrVal) {
+ // Notify the alias analysis implementation that this value is gone.
+ AA.deleteValue(PtrVal);
+
+ // If this is a call instruction, remove the callsite from the appropriate
+ // AliasSet.
+ CallSite CS = CallSite::get(PtrVal);
+ if (CS.getInstruction()) {
+ Function *F = CS.getCalledFunction();
+ if (!F || !AA.doesNotAccessMemory(F)) {
+ if (AliasSet *AS = findAliasSetForCallSite(CS))
+ AS->removeCallSite(CS);
+ }
+ }
+
+ // First, look up the PointerRec for this pointer.
+ hash_map<Value*, AliasSet::PointerRec>::iterator I = PointerMap.find(PtrVal);
+ if (I == PointerMap.end()) return; // Noop
+
+ // If we found one, remove the pointer from the alias set it is in.
+ AliasSet::HashNodePair &PtrValEnt = *I;
+ AliasSet *AS = PtrValEnt.second.getAliasSet(*this);
+
+ // Unlink from the list of values...
+ PtrValEnt.second.removeFromList();
+ // Stop using the alias set
+ AS->dropRef(*this);
+ PointerMap.erase(I);
+}
+
+// copyValue - This method should be used whenever a preexisting value in the
+// program is copied or cloned, introducing a new value. Note that it is ok for
+// clients that use this method to introduce the same value multiple times: if
+// the tracker already knows about a value, it will ignore the request.
+//
+void AliasSetTracker::copyValue(Value *From, Value *To) {
+ // Notify the alias analysis implementation that this value is copied.
+ AA.copyValue(From, To);
+
+ // First, look up the PointerRec for this pointer.
+ hash_map<Value*, AliasSet::PointerRec>::iterator I = PointerMap.find(From);
+ if (I == PointerMap.end() || !I->second.hasAliasSet())
+ return; // Noop
+
+ AliasSet::HashNodePair &Entry = getEntryFor(To);
+ if (Entry.second.hasAliasSet()) return; // Already in the tracker!
+
+ // Add it to the alias set it aliases...
+ AliasSet *AS = I->second.getAliasSet(*this);
+ AS->addPointer(*this, Entry, I->second.getSize(), true);
+}
+
+
+
+//===----------------------------------------------------------------------===//
+// AliasSet/AliasSetTracker Printing Support
+//===----------------------------------------------------------------------===//
+
+void AliasSet::print(std::ostream &OS) const {
+ OS << " AliasSet[" << (void*)this << "," << RefCount << "] ";
+ OS << (AliasTy == MustAlias ? "must" : "may ") << " alias, ";
+ switch (AccessTy) {
+ case NoModRef: OS << "No access "; break;
+ case Refs : OS << "Ref "; break;
+ case Mods : OS << "Mod "; break;
+ case ModRef : OS << "Mod/Ref "; break;
+ default: assert(0 && "Bad value for AccessTy!");
+ }
+ if (isVolatile()) OS << "[volatile] ";
+ if (Forward)
+ OS << " forwarding to " << (void*)Forward;
+
+
+ if (begin() != end()) {
+ OS << "Pointers: ";
+ for (iterator I = begin(), E = end(); I != E; ++I) {
+ if (I != begin()) OS << ", ";
+ WriteAsOperand(OS << "(", I.getPointer());
+ OS << ", " << I.getSize() << ")";
+ }
+ }
+ if (!CallSites.empty()) {
+ OS << "\n " << CallSites.size() << " Call Sites: ";
+ for (unsigned i = 0, e = CallSites.size(); i != e; ++i) {
+ if (i) OS << ", ";
+ WriteAsOperand(OS, CallSites[i].getCalledValue());
+ }
+ }
+ OS << "\n";
+}
+
+void AliasSetTracker::print(std::ostream &OS) const {
+ OS << "Alias Set Tracker: " << AliasSets.size() << " alias sets for "
+ << PointerMap.size() << " pointer values.\n";
+ for (const_iterator I = begin(), E = end(); I != E; ++I)
+ I->print(OS);
+ OS << "\n";
+}
+
+void AliasSet::dump() const { print (cerr); }
+void AliasSetTracker::dump() const { print(cerr); }
+
+//===----------------------------------------------------------------------===//
+// AliasSetPrinter Pass
+//===----------------------------------------------------------------------===//
+
+namespace {
+ class VISIBILITY_HIDDEN AliasSetPrinter : public FunctionPass {
+ AliasSetTracker *Tracker;
+ public:
+ static char ID; // Pass identification, replacement for typeid
+ AliasSetPrinter() : FunctionPass((intptr_t)&ID) {}
+
+ virtual void getAnalysisUsage(AnalysisUsage &AU) const {
+ AU.setPreservesAll();
+ AU.addRequired<AliasAnalysis>();
+ }
+
+ virtual bool runOnFunction(Function &F) {
+ Tracker = new AliasSetTracker(getAnalysis<AliasAnalysis>());
+
+ for (inst_iterator I = inst_begin(F), E = inst_end(F); I != E; ++I)
+ Tracker->add(&*I);
+ Tracker->print(cerr);
+ delete Tracker;
+ return false;
+ }
+ };
+ char AliasSetPrinter::ID = 0;
+ RegisterPass<AliasSetPrinter> X("print-alias-sets", "Alias Set Printer");
+}
diff --git a/lib/Analysis/BasicAliasAnalysis.cpp b/lib/Analysis/BasicAliasAnalysis.cpp
new file mode 100644
index 0000000..580f7e5
--- /dev/null
+++ b/lib/Analysis/BasicAliasAnalysis.cpp
@@ -0,0 +1,890 @@
+//===- BasicAliasAnalysis.cpp - Local Alias Analysis Impl -----------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the default implementation of the Alias Analysis interface
+// that simply implements a few identities (two different globals cannot alias,
+// etc), but otherwise does no analysis.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Analysis/AliasAnalysis.h"
+#include "llvm/Analysis/Passes.h"
+#include "llvm/Constants.h"
+#include "llvm/DerivedTypes.h"
+#include "llvm/Function.h"
+#include "llvm/GlobalVariable.h"
+#include "llvm/Instructions.h"
+#include "llvm/Pass.h"
+#include "llvm/Target/TargetData.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/Support/Compiler.h"
+#include "llvm/Support/GetElementPtrTypeIterator.h"
+#include "llvm/Support/ManagedStatic.h"
+#include <algorithm>
+using namespace llvm;
+
+namespace {
+ /// NoAA - This class implements the -no-aa pass, which always returns "I
+ /// don't know" for alias queries. NoAA is unlike other alias analysis
+ /// implementations, in that it does not chain to a previous analysis. As
+ /// such it doesn't follow many of the rules that other alias analyses must.
+ ///
+ struct VISIBILITY_HIDDEN NoAA : public ImmutablePass, public AliasAnalysis {
+ static char ID; // Class identification, replacement for typeinfo
+ NoAA() : ImmutablePass((intptr_t)&ID) {}
+ explicit NoAA(intptr_t PID) : ImmutablePass(PID) { }
+
+ virtual void getAnalysisUsage(AnalysisUsage &AU) const {
+ AU.addRequired<TargetData>();
+ }
+
+ virtual void initializePass() {
+ TD = &getAnalysis<TargetData>();
+ }
+
+ virtual AliasResult alias(const Value *V1, unsigned V1Size,
+ const Value *V2, unsigned V2Size) {
+ return MayAlias;
+ }
+
+ virtual ModRefBehavior getModRefBehavior(Function *F, CallSite CS,
+ std::vector<PointerAccessInfo> *Info) {
+ return UnknownModRefBehavior;
+ }
+
+ virtual void getArgumentAccesses(Function *F, CallSite CS,
+ std::vector<PointerAccessInfo> &Info) {
+ assert(0 && "This method may not be called on this function!");
+ }
+
+ virtual void getMustAliases(Value *P, std::vector<Value*> &RetVals) { }
+ virtual bool pointsToConstantMemory(const Value *P) { return false; }
+ virtual ModRefResult getModRefInfo(CallSite CS, Value *P, unsigned Size) {
+ return ModRef;
+ }
+ virtual ModRefResult getModRefInfo(CallSite CS1, CallSite CS2) {
+ return ModRef;
+ }
+ virtual bool hasNoModRefInfoForCalls() const { return true; }
+
+ virtual void deleteValue(Value *V) {}
+ virtual void copyValue(Value *From, Value *To) {}
+ };
+
+ // Register this pass...
+ char NoAA::ID = 0;
+ RegisterPass<NoAA>
+ U("no-aa", "No Alias Analysis (always returns 'may' alias)");
+
+ // Declare that we implement the AliasAnalysis interface
+ RegisterAnalysisGroup<AliasAnalysis> V(U);
+} // End of anonymous namespace
+
+ImmutablePass *llvm::createNoAAPass() { return new NoAA(); }
+
+namespace {
+ /// BasicAliasAnalysis - This is the default alias analysis implementation.
+ /// Because it doesn't chain to a previous alias analysis (like -no-aa), it
+ /// derives from the NoAA class.
+ struct VISIBILITY_HIDDEN BasicAliasAnalysis : public NoAA {
+ static char ID; // Class identification, replacement for typeinfo
+ BasicAliasAnalysis() : NoAA((intptr_t)&ID) { }
+ AliasResult alias(const Value *V1, unsigned V1Size,
+ const Value *V2, unsigned V2Size);
+
+ ModRefResult getModRefInfo(CallSite CS, Value *P, unsigned Size);
+ ModRefResult getModRefInfo(CallSite CS1, CallSite CS2) {
+ return NoAA::getModRefInfo(CS1,CS2);
+ }
+
+ /// hasNoModRefInfoForCalls - We can provide mod/ref information against
+ /// non-escaping allocations.
+ virtual bool hasNoModRefInfoForCalls() const { return false; }
+
+ /// pointsToConstantMemory - Chase pointers until we find a (constant
+ /// global) or not.
+ bool pointsToConstantMemory(const Value *P);
+
+ virtual ModRefBehavior getModRefBehavior(Function *F, CallSite CS,
+ std::vector<PointerAccessInfo> *Info);
+
+ private:
+ // CheckGEPInstructions - Check two GEP instructions with known
+ // must-aliasing base pointers. This checks to see if the index expressions
+ // preclude the pointers from aliasing...
+ AliasResult
+ CheckGEPInstructions(const Type* BasePtr1Ty,
+ Value **GEP1Ops, unsigned NumGEP1Ops, unsigned G1Size,
+ const Type *BasePtr2Ty,
+ Value **GEP2Ops, unsigned NumGEP2Ops, unsigned G2Size);
+ };
+
+ // Register this pass...
+ char BasicAliasAnalysis::ID = 0;
+ RegisterPass<BasicAliasAnalysis>
+ X("basicaa", "Basic Alias Analysis (default AA impl)");
+
+ // Declare that we implement the AliasAnalysis interface
+ RegisterAnalysisGroup<AliasAnalysis, true> Y(X);
+} // End of anonymous namespace
+
+ImmutablePass *llvm::createBasicAliasAnalysisPass() {
+ return new BasicAliasAnalysis();
+}
+
+// getUnderlyingObject - This traverses the use chain to figure out what object
+// the specified value points to. If the value points to, or is derived from, a
+// unique object or an argument, return it.
+static const Value *getUnderlyingObject(const Value *V) {
+ if (!isa<PointerType>(V->getType())) return 0;
+
+ // If we are at some type of object, return it. GlobalValues and Allocations
+ // have unique addresses.
+ if (isa<GlobalValue>(V) || isa<AllocationInst>(V) || isa<Argument>(V))
+ return V;
+
+ // Traverse through different addressing mechanisms...
+ if (const Instruction *I = dyn_cast<Instruction>(V)) {
+ if (isa<BitCastInst>(I) || isa<GetElementPtrInst>(I))
+ return getUnderlyingObject(I->getOperand(0));
+ } else if (const ConstantExpr *CE = dyn_cast<ConstantExpr>(V)) {
+ if (CE->getOpcode() == Instruction::BitCast ||
+ CE->getOpcode() == Instruction::GetElementPtr)
+ return getUnderlyingObject(CE->getOperand(0));
+ }
+ return 0;
+}
+
+static const User *isGEP(const Value *V) {
+ if (isa<GetElementPtrInst>(V) ||
+ (isa<ConstantExpr>(V) &&
+ cast<ConstantExpr>(V)->getOpcode() == Instruction::GetElementPtr))
+ return cast<User>(V);
+ return 0;
+}
+
+static const Value *GetGEPOperands(const Value *V,
+ SmallVector<Value*, 16> &GEPOps){
+ assert(GEPOps.empty() && "Expect empty list to populate!");
+ GEPOps.insert(GEPOps.end(), cast<User>(V)->op_begin()+1,
+ cast<User>(V)->op_end());
+
+ // Accumulate all of the chained indexes into the operand array
+ V = cast<User>(V)->getOperand(0);
+
+ while (const User *G = isGEP(V)) {
+ if (!isa<Constant>(GEPOps[0]) || isa<GlobalValue>(GEPOps[0]) ||
+ !cast<Constant>(GEPOps[0])->isNullValue())
+ break; // Don't handle folding arbitrary pointer offsets yet...
+ GEPOps.erase(GEPOps.begin()); // Drop the zero index
+ GEPOps.insert(GEPOps.begin(), G->op_begin()+1, G->op_end());
+ V = G->getOperand(0);
+ }
+ return V;
+}
+
+/// pointsToConstantMemory - Chase pointers until we find a (constant
+/// global) or not.
+bool BasicAliasAnalysis::pointsToConstantMemory(const Value *P) {
+ if (const Value *V = getUnderlyingObject(P))
+ if (const GlobalVariable *GV = dyn_cast<GlobalVariable>(V))
+ return GV->isConstant();
+ return false;
+}
+
+// Determine if an AllocationInst instruction escapes from the function it is
+// contained in. If it does not escape, there is no way for another function to
+// mod/ref it. We do this by looking at its uses and determining if the uses
+// can escape (recursively).
+static bool AddressMightEscape(const Value *V) {
+ for (Value::use_const_iterator UI = V->use_begin(), E = V->use_end();
+ UI != E; ++UI) {
+ const Instruction *I = cast<Instruction>(*UI);
+ switch (I->getOpcode()) {
+ case Instruction::Load:
+ break; //next use.
+ case Instruction::Store:
+ if (I->getOperand(0) == V)
+ return true; // Escapes if the pointer is stored.
+ break; // next use.
+ case Instruction::GetElementPtr:
+ if (AddressMightEscape(I))
+ return true;
+ case Instruction::BitCast:
+ if (!isa<PointerType>(I->getType()))
+ return true;
+ if (AddressMightEscape(I))
+ return true;
+ break; // next use
+ case Instruction::Ret:
+ // If returned, the address will escape to calling functions, but no
+ // callees could modify it.
+ break; // next use
+ default:
+ return true;
+ }
+ }
+ return false;
+}
+
+// getModRefInfo - Check to see if the specified callsite can clobber the
+// specified memory object. Since we only look at local properties of this
+// function, we really can't say much about this query. We do, however, use
+// simple "address taken" analysis on local objects.
+//
+AliasAnalysis::ModRefResult
+BasicAliasAnalysis::getModRefInfo(CallSite CS, Value *P, unsigned Size) {
+ if (!isa<Constant>(P))
+ if (const AllocationInst *AI =
+ dyn_cast_or_null<AllocationInst>(getUnderlyingObject(P))) {
+ // Okay, the pointer is to a stack allocated object. If we can prove that
+ // the pointer never "escapes", then we know the call cannot clobber it,
+ // because it simply can't get its address.
+ if (!AddressMightEscape(AI))
+ return NoModRef;
+
+ // If this is a tail call and P points to a stack location, we know that
+ // the tail call cannot access or modify the local stack.
+ if (CallInst *CI = dyn_cast<CallInst>(CS.getInstruction()))
+ if (CI->isTailCall() && isa<AllocaInst>(AI))
+ return NoModRef;
+ }
+
+ // The AliasAnalysis base class has some smarts, lets use them.
+ return AliasAnalysis::getModRefInfo(CS, P, Size);
+}
+
+// alias - Provide a bunch of ad-hoc rules to disambiguate in common cases, such
+// as array references. Note that this function is heavily tail recursive.
+// Hopefully we have a smart C++ compiler. :)
+//
+AliasAnalysis::AliasResult
+BasicAliasAnalysis::alias(const Value *V1, unsigned V1Size,
+ const Value *V2, unsigned V2Size) {
+ // Strip off any constant expression casts if they exist
+ if (const ConstantExpr *CE = dyn_cast<ConstantExpr>(V1))
+ if (CE->isCast() && isa<PointerType>(CE->getOperand(0)->getType()))
+ V1 = CE->getOperand(0);
+ if (const ConstantExpr *CE = dyn_cast<ConstantExpr>(V2))
+ if (CE->isCast() && isa<PointerType>(CE->getOperand(0)->getType()))
+ V2 = CE->getOperand(0);
+
+ // Are we checking for alias of the same value?
+ if (V1 == V2) return MustAlias;
+
+ if ((!isa<PointerType>(V1->getType()) || !isa<PointerType>(V2->getType())) &&
+ V1->getType() != Type::Int64Ty && V2->getType() != Type::Int64Ty)
+ return NoAlias; // Scalars cannot alias each other
+
+ // Strip off cast instructions...
+ if (const BitCastInst *I = dyn_cast<BitCastInst>(V1))
+ return alias(I->getOperand(0), V1Size, V2, V2Size);
+ if (const BitCastInst *I = dyn_cast<BitCastInst>(V2))
+ return alias(V1, V1Size, I->getOperand(0), V2Size);
+
+ // Figure out what objects these things are pointing to if we can...
+ const Value *O1 = getUnderlyingObject(V1);
+ const Value *O2 = getUnderlyingObject(V2);
+
+ // Pointing at a discernible object?
+ if (O1) {
+ if (O2) {
+ if (isa<Argument>(O1)) {
+ // Incoming argument cannot alias locally allocated object!
+ if (isa<AllocationInst>(O2)) return NoAlias;
+ // Otherwise, nothing is known...
+ } else if (isa<Argument>(O2)) {
+ // Incoming argument cannot alias locally allocated object!
+ if (isa<AllocationInst>(O1)) return NoAlias;
+ // Otherwise, nothing is known...
+ } else if (O1 != O2) {
+ // If they are two different objects, we know that we have no alias...
+ return NoAlias;
+ }
+
+ // If they are the same object, they we can look at the indexes. If they
+ // index off of the object is the same for both pointers, they must alias.
+ // If they are provably different, they must not alias. Otherwise, we
+ // can't tell anything.
+ }
+
+
+ if (!isa<Argument>(O1) && isa<ConstantPointerNull>(V2))
+ return NoAlias; // Unique values don't alias null
+
+ if (isa<GlobalVariable>(O1) ||
+ (isa<AllocationInst>(O1) &&
+ !cast<AllocationInst>(O1)->isArrayAllocation()))
+ if (cast<PointerType>(O1->getType())->getElementType()->isSized()) {
+ // If the size of the other access is larger than the total size of the
+ // global/alloca/malloc, it cannot be accessing the global (it's
+ // undefined to load or store bytes before or after an object).
+ const Type *ElTy = cast<PointerType>(O1->getType())->getElementType();
+ unsigned GlobalSize = getTargetData().getTypeSize(ElTy);
+ if (GlobalSize < V2Size && V2Size != ~0U)
+ return NoAlias;
+ }
+ }
+
+ if (O2) {
+ if (!isa<Argument>(O2) && isa<ConstantPointerNull>(V1))
+ return NoAlias; // Unique values don't alias null
+
+ if (isa<GlobalVariable>(O2) ||
+ (isa<AllocationInst>(O2) &&
+ !cast<AllocationInst>(O2)->isArrayAllocation()))
+ if (cast<PointerType>(O2->getType())->getElementType()->isSized()) {
+ // If the size of the other access is larger than the total size of the
+ // global/alloca/malloc, it cannot be accessing the object (it's
+ // undefined to load or store bytes before or after an object).
+ const Type *ElTy = cast<PointerType>(O2->getType())->getElementType();
+ unsigned GlobalSize = getTargetData().getTypeSize(ElTy);
+ if (GlobalSize < V1Size && V1Size != ~0U)
+ return NoAlias;
+ }
+ }
+
+ // If we have two gep instructions with must-alias'ing base pointers, figure
+ // out if the indexes to the GEP tell us anything about the derived pointer.
+ // Note that we also handle chains of getelementptr instructions as well as
+ // constant expression getelementptrs here.
+ //
+ if (isGEP(V1) && isGEP(V2)) {
+ // Drill down into the first non-gep value, to test for must-aliasing of
+ // the base pointers.
+ const Value *BasePtr1 = V1, *BasePtr2 = V2;
+ do {
+ BasePtr1 = cast<User>(BasePtr1)->getOperand(0);
+ } while (isGEP(BasePtr1) &&
+ cast<User>(BasePtr1)->getOperand(1) ==
+ Constant::getNullValue(cast<User>(BasePtr1)->getOperand(1)->getType()));
+ do {
+ BasePtr2 = cast<User>(BasePtr2)->getOperand(0);
+ } while (isGEP(BasePtr2) &&
+ cast<User>(BasePtr2)->getOperand(1) ==
+ Constant::getNullValue(cast<User>(BasePtr2)->getOperand(1)->getType()));
+
+ // Do the base pointers alias?
+ AliasResult BaseAlias = alias(BasePtr1, ~0U, BasePtr2, ~0U);
+ if (BaseAlias == NoAlias) return NoAlias;
+ if (BaseAlias == MustAlias) {
+ // If the base pointers alias each other exactly, check to see if we can
+ // figure out anything about the resultant pointers, to try to prove
+ // non-aliasing.
+
+ // Collect all of the chained GEP operands together into one simple place
+ SmallVector<Value*, 16> GEP1Ops, GEP2Ops;
+ BasePtr1 = GetGEPOperands(V1, GEP1Ops);
+ BasePtr2 = GetGEPOperands(V2, GEP2Ops);
+
+ // If GetGEPOperands were able to fold to the same must-aliased pointer,
+ // do the comparison.
+ if (BasePtr1 == BasePtr2) {
+ AliasResult GAlias =
+ CheckGEPInstructions(BasePtr1->getType(),
+ &GEP1Ops[0], GEP1Ops.size(), V1Size,
+ BasePtr2->getType(),
+ &GEP2Ops[0], GEP2Ops.size(), V2Size);
+ if (GAlias != MayAlias)
+ return GAlias;
+ }
+ }
+ }
+
+ // Check to see if these two pointers are related by a getelementptr
+ // instruction. If one pointer is a GEP with a non-zero index of the other
+ // pointer, we know they cannot alias.
+ //
+ if (isGEP(V2)) {
+ std::swap(V1, V2);
+ std::swap(V1Size, V2Size);
+ }
+
+ if (V1Size != ~0U && V2Size != ~0U)
+ if (isGEP(V1)) {
+ SmallVector<Value*, 16> GEPOperands;
+ const Value *BasePtr = GetGEPOperands(V1, GEPOperands);
+
+ AliasResult R = alias(BasePtr, V1Size, V2, V2Size);
+ if (R == MustAlias) {
+ // If there is at least one non-zero constant index, we know they cannot
+ // alias.
+ bool ConstantFound = false;
+ bool AllZerosFound = true;
+ for (unsigned i = 0, e = GEPOperands.size(); i != e; ++i)
+ if (const Constant *C = dyn_cast<Constant>(GEPOperands[i])) {
+ if (!C->isNullValue()) {
+ ConstantFound = true;
+ AllZerosFound = false;
+ break;
+ }
+ } else {
+ AllZerosFound = false;
+ }
+
+ // If we have getelementptr <ptr>, 0, 0, 0, 0, ... and V2 must aliases
+ // the ptr, the end result is a must alias also.
+ if (AllZerosFound)
+ return MustAlias;
+
+ if (ConstantFound) {
+ if (V2Size <= 1 && V1Size <= 1) // Just pointer check?
+ return NoAlias;
+
+ // Otherwise we have to check to see that the distance is more than
+ // the size of the argument... build an index vector that is equal to
+ // the arguments provided, except substitute 0's for any variable
+ // indexes we find...
+ if (cast<PointerType>(
+ BasePtr->getType())->getElementType()->isSized()) {
+ for (unsigned i = 0; i != GEPOperands.size(); ++i)
+ if (!isa<ConstantInt>(GEPOperands[i]))
+ GEPOperands[i] =
+ Constant::getNullValue(GEPOperands[i]->getType());
+ int64_t Offset =
+ getTargetData().getIndexedOffset(BasePtr->getType(),
+ &GEPOperands[0],
+ GEPOperands.size());
+
+ if (Offset >= (int64_t)V2Size || Offset <= -(int64_t)V1Size)
+ return NoAlias;
+ }
+ }
+ }
+ }
+
+ return MayAlias;
+}
+
+// This function is used to determin if the indices of two GEP instructions are
+// equal. V1 and V2 are the indices.
+static bool IndexOperandsEqual(Value *V1, Value *V2) {
+ if (V1->getType() == V2->getType())
+ return V1 == V2;
+ if (Constant *C1 = dyn_cast<Constant>(V1))
+ if (Constant *C2 = dyn_cast<Constant>(V2)) {
+ // Sign extend the constants to long types, if necessary
+ if (C1->getType() != Type::Int64Ty)
+ C1 = ConstantExpr::getSExt(C1, Type::Int64Ty);
+ if (C2->getType() != Type::Int64Ty)
+ C2 = ConstantExpr::getSExt(C2, Type::Int64Ty);
+ return C1 == C2;
+ }
+ return false;
+}
+
+/// CheckGEPInstructions - Check two GEP instructions with known must-aliasing
+/// base pointers. This checks to see if the index expressions preclude the
+/// pointers from aliasing...
+AliasAnalysis::AliasResult
+BasicAliasAnalysis::CheckGEPInstructions(
+ const Type* BasePtr1Ty, Value **GEP1Ops, unsigned NumGEP1Ops, unsigned G1S,
+ const Type *BasePtr2Ty, Value **GEP2Ops, unsigned NumGEP2Ops, unsigned G2S) {
+ // We currently can't handle the case when the base pointers have different
+ // primitive types. Since this is uncommon anyway, we are happy being
+ // extremely conservative.
+ if (BasePtr1Ty != BasePtr2Ty)
+ return MayAlias;
+
+ const PointerType *GEPPointerTy = cast<PointerType>(BasePtr1Ty);
+
+ // Find the (possibly empty) initial sequence of equal values... which are not
+ // necessarily constants.
+ unsigned NumGEP1Operands = NumGEP1Ops, NumGEP2Operands = NumGEP2Ops;
+ unsigned MinOperands = std::min(NumGEP1Operands, NumGEP2Operands);
+ unsigned MaxOperands = std::max(NumGEP1Operands, NumGEP2Operands);
+ unsigned UnequalOper = 0;
+ while (UnequalOper != MinOperands &&
+ IndexOperandsEqual(GEP1Ops[UnequalOper], GEP2Ops[UnequalOper])) {
+ // Advance through the type as we go...
+ ++UnequalOper;
+ if (const CompositeType *CT = dyn_cast<CompositeType>(BasePtr1Ty))
+ BasePtr1Ty = CT->getTypeAtIndex(GEP1Ops[UnequalOper-1]);
+ else {
+ // If all operands equal each other, then the derived pointers must
+ // alias each other...
+ BasePtr1Ty = 0;
+ assert(UnequalOper == NumGEP1Operands && UnequalOper == NumGEP2Operands &&
+ "Ran out of type nesting, but not out of operands?");
+ return MustAlias;
+ }
+ }
+
+ // If we have seen all constant operands, and run out of indexes on one of the
+ // getelementptrs, check to see if the tail of the leftover one is all zeros.
+ // If so, return mustalias.
+ if (UnequalOper == MinOperands) {
+ if (NumGEP1Ops < NumGEP2Ops) {
+ std::swap(GEP1Ops, GEP2Ops);
+ std::swap(NumGEP1Ops, NumGEP2Ops);
+ }
+
+ bool AllAreZeros = true;
+ for (unsigned i = UnequalOper; i != MaxOperands; ++i)
+ if (!isa<Constant>(GEP1Ops[i]) ||
+ !cast<Constant>(GEP1Ops[i])->isNullValue()) {
+ AllAreZeros = false;
+ break;
+ }
+ if (AllAreZeros) return MustAlias;
+ }
+
+
+ // So now we know that the indexes derived from the base pointers,
+ // which are known to alias, are different. We can still determine a
+ // no-alias result if there are differing constant pairs in the index
+ // chain. For example:
+ // A[i][0] != A[j][1] iff (&A[0][1]-&A[0][0] >= std::max(G1S, G2S))
+ //
+ // We have to be careful here about array accesses. In particular, consider:
+ // A[1][0] vs A[0][i]
+ // In this case, we don't *know* that the array will be accessed in bounds:
+ // the index could even be negative. Because of this, we have to
+ // conservatively *give up* and return may alias. We disregard differing
+ // array subscripts that are followed by a variable index without going
+ // through a struct.
+ //
+ unsigned SizeMax = std::max(G1S, G2S);
+ if (SizeMax == ~0U) return MayAlias; // Avoid frivolous work.
+
+ // Scan for the first operand that is constant and unequal in the
+ // two getelementptrs...
+ unsigned FirstConstantOper = UnequalOper;
+ for (; FirstConstantOper != MinOperands; ++FirstConstantOper) {
+ const Value *G1Oper = GEP1Ops[FirstConstantOper];
+ const Value *G2Oper = GEP2Ops[FirstConstantOper];
+
+ if (G1Oper != G2Oper) // Found non-equal constant indexes...
+ if (Constant *G1OC = dyn_cast<ConstantInt>(const_cast<Value*>(G1Oper)))
+ if (Constant *G2OC = dyn_cast<ConstantInt>(const_cast<Value*>(G2Oper))){
+ if (G1OC->getType() != G2OC->getType()) {
+ // Sign extend both operands to long.
+ if (G1OC->getType() != Type::Int64Ty)
+ G1OC = ConstantExpr::getSExt(G1OC, Type::Int64Ty);
+ if (G2OC->getType() != Type::Int64Ty)
+ G2OC = ConstantExpr::getSExt(G2OC, Type::Int64Ty);
+ GEP1Ops[FirstConstantOper] = G1OC;
+ GEP2Ops[FirstConstantOper] = G2OC;
+ }
+
+ if (G1OC != G2OC) {
+ // Handle the "be careful" case above: if this is an array/vector
+ // subscript, scan for a subsequent variable array index.
+ if (isa<SequentialType>(BasePtr1Ty)) {
+ const Type *NextTy =
+ cast<SequentialType>(BasePtr1Ty)->getElementType();
+ bool isBadCase = false;
+
+ for (unsigned Idx = FirstConstantOper+1;
+ Idx != MinOperands && isa<SequentialType>(NextTy); ++Idx) {
+ const Value *V1 = GEP1Ops[Idx], *V2 = GEP2Ops[Idx];
+ if (!isa<Constant>(V1) || !isa<Constant>(V2)) {
+ isBadCase = true;
+ break;
+ }
+ NextTy = cast<SequentialType>(NextTy)->getElementType();
+ }
+
+ if (isBadCase) G1OC = 0;
+ }
+
+ // Make sure they are comparable (ie, not constant expressions), and
+ // make sure the GEP with the smaller leading constant is GEP1.
+ if (G1OC) {
+ Constant *Compare = ConstantExpr::getICmp(ICmpInst::ICMP_SGT,
+ G1OC, G2OC);
+ if (ConstantInt *CV = dyn_cast<ConstantInt>(Compare)) {
+ if (CV->getZExtValue()) { // If they are comparable and G2 > G1
+ std::swap(GEP1Ops, GEP2Ops); // Make GEP1 < GEP2
+ std::swap(NumGEP1Ops, NumGEP2Ops);
+ }
+ break;
+ }
+ }
+ }
+ }
+ BasePtr1Ty = cast<CompositeType>(BasePtr1Ty)->getTypeAtIndex(G1Oper);
+ }
+
+ // No shared constant operands, and we ran out of common operands. At this
+ // point, the GEP instructions have run through all of their operands, and we
+ // haven't found evidence that there are any deltas between the GEP's.
+ // However, one GEP may have more operands than the other. If this is the
+ // case, there may still be hope. Check this now.
+ if (FirstConstantOper == MinOperands) {
+ // Make GEP1Ops be the longer one if there is a longer one.
+ if (NumGEP1Ops < NumGEP2Ops) {
+ std::swap(GEP1Ops, GEP2Ops);
+ std::swap(NumGEP1Ops, NumGEP2Ops);
+ }
+
+ // Is there anything to check?
+ if (NumGEP1Ops > MinOperands) {
+ for (unsigned i = FirstConstantOper; i != MaxOperands; ++i)
+ if (isa<ConstantInt>(GEP1Ops[i]) &&
+ !cast<ConstantInt>(GEP1Ops[i])->isZero()) {
+ // Yup, there's a constant in the tail. Set all variables to
+ // constants in the GEP instruction to make it suiteable for
+ // TargetData::getIndexedOffset.
+ for (i = 0; i != MaxOperands; ++i)
+ if (!isa<ConstantInt>(GEP1Ops[i]))
+ GEP1Ops[i] = Constant::getNullValue(GEP1Ops[i]->getType());
+ // Okay, now get the offset. This is the relative offset for the full
+ // instruction.
+ const TargetData &TD = getTargetData();
+ int64_t Offset1 = TD.getIndexedOffset(GEPPointerTy, GEP1Ops,
+ NumGEP1Ops);
+
+ // Now check without any constants at the end.
+ int64_t Offset2 = TD.getIndexedOffset(GEPPointerTy, GEP1Ops,
+ MinOperands);
+
+ // If the tail provided a bit enough offset, return noalias!
+ if ((uint64_t)(Offset2-Offset1) >= SizeMax)
+ return NoAlias;
+ }
+ }
+
+ // Couldn't find anything useful.
+ return MayAlias;
+ }
+
+ // If there are non-equal constants arguments, then we can figure
+ // out a minimum known delta between the two index expressions... at
+ // this point we know that the first constant index of GEP1 is less
+ // than the first constant index of GEP2.
+
+ // Advance BasePtr[12]Ty over this first differing constant operand.
+ BasePtr2Ty = cast<CompositeType>(BasePtr1Ty)->
+ getTypeAtIndex(GEP2Ops[FirstConstantOper]);
+ BasePtr1Ty = cast<CompositeType>(BasePtr1Ty)->
+ getTypeAtIndex(GEP1Ops[FirstConstantOper]);
+
+ // We are going to be using TargetData::getIndexedOffset to determine the
+ // offset that each of the GEP's is reaching. To do this, we have to convert
+ // all variable references to constant references. To do this, we convert the
+ // initial sequence of array subscripts into constant zeros to start with.
+ const Type *ZeroIdxTy = GEPPointerTy;
+ for (unsigned i = 0; i != FirstConstantOper; ++i) {
+ if (!isa<StructType>(ZeroIdxTy))
+ GEP1Ops[i] = GEP2Ops[i] = Constant::getNullValue(Type::Int32Ty);
+
+ if (const CompositeType *CT = dyn_cast<CompositeType>(ZeroIdxTy))
+ ZeroIdxTy = CT->getTypeAtIndex(GEP1Ops[i]);
+ }
+
+ // We know that GEP1Ops[FirstConstantOper] & GEP2Ops[FirstConstantOper] are ok
+
+ // Loop over the rest of the operands...
+ for (unsigned i = FirstConstantOper+1; i != MaxOperands; ++i) {
+ const Value *Op1 = i < NumGEP1Ops ? GEP1Ops[i] : 0;
+ const Value *Op2 = i < NumGEP2Ops ? GEP2Ops[i] : 0;
+ // If they are equal, use a zero index...
+ if (Op1 == Op2 && BasePtr1Ty == BasePtr2Ty) {
+ if (!isa<ConstantInt>(Op1))
+ GEP1Ops[i] = GEP2Ops[i] = Constant::getNullValue(Op1->getType());
+ // Otherwise, just keep the constants we have.
+ } else {
+ if (Op1) {
+ if (const ConstantInt *Op1C = dyn_cast<ConstantInt>(Op1)) {
+ // If this is an array index, make sure the array element is in range.
+ if (const ArrayType *AT = dyn_cast<ArrayType>(BasePtr1Ty)) {
+ if (Op1C->getZExtValue() >= AT->getNumElements())
+ return MayAlias; // Be conservative with out-of-range accesses
+ } else if (const VectorType *PT = dyn_cast<VectorType>(BasePtr1Ty)) {
+ if (Op1C->getZExtValue() >= PT->getNumElements())
+ return MayAlias; // Be conservative with out-of-range accesses
+ }
+
+ } else {
+ // GEP1 is known to produce a value less than GEP2. To be
+ // conservatively correct, we must assume the largest possible
+ // constant is used in this position. This cannot be the initial
+ // index to the GEP instructions (because we know we have at least one
+ // element before this one with the different constant arguments), so
+ // we know that the current index must be into either a struct or
+ // array. Because we know it's not constant, this cannot be a
+ // structure index. Because of this, we can calculate the maximum
+ // value possible.
+ //
+ if (const ArrayType *AT = dyn_cast<ArrayType>(BasePtr1Ty))
+ GEP1Ops[i] = ConstantInt::get(Type::Int64Ty,AT->getNumElements()-1);
+ else if (const VectorType *PT = dyn_cast<VectorType>(BasePtr1Ty))
+ GEP1Ops[i] = ConstantInt::get(Type::Int64Ty,PT->getNumElements()-1);
+
+ }
+ }
+
+ if (Op2) {
+ if (const ConstantInt *Op2C = dyn_cast<ConstantInt>(Op2)) {
+ // If this is an array index, make sure the array element is in range.
+ if (const ArrayType *AT = dyn_cast<ArrayType>(BasePtr1Ty)) {
+ if (Op2C->getZExtValue() >= AT->getNumElements())
+ return MayAlias; // Be conservative with out-of-range accesses
+ } else if (const VectorType *PT = dyn_cast<VectorType>(BasePtr1Ty)) {
+ if (Op2C->getZExtValue() >= PT->getNumElements())
+ return MayAlias; // Be conservative with out-of-range accesses
+ }
+ } else { // Conservatively assume the minimum value for this index
+ GEP2Ops[i] = Constant::getNullValue(Op2->getType());
+ }
+ }
+ }
+
+ if (BasePtr1Ty && Op1) {
+ if (const CompositeType *CT = dyn_cast<CompositeType>(BasePtr1Ty))
+ BasePtr1Ty = CT->getTypeAtIndex(GEP1Ops[i]);
+ else
+ BasePtr1Ty = 0;
+ }
+
+ if (BasePtr2Ty && Op2) {
+ if (const CompositeType *CT = dyn_cast<CompositeType>(BasePtr2Ty))
+ BasePtr2Ty = CT->getTypeAtIndex(GEP2Ops[i]);
+ else
+ BasePtr2Ty = 0;
+ }
+ }
+
+ if (GEPPointerTy->getElementType()->isSized()) {
+ int64_t Offset1 =
+ getTargetData().getIndexedOffset(GEPPointerTy, GEP1Ops, NumGEP1Ops);
+ int64_t Offset2 =
+ getTargetData().getIndexedOffset(GEPPointerTy, GEP2Ops, NumGEP2Ops);
+ assert(Offset1<Offset2 && "There is at least one different constant here!");
+
+ if ((uint64_t)(Offset2-Offset1) >= SizeMax) {
+ //cerr << "Determined that these two GEP's don't alias ["
+ // << SizeMax << " bytes]: \n" << *GEP1 << *GEP2;
+ return NoAlias;
+ }
+ }
+ return MayAlias;
+}
+
+namespace {
+ struct VISIBILITY_HIDDEN StringCompare {
+ bool operator()(const char *LHS, const char *RHS) {
+ return strcmp(LHS, RHS) < 0;
+ }
+ };
+}
+
+// Note that this list cannot contain libm functions (such as acos and sqrt)
+// that set errno on a domain or other error.
+static const char *DoesntAccessMemoryFns[] = {
+ "abs", "labs", "llabs", "imaxabs", "fabs", "fabsf", "fabsl",
+ "trunc", "truncf", "truncl", "ldexp",
+
+ "atan", "atanf", "atanl", "atan2", "atan2f", "atan2l",
+ "cbrt",
+ "cos", "cosf", "cosl",
+ "exp", "expf", "expl",
+ "hypot",
+ "sin", "sinf", "sinl",
+ "tan", "tanf", "tanl", "tanh", "tanhf", "tanhl",
+
+ "floor", "floorf", "floorl", "ceil", "ceilf", "ceill",
+
+ // ctype.h
+ "isalnum", "isalpha", "iscntrl", "isdigit", "isgraph", "islower", "isprint"
+ "ispunct", "isspace", "isupper", "isxdigit", "tolower", "toupper",
+
+ // wctype.h"
+ "iswalnum", "iswalpha", "iswcntrl", "iswdigit", "iswgraph", "iswlower",
+ "iswprint", "iswpunct", "iswspace", "iswupper", "iswxdigit",
+
+ "iswctype", "towctrans", "towlower", "towupper",
+
+ "btowc", "wctob",
+
+ "isinf", "isnan", "finite",
+
+ // C99 math functions
+ "copysign", "copysignf", "copysignd",
+ "nexttoward", "nexttowardf", "nexttowardd",
+ "nextafter", "nextafterf", "nextafterd",
+
+ // ISO C99:
+ "__signbit", "__signbitf", "__signbitl",
+};
+
+
+static const char *OnlyReadsMemoryFns[] = {
+ "atoi", "atol", "atof", "atoll", "atoq", "a64l",
+ "bcmp", "memcmp", "memchr", "memrchr", "wmemcmp", "wmemchr",
+
+ // Strings
+ "strcmp", "strcasecmp", "strcoll", "strncmp", "strncasecmp",
+ "strchr", "strcspn", "strlen", "strpbrk", "strrchr", "strspn", "strstr",
+ "index", "rindex",
+
+ // Wide char strings
+ "wcschr", "wcscmp", "wcscoll", "wcscspn", "wcslen", "wcsncmp", "wcspbrk",
+ "wcsrchr", "wcsspn", "wcsstr",
+
+ // glibc
+ "alphasort", "alphasort64", "versionsort", "versionsort64",
+
+ // C99
+ "nan", "nanf", "nand",
+
+ // File I/O
+ "feof", "ferror", "fileno",
+ "feof_unlocked", "ferror_unlocked", "fileno_unlocked"
+};
+
+static ManagedStatic<std::vector<const char*> > NoMemoryTable;
+static ManagedStatic<std::vector<const char*> > OnlyReadsMemoryTable;
+
+
+AliasAnalysis::ModRefBehavior
+BasicAliasAnalysis::getModRefBehavior(Function *F, CallSite CS,
+ std::vector<PointerAccessInfo> *Info) {
+ if (!F->isDeclaration()) return UnknownModRefBehavior;
+
+ static bool Initialized = false;
+ if (!Initialized) {
+ NoMemoryTable->insert(NoMemoryTable->end(),
+ DoesntAccessMemoryFns,
+ DoesntAccessMemoryFns+
+ sizeof(DoesntAccessMemoryFns)/sizeof(DoesntAccessMemoryFns[0]));
+
+ OnlyReadsMemoryTable->insert(OnlyReadsMemoryTable->end(),
+ OnlyReadsMemoryFns,
+ OnlyReadsMemoryFns+
+ sizeof(OnlyReadsMemoryFns)/sizeof(OnlyReadsMemoryFns[0]));
+#define GET_MODREF_BEHAVIOR
+#include "llvm/Intrinsics.gen"
+#undef GET_MODREF_BEHAVIOR
+
+ // Sort the table the first time through.
+ std::sort(NoMemoryTable->begin(), NoMemoryTable->end(), StringCompare());
+ std::sort(OnlyReadsMemoryTable->begin(), OnlyReadsMemoryTable->end(),
+ StringCompare());
+ Initialized = true;
+ }
+
+ std::vector<const char*>::iterator Ptr =
+ std::lower_bound(NoMemoryTable->begin(), NoMemoryTable->end(),
+ F->getName().c_str(), StringCompare());
+ if (Ptr != NoMemoryTable->end() && *Ptr == F->getName())
+ return DoesNotAccessMemory;
+
+ Ptr = std::lower_bound(OnlyReadsMemoryTable->begin(),
+ OnlyReadsMemoryTable->end(),
+ F->getName().c_str(), StringCompare());
+ if (Ptr != OnlyReadsMemoryTable->end() && *Ptr == F->getName())
+ return OnlyReadsMemory;
+
+ return UnknownModRefBehavior;
+}
+
+// Make sure that anything that uses AliasAnalysis pulls in this file...
+DEFINING_FILE_FOR(BasicAliasAnalysis)
diff --git a/lib/Analysis/CFGPrinter.cpp b/lib/Analysis/CFGPrinter.cpp
new file mode 100644
index 0000000..d32481e
--- /dev/null
+++ b/lib/Analysis/CFGPrinter.cpp
@@ -0,0 +1,214 @@
+//===- CFGPrinter.cpp - DOT printer for the control flow graph ------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines a '-print-cfg' analysis pass, which emits the
+// cfg.<fnname>.dot file for each function in the program, with a graph of the
+// CFG for that function.
+//
+// The other main feature of this file is that it implements the
+// Function::viewCFG method, which is useful for debugging passes which operate
+// on the CFG.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Function.h"
+#include "llvm/Instructions.h"
+#include "llvm/Pass.h"
+#include "llvm/Analysis/CFGPrinter.h"
+#include "llvm/Assembly/Writer.h"
+#include "llvm/Support/CFG.h"
+#include "llvm/Support/Compiler.h"
+#include "llvm/Support/GraphWriter.h"
+#include "llvm/Config/config.h"
+#include <iosfwd>
+#include <sstream>
+#include <fstream>
+using namespace llvm;
+
+/// CFGOnly flag - This is used to control whether or not the CFG graph printer
+/// prints out the contents of basic blocks or not. This is acceptable because
+/// this code is only really used for debugging purposes.
+///
+static bool CFGOnly = false;
+
+namespace llvm {
+template<>
+struct DOTGraphTraits<const Function*> : public DefaultDOTGraphTraits {
+ static std::string getGraphName(const Function *F) {
+ return "CFG for '" + F->getName() + "' function";
+ }
+
+ static std::string getNodeLabel(const BasicBlock *Node,
+ const Function *Graph) {
+ if (CFGOnly && !Node->getName().empty())
+ return Node->getName() + ":";
+
+ std::ostringstream Out;
+ if (CFGOnly) {
+ WriteAsOperand(Out, Node, false);
+ return Out.str();
+ }
+
+ if (Node->getName().empty()) {
+ WriteAsOperand(Out, Node, false);
+ Out << ":";
+ }
+
+ Out << *Node;
+ std::string OutStr = Out.str();
+ if (OutStr[0] == '\n') OutStr.erase(OutStr.begin());
+
+ // Process string output to make it nicer...
+ for (unsigned i = 0; i != OutStr.length(); ++i)
+ if (OutStr[i] == '\n') { // Left justify
+ OutStr[i] = '\\';
+ OutStr.insert(OutStr.begin()+i+1, 'l');
+ } else if (OutStr[i] == ';') { // Delete comments!
+ unsigned Idx = OutStr.find('\n', i+1); // Find end of line
+ OutStr.erase(OutStr.begin()+i, OutStr.begin()+Idx);
+ --i;
+ }
+
+ return OutStr;
+ }
+
+ static std::string getEdgeSourceLabel(const BasicBlock *Node,
+ succ_const_iterator I) {
+ // Label source of conditional branches with "T" or "F"
+ if (const BranchInst *BI = dyn_cast<BranchInst>(Node->getTerminator()))
+ if (BI->isConditional())
+ return (I == succ_begin(Node)) ? "T" : "F";
+ return "";
+ }
+};
+}
+
+namespace {
+ struct VISIBILITY_HIDDEN CFGViewer : public FunctionPass {
+ static char ID; // Pass identifcation, replacement for typeid
+ CFGViewer() : FunctionPass((intptr_t)&ID) {}
+
+ virtual bool runOnFunction(Function &F) {
+ F.viewCFG();
+ return false;
+ }
+
+ void print(std::ostream &OS, const Module* = 0) const {}
+
+ virtual void getAnalysisUsage(AnalysisUsage &AU) const {
+ AU.setPreservesAll();
+ }
+ };
+
+ char CFGViewer::ID = 0;
+ RegisterPass<CFGViewer> V0("view-cfg",
+ "View CFG of function");
+
+ struct VISIBILITY_HIDDEN CFGOnlyViewer : public FunctionPass {
+ static char ID; // Pass identifcation, replacement for typeid
+ CFGOnlyViewer() : FunctionPass((intptr_t)&ID) {}
+
+ virtual bool runOnFunction(Function &F) {
+ CFGOnly = true;
+ F.viewCFG();
+ CFGOnly = false;
+ return false;
+ }
+
+ void print(std::ostream &OS, const Module* = 0) const {}
+
+ virtual void getAnalysisUsage(AnalysisUsage &AU) const {
+ AU.setPreservesAll();
+ }
+ };
+
+ char CFGOnlyViewer::ID = 0;
+ RegisterPass<CFGOnlyViewer> V1("view-cfg-only",
+ "View CFG of function (with no function bodies)");
+
+ struct VISIBILITY_HIDDEN CFGPrinter : public FunctionPass {
+ static char ID; // Pass identification, replacement for typeid
+ CFGPrinter() : FunctionPass((intptr_t)&ID) {}
+ explicit CFGPrinter(intptr_t pid) : FunctionPass(pid) {}
+
+ virtual bool runOnFunction(Function &F) {
+ std::string Filename = "cfg." + F.getName() + ".dot";
+ cerr << "Writing '" << Filename << "'...";
+ std::ofstream File(Filename.c_str());
+
+ if (File.good())
+ WriteGraph(File, (const Function*)&F);
+ else
+ cerr << " error opening file for writing!";
+ cerr << "\n";
+ return false;
+ }
+
+ void print(std::ostream &OS, const Module* = 0) const {}
+
+ virtual void getAnalysisUsage(AnalysisUsage &AU) const {
+ AU.setPreservesAll();
+ }
+ };
+
+ char CFGPrinter::ID = 0;
+ RegisterPass<CFGPrinter> P1("print-cfg",
+ "Print CFG of function to 'dot' file");
+
+ struct VISIBILITY_HIDDEN CFGOnlyPrinter : public CFGPrinter {
+ static char ID; // Pass identification, replacement for typeid
+ CFGOnlyPrinter() : CFGPrinter((intptr_t)&ID) {}
+ virtual bool runOnFunction(Function &F) {
+ bool OldCFGOnly = CFGOnly;
+ CFGOnly = true;
+ CFGPrinter::runOnFunction(F);
+ CFGOnly = OldCFGOnly;
+ return false;
+ }
+ void print(std::ostream &OS, const Module* = 0) const {}
+
+ virtual void getAnalysisUsage(AnalysisUsage &AU) const {
+ AU.setPreservesAll();
+ }
+ };
+
+ char CFGOnlyPrinter::ID = 0;
+ RegisterPass<CFGOnlyPrinter>
+ P2("print-cfg-only",
+ "Print CFG of function to 'dot' file (with no function bodies)");
+}
+
+/// viewCFG - This function is meant for use from the debugger. You can just
+/// say 'call F->viewCFG()' and a ghostview window should pop up from the
+/// program, displaying the CFG of the current function. This depends on there
+/// being a 'dot' and 'gv' program in your path.
+///
+void Function::viewCFG() const {
+ ViewGraph(this, "cfg" + getName());
+}
+
+/// viewCFGOnly - This function is meant for use from the debugger. It works
+/// just like viewCFG, but it does not include the contents of basic blocks
+/// into the nodes, just the label. If you are only interested in the CFG t
+/// his can make the graph smaller.
+///
+void Function::viewCFGOnly() const {
+ CFGOnly = true;
+ viewCFG();
+ CFGOnly = false;
+}
+
+FunctionPass *llvm::createCFGPrinterPass () {
+ return new CFGPrinter();
+}
+
+FunctionPass *llvm::createCFGOnlyPrinterPass () {
+ return new CFGOnlyPrinter();
+}
+
diff --git a/lib/Analysis/ConstantFolding.cpp b/lib/Analysis/ConstantFolding.cpp
new file mode 100644
index 0000000..e85d150
--- /dev/null
+++ b/lib/Analysis/ConstantFolding.cpp
@@ -0,0 +1,486 @@
+//===-- ConstantFolding.cpp - Analyze constant folding possibilities ------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This family of functions determines the possibility of performing constant
+// folding.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Analysis/ConstantFolding.h"
+#include "llvm/Constants.h"
+#include "llvm/DerivedTypes.h"
+#include "llvm/Function.h"
+#include "llvm/Instructions.h"
+#include "llvm/Intrinsics.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/Target/TargetData.h"
+#include "llvm/Support/GetElementPtrTypeIterator.h"
+#include "llvm/Support/MathExtras.h"
+#include <cerrno>
+#include <cmath>
+using namespace llvm;
+
+//===----------------------------------------------------------------------===//
+// Constant Folding internal helper functions
+//===----------------------------------------------------------------------===//
+
+/// IsConstantOffsetFromGlobal - If this constant is actually a constant offset
+/// from a global, return the global and the constant. Because of
+/// constantexprs, this function is recursive.
+static bool IsConstantOffsetFromGlobal(Constant *C, GlobalValue *&GV,
+ int64_t &Offset, const TargetData &TD) {
+ // Trivial case, constant is the global.
+ if ((GV = dyn_cast<GlobalValue>(C))) {
+ Offset = 0;
+ return true;
+ }
+
+ // Otherwise, if this isn't a constant expr, bail out.
+ ConstantExpr *CE = dyn_cast<ConstantExpr>(C);
+ if (!CE) return false;
+
+ // Look through ptr->int and ptr->ptr casts.
+ if (CE->getOpcode() == Instruction::PtrToInt ||
+ CE->getOpcode() == Instruction::BitCast)
+ return IsConstantOffsetFromGlobal(CE->getOperand(0), GV, Offset, TD);
+
+ // i32* getelementptr ([5 x i32]* @a, i32 0, i32 5)
+ if (CE->getOpcode() == Instruction::GetElementPtr) {
+ // Cannot compute this if the element type of the pointer is missing size
+ // info.
+ if (!cast<PointerType>(CE->getOperand(0)->getType())->getElementType()->isSized())
+ return false;
+
+ // If the base isn't a global+constant, we aren't either.
+ if (!IsConstantOffsetFromGlobal(CE->getOperand(0), GV, Offset, TD))
+ return false;
+
+ // Otherwise, add any offset that our operands provide.
+ gep_type_iterator GTI = gep_type_begin(CE);
+ for (unsigned i = 1, e = CE->getNumOperands(); i != e; ++i, ++GTI) {
+ ConstantInt *CI = dyn_cast<ConstantInt>(CE->getOperand(i));
+ if (!CI) return false; // Index isn't a simple constant?
+ if (CI->getZExtValue() == 0) continue; // Not adding anything.
+
+ if (const StructType *ST = dyn_cast<StructType>(*GTI)) {
+ // N = N + Offset
+ Offset += TD.getStructLayout(ST)->getElementOffset(CI->getZExtValue());
+ } else {
+ const SequentialType *SQT = cast<SequentialType>(*GTI);
+ Offset += TD.getTypeSize(SQT->getElementType())*CI->getSExtValue();
+ }
+ }
+ return true;
+ }
+
+ return false;
+}
+
+
+/// SymbolicallyEvaluateBinop - One of Op0/Op1 is a constant expression.
+/// Attempt to symbolically evaluate the result of a binary operator merging
+/// these together. If target data info is available, it is provided as TD,
+/// otherwise TD is null.
+static Constant *SymbolicallyEvaluateBinop(unsigned Opc, Constant *Op0,
+ Constant *Op1, const TargetData *TD){
+ // SROA
+
+ // Fold (and 0xffffffff00000000, (shl x, 32)) -> shl.
+ // Fold (lshr (or X, Y), 32) -> (lshr [X/Y], 32) if one doesn't contribute
+ // bits.
+
+
+ // If the constant expr is something like &A[123] - &A[4].f, fold this into a
+ // constant. This happens frequently when iterating over a global array.
+ if (Opc == Instruction::Sub && TD) {
+ GlobalValue *GV1, *GV2;
+ int64_t Offs1, Offs2;
+
+ if (IsConstantOffsetFromGlobal(Op0, GV1, Offs1, *TD))
+ if (IsConstantOffsetFromGlobal(Op1, GV2, Offs2, *TD) &&
+ GV1 == GV2) {
+ // (&GV+C1) - (&GV+C2) -> C1-C2, pointer arithmetic cannot overflow.
+ return ConstantInt::get(Op0->getType(), Offs1-Offs2);
+ }
+ }
+
+ // TODO: Fold icmp setne/seteq as well.
+ return 0;
+}
+
+/// SymbolicallyEvaluateGEP - If we can symbolically evaluate the specified GEP
+/// constant expression, do so.
+static Constant *SymbolicallyEvaluateGEP(Constant** Ops, unsigned NumOps,
+ const Type *ResultTy,
+ const TargetData *TD) {
+ Constant *Ptr = Ops[0];
+ if (!cast<PointerType>(Ptr->getType())->getElementType()->isSized())
+ return 0;
+
+ if (TD && Ptr->isNullValue()) {
+ // If this is a constant expr gep that is effectively computing an
+ // "offsetof", fold it into 'cast int Size to T*' instead of 'gep 0, 0, 12'
+ bool isFoldableGEP = true;
+ for (unsigned i = 1; i != NumOps; ++i)
+ if (!isa<ConstantInt>(Ops[i])) {
+ isFoldableGEP = false;
+ break;
+ }
+ if (isFoldableGEP) {
+ uint64_t Offset = TD->getIndexedOffset(Ptr->getType(),
+ (Value**)Ops+1, NumOps-1);
+ Constant *C = ConstantInt::get(TD->getIntPtrType(), Offset);
+ return ConstantExpr::getIntToPtr(C, ResultTy);
+ }
+ }
+
+ return 0;
+}
+
+
+//===----------------------------------------------------------------------===//
+// Constant Folding public APIs
+//===----------------------------------------------------------------------===//
+
+
+/// ConstantFoldInstruction - Attempt to constant fold the specified
+/// instruction. If successful, the constant result is returned, if not, null
+/// is returned. Note that this function can only fail when attempting to fold
+/// instructions like loads and stores, which have no constant expression form.
+///
+Constant *llvm::ConstantFoldInstruction(Instruction *I, const TargetData *TD) {
+ if (PHINode *PN = dyn_cast<PHINode>(I)) {
+ if (PN->getNumIncomingValues() == 0)
+ return Constant::getNullValue(PN->getType());
+
+ Constant *Result = dyn_cast<Constant>(PN->getIncomingValue(0));
+ if (Result == 0) return 0;
+
+ // Handle PHI nodes specially here...
+ for (unsigned i = 1, e = PN->getNumIncomingValues(); i != e; ++i)
+ if (PN->getIncomingValue(i) != Result && PN->getIncomingValue(i) != PN)
+ return 0; // Not all the same incoming constants...
+
+ // If we reach here, all incoming values are the same constant.
+ return Result;
+ }
+
+ // Scan the operand list, checking to see if they are all constants, if so,
+ // hand off to ConstantFoldInstOperands.
+ SmallVector<Constant*, 8> Ops;
+ for (unsigned i = 0, e = I->getNumOperands(); i != e; ++i)
+ if (Constant *Op = dyn_cast<Constant>(I->getOperand(i)))
+ Ops.push_back(Op);
+ else
+ return 0; // All operands not constant!
+
+ return ConstantFoldInstOperands(I, &Ops[0], Ops.size(), TD);
+}
+
+/// ConstantFoldInstOperands - Attempt to constant fold an instruction with the
+/// specified opcode and operands. If successful, the constant result is
+/// returned, if not, null is returned. Note that this function can fail when
+/// attempting to fold instructions like loads and stores, which have no
+/// constant expression form.
+///
+Constant *llvm::ConstantFoldInstOperands(const Instruction* I,
+ Constant** Ops, unsigned NumOps,
+ const TargetData *TD) {
+ unsigned Opc = I->getOpcode();
+ const Type *DestTy = I->getType();
+
+ // Handle easy binops first.
+ if (isa<BinaryOperator>(I)) {
+ if (isa<ConstantExpr>(Ops[0]) || isa<ConstantExpr>(Ops[1]))
+ if (Constant *C = SymbolicallyEvaluateBinop(I->getOpcode(), Ops[0],
+ Ops[1], TD))
+ return C;
+
+ return ConstantExpr::get(Opc, Ops[0], Ops[1]);
+ }
+
+ switch (Opc) {
+ default: return 0;
+ case Instruction::Call:
+ if (Function *F = dyn_cast<Function>(Ops[0]))
+ if (canConstantFoldCallTo(F))
+ return ConstantFoldCall(F, Ops+1, NumOps-1);
+ return 0;
+ case Instruction::ICmp:
+ case Instruction::FCmp:
+ return ConstantExpr::getCompare(cast<CmpInst>(I)->getPredicate(), Ops[0],
+ Ops[1]);
+ case Instruction::Trunc:
+ case Instruction::ZExt:
+ case Instruction::SExt:
+ case Instruction::FPTrunc:
+ case Instruction::FPExt:
+ case Instruction::UIToFP:
+ case Instruction::SIToFP:
+ case Instruction::FPToUI:
+ case Instruction::FPToSI:
+ case Instruction::PtrToInt:
+ case Instruction::IntToPtr:
+ case Instruction::BitCast:
+ return ConstantExpr::getCast(Opc, Ops[0], DestTy);
+ case Instruction::Select:
+ return ConstantExpr::getSelect(Ops[0], Ops[1], Ops[2]);
+ case Instruction::ExtractElement:
+ return ConstantExpr::getExtractElement(Ops[0], Ops[1]);
+ case Instruction::InsertElement:
+ return ConstantExpr::getInsertElement(Ops[0], Ops[1], Ops[2]);
+ case Instruction::ShuffleVector:
+ return ConstantExpr::getShuffleVector(Ops[0], Ops[1], Ops[2]);
+ case Instruction::GetElementPtr:
+ if (Constant *C = SymbolicallyEvaluateGEP(Ops, NumOps, I->getType(), TD))
+ return C;
+
+ return ConstantExpr::getGetElementPtr(Ops[0], Ops+1, NumOps-1);
+ }
+}
+
+/// ConstantFoldLoadThroughGEPConstantExpr - Given a constant and a
+/// getelementptr constantexpr, return the constant value being addressed by the
+/// constant expression, or null if something is funny and we can't decide.
+Constant *llvm::ConstantFoldLoadThroughGEPConstantExpr(Constant *C,
+ ConstantExpr *CE) {
+ if (CE->getOperand(1) != Constant::getNullValue(CE->getOperand(1)->getType()))
+ return 0; // Do not allow stepping over the value!
+
+ // Loop over all of the operands, tracking down which value we are
+ // addressing...
+ gep_type_iterator I = gep_type_begin(CE), E = gep_type_end(CE);
+ for (++I; I != E; ++I)
+ if (const StructType *STy = dyn_cast<StructType>(*I)) {
+ ConstantInt *CU = cast<ConstantInt>(I.getOperand());
+ assert(CU->getZExtValue() < STy->getNumElements() &&
+ "Struct index out of range!");
+ unsigned El = (unsigned)CU->getZExtValue();
+ if (ConstantStruct *CS = dyn_cast<ConstantStruct>(C)) {
+ C = CS->getOperand(El);
+ } else if (isa<ConstantAggregateZero>(C)) {
+ C = Constant::getNullValue(STy->getElementType(El));
+ } else if (isa<UndefValue>(C)) {
+ C = UndefValue::get(STy->getElementType(El));
+ } else {
+ return 0;
+ }
+ } else if (ConstantInt *CI = dyn_cast<ConstantInt>(I.getOperand())) {
+ if (const ArrayType *ATy = dyn_cast<ArrayType>(*I)) {
+ if (CI->getZExtValue() >= ATy->getNumElements())
+ return 0;
+ if (ConstantArray *CA = dyn_cast<ConstantArray>(C))
+ C = CA->getOperand(CI->getZExtValue());
+ else if (isa<ConstantAggregateZero>(C))
+ C = Constant::getNullValue(ATy->getElementType());
+ else if (isa<UndefValue>(C))
+ C = UndefValue::get(ATy->getElementType());
+ else
+ return 0;
+ } else if (const VectorType *PTy = dyn_cast<VectorType>(*I)) {
+ if (CI->getZExtValue() >= PTy->getNumElements())
+ return 0;
+ if (ConstantVector *CP = dyn_cast<ConstantVector>(C))
+ C = CP->getOperand(CI->getZExtValue());
+ else if (isa<ConstantAggregateZero>(C))
+ C = Constant::getNullValue(PTy->getElementType());
+ else if (isa<UndefValue>(C))
+ C = UndefValue::get(PTy->getElementType());
+ else
+ return 0;
+ } else {
+ return 0;
+ }
+ } else {
+ return 0;
+ }
+ return C;
+}
+
+
+//===----------------------------------------------------------------------===//
+// Constant Folding for Calls
+//
+
+/// canConstantFoldCallTo - Return true if its even possible to fold a call to
+/// the specified function.
+bool
+llvm::canConstantFoldCallTo(Function *F) {
+ const std::string &Name = F->getName();
+
+ switch (F->getIntrinsicID()) {
+ case Intrinsic::sqrt_f32:
+ case Intrinsic::sqrt_f64:
+ case Intrinsic::powi_f32:
+ case Intrinsic::powi_f64:
+ case Intrinsic::bswap:
+ case Intrinsic::ctpop:
+ case Intrinsic::ctlz:
+ case Intrinsic::cttz:
+ return true;
+ default: break;
+ }
+
+ switch (Name[0])
+ {
+ case 'a':
+ return Name == "acos" || Name == "asin" || Name == "atan" ||
+ Name == "atan2";
+ case 'c':
+ return Name == "ceil" || Name == "cos" || Name == "cosf" ||
+ Name == "cosh";
+ case 'e':
+ return Name == "exp";
+ case 'f':
+ return Name == "fabs" || Name == "fmod" || Name == "floor";
+ case 'l':
+ return Name == "log" || Name == "log10";
+ case 'p':
+ return Name == "pow";
+ case 's':
+ return Name == "sin" || Name == "sinh" ||
+ Name == "sqrt" || Name == "sqrtf";
+ case 't':
+ return Name == "tan" || Name == "tanh";
+ default:
+ return false;
+ }
+}
+
+static Constant *ConstantFoldFP(double (*NativeFP)(double), double V,
+ const Type *Ty) {
+ errno = 0;
+ V = NativeFP(V);
+ if (errno == 0)
+ return ConstantFP::get(Ty, V);
+ errno = 0;
+ return 0;
+}
+
+static Constant *ConstantFoldBinaryFP(double (*NativeFP)(double, double),
+ double V, double W,
+ const Type *Ty) {
+ errno = 0;
+ V = NativeFP(V, W);
+ if (errno == 0)
+ return ConstantFP::get(Ty, V);
+ errno = 0;
+ return 0;
+}
+
+/// ConstantFoldCall - Attempt to constant fold a call to the specified function
+/// with the specified arguments, returning null if unsuccessful.
+Constant *
+llvm::ConstantFoldCall(Function *F, Constant** Operands, unsigned NumOperands) {
+ const std::string &Name = F->getName();
+ const Type *Ty = F->getReturnType();
+
+ if (NumOperands == 1) {
+ if (ConstantFP *Op = dyn_cast<ConstantFP>(Operands[0])) {
+ double V = Op->getValue();
+ switch (Name[0])
+ {
+ case 'a':
+ if (Name == "acos")
+ return ConstantFoldFP(acos, V, Ty);
+ else if (Name == "asin")
+ return ConstantFoldFP(asin, V, Ty);
+ else if (Name == "atan")
+ return ConstantFoldFP(atan, V, Ty);
+ break;
+ case 'c':
+ if (Name == "ceil")
+ return ConstantFoldFP(ceil, V, Ty);
+ else if (Name == "cos")
+ return ConstantFoldFP(cos, V, Ty);
+ else if (Name == "cosh")
+ return ConstantFoldFP(cosh, V, Ty);
+ break;
+ case 'e':
+ if (Name == "exp")
+ return ConstantFoldFP(exp, V, Ty);
+ break;
+ case 'f':
+ if (Name == "fabs")
+ return ConstantFP::get(Ty, fabs(V));
+ else if (Name == "floor")
+ return ConstantFoldFP(floor, V, Ty);
+ break;
+ case 'l':
+ if (Name == "log" && V > 0)
+ return ConstantFoldFP(log, V, Ty);
+ else if (Name == "log10" && V > 0)
+ return ConstantFoldFP(log10, V, Ty);
+ else if (Name == "llvm.sqrt.f32" || Name == "llvm.sqrt.f64") {
+ if (V >= -0.0)
+ return ConstantFP::get(Ty, sqrt(V));
+ else // Undefined
+ return ConstantFP::get(Ty, 0.0);
+ }
+ break;
+ case 's':
+ if (Name == "sin")
+ return ConstantFoldFP(sin, V, Ty);
+ else if (Name == "sinh")
+ return ConstantFoldFP(sinh, V, Ty);
+ else if (Name == "sqrt" && V >= 0)
+ return ConstantFoldFP(sqrt, V, Ty);
+ else if (Name == "sqrtf" && V >= 0)
+ return ConstantFoldFP(sqrt, V, Ty);
+ break;
+ case 't':
+ if (Name == "tan")
+ return ConstantFoldFP(tan, V, Ty);
+ else if (Name == "tanh")
+ return ConstantFoldFP(tanh, V, Ty);
+ break;
+ default:
+ break;
+ }
+ } else if (ConstantInt *Op = dyn_cast<ConstantInt>(Operands[0])) {
+ if (Name.size() > 11 && !memcmp(&Name[0], "llvm.bswap", 10)) {
+ return ConstantInt::get(Op->getValue().byteSwap());
+ } else if (Name.size() > 11 && !memcmp(&Name[0],"llvm.ctpop",10)) {
+ uint64_t ctpop = Op->getValue().countPopulation();
+ return ConstantInt::get(Type::Int32Ty, ctpop);
+ } else if (Name.size() > 10 && !memcmp(&Name[0], "llvm.cttz", 9)) {
+ uint64_t cttz = Op->getValue().countTrailingZeros();
+ return ConstantInt::get(Type::Int32Ty, cttz);
+ } else if (Name.size() > 10 && !memcmp(&Name[0], "llvm.ctlz", 9)) {
+ uint64_t ctlz = Op->getValue().countLeadingZeros();
+ return ConstantInt::get(Type::Int32Ty, ctlz);
+ }
+ }
+ } else if (NumOperands == 2) {
+ if (ConstantFP *Op1 = dyn_cast<ConstantFP>(Operands[0])) {
+ double Op1V = Op1->getValue();
+ if (ConstantFP *Op2 = dyn_cast<ConstantFP>(Operands[1])) {
+ double Op2V = Op2->getValue();
+
+ if (Name == "pow") {
+ return ConstantFoldBinaryFP(pow, Op1V, Op2V, Ty);
+ } else if (Name == "fmod") {
+ return ConstantFoldBinaryFP(fmod, Op1V, Op2V, Ty);
+ } else if (Name == "atan2") {
+ return ConstantFoldBinaryFP(atan2, Op1V, Op2V, Ty);
+ }
+ } else if (ConstantInt *Op2C = dyn_cast<ConstantInt>(Operands[1])) {
+ if (Name == "llvm.powi.f32") {
+ return ConstantFP::get(Ty, std::pow((float)Op1V,
+ (int)Op2C->getZExtValue()));
+ } else if (Name == "llvm.powi.f64") {
+ return ConstantFP::get(Ty, std::pow((double)Op1V,
+ (int)Op2C->getZExtValue()));
+ }
+ }
+ }
+ }
+ return 0;
+}
+
diff --git a/lib/Analysis/IPA/Andersens.cpp b/lib/Analysis/IPA/Andersens.cpp
new file mode 100644
index 0000000..4c0d246
--- /dev/null
+++ b/lib/Analysis/IPA/Andersens.cpp
@@ -0,0 +1,1177 @@
+//===- Andersens.cpp - Andersen's Interprocedural Alias Analysis ----------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines a very simple implementation of Andersen's interprocedural
+// alias analysis. This implementation does not include any of the fancy
+// features that make Andersen's reasonably efficient (like cycle elimination or
+// variable substitution), but it should be useful for getting precision
+// numbers and can be extended in the future.
+//
+// In pointer analysis terms, this is a subset-based, flow-insensitive,
+// field-insensitive, and context-insensitive algorithm pointer algorithm.
+//
+// This algorithm is implemented as three stages:
+// 1. Object identification.
+// 2. Inclusion constraint identification.
+// 3. Inclusion constraint solving.
+//
+// The object identification stage identifies all of the memory objects in the
+// program, which includes globals, heap allocated objects, and stack allocated
+// objects.
+//
+// The inclusion constraint identification stage finds all inclusion constraints
+// in the program by scanning the program, looking for pointer assignments and
+// other statements that effect the points-to graph. For a statement like "A =
+// B", this statement is processed to indicate that A can point to anything that
+// B can point to. Constraints can handle copies, loads, and stores.
+//
+// The inclusion constraint solving phase iteratively propagates the inclusion
+// constraints until a fixed point is reached. This is an O(N^3) algorithm.
+//
+// In the initial pass, all indirect function calls are completely ignored. As
+// the analysis discovers new targets of function pointers, it iteratively
+// resolves a precise (and conservative) call graph. Also related, this
+// analysis initially assumes that all internal functions have known incoming
+// pointers. If we find that an internal function's address escapes outside of
+// the program, we update this assumption.
+//
+// Future Improvements:
+// This implementation of Andersen's algorithm is extremely slow. To make it
+// scale reasonably well, the inclusion constraints could be sorted (easy),
+// offline variable substitution would be a huge win (straight-forward), and
+// online cycle elimination (trickier) might help as well.
+//
+//===----------------------------------------------------------------------===//
+
+#define DEBUG_TYPE "anders-aa"
+#include "llvm/Constants.h"
+#include "llvm/DerivedTypes.h"
+#include "llvm/Instructions.h"
+#include "llvm/Module.h"
+#include "llvm/Pass.h"
+#include "llvm/Support/Compiler.h"
+#include "llvm/Support/InstIterator.h"
+#include "llvm/Support/InstVisitor.h"
+#include "llvm/Analysis/AliasAnalysis.h"
+#include "llvm/Analysis/Passes.h"
+#include "llvm/Support/Debug.h"
+#include "llvm/ADT/Statistic.h"
+#include <algorithm>
+#include <set>
+using namespace llvm;
+
+STATISTIC(NumIters , "Number of iterations to reach convergence");
+STATISTIC(NumConstraints , "Number of constraints");
+STATISTIC(NumNodes , "Number of nodes");
+STATISTIC(NumEscapingFunctions, "Number of internal functions that escape");
+STATISTIC(NumIndirectCallees , "Number of indirect callees found");
+
+namespace {
+ class VISIBILITY_HIDDEN Andersens : public ModulePass, public AliasAnalysis,
+ private InstVisitor<Andersens> {
+ public:
+ static char ID; // Class identification, replacement for typeinfo
+ Andersens() : ModulePass((intptr_t)&ID) {}
+ private:
+ /// Node class - This class is used to represent a memory object in the
+ /// program, and is the primitive used to build the points-to graph.
+ class Node {
+ std::vector<Node*> Pointees;
+ Value *Val;
+ public:
+ static const unsigned ID; // Pass identification, replacement for typeid
+ Node() : Val(0) {}
+ Node *setValue(Value *V) {
+ assert(Val == 0 && "Value already set for this node!");
+ Val = V;
+ return this;
+ }
+
+ /// getValue - Return the LLVM value corresponding to this node.
+ ///
+ Value *getValue() const { return Val; }
+
+ typedef std::vector<Node*>::const_iterator iterator;
+ iterator begin() const { return Pointees.begin(); }
+ iterator end() const { return Pointees.end(); }
+
+ /// addPointerTo - Add a pointer to the list of pointees of this node,
+ /// returning true if this caused a new pointer to be added, or false if
+ /// we already knew about the points-to relation.
+ bool addPointerTo(Node *N) {
+ std::vector<Node*>::iterator I = std::lower_bound(Pointees.begin(),
+ Pointees.end(),
+ N);
+ if (I != Pointees.end() && *I == N)
+ return false;
+ Pointees.insert(I, N);
+ return true;
+ }
+
+ /// intersects - Return true if the points-to set of this node intersects
+ /// with the points-to set of the specified node.
+ bool intersects(Node *N) const;
+
+ /// intersectsIgnoring - Return true if the points-to set of this node
+ /// intersects with the points-to set of the specified node on any nodes
+ /// except for the specified node to ignore.
+ bool intersectsIgnoring(Node *N, Node *Ignoring) const;
+
+ // Constraint application methods.
+ bool copyFrom(Node *N);
+ bool loadFrom(Node *N);
+ bool storeThrough(Node *N);
+ };
+
+ /// GraphNodes - This vector is populated as part of the object
+ /// identification stage of the analysis, which populates this vector with a
+ /// node for each memory object and fills in the ValueNodes map.
+ std::vector<Node> GraphNodes;
+
+ /// ValueNodes - This map indicates the Node that a particular Value* is
+ /// represented by. This contains entries for all pointers.
+ std::map<Value*, unsigned> ValueNodes;
+
+ /// ObjectNodes - This map contains entries for each memory object in the
+ /// program: globals, alloca's and mallocs.
+ std::map<Value*, unsigned> ObjectNodes;
+
+ /// ReturnNodes - This map contains an entry for each function in the
+ /// program that returns a value.
+ std::map<Function*, unsigned> ReturnNodes;
+
+ /// VarargNodes - This map contains the entry used to represent all pointers
+ /// passed through the varargs portion of a function call for a particular
+ /// function. An entry is not present in this map for functions that do not
+ /// take variable arguments.
+ std::map<Function*, unsigned> VarargNodes;
+
+ /// Constraint - Objects of this structure are used to represent the various
+ /// constraints identified by the algorithm. The constraints are 'copy',
+ /// for statements like "A = B", 'load' for statements like "A = *B", and
+ /// 'store' for statements like "*A = B".
+ struct Constraint {
+ enum ConstraintType { Copy, Load, Store } Type;
+ Node *Dest, *Src;
+
+ Constraint(ConstraintType Ty, Node *D, Node *S)
+ : Type(Ty), Dest(D), Src(S) {}
+ };
+
+ /// Constraints - This vector contains a list of all of the constraints
+ /// identified by the program.
+ std::vector<Constraint> Constraints;
+
+ /// EscapingInternalFunctions - This set contains all of the internal
+ /// functions that are found to escape from the program. If the address of
+ /// an internal function is passed to an external function or otherwise
+ /// escapes from the analyzed portion of the program, we must assume that
+ /// any pointer arguments can alias the universal node. This set keeps
+ /// track of those functions we are assuming to escape so far.
+ std::set<Function*> EscapingInternalFunctions;
+
+ /// IndirectCalls - This contains a list of all of the indirect call sites
+ /// in the program. Since the call graph is iteratively discovered, we may
+ /// need to add constraints to our graph as we find new targets of function
+ /// pointers.
+ std::vector<CallSite> IndirectCalls;
+
+ /// IndirectCallees - For each call site in the indirect calls list, keep
+ /// track of the callees that we have discovered so far. As the analysis
+ /// proceeds, more callees are discovered, until the call graph finally
+ /// stabilizes.
+ std::map<CallSite, std::vector<Function*> > IndirectCallees;
+
+ /// This enum defines the GraphNodes indices that correspond to important
+ /// fixed sets.
+ enum {
+ UniversalSet = 0,
+ NullPtr = 1,
+ NullObject = 2
+ };
+
+ public:
+ bool runOnModule(Module &M) {
+ InitializeAliasAnalysis(this);
+ IdentifyObjects(M);
+ CollectConstraints(M);
+ DEBUG(PrintConstraints());
+ SolveConstraints();
+ DEBUG(PrintPointsToGraph());
+
+ // Free the constraints list, as we don't need it to respond to alias
+ // requests.
+ ObjectNodes.clear();
+ ReturnNodes.clear();
+ VarargNodes.clear();
+ EscapingInternalFunctions.clear();
+ std::vector<Constraint>().swap(Constraints);
+ return false;
+ }
+
+ void releaseMemory() {
+ // FIXME: Until we have transitively required passes working correctly,
+ // this cannot be enabled! Otherwise, using -count-aa with the pass
+ // causes memory to be freed too early. :(
+#if 0
+ // The memory objects and ValueNodes data structures at the only ones that
+ // are still live after construction.
+ std::vector<Node>().swap(GraphNodes);
+ ValueNodes.clear();
+#endif
+ }
+
+ virtual void getAnalysisUsage(AnalysisUsage &AU) const {
+ AliasAnalysis::getAnalysisUsage(AU);
+ AU.setPreservesAll(); // Does not transform code
+ }
+
+ //------------------------------------------------
+ // Implement the AliasAnalysis API
+ //
+ AliasResult alias(const Value *V1, unsigned V1Size,
+ const Value *V2, unsigned V2Size);
+ virtual ModRefResult getModRefInfo(CallSite CS, Value *P, unsigned Size);
+ virtual ModRefResult getModRefInfo(CallSite CS1, CallSite CS2);
+ void getMustAliases(Value *P, std::vector<Value*> &RetVals);
+ bool pointsToConstantMemory(const Value *P);
+
+ virtual void deleteValue(Value *V) {
+ ValueNodes.erase(V);
+ getAnalysis<AliasAnalysis>().deleteValue(V);
+ }
+
+ virtual void copyValue(Value *From, Value *To) {
+ ValueNodes[To] = ValueNodes[From];
+ getAnalysis<AliasAnalysis>().copyValue(From, To);
+ }
+
+ private:
+ /// getNode - Return the node corresponding to the specified pointer scalar.
+ ///
+ Node *getNode(Value *V) {
+ if (Constant *C = dyn_cast<Constant>(V))
+ if (!isa<GlobalValue>(C))
+ return getNodeForConstantPointer(C);
+
+ std::map<Value*, unsigned>::iterator I = ValueNodes.find(V);
+ if (I == ValueNodes.end()) {
+#ifndef NDEBUG
+ V->dump();
+#endif
+ assert(0 && "Value does not have a node in the points-to graph!");
+ }
+ return &GraphNodes[I->second];
+ }
+
+ /// getObject - Return the node corresponding to the memory object for the
+ /// specified global or allocation instruction.
+ Node *getObject(Value *V) {
+ std::map<Value*, unsigned>::iterator I = ObjectNodes.find(V);
+ assert(I != ObjectNodes.end() &&
+ "Value does not have an object in the points-to graph!");
+ return &GraphNodes[I->second];
+ }
+
+ /// getReturnNode - Return the node representing the return value for the
+ /// specified function.
+ Node *getReturnNode(Function *F) {
+ std::map<Function*, unsigned>::iterator I = ReturnNodes.find(F);
+ assert(I != ReturnNodes.end() && "Function does not return a value!");
+ return &GraphNodes[I->second];
+ }
+
+ /// getVarargNode - Return the node representing the variable arguments
+ /// formal for the specified function.
+ Node *getVarargNode(Function *F) {
+ std::map<Function*, unsigned>::iterator I = VarargNodes.find(F);
+ assert(I != VarargNodes.end() && "Function does not take var args!");
+ return &GraphNodes[I->second];
+ }
+
+ /// getNodeValue - Get the node for the specified LLVM value and set the
+ /// value for it to be the specified value.
+ Node *getNodeValue(Value &V) {
+ return getNode(&V)->setValue(&V);
+ }
+
+ void IdentifyObjects(Module &M);
+ void CollectConstraints(Module &M);
+ void SolveConstraints();
+
+ Node *getNodeForConstantPointer(Constant *C);
+ Node *getNodeForConstantPointerTarget(Constant *C);
+ void AddGlobalInitializerConstraints(Node *N, Constant *C);
+
+ void AddConstraintsForNonInternalLinkage(Function *F);
+ void AddConstraintsForCall(CallSite CS, Function *F);
+ bool AddConstraintsForExternalCall(CallSite CS, Function *F);
+
+
+ void PrintNode(Node *N);
+ void PrintConstraints();
+ void PrintPointsToGraph();
+
+ //===------------------------------------------------------------------===//
+ // Instruction visitation methods for adding constraints
+ //
+ friend class InstVisitor<Andersens>;
+ void visitReturnInst(ReturnInst &RI);
+ void visitInvokeInst(InvokeInst &II) { visitCallSite(CallSite(&II)); }
+ void visitCallInst(CallInst &CI) { visitCallSite(CallSite(&CI)); }
+ void visitCallSite(CallSite CS);
+ void visitAllocationInst(AllocationInst &AI);
+ void visitLoadInst(LoadInst &LI);
+ void visitStoreInst(StoreInst &SI);
+ void visitGetElementPtrInst(GetElementPtrInst &GEP);
+ void visitPHINode(PHINode &PN);
+ void visitCastInst(CastInst &CI);
+ void visitICmpInst(ICmpInst &ICI) {} // NOOP!
+ void visitFCmpInst(FCmpInst &ICI) {} // NOOP!
+ void visitSelectInst(SelectInst &SI);
+ void visitVAArg(VAArgInst &I);
+ void visitInstruction(Instruction &I);
+ };
+
+ char Andersens::ID = 0;
+ RegisterPass<Andersens> X("anders-aa",
+ "Andersen's Interprocedural Alias Analysis");
+ RegisterAnalysisGroup<AliasAnalysis> Y(X);
+}
+
+ModulePass *llvm::createAndersensPass() { return new Andersens(); }
+
+//===----------------------------------------------------------------------===//
+// AliasAnalysis Interface Implementation
+//===----------------------------------------------------------------------===//
+
+AliasAnalysis::AliasResult Andersens::alias(const Value *V1, unsigned V1Size,
+ const Value *V2, unsigned V2Size) {
+ Node *N1 = getNode(const_cast<Value*>(V1));
+ Node *N2 = getNode(const_cast<Value*>(V2));
+
+ // Check to see if the two pointers are known to not alias. They don't alias
+ // if their points-to sets do not intersect.
+ if (!N1->intersectsIgnoring(N2, &GraphNodes[NullObject]))
+ return NoAlias;
+
+ return AliasAnalysis::alias(V1, V1Size, V2, V2Size);
+}
+
+AliasAnalysis::ModRefResult
+Andersens::getModRefInfo(CallSite CS, Value *P, unsigned Size) {
+ // The only thing useful that we can contribute for mod/ref information is
+ // when calling external function calls: if we know that memory never escapes
+ // from the program, it cannot be modified by an external call.
+ //
+ // NOTE: This is not really safe, at least not when the entire program is not
+ // available. The deal is that the external function could call back into the
+ // program and modify stuff. We ignore this technical niggle for now. This
+ // is, after all, a "research quality" implementation of Andersen's analysis.
+ if (Function *F = CS.getCalledFunction())
+ if (F->isDeclaration()) {
+ Node *N1 = getNode(P);
+
+ if (N1->begin() == N1->end())
+ return NoModRef; // P doesn't point to anything.
+
+ // Get the first pointee.
+ Node *FirstPointee = *N1->begin();
+ if (FirstPointee != &GraphNodes[UniversalSet])
+ return NoModRef; // P doesn't point to the universal set.
+ }
+
+ return AliasAnalysis::getModRefInfo(CS, P, Size);
+}
+
+AliasAnalysis::ModRefResult
+Andersens::getModRefInfo(CallSite CS1, CallSite CS2) {
+ return AliasAnalysis::getModRefInfo(CS1,CS2);
+}
+
+/// getMustAlias - We can provide must alias information if we know that a
+/// pointer can only point to a specific function or the null pointer.
+/// Unfortunately we cannot determine must-alias information for global
+/// variables or any other memory memory objects because we do not track whether
+/// a pointer points to the beginning of an object or a field of it.
+void Andersens::getMustAliases(Value *P, std::vector<Value*> &RetVals) {
+ Node *N = getNode(P);
+ Node::iterator I = N->begin();
+ if (I != N->end()) {
+ // If there is exactly one element in the points-to set for the object...
+ ++I;
+ if (I == N->end()) {
+ Node *Pointee = *N->begin();
+
+ // If a function is the only object in the points-to set, then it must be
+ // the destination. Note that we can't handle global variables here,
+ // because we don't know if the pointer is actually pointing to a field of
+ // the global or to the beginning of it.
+ if (Value *V = Pointee->getValue()) {
+ if (Function *F = dyn_cast<Function>(V))
+ RetVals.push_back(F);
+ } else {
+ // If the object in the points-to set is the null object, then the null
+ // pointer is a must alias.
+ if (Pointee == &GraphNodes[NullObject])
+ RetVals.push_back(Constant::getNullValue(P->getType()));
+ }
+ }
+ }
+
+ AliasAnalysis::getMustAliases(P, RetVals);
+}
+
+/// pointsToConstantMemory - If we can determine that this pointer only points
+/// to constant memory, return true. In practice, this means that if the
+/// pointer can only point to constant globals, functions, or the null pointer,
+/// return true.
+///
+bool Andersens::pointsToConstantMemory(const Value *P) {
+ Node *N = getNode((Value*)P);
+ for (Node::iterator I = N->begin(), E = N->end(); I != E; ++I) {
+ if (Value *V = (*I)->getValue()) {
+ if (!isa<GlobalValue>(V) || (isa<GlobalVariable>(V) &&
+ !cast<GlobalVariable>(V)->isConstant()))
+ return AliasAnalysis::pointsToConstantMemory(P);
+ } else {
+ if (*I != &GraphNodes[NullObject])
+ return AliasAnalysis::pointsToConstantMemory(P);
+ }
+ }
+
+ return true;
+}
+
+//===----------------------------------------------------------------------===//
+// Object Identification Phase
+//===----------------------------------------------------------------------===//
+
+/// IdentifyObjects - This stage scans the program, adding an entry to the
+/// GraphNodes list for each memory object in the program (global stack or
+/// heap), and populates the ValueNodes and ObjectNodes maps for these objects.
+///
+void Andersens::IdentifyObjects(Module &M) {
+ unsigned NumObjects = 0;
+
+ // Object #0 is always the universal set: the object that we don't know
+ // anything about.
+ assert(NumObjects == UniversalSet && "Something changed!");
+ ++NumObjects;
+
+ // Object #1 always represents the null pointer.
+ assert(NumObjects == NullPtr && "Something changed!");
+ ++NumObjects;
+
+ // Object #2 always represents the null object (the object pointed to by null)
+ assert(NumObjects == NullObject && "Something changed!");
+ ++NumObjects;
+
+ // Add all the globals first.
+ for (Module::global_iterator I = M.global_begin(), E = M.global_end();
+ I != E; ++I) {
+ ObjectNodes[I] = NumObjects++;
+ ValueNodes[I] = NumObjects++;
+ }
+
+ // Add nodes for all of the functions and the instructions inside of them.
+ for (Module::iterator F = M.begin(), E = M.end(); F != E; ++F) {
+ // The function itself is a memory object.
+ ValueNodes[F] = NumObjects++;
+ ObjectNodes[F] = NumObjects++;
+ if (isa<PointerType>(F->getFunctionType()->getReturnType()))
+ ReturnNodes[F] = NumObjects++;
+ if (F->getFunctionType()->isVarArg())
+ VarargNodes[F] = NumObjects++;
+
+ // Add nodes for all of the incoming pointer arguments.
+ for (Function::arg_iterator I = F->arg_begin(), E = F->arg_end();
+ I != E; ++I)
+ if (isa<PointerType>(I->getType()))
+ ValueNodes[I] = NumObjects++;
+
+ // Scan the function body, creating a memory object for each heap/stack
+ // allocation in the body of the function and a node to represent all
+ // pointer values defined by instructions and used as operands.
+ for (inst_iterator II = inst_begin(F), E = inst_end(F); II != E; ++II) {
+ // If this is an heap or stack allocation, create a node for the memory
+ // object.
+ if (isa<PointerType>(II->getType())) {
+ ValueNodes[&*II] = NumObjects++;
+ if (AllocationInst *AI = dyn_cast<AllocationInst>(&*II))
+ ObjectNodes[AI] = NumObjects++;
+ }
+ }
+ }
+
+ // Now that we know how many objects to create, make them all now!
+ GraphNodes.resize(NumObjects);
+ NumNodes += NumObjects;
+}
+
+//===----------------------------------------------------------------------===//
+// Constraint Identification Phase
+//===----------------------------------------------------------------------===//
+
+/// getNodeForConstantPointer - Return the node corresponding to the constant
+/// pointer itself.
+Andersens::Node *Andersens::getNodeForConstantPointer(Constant *C) {
+ assert(isa<PointerType>(C->getType()) && "Not a constant pointer!");
+
+ if (isa<ConstantPointerNull>(C) || isa<UndefValue>(C))
+ return &GraphNodes[NullPtr];
+ else if (GlobalValue *GV = dyn_cast<GlobalValue>(C))
+ return getNode(GV);
+ else if (ConstantExpr *CE = dyn_cast<ConstantExpr>(C)) {
+ switch (CE->getOpcode()) {
+ case Instruction::GetElementPtr:
+ return getNodeForConstantPointer(CE->getOperand(0));
+ case Instruction::IntToPtr:
+ return &GraphNodes[UniversalSet];
+ case Instruction::BitCast:
+ return getNodeForConstantPointer(CE->getOperand(0));
+ default:
+ cerr << "Constant Expr not yet handled: " << *CE << "\n";
+ assert(0);
+ }
+ } else {
+ assert(0 && "Unknown constant pointer!");
+ }
+ return 0;
+}
+
+/// getNodeForConstantPointerTarget - Return the node POINTED TO by the
+/// specified constant pointer.
+Andersens::Node *Andersens::getNodeForConstantPointerTarget(Constant *C) {
+ assert(isa<PointerType>(C->getType()) && "Not a constant pointer!");
+
+ if (isa<ConstantPointerNull>(C))
+ return &GraphNodes[NullObject];
+ else if (GlobalValue *GV = dyn_cast<GlobalValue>(C))
+ return getObject(GV);
+ else if (ConstantExpr *CE = dyn_cast<ConstantExpr>(C)) {
+ switch (CE->getOpcode()) {
+ case Instruction::GetElementPtr:
+ return getNodeForConstantPointerTarget(CE->getOperand(0));
+ case Instruction::IntToPtr:
+ return &GraphNodes[UniversalSet];
+ case Instruction::BitCast:
+ return getNodeForConstantPointerTarget(CE->getOperand(0));
+ default:
+ cerr << "Constant Expr not yet handled: " << *CE << "\n";
+ assert(0);
+ }
+ } else {
+ assert(0 && "Unknown constant pointer!");
+ }
+ return 0;
+}
+
+/// AddGlobalInitializerConstraints - Add inclusion constraints for the memory
+/// object N, which contains values indicated by C.
+void Andersens::AddGlobalInitializerConstraints(Node *N, Constant *C) {
+ if (C->getType()->isFirstClassType()) {
+ if (isa<PointerType>(C->getType()))
+ N->copyFrom(getNodeForConstantPointer(C));
+
+ } else if (C->isNullValue()) {
+ N->addPointerTo(&GraphNodes[NullObject]);
+ return;
+ } else if (!isa<UndefValue>(C)) {
+ // If this is an array or struct, include constraints for each element.
+ assert(isa<ConstantArray>(C) || isa<ConstantStruct>(C));
+ for (unsigned i = 0, e = C->getNumOperands(); i != e; ++i)
+ AddGlobalInitializerConstraints(N, cast<Constant>(C->getOperand(i)));
+ }
+}
+
+/// AddConstraintsForNonInternalLinkage - If this function does not have
+/// internal linkage, realize that we can't trust anything passed into or
+/// returned by this function.
+void Andersens::AddConstraintsForNonInternalLinkage(Function *F) {
+ for (Function::arg_iterator I = F->arg_begin(), E = F->arg_end(); I != E; ++I)
+ if (isa<PointerType>(I->getType()))
+ // If this is an argument of an externally accessible function, the
+ // incoming pointer might point to anything.
+ Constraints.push_back(Constraint(Constraint::Copy, getNode(I),
+ &GraphNodes[UniversalSet]));
+}
+
+/// AddConstraintsForCall - If this is a call to a "known" function, add the
+/// constraints and return true. If this is a call to an unknown function,
+/// return false.
+bool Andersens::AddConstraintsForExternalCall(CallSite CS, Function *F) {
+ assert(F->isDeclaration() && "Not an external function!");
+
+ // These functions don't induce any points-to constraints.
+ if (F->getName() == "atoi" || F->getName() == "atof" ||
+ F->getName() == "atol" || F->getName() == "atoll" ||
+ F->getName() == "remove" || F->getName() == "unlink" ||
+ F->getName() == "rename" || F->getName() == "memcmp" ||
+ F->getName() == "llvm.memset.i32" ||
+ F->getName() == "llvm.memset.i64" ||
+ F->getName() == "strcmp" || F->getName() == "strncmp" ||
+ F->getName() == "execl" || F->getName() == "execlp" ||
+ F->getName() == "execle" || F->getName() == "execv" ||
+ F->getName() == "execvp" || F->getName() == "chmod" ||
+ F->getName() == "puts" || F->getName() == "write" ||
+ F->getName() == "open" || F->getName() == "create" ||
+ F->getName() == "truncate" || F->getName() == "chdir" ||
+ F->getName() == "mkdir" || F->getName() == "rmdir" ||
+ F->getName() == "read" || F->getName() == "pipe" ||
+ F->getName() == "wait" || F->getName() == "time" ||
+ F->getName() == "stat" || F->getName() == "fstat" ||
+ F->getName() == "lstat" || F->getName() == "strtod" ||
+ F->getName() == "strtof" || F->getName() == "strtold" ||
+ F->getName() == "fopen" || F->getName() == "fdopen" ||
+ F->getName() == "freopen" ||
+ F->getName() == "fflush" || F->getName() == "feof" ||
+ F->getName() == "fileno" || F->getName() == "clearerr" ||
+ F->getName() == "rewind" || F->getName() == "ftell" ||
+ F->getName() == "ferror" || F->getName() == "fgetc" ||
+ F->getName() == "fgetc" || F->getName() == "_IO_getc" ||
+ F->getName() == "fwrite" || F->getName() == "fread" ||
+ F->getName() == "fgets" || F->getName() == "ungetc" ||
+ F->getName() == "fputc" ||
+ F->getName() == "fputs" || F->getName() == "putc" ||
+ F->getName() == "ftell" || F->getName() == "rewind" ||
+ F->getName() == "_IO_putc" || F->getName() == "fseek" ||
+ F->getName() == "fgetpos" || F->getName() == "fsetpos" ||
+ F->getName() == "printf" || F->getName() == "fprintf" ||
+ F->getName() == "sprintf" || F->getName() == "vprintf" ||
+ F->getName() == "vfprintf" || F->getName() == "vsprintf" ||
+ F->getName() == "scanf" || F->getName() == "fscanf" ||
+ F->getName() == "sscanf" || F->getName() == "__assert_fail" ||
+ F->getName() == "modf")
+ return true;
+
+
+ // These functions do induce points-to edges.
+ if (F->getName() == "llvm.memcpy.i32" || F->getName() == "llvm.memcpy.i64" ||
+ F->getName() == "llvm.memmove.i32" ||F->getName() == "llvm.memmove.i64" ||
+ F->getName() == "memmove") {
+ // Note: this is a poor approximation, this says Dest = Src, instead of
+ // *Dest = *Src.
+ Constraints.push_back(Constraint(Constraint::Copy,
+ getNode(CS.getArgument(0)),
+ getNode(CS.getArgument(1))));
+ return true;
+ }
+
+ // Result = Arg0
+ if (F->getName() == "realloc" || F->getName() == "strchr" ||
+ F->getName() == "strrchr" || F->getName() == "strstr" ||
+ F->getName() == "strtok") {
+ Constraints.push_back(Constraint(Constraint::Copy,
+ getNode(CS.getInstruction()),
+ getNode(CS.getArgument(0))));
+ return true;
+ }
+
+ return false;
+}
+
+
+
+/// CollectConstraints - This stage scans the program, adding a constraint to
+/// the Constraints list for each instruction in the program that induces a
+/// constraint, and setting up the initial points-to graph.
+///
+void Andersens::CollectConstraints(Module &M) {
+ // First, the universal set points to itself.
+ GraphNodes[UniversalSet].addPointerTo(&GraphNodes[UniversalSet]);
+ //Constraints.push_back(Constraint(Constraint::Load, &GraphNodes[UniversalSet],
+ // &GraphNodes[UniversalSet]));
+ Constraints.push_back(Constraint(Constraint::Store, &GraphNodes[UniversalSet],
+ &GraphNodes[UniversalSet]));
+
+ // Next, the null pointer points to the null object.
+ GraphNodes[NullPtr].addPointerTo(&GraphNodes[NullObject]);
+
+ // Next, add any constraints on global variables and their initializers.
+ for (Module::global_iterator I = M.global_begin(), E = M.global_end();
+ I != E; ++I) {
+ // Associate the address of the global object as pointing to the memory for
+ // the global: &G = <G memory>
+ Node *Object = getObject(I);
+ Object->setValue(I);
+ getNodeValue(*I)->addPointerTo(Object);
+
+ if (I->hasInitializer()) {
+ AddGlobalInitializerConstraints(Object, I->getInitializer());
+ } else {
+ // If it doesn't have an initializer (i.e. it's defined in another
+ // translation unit), it points to the universal set.
+ Constraints.push_back(Constraint(Constraint::Copy, Object,
+ &GraphNodes[UniversalSet]));
+ }
+ }
+
+ for (Module::iterator F = M.begin(), E = M.end(); F != E; ++F) {
+ // Make the function address point to the function object.
+ getNodeValue(*F)->addPointerTo(getObject(F)->setValue(F));
+
+ // Set up the return value node.
+ if (isa<PointerType>(F->getFunctionType()->getReturnType()))
+ getReturnNode(F)->setValue(F);
+ if (F->getFunctionType()->isVarArg())
+ getVarargNode(F)->setValue(F);
+
+ // Set up incoming argument nodes.
+ for (Function::arg_iterator I = F->arg_begin(), E = F->arg_end();
+ I != E; ++I)
+ if (isa<PointerType>(I->getType()))
+ getNodeValue(*I);
+
+ if (!F->hasInternalLinkage())
+ AddConstraintsForNonInternalLinkage(F);
+
+ if (!F->isDeclaration()) {
+ // Scan the function body, creating a memory object for each heap/stack
+ // allocation in the body of the function and a node to represent all
+ // pointer values defined by instructions and used as operands.
+ visit(F);
+ } else {
+ // External functions that return pointers return the universal set.
+ if (isa<PointerType>(F->getFunctionType()->getReturnType()))
+ Constraints.push_back(Constraint(Constraint::Copy,
+ getReturnNode(F),
+ &GraphNodes[UniversalSet]));
+
+ // Any pointers that are passed into the function have the universal set
+ // stored into them.
+ for (Function::arg_iterator I = F->arg_begin(), E = F->arg_end();
+ I != E; ++I)
+ if (isa<PointerType>(I->getType())) {
+ // Pointers passed into external functions could have anything stored
+ // through them.
+ Constraints.push_back(Constraint(Constraint::Store, getNode(I),
+ &GraphNodes[UniversalSet]));
+ // Memory objects passed into external function calls can have the
+ // universal set point to them.
+ Constraints.push_back(Constraint(Constraint::Copy,
+ &GraphNodes[UniversalSet],
+ getNode(I)));
+ }
+
+ // If this is an external varargs function, it can also store pointers
+ // into any pointers passed through the varargs section.
+ if (F->getFunctionType()->isVarArg())
+ Constraints.push_back(Constraint(Constraint::Store, getVarargNode(F),
+ &GraphNodes[UniversalSet]));
+ }
+ }
+ NumConstraints += Constraints.size();
+}
+
+
+void Andersens::visitInstruction(Instruction &I) {
+#ifdef NDEBUG
+ return; // This function is just a big assert.
+#endif
+ if (isa<BinaryOperator>(I))
+ return;
+ // Most instructions don't have any effect on pointer values.
+ switch (I.getOpcode()) {
+ case Instruction::Br:
+ case Instruction::Switch:
+ case Instruction::Unwind:
+ case Instruction::Unreachable:
+ case Instruction::Free:
+ case Instruction::ICmp:
+ case Instruction::FCmp:
+ return;
+ default:
+ // Is this something we aren't handling yet?
+ cerr << "Unknown instruction: " << I;
+ abort();
+ }
+}
+
+void Andersens::visitAllocationInst(AllocationInst &AI) {
+ getNodeValue(AI)->addPointerTo(getObject(&AI)->setValue(&AI));
+}
+
+void Andersens::visitReturnInst(ReturnInst &RI) {
+ if (RI.getNumOperands() && isa<PointerType>(RI.getOperand(0)->getType()))
+ // return V --> <Copy/retval{F}/v>
+ Constraints.push_back(Constraint(Constraint::Copy,
+ getReturnNode(RI.getParent()->getParent()),
+ getNode(RI.getOperand(0))));
+}
+
+void Andersens::visitLoadInst(LoadInst &LI) {
+ if (isa<PointerType>(LI.getType()))
+ // P1 = load P2 --> <Load/P1/P2>
+ Constraints.push_back(Constraint(Constraint::Load, getNodeValue(LI),
+ getNode(LI.getOperand(0))));
+}
+
+void Andersens::visitStoreInst(StoreInst &SI) {
+ if (isa<PointerType>(SI.getOperand(0)->getType()))
+ // store P1, P2 --> <Store/P2/P1>
+ Constraints.push_back(Constraint(Constraint::Store,
+ getNode(SI.getOperand(1)),
+ getNode(SI.getOperand(0))));
+}
+
+void Andersens::visitGetElementPtrInst(GetElementPtrInst &GEP) {
+ // P1 = getelementptr P2, ... --> <Copy/P1/P2>
+ Constraints.push_back(Constraint(Constraint::Copy, getNodeValue(GEP),
+ getNode(GEP.getOperand(0))));
+}
+
+void Andersens::visitPHINode(PHINode &PN) {
+ if (isa<PointerType>(PN.getType())) {
+ Node *PNN = getNodeValue(PN);
+ for (unsigned i = 0, e = PN.getNumIncomingValues(); i != e; ++i)
+ // P1 = phi P2, P3 --> <Copy/P1/P2>, <Copy/P1/P3>, ...
+ Constraints.push_back(Constraint(Constraint::Copy, PNN,
+ getNode(PN.getIncomingValue(i))));
+ }
+}
+
+void Andersens::visitCastInst(CastInst &CI) {
+ Value *Op = CI.getOperand(0);
+ if (isa<PointerType>(CI.getType())) {
+ if (isa<PointerType>(Op->getType())) {
+ // P1 = cast P2 --> <Copy/P1/P2>
+ Constraints.push_back(Constraint(Constraint::Copy, getNodeValue(CI),
+ getNode(CI.getOperand(0))));
+ } else {
+ // P1 = cast int --> <Copy/P1/Univ>
+#if 0
+ Constraints.push_back(Constraint(Constraint::Copy, getNodeValue(CI),
+ &GraphNodes[UniversalSet]));
+#else
+ getNodeValue(CI);
+#endif
+ }
+ } else if (isa<PointerType>(Op->getType())) {
+ // int = cast P1 --> <Copy/Univ/P1>
+#if 0
+ Constraints.push_back(Constraint(Constraint::Copy,
+ &GraphNodes[UniversalSet],
+ getNode(CI.getOperand(0))));
+#else
+ getNode(CI.getOperand(0));
+#endif
+ }
+}
+
+void Andersens::visitSelectInst(SelectInst &SI) {
+ if (isa<PointerType>(SI.getType())) {
+ Node *SIN = getNodeValue(SI);
+ // P1 = select C, P2, P3 ---> <Copy/P1/P2>, <Copy/P1/P3>
+ Constraints.push_back(Constraint(Constraint::Copy, SIN,
+ getNode(SI.getOperand(1))));
+ Constraints.push_back(Constraint(Constraint::Copy, SIN,
+ getNode(SI.getOperand(2))));
+ }
+}
+
+void Andersens::visitVAArg(VAArgInst &I) {
+ assert(0 && "vaarg not handled yet!");
+}
+
+/// AddConstraintsForCall - Add constraints for a call with actual arguments
+/// specified by CS to the function specified by F. Note that the types of
+/// arguments might not match up in the case where this is an indirect call and
+/// the function pointer has been casted. If this is the case, do something
+/// reasonable.
+void Andersens::AddConstraintsForCall(CallSite CS, Function *F) {
+ // If this is a call to an external function, handle it directly to get some
+ // taste of context sensitivity.
+ if (F->isDeclaration() && AddConstraintsForExternalCall(CS, F))
+ return;
+
+ if (isa<PointerType>(CS.getType())) {
+ Node *CSN = getNode(CS.getInstruction());
+ if (isa<PointerType>(F->getFunctionType()->getReturnType())) {
+ Constraints.push_back(Constraint(Constraint::Copy, CSN,
+ getReturnNode(F)));
+ } else {
+ // If the function returns a non-pointer value, handle this just like we
+ // treat a nonpointer cast to pointer.
+ Constraints.push_back(Constraint(Constraint::Copy, CSN,
+ &GraphNodes[UniversalSet]));
+ }
+ } else if (isa<PointerType>(F->getFunctionType()->getReturnType())) {
+ Constraints.push_back(Constraint(Constraint::Copy,
+ &GraphNodes[UniversalSet],
+ getReturnNode(F)));
+ }
+
+ Function::arg_iterator AI = F->arg_begin(), AE = F->arg_end();
+ CallSite::arg_iterator ArgI = CS.arg_begin(), ArgE = CS.arg_end();
+ for (; AI != AE && ArgI != ArgE; ++AI, ++ArgI)
+ if (isa<PointerType>(AI->getType())) {
+ if (isa<PointerType>((*ArgI)->getType())) {
+ // Copy the actual argument into the formal argument.
+ Constraints.push_back(Constraint(Constraint::Copy, getNode(AI),
+ getNode(*ArgI)));
+ } else {
+ Constraints.push_back(Constraint(Constraint::Copy, getNode(AI),
+ &GraphNodes[UniversalSet]));
+ }
+ } else if (isa<PointerType>((*ArgI)->getType())) {
+ Constraints.push_back(Constraint(Constraint::Copy,
+ &GraphNodes[UniversalSet],
+ getNode(*ArgI)));
+ }
+
+ // Copy all pointers passed through the varargs section to the varargs node.
+ if (F->getFunctionType()->isVarArg())
+ for (; ArgI != ArgE; ++ArgI)
+ if (isa<PointerType>((*ArgI)->getType()))
+ Constraints.push_back(Constraint(Constraint::Copy, getVarargNode(F),
+ getNode(*ArgI)));
+ // If more arguments are passed in than we track, just drop them on the floor.
+}
+
+void Andersens::visitCallSite(CallSite CS) {
+ if (isa<PointerType>(CS.getType()))
+ getNodeValue(*CS.getInstruction());
+
+ if (Function *F = CS.getCalledFunction()) {
+ AddConstraintsForCall(CS, F);
+ } else {
+ // We don't handle indirect call sites yet. Keep track of them for when we
+ // discover the call graph incrementally.
+ IndirectCalls.push_back(CS);
+ }
+}
+
+//===----------------------------------------------------------------------===//
+// Constraint Solving Phase
+//===----------------------------------------------------------------------===//
+
+/// intersects - Return true if the points-to set of this node intersects
+/// with the points-to set of the specified node.
+bool Andersens::Node::intersects(Node *N) const {
+ iterator I1 = begin(), I2 = N->begin(), E1 = end(), E2 = N->end();
+ while (I1 != E1 && I2 != E2) {
+ if (*I1 == *I2) return true;
+ if (*I1 < *I2)
+ ++I1;
+ else
+ ++I2;
+ }
+ return false;
+}
+
+/// intersectsIgnoring - Return true if the points-to set of this node
+/// intersects with the points-to set of the specified node on any nodes
+/// except for the specified node to ignore.
+bool Andersens::Node::intersectsIgnoring(Node *N, Node *Ignoring) const {
+ iterator I1 = begin(), I2 = N->begin(), E1 = end(), E2 = N->end();
+ while (I1 != E1 && I2 != E2) {
+ if (*I1 == *I2) {
+ if (*I1 != Ignoring) return true;
+ ++I1; ++I2;
+ } else if (*I1 < *I2)
+ ++I1;
+ else
+ ++I2;
+ }
+ return false;
+}
+
+// Copy constraint: all edges out of the source node get copied to the
+// destination node. This returns true if a change is made.
+bool Andersens::Node::copyFrom(Node *N) {
+ // Use a mostly linear-time merge since both of the lists are sorted.
+ bool Changed = false;
+ iterator I = N->begin(), E = N->end();
+ unsigned i = 0;
+ while (I != E && i != Pointees.size()) {
+ if (Pointees[i] < *I) {
+ ++i;
+ } else if (Pointees[i] == *I) {
+ ++i; ++I;
+ } else {
+ // We found a new element to copy over.
+ Changed = true;
+ Pointees.insert(Pointees.begin()+i, *I);
+ ++i; ++I;
+ }
+ }
+
+ if (I != E) {
+ Pointees.insert(Pointees.end(), I, E);
+ Changed = true;
+ }
+
+ return Changed;
+}
+
+bool Andersens::Node::loadFrom(Node *N) {
+ bool Changed = false;
+ for (iterator I = N->begin(), E = N->end(); I != E; ++I)
+ Changed |= copyFrom(*I);
+ return Changed;
+}
+
+bool Andersens::Node::storeThrough(Node *N) {
+ bool Changed = false;
+ for (iterator I = begin(), E = end(); I != E; ++I)
+ Changed |= (*I)->copyFrom(N);
+ return Changed;
+}
+
+
+/// SolveConstraints - This stage iteratively processes the constraints list
+/// propagating constraints (adding edges to the Nodes in the points-to graph)
+/// until a fixed point is reached.
+///
+void Andersens::SolveConstraints() {
+ bool Changed = true;
+ unsigned Iteration = 0;
+ while (Changed) {
+ Changed = false;
+ ++NumIters;
+ DOUT << "Starting iteration #" << Iteration++ << "!\n";
+
+ // Loop over all of the constraints, applying them in turn.
+ for (unsigned i = 0, e = Constraints.size(); i != e; ++i) {
+ Constraint &C = Constraints[i];
+ switch (C.Type) {
+ case Constraint::Copy:
+ Changed |= C.Dest->copyFrom(C.Src);
+ break;
+ case Constraint::Load:
+ Changed |= C.Dest->loadFrom(C.Src);
+ break;
+ case Constraint::Store:
+ Changed |= C.Dest->storeThrough(C.Src);
+ break;
+ default:
+ assert(0 && "Unknown constraint!");
+ }
+ }
+
+ if (Changed) {
+ // Check to see if any internal function's addresses have been passed to
+ // external functions. If so, we have to assume that their incoming
+ // arguments could be anything. If there are any internal functions in
+ // the universal node that we don't know about, we must iterate.
+ for (Node::iterator I = GraphNodes[UniversalSet].begin(),
+ E = GraphNodes[UniversalSet].end(); I != E; ++I)
+ if (Function *F = dyn_cast_or_null<Function>((*I)->getValue()))
+ if (F->hasInternalLinkage() &&
+ EscapingInternalFunctions.insert(F).second) {
+ // We found a function that is just now escaping. Mark it as if it
+ // didn't have internal linkage.
+ AddConstraintsForNonInternalLinkage(F);
+ DOUT << "Found escaping internal function: " << F->getName() <<"\n";
+ ++NumEscapingFunctions;
+ }
+
+ // Check to see if we have discovered any new callees of the indirect call
+ // sites. If so, add constraints to the analysis.
+ for (unsigned i = 0, e = IndirectCalls.size(); i != e; ++i) {
+ CallSite CS = IndirectCalls[i];
+ std::vector<Function*> &KnownCallees = IndirectCallees[CS];
+ Node *CN = getNode(CS.getCalledValue());
+
+ for (Node::iterator NI = CN->begin(), E = CN->end(); NI != E; ++NI)
+ if (Function *F = dyn_cast_or_null<Function>((*NI)->getValue())) {
+ std::vector<Function*>::iterator IP =
+ std::lower_bound(KnownCallees.begin(), KnownCallees.end(), F);
+ if (IP == KnownCallees.end() || *IP != F) {
+ // Add the constraints for the call now.
+ AddConstraintsForCall(CS, F);
+ DOUT << "Found actual callee '"
+ << F->getName() << "' for call: "
+ << *CS.getInstruction() << "\n";
+ ++NumIndirectCallees;
+ KnownCallees.insert(IP, F);
+ }
+ }
+ }
+ }
+ }
+}
+
+
+
+//===----------------------------------------------------------------------===//
+// Debugging Output
+//===----------------------------------------------------------------------===//
+
+void Andersens::PrintNode(Node *N) {
+ if (N == &GraphNodes[UniversalSet]) {
+ cerr << "<universal>";
+ return;
+ } else if (N == &GraphNodes[NullPtr]) {
+ cerr << "<nullptr>";
+ return;
+ } else if (N == &GraphNodes[NullObject]) {
+ cerr << "<null>";
+ return;
+ }
+
+ assert(N->getValue() != 0 && "Never set node label!");
+ Value *V = N->getValue();
+ if (Function *F = dyn_cast<Function>(V)) {
+ if (isa<PointerType>(F->getFunctionType()->getReturnType()) &&
+ N == getReturnNode(F)) {
+ cerr << F->getName() << ":retval";
+ return;
+ } else if (F->getFunctionType()->isVarArg() && N == getVarargNode(F)) {
+ cerr << F->getName() << ":vararg";
+ return;
+ }
+ }
+
+ if (Instruction *I = dyn_cast<Instruction>(V))
+ cerr << I->getParent()->getParent()->getName() << ":";
+ else if (Argument *Arg = dyn_cast<Argument>(V))
+ cerr << Arg->getParent()->getName() << ":";
+
+ if (V->hasName())
+ cerr << V->getName();
+ else
+ cerr << "(unnamed)";
+
+ if (isa<GlobalValue>(V) || isa<AllocationInst>(V))
+ if (N == getObject(V))
+ cerr << "<mem>";
+}
+
+void Andersens::PrintConstraints() {
+ cerr << "Constraints:\n";
+ for (unsigned i = 0, e = Constraints.size(); i != e; ++i) {
+ cerr << " #" << i << ": ";
+ Constraint &C = Constraints[i];
+ if (C.Type == Constraint::Store)
+ cerr << "*";
+ PrintNode(C.Dest);
+ cerr << " = ";
+ if (C.Type == Constraint::Load)
+ cerr << "*";
+ PrintNode(C.Src);
+ cerr << "\n";
+ }
+}
+
+void Andersens::PrintPointsToGraph() {
+ cerr << "Points-to graph:\n";
+ for (unsigned i = 0, e = GraphNodes.size(); i != e; ++i) {
+ Node *N = &GraphNodes[i];
+ cerr << "[" << (N->end() - N->begin()) << "] ";
+ PrintNode(N);
+ cerr << "\t--> ";
+ for (Node::iterator I = N->begin(), E = N->end(); I != E; ++I) {
+ if (I != N->begin()) cerr << ", ";
+ PrintNode(*I);
+ }
+ cerr << "\n";
+ }
+}
diff --git a/lib/Analysis/IPA/CallGraph.cpp b/lib/Analysis/IPA/CallGraph.cpp
new file mode 100644
index 0000000..5f9850c
--- /dev/null
+++ b/lib/Analysis/IPA/CallGraph.cpp
@@ -0,0 +1,309 @@
+//===- CallGraph.cpp - Build a Module's call graph ------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the CallGraph class and provides the BasicCallGraph
+// default implementation.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Analysis/CallGraph.h"
+#include "llvm/Module.h"
+#include "llvm/Instructions.h"
+#include "llvm/Support/CallSite.h"
+#include "llvm/Support/Compiler.h"
+#include "llvm/Support/Streams.h"
+#include <ostream>
+using namespace llvm;
+
+/// isOnlyADirectCall - Return true if this callsite is *just* a direct call to
+/// the specified function. Specifically return false if the callsite also
+/// takes the address of the function.
+static bool isOnlyADirectCall(Function *F, CallSite CS) {
+ if (!CS.getInstruction()) return false;
+ for (CallSite::arg_iterator I = CS.arg_begin(), E = CS.arg_end(); I != E; ++I)
+ if (*I == F) return false;
+ return true;
+}
+
+namespace {
+
+//===----------------------------------------------------------------------===//
+// BasicCallGraph class definition
+//
+class VISIBILITY_HIDDEN BasicCallGraph : public CallGraph, public ModulePass {
+ // Root is root of the call graph, or the external node if a 'main' function
+ // couldn't be found.
+ //
+ CallGraphNode *Root;
+
+ // ExternalCallingNode - This node has edges to all external functions and
+ // those internal functions that have their address taken.
+ CallGraphNode *ExternalCallingNode;
+
+ // CallsExternalNode - This node has edges to it from all functions making
+ // indirect calls or calling an external function.
+ CallGraphNode *CallsExternalNode;
+
+public:
+ static char ID; // Class identification, replacement for typeinfo
+ BasicCallGraph() : ModulePass((intptr_t)&ID), Root(0),
+ ExternalCallingNode(0), CallsExternalNode(0) {}
+
+ // runOnModule - Compute the call graph for the specified module.
+ virtual bool runOnModule(Module &M) {
+ CallGraph::initialize(M);
+
+ ExternalCallingNode = getOrInsertFunction(0);
+ CallsExternalNode = new CallGraphNode(0);
+ Root = 0;
+
+ // Add every function to the call graph...
+ for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I)
+ addToCallGraph(I);
+
+ // If we didn't find a main function, use the external call graph node
+ if (Root == 0) Root = ExternalCallingNode;
+
+ return false;
+ }
+
+ virtual void getAnalysisUsage(AnalysisUsage &AU) const {
+ AU.setPreservesAll();
+ }
+
+ void print(std::ostream *o, const Module *M) const {
+ if (o) print(*o, M);
+ }
+
+ virtual void print(std::ostream &o, const Module *M) const {
+ o << "CallGraph Root is: ";
+ if (Function *F = getRoot()->getFunction())
+ o << F->getName() << "\n";
+ else
+ o << "<<null function: 0x" << getRoot() << ">>\n";
+
+ CallGraph::print(o, M);
+ }
+
+ virtual void releaseMemory() {
+ destroy();
+ }
+
+ /// dump - Print out this call graph.
+ ///
+ inline void dump() const {
+ print(cerr, Mod);
+ }
+
+ CallGraphNode* getExternalCallingNode() const { return ExternalCallingNode; }
+ CallGraphNode* getCallsExternalNode() const { return CallsExternalNode; }
+
+ // getRoot - Return the root of the call graph, which is either main, or if
+ // main cannot be found, the external node.
+ //
+ CallGraphNode *getRoot() { return Root; }
+ const CallGraphNode *getRoot() const { return Root; }
+
+private:
+ //===---------------------------------------------------------------------
+ // Implementation of CallGraph construction
+ //
+
+ // addToCallGraph - Add a function to the call graph, and link the node to all
+ // of the functions that it calls.
+ //
+ void addToCallGraph(Function *F) {
+ CallGraphNode *Node = getOrInsertFunction(F);
+
+ // If this function has external linkage, anything could call it.
+ if (!F->hasInternalLinkage()) {
+ ExternalCallingNode->addCalledFunction(CallSite(), Node);
+
+ // Found the entry point?
+ if (F->getName() == "main") {
+ if (Root) // Found multiple external mains? Don't pick one.
+ Root = ExternalCallingNode;
+ else
+ Root = Node; // Found a main, keep track of it!
+ }
+ }
+
+ // If this function is not defined in this translation unit, it could call
+ // anything.
+ if (F->isDeclaration() && !F->getIntrinsicID())
+ Node->addCalledFunction(CallSite(), CallsExternalNode);
+
+ // Loop over all of the users of the function... looking for callers...
+ //
+ bool isUsedExternally = false;
+ for (Value::use_iterator I = F->use_begin(), E = F->use_end(); I != E; ++I){
+ if (Instruction *Inst = dyn_cast<Instruction>(*I)) {
+ CallSite CS = CallSite::get(Inst);
+ if (isOnlyADirectCall(F, CS))
+ getOrInsertFunction(Inst->getParent()->getParent())
+ ->addCalledFunction(CS, Node);
+ else
+ isUsedExternally = true;
+ } else if (GlobalValue *GV = dyn_cast<GlobalValue>(*I)) {
+ for (Value::use_iterator I = GV->use_begin(), E = GV->use_end();
+ I != E; ++I)
+ if (Instruction *Inst = dyn_cast<Instruction>(*I)) {
+ CallSite CS = CallSite::get(Inst);
+ if (isOnlyADirectCall(F, CS))
+ getOrInsertFunction(Inst->getParent()->getParent())
+ ->addCalledFunction(CS, Node);
+ else
+ isUsedExternally = true;
+ } else {
+ isUsedExternally = true;
+ }
+ } else { // Can't classify the user!
+ isUsedExternally = true;
+ }
+ }
+ if (isUsedExternally)
+ ExternalCallingNode->addCalledFunction(CallSite(), Node);
+
+ // Look for an indirect function call.
+ for (Function::iterator BB = F->begin(), BBE = F->end(); BB != BBE; ++BB)
+ for (BasicBlock::iterator II = BB->begin(), IE = BB->end();
+ II != IE; ++II) {
+ CallSite CS = CallSite::get(II);
+ if (CS.getInstruction() && !CS.getCalledFunction())
+ Node->addCalledFunction(CS, CallsExternalNode);
+ }
+ }
+
+ //
+ // destroy - Release memory for the call graph
+ virtual void destroy() {
+ /// CallsExternalNode is not in the function map, delete it explicitly.
+ delete CallsExternalNode;
+ CallsExternalNode = 0;
+ CallGraph::destroy();
+ }
+};
+
+RegisterAnalysisGroup<CallGraph> X("Call Graph");
+RegisterPass<BasicCallGraph> Y("basiccg", "Basic CallGraph Construction");
+RegisterAnalysisGroup<CallGraph, true> Z(Y);
+
+} //End anonymous namespace
+
+char CallGraph::ID = 0;
+char BasicCallGraph::ID = 0;
+
+void CallGraph::initialize(Module &M) {
+ Mod = &M;
+}
+
+void CallGraph::destroy() {
+ if (!FunctionMap.empty()) {
+ for (FunctionMapTy::iterator I = FunctionMap.begin(), E = FunctionMap.end();
+ I != E; ++I)
+ delete I->second;
+ FunctionMap.clear();
+ }
+}
+
+void CallGraph::print(std::ostream &OS, const Module *M) const {
+ for (CallGraph::const_iterator I = begin(), E = end(); I != E; ++I)
+ I->second->print(OS);
+}
+
+void CallGraph::dump() const {
+ print(cerr, 0);
+}
+
+//===----------------------------------------------------------------------===//
+// Implementations of public modification methods
+//
+
+// removeFunctionFromModule - Unlink the function from this module, returning
+// it. Because this removes the function from the module, the call graph node
+// is destroyed. This is only valid if the function does not call any other
+// functions (ie, there are no edges in it's CGN). The easiest way to do this
+// is to dropAllReferences before calling this.
+//
+Function *CallGraph::removeFunctionFromModule(CallGraphNode *CGN) {
+ assert(CGN->CalledFunctions.empty() && "Cannot remove function from call "
+ "graph if it references other functions!");
+ Function *F = CGN->getFunction(); // Get the function for the call graph node
+ delete CGN; // Delete the call graph node for this func
+ FunctionMap.erase(F); // Remove the call graph node from the map
+
+ Mod->getFunctionList().remove(F);
+ return F;
+}
+
+// changeFunction - This method changes the function associated with this
+// CallGraphNode, for use by transformations that need to change the prototype
+// of a Function (thus they must create a new Function and move the old code
+// over).
+void CallGraph::changeFunction(Function *OldF, Function *NewF) {
+ iterator I = FunctionMap.find(OldF);
+ CallGraphNode *&New = FunctionMap[NewF];
+ assert(I != FunctionMap.end() && I->second && !New &&
+ "OldF didn't exist in CG or NewF already does!");
+ New = I->second;
+ New->F = NewF;
+ FunctionMap.erase(I);
+}
+
+// getOrInsertFunction - This method is identical to calling operator[], but
+// it will insert a new CallGraphNode for the specified function if one does
+// not already exist.
+CallGraphNode *CallGraph::getOrInsertFunction(const Function *F) {
+ CallGraphNode *&CGN = FunctionMap[F];
+ if (CGN) return CGN;
+
+ assert((!F || F->getParent() == Mod) && "Function not in current module!");
+ return CGN = new CallGraphNode(const_cast<Function*>(F));
+}
+
+void CallGraphNode::print(std::ostream &OS) const {
+ if (Function *F = getFunction())
+ OS << "Call graph node for function: '" << F->getName() <<"'\n";
+ else
+ OS << "Call graph node <<null function: 0x" << this << ">>:\n";
+
+ for (const_iterator I = begin(), E = end(); I != E; ++I)
+ if (I->second->getFunction())
+ OS << " Calls function '" << I->second->getFunction()->getName() <<"'\n";
+ else
+ OS << " Calls external node\n";
+ OS << "\n";
+}
+
+void CallGraphNode::dump() const { print(cerr); }
+
+void CallGraphNode::removeCallEdgeTo(CallGraphNode *Callee) {
+ for (unsigned i = CalledFunctions.size(); ; --i) {
+ assert(i && "Cannot find callee to remove!");
+ if (CalledFunctions[i-1].second == Callee) {
+ CalledFunctions.erase(CalledFunctions.begin()+i-1);
+ return;
+ }
+ }
+}
+
+// removeAnyCallEdgeTo - This method removes any call edges from this node to
+// the specified callee function. This takes more time to execute than
+// removeCallEdgeTo, so it should not be used unless necessary.
+void CallGraphNode::removeAnyCallEdgeTo(CallGraphNode *Callee) {
+ for (unsigned i = 0, e = CalledFunctions.size(); i != e; ++i)
+ if (CalledFunctions[i].second == Callee) {
+ CalledFunctions[i] = CalledFunctions.back();
+ CalledFunctions.pop_back();
+ --i; --e;
+ }
+}
+
+// Enuse that users of CallGraph.h also link with this file
+DEFINING_FILE_FOR(CallGraph)
diff --git a/lib/Analysis/IPA/CallGraphSCCPass.cpp b/lib/Analysis/IPA/CallGraphSCCPass.cpp
new file mode 100644
index 0000000..a7e9dd0
--- /dev/null
+++ b/lib/Analysis/IPA/CallGraphSCCPass.cpp
@@ -0,0 +1,196 @@
+//===- CallGraphSCCPass.cpp - Pass that operates BU on call graph ---------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the CallGraphSCCPass class, which is used for passes
+// which are implemented as bottom-up traversals on the call graph. Because
+// there may be cycles in the call graph, passes of this type operate on the
+// call-graph in SCC order: that is, they process function bottom-up, except for
+// recursive functions, which they process all at once.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/CallGraphSCCPass.h"
+#include "llvm/Analysis/CallGraph.h"
+#include "llvm/ADT/SCCIterator.h"
+#include "llvm/PassManagers.h"
+#include "llvm/Function.h"
+using namespace llvm;
+
+//===----------------------------------------------------------------------===//
+// CGPassManager
+//
+/// CGPassManager manages FPPassManagers and CalLGraphSCCPasses.
+
+class CGPassManager : public ModulePass, public PMDataManager {
+
+public:
+ static char ID;
+ CGPassManager(int Depth)
+ : ModulePass((intptr_t)&ID), PMDataManager(Depth) { }
+
+ /// run - Execute all of the passes scheduled for execution. Keep track of
+ /// whether any of the passes modifies the module, and if so, return true.
+ bool runOnModule(Module &M);
+
+ bool doInitialization(CallGraph &CG);
+ bool doFinalization(CallGraph &CG);
+
+ /// Pass Manager itself does not invalidate any analysis info.
+ void getAnalysisUsage(AnalysisUsage &Info) const {
+ // CGPassManager walks SCC and it needs CallGraph.
+ Info.addRequired<CallGraph>();
+ Info.setPreservesAll();
+ }
+
+ virtual const char *getPassName() const {
+ return "CallGraph Pass Manager";
+ }
+
+ // Print passes managed by this manager
+ void dumpPassStructure(unsigned Offset) {
+ llvm::cerr << std::string(Offset*2, ' ') << "Call Graph SCC Pass Manager\n";
+ for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index) {
+ Pass *P = getContainedPass(Index);
+ P->dumpPassStructure(Offset + 1);
+ dumpLastUses(P, Offset+1);
+ }
+ }
+
+ Pass *getContainedPass(unsigned N) {
+ assert ( N < PassVector.size() && "Pass number out of range!");
+ Pass *FP = static_cast<Pass *>(PassVector[N]);
+ return FP;
+ }
+
+ virtual PassManagerType getPassManagerType() const {
+ return PMT_CallGraphPassManager;
+ }
+};
+
+char CGPassManager::ID = 0;
+/// run - Execute all of the passes scheduled for execution. Keep track of
+/// whether any of the passes modifies the module, and if so, return true.
+bool CGPassManager::runOnModule(Module &M) {
+ CallGraph &CG = getAnalysis<CallGraph>();
+ bool Changed = doInitialization(CG);
+
+ // Walk SCC
+ for (scc_iterator<CallGraph*> I = scc_begin(&CG), E = scc_end(&CG);
+ I != E; ++I) {
+
+ // Run all passes on current SCC
+ for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index) {
+ Pass *P = getContainedPass(Index);
+ AnalysisUsage AnUsage;
+ P->getAnalysisUsage(AnUsage);
+
+ dumpPassInfo(P, EXECUTION_MSG, ON_CG_MSG, "");
+ dumpAnalysisSetInfo("Required", P, AnUsage.getRequiredSet());
+
+ initializeAnalysisImpl(P);
+
+ StartPassTimer(P);
+ if (CallGraphSCCPass *CGSP = dynamic_cast<CallGraphSCCPass *>(P))
+ Changed |= CGSP->runOnSCC(*I); // TODO : What if CG is changed ?
+ else {
+ FPPassManager *FPP = dynamic_cast<FPPassManager *>(P);
+ assert (FPP && "Invalid CGPassManager member");
+
+ // Run pass P on all functions current SCC
+ std::vector<CallGraphNode*> &SCC = *I;
+ for (unsigned i = 0, e = SCC.size(); i != e; ++i) {
+ Function *F = SCC[i]->getFunction();
+ if (F) {
+ dumpPassInfo(P, EXECUTION_MSG, ON_FUNCTION_MSG, F->getName());
+ Changed |= FPP->runOnFunction(*F);
+ }
+ }
+ }
+ StopPassTimer(P);
+
+ if (Changed)
+ dumpPassInfo(P, MODIFICATION_MSG, ON_CG_MSG, "");
+ dumpAnalysisSetInfo("Preserved", P, AnUsage.getPreservedSet());
+
+ removeNotPreservedAnalysis(P);
+ recordAvailableAnalysis(P);
+ removeDeadPasses(P, "", ON_CG_MSG);
+ }
+ }
+ Changed |= doFinalization(CG);
+ return Changed;
+}
+
+/// 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);
+ }
+ return Changed;
+}
+
+/// 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);
+ }
+ return Changed;
+}
+
+/// Assign pass manager to manage this pass.
+void CallGraphSCCPass::assignPassManager(PMStack &PMS,
+ PassManagerType PreferredType) {
+ // Find CGPassManager
+ while (!PMS.empty()) {
+ if (PMS.top()->getPassManagerType() > PMT_CallGraphPassManager)
+ PMS.pop();
+ else;
+ break;
+ }
+
+ 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");
+ PMDataManager *PMD = PMS.top();
+
+ // [1] Create new Call Graph Pass Manager
+ CGP = new CGPassManager(PMD->getDepth() + 1);
+
+ // [2] Set up new manager's top level manager
+ PMTopLevelManager *TPM = PMD->getTopLevelManager();
+ TPM->addIndirectPassManager(CGP);
+
+ // [3] Assign manager to manage this new manager. This may create
+ // and push new managers into PMS
+ Pass *P = dynamic_cast<Pass *>(CGP);
+ TPM->schedulePass(P);
+
+ // [4] Push new manager into PMS
+ PMS.push(CGP);
+ }
+
+ CGP->add(this);
+}
+
+/// getAnalysisUsage - For this class, we declare that we require and preserve
+/// the call graph. If the derived class implements this method, it should
+/// always explicitly call the implementation here.
+void CallGraphSCCPass::getAnalysisUsage(AnalysisUsage &AU) const {
+ AU.addRequired<CallGraph>();
+ AU.addPreserved<CallGraph>();
+}
diff --git a/lib/Analysis/IPA/FindUsedTypes.cpp b/lib/Analysis/IPA/FindUsedTypes.cpp
new file mode 100644
index 0000000..a954414
--- /dev/null
+++ b/lib/Analysis/IPA/FindUsedTypes.cpp
@@ -0,0 +1,101 @@
+//===- FindUsedTypes.cpp - Find all Types used by a module ----------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This pass is used to seek out all of the types in use by the program. Note
+// that this analysis explicitly does not include types only used by the symbol
+// table.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Analysis/FindUsedTypes.h"
+#include "llvm/Constants.h"
+#include "llvm/DerivedTypes.h"
+#include "llvm/Module.h"
+#include "llvm/Assembly/Writer.h"
+#include "llvm/Support/InstIterator.h"
+using namespace llvm;
+
+char FindUsedTypes::ID = 0;
+static RegisterPass<FindUsedTypes>
+X("printusedtypes", "Find Used Types");
+
+// IncorporateType - Incorporate one type and all of its subtypes into the
+// collection of used types.
+//
+void FindUsedTypes::IncorporateType(const Type *Ty) {
+ // If ty doesn't already exist in the used types map, add it now, otherwise
+ // return.
+ if (!UsedTypes.insert(Ty).second) return; // Already contain Ty.
+
+ // Make sure to add any types this type references now.
+ //
+ for (Type::subtype_iterator I = Ty->subtype_begin(), E = Ty->subtype_end();
+ I != E; ++I)
+ IncorporateType(*I);
+}
+
+void FindUsedTypes::IncorporateValue(const Value *V) {
+ IncorporateType(V->getType());
+
+ // If this is a constant, it could be using other types...
+ if (const Constant *C = dyn_cast<Constant>(V)) {
+ if (!isa<GlobalValue>(C))
+ for (User::const_op_iterator OI = C->op_begin(), OE = C->op_end();
+ OI != OE; ++OI)
+ IncorporateValue(*OI);
+ }
+}
+
+
+// run - This incorporates all types used by the specified module
+//
+bool FindUsedTypes::runOnModule(Module &m) {
+ UsedTypes.clear(); // reset if run multiple times...
+
+ // Loop over global variables, incorporating their types
+ for (Module::const_global_iterator I = m.global_begin(), E = m.global_end(); I != E; ++I) {
+ IncorporateType(I->getType());
+ if (I->hasInitializer())
+ IncorporateValue(I->getInitializer());
+ }
+
+ for (Module::iterator MI = m.begin(), ME = m.end(); MI != ME; ++MI) {
+ IncorporateType(MI->getType());
+ const Function &F = *MI;
+
+ // Loop over all of the instructions in the function, adding their return
+ // type as well as the types of their operands.
+ //
+ for (const_inst_iterator II = inst_begin(F), IE = inst_end(F);
+ II != IE; ++II) {
+ const Instruction &I = *II;
+
+ IncorporateType(I.getType()); // Incorporate the type of the instruction
+ for (User::const_op_iterator OI = I.op_begin(), OE = I.op_end();
+ OI != OE; ++OI)
+ IncorporateValue(*OI); // Insert inst operand types as well
+ }
+ }
+
+ return false;
+}
+
+// Print the types found in the module. If the optional Module parameter is
+// passed in, then the types are printed symbolically if possible, using the
+// symbol table from the module.
+//
+void FindUsedTypes::print(std::ostream &o, const Module *M) const {
+ o << "Types in use by this module:\n";
+ for (std::set<const Type *>::const_iterator I = UsedTypes.begin(),
+ E = UsedTypes.end(); I != E; ++I)
+ WriteTypeSymbolic(o << " ", *I, M) << "\n";
+}
+
+// Ensure that this file gets linked in when FindUsedTypes.h is used.
+DEFINING_FILE_FOR(FindUsedTypes)
diff --git a/lib/Analysis/IPA/GlobalsModRef.cpp b/lib/Analysis/IPA/GlobalsModRef.cpp
new file mode 100644
index 0000000..63ddb89
--- /dev/null
+++ b/lib/Analysis/IPA/GlobalsModRef.cpp
@@ -0,0 +1,554 @@
+//===- GlobalsModRef.cpp - Simple Mod/Ref Analysis for Globals ------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This simple pass provides alias and mod/ref information for global values
+// that do not have their address taken, and keeps track of whether functions
+// read or write memory (are "pure"). For this simple (but very common) case,
+// we can provide pretty accurate and useful information.
+//
+//===----------------------------------------------------------------------===//
+
+#define DEBUG_TYPE "globalsmodref-aa"
+#include "llvm/Analysis/Passes.h"
+#include "llvm/Module.h"
+#include "llvm/Pass.h"
+#include "llvm/Instructions.h"
+#include "llvm/Constants.h"
+#include "llvm/DerivedTypes.h"
+#include "llvm/Analysis/AliasAnalysis.h"
+#include "llvm/Analysis/CallGraph.h"
+#include "llvm/Support/Compiler.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/InstIterator.h"
+#include "llvm/ADT/Statistic.h"
+#include "llvm/ADT/SCCIterator.h"
+#include <set>
+using namespace llvm;
+
+STATISTIC(NumNonAddrTakenGlobalVars,
+ "Number of global vars without address taken");
+STATISTIC(NumNonAddrTakenFunctions,"Number of functions without address taken");
+STATISTIC(NumNoMemFunctions, "Number of functions that do not access memory");
+STATISTIC(NumReadMemFunctions, "Number of functions that only read memory");
+STATISTIC(NumIndirectGlobalVars, "Number of indirect global objects");
+
+namespace {
+ /// FunctionRecord - One instance of this structure is stored for every
+ /// function in the program. Later, the entries for these functions are
+ /// removed if the function is found to call an external function (in which
+ /// case we know nothing about it.
+ struct VISIBILITY_HIDDEN FunctionRecord {
+ /// GlobalInfo - Maintain mod/ref info for all of the globals without
+ /// addresses taken that are read or written (transitively) by this
+ /// function.
+ std::map<GlobalValue*, unsigned> GlobalInfo;
+
+ unsigned getInfoForGlobal(GlobalValue *GV) const {
+ std::map<GlobalValue*, unsigned>::const_iterator I = GlobalInfo.find(GV);
+ if (I != GlobalInfo.end())
+ return I->second;
+ return 0;
+ }
+
+ /// FunctionEffect - Capture whether or not this function reads or writes to
+ /// ANY memory. If not, we can do a lot of aggressive analysis on it.
+ unsigned FunctionEffect;
+
+ FunctionRecord() : FunctionEffect(0) {}
+ };
+
+ /// GlobalsModRef - The actual analysis pass.
+ class VISIBILITY_HIDDEN GlobalsModRef
+ : public ModulePass, public AliasAnalysis {
+ /// NonAddressTakenGlobals - The globals that do not have their addresses
+ /// taken.
+ std::set<GlobalValue*> NonAddressTakenGlobals;
+
+ /// IndirectGlobals - The memory pointed to by this global is known to be
+ /// 'owned' by the global.
+ std::set<GlobalValue*> IndirectGlobals;
+
+ /// AllocsForIndirectGlobals - If an instruction allocates memory for an
+ /// indirect global, this map indicates which one.
+ std::map<Value*, GlobalValue*> AllocsForIndirectGlobals;
+
+ /// FunctionInfo - For each function, keep track of what globals are
+ /// modified or read.
+ std::map<Function*, FunctionRecord> FunctionInfo;
+
+ public:
+ static char ID;
+ GlobalsModRef() : ModulePass((intptr_t)&ID) {}
+
+ bool runOnModule(Module &M) {
+ InitializeAliasAnalysis(this); // set up super class
+ AnalyzeGlobals(M); // find non-addr taken globals
+ AnalyzeCallGraph(getAnalysis<CallGraph>(), M); // Propagate on CG
+ return false;
+ }
+
+ virtual void getAnalysisUsage(AnalysisUsage &AU) const {
+ AliasAnalysis::getAnalysisUsage(AU);
+ AU.addRequired<CallGraph>();
+ AU.setPreservesAll(); // Does not transform code
+ }
+
+ //------------------------------------------------
+ // Implement the AliasAnalysis API
+ //
+ AliasResult alias(const Value *V1, unsigned V1Size,
+ const Value *V2, unsigned V2Size);
+ ModRefResult getModRefInfo(CallSite CS, Value *P, unsigned Size);
+ ModRefResult getModRefInfo(CallSite CS1, CallSite CS2) {
+ return AliasAnalysis::getModRefInfo(CS1,CS2);
+ }
+ bool hasNoModRefInfoForCalls() const { return false; }
+
+ /// getModRefBehavior - Return the behavior of the specified function if
+ /// called from the specified call site. The call site may be null in which
+ /// case the most generic behavior of this function should be returned.
+ virtual ModRefBehavior getModRefBehavior(Function *F, CallSite CS,
+ std::vector<PointerAccessInfo> *Info) {
+ if (FunctionRecord *FR = getFunctionInfo(F))
+ if (FR->FunctionEffect == 0)
+ return DoesNotAccessMemory;
+ else if ((FR->FunctionEffect & Mod) == 0)
+ return OnlyReadsMemory;
+ return AliasAnalysis::getModRefBehavior(F, CS, Info);
+ }
+
+ virtual void deleteValue(Value *V);
+ virtual void copyValue(Value *From, Value *To);
+
+ private:
+ /// getFunctionInfo - Return the function info for the function, or null if
+ /// the function calls an external function (in which case we don't have
+ /// anything useful to say about it).
+ FunctionRecord *getFunctionInfo(Function *F) {
+ std::map<Function*, FunctionRecord>::iterator I = FunctionInfo.find(F);
+ if (I != FunctionInfo.end())
+ return &I->second;
+ return 0;
+ }
+
+ void AnalyzeGlobals(Module &M);
+ void AnalyzeCallGraph(CallGraph &CG, Module &M);
+ void AnalyzeSCC(std::vector<CallGraphNode *> &SCC);
+ bool AnalyzeUsesOfPointer(Value *V, std::vector<Function*> &Readers,
+ std::vector<Function*> &Writers,
+ GlobalValue *OkayStoreDest = 0);
+ bool AnalyzeIndirectGlobalMemory(GlobalValue *GV);
+ };
+
+ char GlobalsModRef::ID = 0;
+ RegisterPass<GlobalsModRef> X("globalsmodref-aa",
+ "Simple mod/ref analysis for globals");
+ RegisterAnalysisGroup<AliasAnalysis> Y(X);
+}
+
+Pass *llvm::createGlobalsModRefPass() { return new GlobalsModRef(); }
+
+/// getUnderlyingObject - This traverses the use chain to figure out what object
+/// the specified value points to. If the value points to, or is derived from,
+/// a global object, return it.
+static Value *getUnderlyingObject(Value *V) {
+ if (!isa<PointerType>(V->getType())) return V;
+
+ // If we are at some type of object... return it.
+ if (GlobalValue *GV = dyn_cast<GlobalValue>(V)) return GV;
+
+ // Traverse through different addressing mechanisms.
+ if (Instruction *I = dyn_cast<Instruction>(V)) {
+ if (isa<BitCastInst>(I) || isa<GetElementPtrInst>(I))
+ return getUnderlyingObject(I->getOperand(0));
+ } else if (ConstantExpr *CE = dyn_cast<ConstantExpr>(V)) {
+ if (CE->getOpcode() == Instruction::BitCast ||
+ CE->getOpcode() == Instruction::GetElementPtr)
+ return getUnderlyingObject(CE->getOperand(0));
+ }
+
+ // Othewise, we don't know what this is, return it as the base pointer.
+ return V;
+}
+
+/// AnalyzeGlobals - Scan through the users of all of the internal
+/// GlobalValue's in the program. If none of them have their "Address taken"
+/// (really, their address passed to something nontrivial), record this fact,
+/// and record the functions that they are used directly in.
+void GlobalsModRef::AnalyzeGlobals(Module &M) {
+ std::vector<Function*> Readers, Writers;
+ for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I)
+ if (I->hasInternalLinkage()) {
+ if (!AnalyzeUsesOfPointer(I, Readers, Writers)) {
+ // Remember that we are tracking this global.
+ NonAddressTakenGlobals.insert(I);
+ ++NumNonAddrTakenFunctions;
+ }
+ Readers.clear(); Writers.clear();
+ }
+
+ for (Module::global_iterator I = M.global_begin(), E = M.global_end();
+ I != E; ++I)
+ if (I->hasInternalLinkage()) {
+ if (!AnalyzeUsesOfPointer(I, Readers, Writers)) {
+ // Remember that we are tracking this global, and the mod/ref fns
+ NonAddressTakenGlobals.insert(I);
+ for (unsigned i = 0, e = Readers.size(); i != e; ++i)
+ FunctionInfo[Readers[i]].GlobalInfo[I] |= Ref;
+
+ if (!I->isConstant()) // No need to keep track of writers to constants
+ for (unsigned i = 0, e = Writers.size(); i != e; ++i)
+ FunctionInfo[Writers[i]].GlobalInfo[I] |= Mod;
+ ++NumNonAddrTakenGlobalVars;
+
+ // If this global holds a pointer type, see if it is an indirect global.
+ if (isa<PointerType>(I->getType()->getElementType()) &&
+ AnalyzeIndirectGlobalMemory(I))
+ ++NumIndirectGlobalVars;
+ }
+ Readers.clear(); Writers.clear();
+ }
+}
+
+/// AnalyzeUsesOfPointer - Look at all of the users of the specified pointer.
+/// If this is used by anything complex (i.e., the address escapes), return
+/// true. Also, while we are at it, keep track of those functions that read and
+/// write to the value.
+///
+/// If OkayStoreDest is non-null, stores into this global are allowed.
+bool GlobalsModRef::AnalyzeUsesOfPointer(Value *V,
+ std::vector<Function*> &Readers,
+ std::vector<Function*> &Writers,
+ GlobalValue *OkayStoreDest) {
+ if (!isa<PointerType>(V->getType())) return true;
+
+ for (Value::use_iterator UI = V->use_begin(), E = V->use_end(); UI != E; ++UI)
+ if (LoadInst *LI = dyn_cast<LoadInst>(*UI)) {
+ Readers.push_back(LI->getParent()->getParent());
+ } else if (StoreInst *SI = dyn_cast<StoreInst>(*UI)) {
+ if (V == SI->getOperand(1)) {
+ Writers.push_back(SI->getParent()->getParent());
+ } else if (SI->getOperand(1) != OkayStoreDest) {
+ return true; // Storing the pointer
+ }
+ } else if (GetElementPtrInst *GEP = dyn_cast<GetElementPtrInst>(*UI)) {
+ if (AnalyzeUsesOfPointer(GEP, Readers, Writers)) return true;
+ } else if (CallInst *CI = dyn_cast<CallInst>(*UI)) {
+ // Make sure that this is just the function being called, not that it is
+ // passing into the function.
+ for (unsigned i = 1, e = CI->getNumOperands(); i != e; ++i)
+ if (CI->getOperand(i) == V) return true;
+ } else if (InvokeInst *II = dyn_cast<InvokeInst>(*UI)) {
+ // Make sure that this is just the function being called, not that it is
+ // passing into the function.
+ for (unsigned i = 3, e = II->getNumOperands(); i != e; ++i)
+ if (II->getOperand(i) == V) return true;
+ } else if (ConstantExpr *CE = dyn_cast<ConstantExpr>(*UI)) {
+ if (CE->getOpcode() == Instruction::GetElementPtr ||
+ CE->getOpcode() == Instruction::BitCast) {
+ if (AnalyzeUsesOfPointer(CE, Readers, Writers))
+ return true;
+ } else {
+ return true;
+ }
+ } else if (ICmpInst *ICI = dyn_cast<ICmpInst>(*UI)) {
+ if (!isa<ConstantPointerNull>(ICI->getOperand(1)))
+ return true; // Allow comparison against null.
+ } else if (FreeInst *F = dyn_cast<FreeInst>(*UI)) {
+ Writers.push_back(F->getParent()->getParent());
+ } else {
+ return true;
+ }
+ return false;
+}
+
+/// AnalyzeIndirectGlobalMemory - We found an non-address-taken global variable
+/// which holds a pointer type. See if the global always points to non-aliased
+/// heap memory: that is, all initializers of the globals are allocations, and
+/// those allocations have no use other than initialization of the global.
+/// Further, all loads out of GV must directly use the memory, not store the
+/// pointer somewhere. If this is true, we consider the memory pointed to by
+/// GV to be owned by GV and can disambiguate other pointers from it.
+bool GlobalsModRef::AnalyzeIndirectGlobalMemory(GlobalValue *GV) {
+ // Keep track of values related to the allocation of the memory, f.e. the
+ // value produced by the malloc call and any casts.
+ std::vector<Value*> AllocRelatedValues;
+
+ // Walk the user list of the global. If we find anything other than a direct
+ // load or store, bail out.
+ for (Value::use_iterator I = GV->use_begin(), E = GV->use_end(); I != E; ++I){
+ if (LoadInst *LI = dyn_cast<LoadInst>(*I)) {
+ // The pointer loaded from the global can only be used in simple ways:
+ // we allow addressing of it and loading storing to it. We do *not* allow
+ // storing the loaded pointer somewhere else or passing to a function.
+ std::vector<Function*> ReadersWriters;
+ if (AnalyzeUsesOfPointer(LI, ReadersWriters, ReadersWriters))
+ return false; // Loaded pointer escapes.
+ // TODO: Could try some IP mod/ref of the loaded pointer.
+ } else if (StoreInst *SI = dyn_cast<StoreInst>(*I)) {
+ // Storing the global itself.
+ if (SI->getOperand(0) == GV) return false;
+
+ // If storing the null pointer, ignore it.
+ if (isa<ConstantPointerNull>(SI->getOperand(0)))
+ continue;
+
+ // Check the value being stored.
+ Value *Ptr = getUnderlyingObject(SI->getOperand(0));
+
+ if (isa<MallocInst>(Ptr)) {
+ // Okay, easy case.
+ } else if (CallInst *CI = dyn_cast<CallInst>(Ptr)) {
+ Function *F = CI->getCalledFunction();
+ if (!F || !F->isDeclaration()) return false; // Too hard to analyze.
+ if (F->getName() != "calloc") return false; // Not calloc.
+ } else {
+ return false; // Too hard to analyze.
+ }
+
+ // Analyze all uses of the allocation. If any of them are used in a
+ // non-simple way (e.g. stored to another global) bail out.
+ std::vector<Function*> ReadersWriters;
+ if (AnalyzeUsesOfPointer(Ptr, ReadersWriters, ReadersWriters, GV))
+ return false; // Loaded pointer escapes.
+
+ // Remember that this allocation is related to the indirect global.
+ AllocRelatedValues.push_back(Ptr);
+ } else {
+ // Something complex, bail out.
+ return false;
+ }
+ }
+
+ // Okay, this is an indirect global. Remember all of the allocations for
+ // this global in AllocsForIndirectGlobals.
+ while (!AllocRelatedValues.empty()) {
+ AllocsForIndirectGlobals[AllocRelatedValues.back()] = GV;
+ AllocRelatedValues.pop_back();
+ }
+ IndirectGlobals.insert(GV);
+ return true;
+}
+
+/// AnalyzeCallGraph - At this point, we know the functions where globals are
+/// immediately stored to and read from. Propagate this information up the call
+/// graph to all callers and compute the mod/ref info for all memory for each
+/// function.
+void GlobalsModRef::AnalyzeCallGraph(CallGraph &CG, Module &M) {
+ // We do a bottom-up SCC traversal of the call graph. In other words, we
+ // visit all callees before callers (leaf-first).
+ for (scc_iterator<CallGraph*> I = scc_begin(&CG), E = scc_end(&CG); I!=E; ++I)
+ if ((*I).size() != 1) {
+ AnalyzeSCC(*I);
+ } else if (Function *F = (*I)[0]->getFunction()) {
+ if (!F->isDeclaration()) {
+ // Nonexternal function.
+ AnalyzeSCC(*I);
+ } else {
+ // Otherwise external function. Handle intrinsics and other special
+ // cases here.
+ if (getAnalysis<AliasAnalysis>().doesNotAccessMemory(F))
+ // If it does not access memory, process the function, causing us to
+ // realize it doesn't do anything (the body is empty).
+ AnalyzeSCC(*I);
+ else {
+ // Otherwise, don't process it. This will cause us to conservatively
+ // assume the worst.
+ }
+ }
+ } else {
+ // Do not process the external node, assume the worst.
+ }
+}
+
+void GlobalsModRef::AnalyzeSCC(std::vector<CallGraphNode *> &SCC) {
+ assert(!SCC.empty() && "SCC with no functions?");
+ FunctionRecord &FR = FunctionInfo[SCC[0]->getFunction()];
+
+ bool CallsExternal = false;
+ unsigned FunctionEffect = 0;
+
+ // Collect the mod/ref properties due to called functions. We only compute
+ // one mod-ref set
+ for (unsigned i = 0, e = SCC.size(); i != e && !CallsExternal; ++i)
+ for (CallGraphNode::iterator CI = SCC[i]->begin(), E = SCC[i]->end();
+ CI != E; ++CI)
+ if (Function *Callee = CI->second->getFunction()) {
+ if (FunctionRecord *CalleeFR = getFunctionInfo(Callee)) {
+ // Propagate function effect up.
+ FunctionEffect |= CalleeFR->FunctionEffect;
+
+ // Incorporate callee's effects on globals into our info.
+ for (std::map<GlobalValue*, unsigned>::iterator GI =
+ CalleeFR->GlobalInfo.begin(), E = CalleeFR->GlobalInfo.end();
+ GI != E; ++GI)
+ FR.GlobalInfo[GI->first] |= GI->second;
+
+ } else {
+ // Okay, if we can't say anything about it, maybe some other alias
+ // analysis can.
+ ModRefBehavior MRB =
+ AliasAnalysis::getModRefBehavior(Callee, CallSite());
+ if (MRB != DoesNotAccessMemory) {
+ // FIXME: could make this more aggressive for functions that just
+ // read memory. We should just say they read all globals.
+ CallsExternal = true;
+ break;
+ }
+ }
+ } else {
+ CallsExternal = true;
+ break;
+ }
+
+ // If this SCC calls an external function, we can't say anything about it, so
+ // remove all SCC functions from the FunctionInfo map.
+ if (CallsExternal) {
+ for (unsigned i = 0, e = SCC.size(); i != e; ++i)
+ FunctionInfo.erase(SCC[i]->getFunction());
+ return;
+ }
+
+ // Otherwise, unless we already know that this function mod/refs memory, scan
+ // the function bodies to see if there are any explicit loads or stores.
+ if (FunctionEffect != ModRef) {
+ for (unsigned i = 0, e = SCC.size(); i != e && FunctionEffect != ModRef;++i)
+ for (inst_iterator II = inst_begin(SCC[i]->getFunction()),
+ E = inst_end(SCC[i]->getFunction());
+ II != E && FunctionEffect != ModRef; ++II)
+ if (isa<LoadInst>(*II))
+ FunctionEffect |= Ref;
+ else if (isa<StoreInst>(*II))
+ FunctionEffect |= Mod;
+ else if (isa<MallocInst>(*II) || isa<FreeInst>(*II))
+ FunctionEffect |= ModRef;
+ }
+
+ if ((FunctionEffect & Mod) == 0)
+ ++NumReadMemFunctions;
+ if (FunctionEffect == 0)
+ ++NumNoMemFunctions;
+ FR.FunctionEffect = FunctionEffect;
+
+ // Finally, now that we know the full effect on this SCC, clone the
+ // information to each function in the SCC.
+ for (unsigned i = 1, e = SCC.size(); i != e; ++i)
+ FunctionInfo[SCC[i]->getFunction()] = FR;
+}
+
+
+
+/// alias - If one of the pointers is to a global that we are tracking, and the
+/// other is some random pointer, we know there cannot be an alias, because the
+/// address of the global isn't taken.
+AliasAnalysis::AliasResult
+GlobalsModRef::alias(const Value *V1, unsigned V1Size,
+ const Value *V2, unsigned V2Size) {
+ // Get the base object these pointers point to.
+ Value *UV1 = getUnderlyingObject(const_cast<Value*>(V1));
+ Value *UV2 = getUnderlyingObject(const_cast<Value*>(V2));
+
+ // If either of the underlying values is a global, they may be non-addr-taken
+ // globals, which we can answer queries about.
+ GlobalValue *GV1 = dyn_cast<GlobalValue>(UV1);
+ GlobalValue *GV2 = dyn_cast<GlobalValue>(UV2);
+ if (GV1 || GV2) {
+ // If the global's address is taken, pretend we don't know it's a pointer to
+ // the global.
+ if (GV1 && !NonAddressTakenGlobals.count(GV1)) GV1 = 0;
+ if (GV2 && !NonAddressTakenGlobals.count(GV2)) GV2 = 0;
+
+ // If the the two pointers are derived from two different non-addr-taken
+ // globals, or if one is and the other isn't, we know these can't alias.
+ if ((GV1 || GV2) && GV1 != GV2)
+ return NoAlias;
+
+ // Otherwise if they are both derived from the same addr-taken global, we
+ // can't know the two accesses don't overlap.
+ }
+
+ // These pointers may be based on the memory owned by an indirect global. If
+ // so, we may be able to handle this. First check to see if the base pointer
+ // is a direct load from an indirect global.
+ GV1 = GV2 = 0;
+ if (LoadInst *LI = dyn_cast<LoadInst>(UV1))
+ if (GlobalVariable *GV = dyn_cast<GlobalVariable>(LI->getOperand(0)))
+ if (IndirectGlobals.count(GV))
+ GV1 = GV;
+ if (LoadInst *LI = dyn_cast<LoadInst>(UV2))
+ if (GlobalVariable *GV = dyn_cast<GlobalVariable>(LI->getOperand(0)))
+ if (IndirectGlobals.count(GV))
+ GV2 = GV;
+
+ // These pointers may also be from an allocation for the indirect global. If
+ // so, also handle them.
+ if (AllocsForIndirectGlobals.count(UV1))
+ GV1 = AllocsForIndirectGlobals[UV1];
+ if (AllocsForIndirectGlobals.count(UV2))
+ GV2 = AllocsForIndirectGlobals[UV2];
+
+ // Now that we know whether the two pointers are related to indirect globals,
+ // use this to disambiguate the pointers. If either pointer is based on an
+ // indirect global and if they are not both based on the same indirect global,
+ // they cannot alias.
+ if ((GV1 || GV2) && GV1 != GV2)
+ return NoAlias;
+
+ return AliasAnalysis::alias(V1, V1Size, V2, V2Size);
+}
+
+AliasAnalysis::ModRefResult
+GlobalsModRef::getModRefInfo(CallSite CS, Value *P, unsigned Size) {
+ unsigned Known = ModRef;
+
+ // If we are asking for mod/ref info of a direct call with a pointer to a
+ // global we are tracking, return information if we have it.
+ if (GlobalValue *GV = dyn_cast<GlobalValue>(getUnderlyingObject(P)))
+ if (GV->hasInternalLinkage())
+ if (Function *F = CS.getCalledFunction())
+ if (NonAddressTakenGlobals.count(GV))
+ if (FunctionRecord *FR = getFunctionInfo(F))
+ Known = FR->getInfoForGlobal(GV);
+
+ if (Known == NoModRef)
+ return NoModRef; // No need to query other mod/ref analyses
+ return ModRefResult(Known & AliasAnalysis::getModRefInfo(CS, P, Size));
+}
+
+
+//===----------------------------------------------------------------------===//
+// Methods to update the analysis as a result of the client transformation.
+//
+void GlobalsModRef::deleteValue(Value *V) {
+ if (GlobalValue *GV = dyn_cast<GlobalValue>(V)) {
+ if (NonAddressTakenGlobals.erase(GV)) {
+ // This global might be an indirect global. If so, remove it and remove
+ // any AllocRelatedValues for it.
+ if (IndirectGlobals.erase(GV)) {
+ // Remove any entries in AllocsForIndirectGlobals for this global.
+ for (std::map<Value*, GlobalValue*>::iterator
+ I = AllocsForIndirectGlobals.begin(),
+ E = AllocsForIndirectGlobals.end(); I != E; ) {
+ if (I->second == GV) {
+ AllocsForIndirectGlobals.erase(I++);
+ } else {
+ ++I;
+ }
+ }
+ }
+ }
+ }
+
+ // Otherwise, if this is an allocation related to an indirect global, remove
+ // it.
+ AllocsForIndirectGlobals.erase(V);
+}
+
+void GlobalsModRef::copyValue(Value *From, Value *To) {
+}
diff --git a/lib/Analysis/IPA/Makefile b/lib/Analysis/IPA/Makefile
new file mode 100644
index 0000000..786e743
--- /dev/null
+++ b/lib/Analysis/IPA/Makefile
@@ -0,0 +1,14 @@
+##===- lib/Analysis/IPA/Makefile ---------------------------*- Makefile -*-===##
+#
+# The LLVM Compiler Infrastructure
+#
+# This file was developed by the LLVM research group and is distributed under
+# the University of Illinois Open Source License. See LICENSE.TXT for details.
+#
+##===----------------------------------------------------------------------===##
+
+LEVEL = ../../..
+LIBRARYNAME = LLVMipa
+BUILD_ARCHIVE = 1
+include $(LEVEL)/Makefile.common
+
diff --git a/lib/Analysis/InstCount.cpp b/lib/Analysis/InstCount.cpp
new file mode 100644
index 0000000..82b2245
--- /dev/null
+++ b/lib/Analysis/InstCount.cpp
@@ -0,0 +1,86 @@
+//===-- InstCount.cpp - Collects the count of all instructions ------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This pass collects the count of all instructions and reports them
+//
+//===----------------------------------------------------------------------===//
+
+#define DEBUG_TYPE "instcount"
+#include "llvm/Analysis/Passes.h"
+#include "llvm/Pass.h"
+#include "llvm/Function.h"
+#include "llvm/Support/Compiler.h"
+#include "llvm/Support/InstVisitor.h"
+#include "llvm/Support/Streams.h"
+#include "llvm/ADT/Statistic.h"
+#include <ostream>
+using namespace llvm;
+
+STATISTIC(TotalInsts , "Number of instructions (of all types)");
+STATISTIC(TotalBlocks, "Number of basic blocks");
+STATISTIC(TotalFuncs , "Number of non-external functions");
+STATISTIC(TotalMemInst, "Number of memory instructions");
+
+#define HANDLE_INST(N, OPCODE, CLASS) \
+ STATISTIC(Num ## OPCODE ## Inst, "Number of " #OPCODE " insts");
+
+#include "llvm/Instruction.def"
+
+
+namespace {
+ class VISIBILITY_HIDDEN InstCount
+ : public FunctionPass, public InstVisitor<InstCount> {
+ friend class InstVisitor<InstCount>;
+
+ void visitFunction (Function &F) { ++TotalFuncs; }
+ void visitBasicBlock(BasicBlock &BB) { ++TotalBlocks; }
+
+#define HANDLE_INST(N, OPCODE, CLASS) \
+ void visit##OPCODE(CLASS &) { ++Num##OPCODE##Inst; ++TotalInsts; }
+
+#include "llvm/Instruction.def"
+
+ void visitInstruction(Instruction &I) {
+ cerr << "Instruction Count does not know about " << I;
+ abort();
+ }
+ public:
+ static char ID; // Pass identification, replacement for typeid
+ InstCount() : FunctionPass((intptr_t)&ID) {}
+
+ virtual bool runOnFunction(Function &F);
+
+ virtual void getAnalysisUsage(AnalysisUsage &AU) const {
+ AU.setPreservesAll();
+ }
+ virtual void print(std::ostream &O, const Module *M) const {}
+
+ };
+
+ char InstCount::ID = 0;
+ RegisterPass<InstCount> X("instcount",
+ "Counts the various types of Instructions");
+}
+
+FunctionPass *llvm::createInstCountPass() { return new InstCount(); }
+
+// InstCount::run - This is the main Analysis entry point for a
+// function.
+//
+bool InstCount::runOnFunction(Function &F) {
+ unsigned StartMemInsts =
+ NumGetElementPtrInst + NumLoadInst + NumStoreInst + NumCallInst +
+ NumInvokeInst + NumAllocaInst + NumMallocInst + NumFreeInst;
+ visit(F);
+ unsigned EndMemInsts =
+ NumGetElementPtrInst + NumLoadInst + NumStoreInst + NumCallInst +
+ NumInvokeInst + NumAllocaInst + NumMallocInst + NumFreeInst;
+ TotalMemInst += EndMemInsts-StartMemInsts;
+ return false;
+}
diff --git a/lib/Analysis/Interval.cpp b/lib/Analysis/Interval.cpp
new file mode 100644
index 0000000..404d2c2
--- /dev/null
+++ b/lib/Analysis/Interval.cpp
@@ -0,0 +1,57 @@
+//===- Interval.cpp - Interval class code ---------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains the definition of the Interval class, which represents a
+// partition of a control flow graph of some kind.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Analysis/Interval.h"
+#include "llvm/BasicBlock.h"
+#include "llvm/Support/CFG.h"
+#include <algorithm>
+
+using namespace llvm;
+
+//===----------------------------------------------------------------------===//
+// Interval Implementation
+//===----------------------------------------------------------------------===//
+
+// isLoop - Find out if there is a back edge in this interval...
+//
+bool Interval::isLoop() const {
+ // There is a loop in this interval iff one of the predecessors of the header
+ // node lives in the interval.
+ for (::pred_iterator I = ::pred_begin(HeaderNode), E = ::pred_end(HeaderNode);
+ I != E; ++I) {
+ if (contains(*I)) return true;
+ }
+ return false;
+}
+
+
+void Interval::print(std::ostream &o) const {
+ o << "-------------------------------------------------------------\n"
+ << "Interval Contents:\n";
+
+ // Print out all of the basic blocks in the interval...
+ for (std::vector<BasicBlock*>::const_iterator I = Nodes.begin(),
+ E = Nodes.end(); I != E; ++I)
+ o << **I << "\n";
+
+ o << "Interval Predecessors:\n";
+ for (std::vector<BasicBlock*>::const_iterator I = Predecessors.begin(),
+ E = Predecessors.end(); I != E; ++I)
+ o << **I << "\n";
+
+ o << "Interval Successors:\n";
+ for (std::vector<BasicBlock*>::const_iterator I = Successors.begin(),
+ E = Successors.end(); I != E; ++I)
+ o << **I << "\n";
+}
diff --git a/lib/Analysis/IntervalPartition.cpp b/lib/Analysis/IntervalPartition.cpp
new file mode 100644
index 0000000..e339691
--- /dev/null
+++ b/lib/Analysis/IntervalPartition.cpp
@@ -0,0 +1,114 @@
+//===- IntervalPartition.cpp - Interval Partition module code -------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains the definition of the IntervalPartition class, which
+// calculates and represent the interval partition of a function.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Analysis/IntervalIterator.h"
+using namespace llvm;
+
+char IntervalPartition::ID = 0;
+static RegisterPass<IntervalPartition>
+X("intervals", "Interval Partition Construction", true);
+
+//===----------------------------------------------------------------------===//
+// IntervalPartition Implementation
+//===----------------------------------------------------------------------===//
+
+// destroy - Reset state back to before function was analyzed
+void IntervalPartition::destroy() {
+ for (unsigned i = 0, e = Intervals.size(); i != e; ++i)
+ delete Intervals[i];
+ IntervalMap.clear();
+ RootInterval = 0;
+}
+
+void IntervalPartition::print(std::ostream &O, const Module*) const {
+ for(unsigned i = 0, e = Intervals.size(); i != e; ++i)
+ Intervals[i]->print(O);
+}
+
+// addIntervalToPartition - Add an interval to the internal list of intervals,
+// and then add mappings from all of the basic blocks in the interval to the
+// interval itself (in the IntervalMap).
+//
+void IntervalPartition::addIntervalToPartition(Interval *I) {
+ Intervals.push_back(I);
+
+ // Add mappings for all of the basic blocks in I to the IntervalPartition
+ for (Interval::node_iterator It = I->Nodes.begin(), End = I->Nodes.end();
+ It != End; ++It)
+ IntervalMap.insert(std::make_pair(*It, I));
+}
+
+// updatePredecessors - Interval generation only sets the successor fields of
+// the interval data structures. After interval generation is complete,
+// run through all of the intervals and propagate successor info as
+// predecessor info.
+//
+void IntervalPartition::updatePredecessors(Interval *Int) {
+ BasicBlock *Header = Int->getHeaderNode();
+ for (Interval::succ_iterator I = Int->Successors.begin(),
+ E = Int->Successors.end(); I != E; ++I)
+ getBlockInterval(*I)->Predecessors.push_back(Header);
+}
+
+// IntervalPartition ctor - Build the first level interval partition for the
+// specified function...
+//
+bool IntervalPartition::runOnFunction(Function &F) {
+ // Pass false to intervals_begin because we take ownership of it's memory
+ function_interval_iterator I = intervals_begin(&F, false);
+ assert(I != intervals_end(&F) && "No intervals in function!?!?!");
+
+ addIntervalToPartition(RootInterval = *I);
+
+ ++I; // After the first one...
+
+ // Add the rest of the intervals to the partition.
+ for (function_interval_iterator E = intervals_end(&F); I != E; ++I)
+ addIntervalToPartition(*I);
+
+ // Now that we know all of the successor information, propagate this to the
+ // predecessors for each block.
+ for (unsigned i = 0, e = Intervals.size(); i != e; ++i)
+ updatePredecessors(Intervals[i]);
+ return false;
+}
+
+
+// IntervalPartition ctor - Build a reduced interval partition from an
+// existing interval graph. This takes an additional boolean parameter to
+// distinguish it from a copy constructor. Always pass in false for now.
+//
+IntervalPartition::IntervalPartition(IntervalPartition &IP, bool)
+ : FunctionPass((intptr_t) &ID) {
+ Interval *FunctionStart = IP.getRootInterval();
+ assert(FunctionStart && "Cannot operate on empty IntervalPartitions!");
+
+ // Pass false to intervals_begin because we take ownership of it's memory
+ interval_part_interval_iterator I = intervals_begin(IP, false);
+ assert(I != intervals_end(IP) && "No intervals in interval partition!?!?!");
+
+ addIntervalToPartition(RootInterval = *I);
+
+ ++I; // After the first one...
+
+ // Add the rest of the intervals to the partition.
+ for (interval_part_interval_iterator E = intervals_end(IP); I != E; ++I)
+ addIntervalToPartition(*I);
+
+ // Now that we know all of the successor information, propagate this to the
+ // predecessors for each block.
+ for (unsigned i = 0, e = Intervals.size(); i != e; ++i)
+ updatePredecessors(Intervals[i]);
+}
+
diff --git a/lib/Analysis/LoadValueNumbering.cpp b/lib/Analysis/LoadValueNumbering.cpp
new file mode 100644
index 0000000..f1ade95
--- /dev/null
+++ b/lib/Analysis/LoadValueNumbering.cpp
@@ -0,0 +1,529 @@
+//===- LoadValueNumbering.cpp - Load Value #'ing Implementation -*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements a value numbering pass that value numbers load and call
+// instructions. To do this, it finds lexically identical load instructions,
+// and uses alias analysis to determine which loads are guaranteed to produce
+// the same value. To value number call instructions, it looks for calls to
+// functions that do not write to memory which do not have intervening
+// instructions that clobber the memory that is read from.
+//
+// This pass builds off of another value numbering pass to implement value
+// numbering for non-load and non-call instructions. It uses Alias Analysis so
+// that it can disambiguate the load instructions. The more powerful these base
+// analyses are, the more powerful the resultant value numbering will be.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Analysis/LoadValueNumbering.h"
+#include "llvm/Constants.h"
+#include "llvm/Function.h"
+#include "llvm/Instructions.h"
+#include "llvm/Pass.h"
+#include "llvm/Type.h"
+#include "llvm/Analysis/ValueNumbering.h"
+#include "llvm/Analysis/AliasAnalysis.h"
+#include "llvm/Analysis/Dominators.h"
+#include "llvm/Support/CFG.h"
+#include "llvm/Support/Compiler.h"
+#include "llvm/Target/TargetData.h"
+#include <set>
+#include <algorithm>
+using namespace llvm;
+
+namespace {
+ // FIXME: This should not be a FunctionPass.
+ struct VISIBILITY_HIDDEN LoadVN : public FunctionPass, public ValueNumbering {
+ static char ID; // Class identification, replacement for typeinfo
+ LoadVN() : FunctionPass((intptr_t)&ID) {}
+
+ /// Pass Implementation stuff. This doesn't do any analysis.
+ ///
+ bool runOnFunction(Function &) { return false; }
+
+ /// getAnalysisUsage - Does not modify anything. It uses Value Numbering
+ /// and Alias Analysis.
+ ///
+ virtual void getAnalysisUsage(AnalysisUsage &AU) const;
+
+ /// getEqualNumberNodes - Return nodes with the same value number as the
+ /// specified Value. This fills in the argument vector with any equal
+ /// values.
+ ///
+ virtual void getEqualNumberNodes(Value *V1,
+ std::vector<Value*> &RetVals) const;
+
+ /// deleteValue - This method should be called whenever an LLVM Value is
+ /// deleted from the program, for example when an instruction is found to be
+ /// redundant and is eliminated.
+ ///
+ virtual void deleteValue(Value *V) {
+ getAnalysis<AliasAnalysis>().deleteValue(V);
+ }
+
+ /// copyValue - This method should be used whenever a preexisting value in
+ /// the program is copied or cloned, introducing a new value. Note that
+ /// analysis implementations should tolerate clients that use this method to
+ /// introduce the same value multiple times: if the analysis already knows
+ /// about a value, it should ignore the request.
+ ///
+ virtual void copyValue(Value *From, Value *To) {
+ getAnalysis<AliasAnalysis>().copyValue(From, To);
+ }
+
+ /// getCallEqualNumberNodes - Given a call instruction, find other calls
+ /// that have the same value number.
+ void getCallEqualNumberNodes(CallInst *CI,
+ std::vector<Value*> &RetVals) const;
+ };
+
+ char LoadVN::ID = 0;
+ // Register this pass...
+ RegisterPass<LoadVN> X("load-vn", "Load Value Numbering");
+
+ // Declare that we implement the ValueNumbering interface
+ RegisterAnalysisGroup<ValueNumbering> Y(X);
+}
+
+FunctionPass *llvm::createLoadValueNumberingPass() { return new LoadVN(); }
+
+
+/// getAnalysisUsage - Does not modify anything. It uses Value Numbering and
+/// Alias Analysis.
+///
+void LoadVN::getAnalysisUsage(AnalysisUsage &AU) const {
+ AU.setPreservesAll();
+ AU.addRequiredTransitive<AliasAnalysis>();
+ AU.addRequired<ValueNumbering>();
+ AU.addRequiredTransitive<DominatorTree>();
+ AU.addRequiredTransitive<TargetData>();
+}
+
+static bool isPathTransparentTo(BasicBlock *CurBlock, BasicBlock *Dom,
+ Value *Ptr, unsigned Size, AliasAnalysis &AA,
+ std::set<BasicBlock*> &Visited,
+ std::map<BasicBlock*, bool> &TransparentBlocks){
+ // If we have already checked out this path, or if we reached our destination,
+ // stop searching, returning success.
+ if (CurBlock == Dom || !Visited.insert(CurBlock).second)
+ return true;
+
+ // Check whether this block is known transparent or not.
+ std::map<BasicBlock*, bool>::iterator TBI =
+ TransparentBlocks.lower_bound(CurBlock);
+
+ if (TBI == TransparentBlocks.end() || TBI->first != CurBlock) {
+ // If this basic block can modify the memory location, then the path is not
+ // transparent!
+ if (AA.canBasicBlockModify(*CurBlock, Ptr, Size)) {
+ TransparentBlocks.insert(TBI, std::make_pair(CurBlock, false));
+ return false;
+ }
+ TransparentBlocks.insert(TBI, std::make_pair(CurBlock, true));
+ } else if (!TBI->second)
+ // This block is known non-transparent, so that path can't be either.
+ return false;
+
+ // The current block is known to be transparent. The entire path is
+ // transparent if all of the predecessors paths to the parent is also
+ // transparent to the memory location.
+ for (pred_iterator PI = pred_begin(CurBlock), E = pred_end(CurBlock);
+ PI != E; ++PI)
+ if (!isPathTransparentTo(*PI, Dom, Ptr, Size, AA, Visited,
+ TransparentBlocks))
+ return false;
+ return true;
+}
+
+/// getCallEqualNumberNodes - Given a call instruction, find other calls that
+/// have the same value number.
+void LoadVN::getCallEqualNumberNodes(CallInst *CI,
+ std::vector<Value*> &RetVals) const {
+ Function *CF = CI->getCalledFunction();
+ if (CF == 0) return; // Indirect call.
+ AliasAnalysis &AA = getAnalysis<AliasAnalysis>();
+ AliasAnalysis::ModRefBehavior MRB = AA.getModRefBehavior(CF, CI);
+ if (MRB != AliasAnalysis::DoesNotAccessMemory &&
+ MRB != AliasAnalysis::OnlyReadsMemory)
+ return; // Nothing we can do for now.
+
+ // Scan all of the arguments of the function, looking for one that is not
+ // global. In particular, we would prefer to have an argument or instruction
+ // operand to chase the def-use chains of.
+ Value *Op = CF;
+ for (unsigned i = 1, e = CI->getNumOperands(); i != e; ++i)
+ if (isa<Argument>(CI->getOperand(i)) ||
+ isa<Instruction>(CI->getOperand(i))) {
+ Op = CI->getOperand(i);
+ break;
+ }
+
+ // Identify all lexically identical calls in this function.
+ std::vector<CallInst*> IdenticalCalls;
+
+ Function *CIFunc = CI->getParent()->getParent();
+ for (Value::use_iterator UI = Op->use_begin(), E = Op->use_end(); UI != E;
+ ++UI)
+ if (CallInst *C = dyn_cast<CallInst>(*UI))
+ if (C->getNumOperands() == CI->getNumOperands() &&
+ C->getOperand(0) == CI->getOperand(0) &&
+ C->getParent()->getParent() == CIFunc && C != CI) {
+ bool AllOperandsEqual = true;
+ for (unsigned i = 1, e = CI->getNumOperands(); i != e; ++i)
+ if (C->getOperand(i) != CI->getOperand(i)) {
+ AllOperandsEqual = false;
+ break;
+ }
+
+ if (AllOperandsEqual)
+ IdenticalCalls.push_back(C);
+ }
+
+ if (IdenticalCalls.empty()) return;
+
+ // Eliminate duplicates, which could occur if we chose a value that is passed
+ // into a call site multiple times.
+ std::sort(IdenticalCalls.begin(), IdenticalCalls.end());
+ IdenticalCalls.erase(std::unique(IdenticalCalls.begin(),IdenticalCalls.end()),
+ IdenticalCalls.end());
+
+ // If the call reads memory, we must make sure that there are no stores
+ // between the calls in question.
+ //
+ // FIXME: This should use mod/ref information. What we really care about it
+ // whether an intervening instruction could modify memory that is read, not
+ // ANY memory.
+ //
+ if (MRB == AliasAnalysis::OnlyReadsMemory) {
+ DominatorTree &DT = getAnalysis<DominatorTree>();
+ BasicBlock *CIBB = CI->getParent();
+ for (unsigned i = 0; i != IdenticalCalls.size(); ++i) {
+ CallInst *C = IdenticalCalls[i];
+ bool CantEqual = false;
+
+ if (DT.dominates(CIBB, C->getParent())) {
+ // FIXME: we currently only handle the case where both calls are in the
+ // same basic block.
+ if (CIBB != C->getParent()) {
+ CantEqual = true;
+ } else {
+ Instruction *First = CI, *Second = C;
+ if (!DT.dominates(CI, C))
+ std::swap(First, Second);
+
+ // Scan the instructions between the calls, checking for stores or
+ // calls to dangerous functions.
+ BasicBlock::iterator I = First;
+ for (++First; I != BasicBlock::iterator(Second); ++I) {
+ if (isa<StoreInst>(I)) {
+ // FIXME: We could use mod/ref information to make this much
+ // better!
+ CantEqual = true;
+ break;
+ } else if (CallInst *CI = dyn_cast<CallInst>(I)) {
+ if (CI->getCalledFunction() == 0 ||
+ !AA.onlyReadsMemory(CI->getCalledFunction())) {
+ CantEqual = true;
+ break;
+ }
+ } else if (I->mayWriteToMemory()) {
+ CantEqual = true;
+ break;
+ }
+ }
+ }
+
+ } else if (DT.dominates(C->getParent(), CIBB)) {
+ // FIXME: We could implement this, but we don't for now.
+ CantEqual = true;
+ } else {
+ // FIXME: if one doesn't dominate the other, we can't tell yet.
+ CantEqual = true;
+ }
+
+
+ if (CantEqual) {
+ // This call does not produce the same value as the one in the query.
+ std::swap(IdenticalCalls[i--], IdenticalCalls.back());
+ IdenticalCalls.pop_back();
+ }
+ }
+ }
+
+ // Any calls that are identical and not destroyed will produce equal values!
+ for (unsigned i = 0, e = IdenticalCalls.size(); i != e; ++i)
+ RetVals.push_back(IdenticalCalls[i]);
+}
+
+// getEqualNumberNodes - Return nodes with the same value number as the
+// specified Value. This fills in the argument vector with any equal values.
+//
+void LoadVN::getEqualNumberNodes(Value *V,
+ std::vector<Value*> &RetVals) const {
+ // If the alias analysis has any must alias information to share with us, we
+ // can definitely use it.
+ if (isa<PointerType>(V->getType()))
+ getAnalysis<AliasAnalysis>().getMustAliases(V, RetVals);
+
+ if (!isa<LoadInst>(V)) {
+ if (CallInst *CI = dyn_cast<CallInst>(V))
+ getCallEqualNumberNodes(CI, RetVals);
+
+ // Not a load instruction? Just chain to the base value numbering
+ // implementation to satisfy the request...
+ assert(&getAnalysis<ValueNumbering>() != (ValueNumbering*)this &&
+ "getAnalysis() returned this!");
+
+ return getAnalysis<ValueNumbering>().getEqualNumberNodes(V, RetVals);
+ }
+
+ // Volatile loads cannot be replaced with the value of other loads.
+ LoadInst *LI = cast<LoadInst>(V);
+ if (LI->isVolatile())
+ return getAnalysis<ValueNumbering>().getEqualNumberNodes(V, RetVals);
+
+ Value *LoadPtr = LI->getOperand(0);
+ BasicBlock *LoadBB = LI->getParent();
+ Function *F = LoadBB->getParent();
+
+ // Find out how many bytes of memory are loaded by the load instruction...
+ unsigned LoadSize = getAnalysis<TargetData>().getTypeSize(LI->getType());
+ AliasAnalysis &AA = getAnalysis<AliasAnalysis>();
+
+ // Figure out if the load is invalidated from the entry of the block it is in
+ // until the actual instruction. This scans the block backwards from LI. If
+ // we see any candidate load or store instructions, then we know that the
+ // candidates have the same value # as LI.
+ bool LoadInvalidatedInBBBefore = false;
+ for (BasicBlock::iterator I = LI; I != LoadBB->begin(); ) {
+ --I;
+ if (I == LoadPtr) {
+ // If we run into an allocation of the value being loaded, then the
+ // contents are not initialized.
+ if (isa<AllocationInst>(I))
+ RetVals.push_back(UndefValue::get(LI->getType()));
+
+ // Otherwise, since this is the definition of what we are loading, this
+ // loaded value cannot occur before this block.
+ LoadInvalidatedInBBBefore = true;
+ break;
+ } else if (LoadInst *LI = dyn_cast<LoadInst>(I)) {
+ // If this instruction is a candidate load before LI, we know there are no
+ // invalidating instructions between it and LI, so they have the same
+ // value number.
+ if (LI->getOperand(0) == LoadPtr && !LI->isVolatile())
+ RetVals.push_back(I);
+ }
+
+ if (AA.getModRefInfo(I, LoadPtr, LoadSize) & AliasAnalysis::Mod) {
+ // If the invalidating instruction is a store, and its in our candidate
+ // set, then we can do store-load forwarding: the load has the same value
+ // # as the stored value.
+ if (StoreInst *SI = dyn_cast<StoreInst>(I))
+ if (SI->getOperand(1) == LoadPtr)
+ RetVals.push_back(I->getOperand(0));
+
+ LoadInvalidatedInBBBefore = true;
+ break;
+ }
+ }
+
+ // Figure out if the load is invalidated between the load and the exit of the
+ // block it is defined in. While we are scanning the current basic block, if
+ // we see any candidate loads, then we know they have the same value # as LI.
+ //
+ bool LoadInvalidatedInBBAfter = false;
+ {
+ BasicBlock::iterator I = LI;
+ for (++I; I != LoadBB->end(); ++I) {
+ // If this instruction is a load, then this instruction returns the same
+ // value as LI.
+ if (isa<LoadInst>(I) && cast<LoadInst>(I)->getOperand(0) == LoadPtr)
+ RetVals.push_back(I);
+
+ if (AA.getModRefInfo(I, LoadPtr, LoadSize) & AliasAnalysis::Mod) {
+ LoadInvalidatedInBBAfter = true;
+ break;
+ }
+ }
+ }
+
+ // If the pointer is clobbered on entry and on exit to the function, there is
+ // no need to do any global analysis at all.
+ if (LoadInvalidatedInBBBefore && LoadInvalidatedInBBAfter)
+ return;
+
+ // Now that we know the value is not neccesarily killed on entry or exit to
+ // the BB, find out how many load and store instructions (to this location)
+ // live in each BB in the function.
+ //
+ std::map<BasicBlock*, unsigned> CandidateLoads;
+ std::set<BasicBlock*> CandidateStores;
+
+ for (Value::use_iterator UI = LoadPtr->use_begin(), UE = LoadPtr->use_end();
+ UI != UE; ++UI)
+ if (LoadInst *Cand = dyn_cast<LoadInst>(*UI)) {// Is a load of source?
+ if (Cand->getParent()->getParent() == F && // In the same function?
+ // Not in LI's block?
+ Cand->getParent() != LoadBB && !Cand->isVolatile())
+ ++CandidateLoads[Cand->getParent()]; // Got one.
+ } else if (StoreInst *Cand = dyn_cast<StoreInst>(*UI)) {
+ if (Cand->getParent()->getParent() == F && !Cand->isVolatile() &&
+ Cand->getOperand(1) == LoadPtr) // It's a store THROUGH the ptr.
+ CandidateStores.insert(Cand->getParent());
+ }
+
+ // Get dominators.
+ DominatorTree &DT = getAnalysis<DominatorTree>();
+
+ // TransparentBlocks - For each basic block the load/store is alive across,
+ // figure out if the pointer is invalidated or not. If it is invalidated, the
+ // boolean is set to false, if it's not it is set to true. If we don't know
+ // yet, the entry is not in the map.
+ std::map<BasicBlock*, bool> TransparentBlocks;
+
+ // Loop over all of the basic blocks that also load the value. If the value
+ // is live across the CFG from the source to destination blocks, and if the
+ // value is not invalidated in either the source or destination blocks, add it
+ // to the equivalence sets.
+ for (std::map<BasicBlock*, unsigned>::iterator
+ I = CandidateLoads.begin(), E = CandidateLoads.end(); I != E; ++I) {
+ bool CantEqual = false;
+
+ // Right now we only can handle cases where one load dominates the other.
+ // FIXME: generalize this!
+ BasicBlock *BB1 = I->first, *BB2 = LoadBB;
+ if (DT.dominates(BB1, BB2)) {
+ // The other load dominates LI. If the loaded value is killed entering
+ // the LoadBB block, we know the load is not live.
+ if (LoadInvalidatedInBBBefore)
+ CantEqual = true;
+ } else if (DT.dominates(BB2, BB1)) {
+ std::swap(BB1, BB2); // Canonicalize
+ // LI dominates the other load. If the loaded value is killed exiting
+ // the LoadBB block, we know the load is not live.
+ if (LoadInvalidatedInBBAfter)
+ CantEqual = true;
+ } else {
+ // None of these loads can VN the same.
+ CantEqual = true;
+ }
+
+ if (!CantEqual) {
+ // Ok, at this point, we know that BB1 dominates BB2, and that there is
+ // nothing in the LI block that kills the loaded value. Check to see if
+ // the value is live across the CFG.
+ std::set<BasicBlock*> Visited;
+ for (pred_iterator PI = pred_begin(BB2), E = pred_end(BB2); PI!=E; ++PI)
+ if (!isPathTransparentTo(*PI, BB1, LoadPtr, LoadSize, AA,
+ Visited, TransparentBlocks)) {
+ // None of these loads can VN the same.
+ CantEqual = true;
+ break;
+ }
+ }
+
+ // If the loads can equal so far, scan the basic block that contains the
+ // loads under consideration to see if they are invalidated in the block.
+ // For any loads that are not invalidated, add them to the equivalence
+ // set!
+ if (!CantEqual) {
+ unsigned NumLoads = I->second;
+ if (BB1 == LoadBB) {
+ // If LI dominates the block in question, check to see if any of the
+ // loads in this block are invalidated before they are reached.
+ for (BasicBlock::iterator BBI = I->first->begin(); ; ++BBI) {
+ if (LoadInst *LI = dyn_cast<LoadInst>(BBI)) {
+ if (LI->getOperand(0) == LoadPtr && !LI->isVolatile()) {
+ // The load is in the set!
+ RetVals.push_back(BBI);
+ if (--NumLoads == 0) break; // Found last load to check.
+ }
+ } else if (AA.getModRefInfo(BBI, LoadPtr, LoadSize)
+ & AliasAnalysis::Mod) {
+ // If there is a modifying instruction, nothing below it will value
+ // # the same.
+ break;
+ }
+ }
+ } else {
+ // If the block dominates LI, make sure that the loads in the block are
+ // not invalidated before the block ends.
+ BasicBlock::iterator BBI = I->first->end();
+ while (1) {
+ --BBI;
+ if (LoadInst *LI = dyn_cast<LoadInst>(BBI)) {
+ if (LI->getOperand(0) == LoadPtr && !LI->isVolatile()) {
+ // The load is the same as this load!
+ RetVals.push_back(BBI);
+ if (--NumLoads == 0) break; // Found all of the laods.
+ }
+ } else if (AA.getModRefInfo(BBI, LoadPtr, LoadSize)
+ & AliasAnalysis::Mod) {
+ // If there is a modifying instruction, nothing above it will value
+ // # the same.
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ // Handle candidate stores. If the loaded location is clobbered on entrance
+ // to the LoadBB, no store outside of the LoadBB can value number equal, so
+ // quick exit.
+ if (LoadInvalidatedInBBBefore)
+ return;
+
+ // Stores in the load-bb are handled above.
+ CandidateStores.erase(LoadBB);
+
+ for (std::set<BasicBlock*>::iterator I = CandidateStores.begin(),
+ E = CandidateStores.end(); I != E; ++I)
+ if (DT.dominates(*I, LoadBB)) {
+ BasicBlock *StoreBB = *I;
+
+ // Check to see if the path from the store to the load is transparent
+ // w.r.t. the memory location.
+ bool CantEqual = false;
+ std::set<BasicBlock*> Visited;
+ for (pred_iterator PI = pred_begin(LoadBB), E = pred_end(LoadBB);
+ PI != E; ++PI)
+ if (!isPathTransparentTo(*PI, StoreBB, LoadPtr, LoadSize, AA,
+ Visited, TransparentBlocks)) {
+ // None of these stores can VN the same.
+ CantEqual = true;
+ break;
+ }
+ Visited.clear();
+ if (!CantEqual) {
+ // Okay, the path from the store block to the load block is clear, and
+ // we know that there are no invalidating instructions from the start
+ // of the load block to the load itself. Now we just scan the store
+ // block.
+
+ BasicBlock::iterator BBI = StoreBB->end();
+ while (1) {
+ assert(BBI != StoreBB->begin() &&
+ "There is a store in this block of the pointer, but the store"
+ " doesn't mod the address being stored to?? Must be a bug in"
+ " the alias analysis implementation!");
+ --BBI;
+ if (AA.getModRefInfo(BBI, LoadPtr, LoadSize) & AliasAnalysis::Mod) {
+ // If the invalidating instruction is one of the candidates,
+ // then it provides the value the load loads.
+ if (StoreInst *SI = dyn_cast<StoreInst>(BBI))
+ if (SI->getOperand(1) == LoadPtr)
+ RetVals.push_back(SI->getOperand(0));
+ break;
+ }
+ }
+ }
+ }
+}
diff --git a/lib/Analysis/LoopInfo.cpp b/lib/Analysis/LoopInfo.cpp
new file mode 100644
index 0000000..d58f90d
--- /dev/null
+++ b/lib/Analysis/LoopInfo.cpp
@@ -0,0 +1,670 @@
+//===- LoopInfo.cpp - Natural Loop Calculator -----------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the LoopInfo class that is used to identify natural loops
+// and determine the loop depth of various nodes of the CFG. Note that the
+// loops identified may actually be several natural loops that share the same
+// header node... not just a single natural loop.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Analysis/LoopInfo.h"
+#include "llvm/Constants.h"
+#include "llvm/Instructions.h"
+#include "llvm/Analysis/Dominators.h"
+#include "llvm/Assembly/Writer.h"
+#include "llvm/Support/CFG.h"
+#include "llvm/Support/Streams.h"
+#include "llvm/ADT/DepthFirstIterator.h"
+#include "llvm/ADT/SmallPtrSet.h"
+#include <algorithm>
+#include <ostream>
+using namespace llvm;
+
+char LoopInfo::ID = 0;
+static RegisterPass<LoopInfo>
+X("loops", "Natural Loop Construction", true);
+
+//===----------------------------------------------------------------------===//
+// Loop implementation
+//
+bool Loop::contains(const BasicBlock *BB) const {
+ return std::find(Blocks.begin(), Blocks.end(), BB) != Blocks.end();
+}
+
+bool Loop::isLoopExit(const BasicBlock *BB) const {
+ for (succ_const_iterator SI = succ_begin(BB), SE = succ_end(BB);
+ SI != SE; ++SI) {
+ if (!contains(*SI))
+ return true;
+ }
+ return false;
+}
+
+/// getNumBackEdges - Calculate the number of back edges to the loop header.
+///
+unsigned Loop::getNumBackEdges() const {
+ unsigned NumBackEdges = 0;
+ BasicBlock *H = getHeader();
+
+ for (pred_iterator I = pred_begin(H), E = pred_end(H); I != E; ++I)
+ if (contains(*I))
+ ++NumBackEdges;
+
+ return NumBackEdges;
+}
+
+/// isLoopInvariant - Return true if the specified value is loop invariant
+///
+bool Loop::isLoopInvariant(Value *V) const {
+ if (Instruction *I = dyn_cast<Instruction>(V))
+ return !contains(I->getParent());
+ return true; // All non-instructions are loop invariant
+}
+
+void Loop::print(std::ostream &OS, unsigned Depth) const {
+ OS << std::string(Depth*2, ' ') << "Loop Containing: ";
+
+ for (unsigned i = 0; i < getBlocks().size(); ++i) {
+ if (i) OS << ",";
+ WriteAsOperand(OS, getBlocks()[i], false);
+ }
+ OS << "\n";
+
+ for (iterator I = begin(), E = end(); I != E; ++I)
+ (*I)->print(OS, Depth+2);
+}
+
+void Loop::dump() const {
+ print(cerr);
+}
+
+
+//===----------------------------------------------------------------------===//
+// LoopInfo implementation
+//
+bool LoopInfo::runOnFunction(Function &) {
+ releaseMemory();
+ Calculate(getAnalysis<DominatorTree>()); // Update
+ return false;
+}
+
+void LoopInfo::releaseMemory() {
+ for (std::vector<Loop*>::iterator I = TopLevelLoops.begin(),
+ E = TopLevelLoops.end(); I != E; ++I)
+ delete *I; // Delete all of the loops...
+
+ BBMap.clear(); // Reset internal state of analysis
+ TopLevelLoops.clear();
+}
+
+
+void LoopInfo::Calculate(DominatorTree &DT) {
+ BasicBlock *RootNode = DT.getRootNode()->getBlock();
+
+ for (df_iterator<BasicBlock*> NI = df_begin(RootNode),
+ NE = df_end(RootNode); NI != NE; ++NI)
+ if (Loop *L = ConsiderForLoop(*NI, DT))
+ TopLevelLoops.push_back(L);
+}
+
+void LoopInfo::getAnalysisUsage(AnalysisUsage &AU) const {
+ AU.setPreservesAll();
+ AU.addRequired<DominatorTree>();
+}
+
+void LoopInfo::print(std::ostream &OS, const Module* ) const {
+ for (unsigned i = 0; i < TopLevelLoops.size(); ++i)
+ TopLevelLoops[i]->print(OS);
+#if 0
+ for (std::map<BasicBlock*, Loop*>::const_iterator I = BBMap.begin(),
+ E = BBMap.end(); I != E; ++I)
+ OS << "BB '" << I->first->getName() << "' level = "
+ << I->second->getLoopDepth() << "\n";
+#endif
+}
+
+static bool isNotAlreadyContainedIn(Loop *SubLoop, Loop *ParentLoop) {
+ if (SubLoop == 0) return true;
+ if (SubLoop == ParentLoop) return false;
+ return isNotAlreadyContainedIn(SubLoop->getParentLoop(), ParentLoop);
+}
+
+Loop *LoopInfo::ConsiderForLoop(BasicBlock *BB, DominatorTree &DT) {
+ if (BBMap.find(BB) != BBMap.end()) return 0; // Haven't processed this node?
+
+ std::vector<BasicBlock *> TodoStack;
+
+ // Scan the predecessors of BB, checking to see if BB dominates any of
+ // them. This identifies backedges which target this node...
+ for (pred_iterator I = pred_begin(BB), E = pred_end(BB); I != E; ++I)
+ if (DT.dominates(BB, *I)) // If BB dominates it's predecessor...
+ TodoStack.push_back(*I);
+
+ if (TodoStack.empty()) return 0; // No backedges to this block...
+
+ // Create a new loop to represent this basic block...
+ Loop *L = new Loop(BB);
+ BBMap[BB] = L;
+
+ BasicBlock *EntryBlock = &BB->getParent()->getEntryBlock();
+
+ while (!TodoStack.empty()) { // Process all the nodes in the loop
+ BasicBlock *X = TodoStack.back();
+ TodoStack.pop_back();
+
+ if (!L->contains(X) && // As of yet unprocessed??
+ DT.dominates(EntryBlock, X)) { // X is reachable from entry block?
+ // Check to see if this block already belongs to a loop. If this occurs
+ // then we have a case where a loop that is supposed to be a child of the
+ // current loop was processed before the current loop. When this occurs,
+ // this child loop gets added to a part of the current loop, making it a
+ // sibling to the current loop. We have to reparent this loop.
+ if (Loop *SubLoop = const_cast<Loop*>(getLoopFor(X)))
+ if (SubLoop->getHeader() == X && isNotAlreadyContainedIn(SubLoop, L)) {
+ // Remove the subloop from it's current parent...
+ assert(SubLoop->ParentLoop && SubLoop->ParentLoop != L);
+ Loop *SLP = SubLoop->ParentLoop; // SubLoopParent
+ std::vector<Loop*>::iterator I =
+ std::find(SLP->SubLoops.begin(), SLP->SubLoops.end(), SubLoop);
+ assert(I != SLP->SubLoops.end() && "SubLoop not a child of parent?");
+ SLP->SubLoops.erase(I); // Remove from parent...
+
+ // Add the subloop to THIS loop...
+ SubLoop->ParentLoop = L;
+ L->SubLoops.push_back(SubLoop);
+ }
+
+ // Normal case, add the block to our loop...
+ L->Blocks.push_back(X);
+
+ // Add all of the predecessors of X to the end of the work stack...
+ TodoStack.insert(TodoStack.end(), pred_begin(X), pred_end(X));
+ }
+ }
+
+ // If there are any loops nested within this loop, create them now!
+ for (std::vector<BasicBlock*>::iterator I = L->Blocks.begin(),
+ E = L->Blocks.end(); I != E; ++I)
+ if (Loop *NewLoop = ConsiderForLoop(*I, DT)) {
+ L->SubLoops.push_back(NewLoop);
+ NewLoop->ParentLoop = L;
+ }
+
+ // Add the basic blocks that comprise this loop to the BBMap so that this
+ // loop can be found for them.
+ //
+ for (std::vector<BasicBlock*>::iterator I = L->Blocks.begin(),
+ E = L->Blocks.end(); I != E; ++I) {
+ std::map<BasicBlock*, Loop*>::iterator BBMI = BBMap.lower_bound(*I);
+ if (BBMI == BBMap.end() || BBMI->first != *I) // Not in map yet...
+ BBMap.insert(BBMI, std::make_pair(*I, L)); // Must be at this level
+ }
+
+ // Now that we have a list of all of the child loops of this loop, check to
+ // see if any of them should actually be nested inside of each other. We can
+ // accidentally pull loops our of their parents, so we must make sure to
+ // organize the loop nests correctly now.
+ {
+ std::map<BasicBlock*, Loop*> ContainingLoops;
+ for (unsigned i = 0; i != L->SubLoops.size(); ++i) {
+ Loop *Child = L->SubLoops[i];
+ assert(Child->getParentLoop() == L && "Not proper child loop?");
+
+ if (Loop *ContainingLoop = ContainingLoops[Child->getHeader()]) {
+ // If there is already a loop which contains this loop, move this loop
+ // into the containing loop.
+ MoveSiblingLoopInto(Child, ContainingLoop);
+ --i; // The loop got removed from the SubLoops list.
+ } else {
+ // This is currently considered to be a top-level loop. Check to see if
+ // any of the contained blocks are loop headers for subloops we have
+ // already processed.
+ for (unsigned b = 0, e = Child->Blocks.size(); b != e; ++b) {
+ Loop *&BlockLoop = ContainingLoops[Child->Blocks[b]];
+ if (BlockLoop == 0) { // Child block not processed yet...
+ BlockLoop = Child;
+ } else if (BlockLoop != Child) {
+ Loop *SubLoop = BlockLoop;
+ // Reparent all of the blocks which used to belong to BlockLoops
+ for (unsigned j = 0, e = SubLoop->Blocks.size(); j != e; ++j)
+ ContainingLoops[SubLoop->Blocks[j]] = Child;
+
+ // There is already a loop which contains this block, that means
+ // that we should reparent the loop which the block is currently
+ // considered to belong to to be a child of this loop.
+ MoveSiblingLoopInto(SubLoop, Child);
+ --i; // We just shrunk the SubLoops list.
+ }
+ }
+ }
+ }
+ }
+
+ return L;
+}
+
+/// MoveSiblingLoopInto - This method moves the NewChild loop to live inside of
+/// the NewParent Loop, instead of being a sibling of it.
+void LoopInfo::MoveSiblingLoopInto(Loop *NewChild, Loop *NewParent) {
+ Loop *OldParent = NewChild->getParentLoop();
+ assert(OldParent && OldParent == NewParent->getParentLoop() &&
+ NewChild != NewParent && "Not sibling loops!");
+
+ // Remove NewChild from being a child of OldParent
+ std::vector<Loop*>::iterator I =
+ std::find(OldParent->SubLoops.begin(), OldParent->SubLoops.end(), NewChild);
+ assert(I != OldParent->SubLoops.end() && "Parent fields incorrect??");
+ OldParent->SubLoops.erase(I); // Remove from parent's subloops list
+ NewChild->ParentLoop = 0;
+
+ InsertLoopInto(NewChild, NewParent);
+}
+
+/// InsertLoopInto - This inserts loop L into the specified parent loop. If the
+/// parent loop contains a loop which should contain L, the loop gets inserted
+/// into L instead.
+void LoopInfo::InsertLoopInto(Loop *L, Loop *Parent) {
+ BasicBlock *LHeader = L->getHeader();
+ assert(Parent->contains(LHeader) && "This loop should not be inserted here!");
+
+ // Check to see if it belongs in a child loop...
+ for (unsigned i = 0, e = Parent->SubLoops.size(); i != e; ++i)
+ if (Parent->SubLoops[i]->contains(LHeader)) {
+ InsertLoopInto(L, Parent->SubLoops[i]);
+ return;
+ }
+
+ // If not, insert it here!
+ Parent->SubLoops.push_back(L);
+ L->ParentLoop = Parent;
+}
+
+/// changeLoopFor - Change the top-level loop that contains BB to the
+/// specified loop. This should be used by transformations that restructure
+/// the loop hierarchy tree.
+void LoopInfo::changeLoopFor(BasicBlock *BB, Loop *L) {
+ Loop *&OldLoop = BBMap[BB];
+ assert(OldLoop && "Block not in a loop yet!");
+ OldLoop = L;
+}
+
+/// changeTopLevelLoop - Replace the specified loop in the top-level loops
+/// list with the indicated loop.
+void LoopInfo::changeTopLevelLoop(Loop *OldLoop, Loop *NewLoop) {
+ std::vector<Loop*>::iterator I = std::find(TopLevelLoops.begin(),
+ TopLevelLoops.end(), OldLoop);
+ assert(I != TopLevelLoops.end() && "Old loop not at top level!");
+ *I = NewLoop;
+ assert(NewLoop->ParentLoop == 0 && OldLoop->ParentLoop == 0 &&
+ "Loops already embedded into a subloop!");
+}
+
+/// removeLoop - This removes the specified top-level loop from this loop info
+/// object. The loop is not deleted, as it will presumably be inserted into
+/// another loop.
+Loop *LoopInfo::removeLoop(iterator I) {
+ assert(I != end() && "Cannot remove end iterator!");
+ Loop *L = *I;
+ assert(L->getParentLoop() == 0 && "Not a top-level loop!");
+ TopLevelLoops.erase(TopLevelLoops.begin() + (I-begin()));
+ return L;
+}
+
+/// removeBlock - This method completely removes BB from all data structures,
+/// including all of the Loop objects it is nested in and our mapping from
+/// BasicBlocks to loops.
+void LoopInfo::removeBlock(BasicBlock *BB) {
+ std::map<BasicBlock *, Loop*>::iterator I = BBMap.find(BB);
+ if (I != BBMap.end()) {
+ for (Loop *L = I->second; L; L = L->getParentLoop())
+ L->removeBlockFromLoop(BB);
+
+ BBMap.erase(I);
+ }
+}
+
+
+//===----------------------------------------------------------------------===//
+// APIs for simple analysis of the loop.
+//
+
+/// getExitingBlocks - Return all blocks inside the loop that have successors
+/// outside of the loop. These are the blocks _inside of the current loop_
+/// which branch out. The returned list is always unique.
+///
+void Loop::getExitingBlocks(std::vector<BasicBlock*> &ExitingBlocks) const {
+ // Sort the blocks vector so that we can use binary search to do quick
+ // lookups.
+ std::vector<BasicBlock*> LoopBBs(block_begin(), block_end());
+ std::sort(LoopBBs.begin(), LoopBBs.end());
+
+ for (std::vector<BasicBlock*>::const_iterator BI = Blocks.begin(),
+ BE = Blocks.end(); BI != BE; ++BI)
+ for (succ_iterator I = succ_begin(*BI), E = succ_end(*BI); I != E; ++I)
+ if (!std::binary_search(LoopBBs.begin(), LoopBBs.end(), *I)) {
+ // Not in current loop? It must be an exit block.
+ ExitingBlocks.push_back(*BI);
+ break;
+ }
+}
+
+/// getExitBlocks - Return all of the successor blocks of this loop. These
+/// are the blocks _outside of the current loop_ which are branched to.
+///
+void Loop::getExitBlocks(std::vector<BasicBlock*> &ExitBlocks) const {
+ // Sort the blocks vector so that we can use binary search to do quick
+ // lookups.
+ std::vector<BasicBlock*> LoopBBs(block_begin(), block_end());
+ std::sort(LoopBBs.begin(), LoopBBs.end());
+
+ for (std::vector<BasicBlock*>::const_iterator BI = Blocks.begin(),
+ BE = Blocks.end(); BI != BE; ++BI)
+ for (succ_iterator I = succ_begin(*BI), E = succ_end(*BI); I != E; ++I)
+ if (!std::binary_search(LoopBBs.begin(), LoopBBs.end(), *I))
+ // Not in current loop? It must be an exit block.
+ ExitBlocks.push_back(*I);
+}
+
+/// getUniqueExitBlocks - Return all unique successor blocks of this loop. These
+/// are the blocks _outside of the current loop_ which are branched to. This
+/// assumes that loop is in canonical form.
+//
+void Loop::getUniqueExitBlocks(std::vector<BasicBlock*> &ExitBlocks) const {
+ // Sort the blocks vector so that we can use binary search to do quick
+ // lookups.
+ std::vector<BasicBlock*> LoopBBs(block_begin(), block_end());
+ std::sort(LoopBBs.begin(), LoopBBs.end());
+
+ std::vector<BasicBlock*> switchExitBlocks;
+
+ for (std::vector<BasicBlock*>::const_iterator BI = Blocks.begin(),
+ BE = Blocks.end(); BI != BE; ++BI) {
+
+ BasicBlock *current = *BI;
+ switchExitBlocks.clear();
+
+ for (succ_iterator I = succ_begin(*BI), E = succ_end(*BI); I != E; ++I) {
+ if (std::binary_search(LoopBBs.begin(), LoopBBs.end(), *I))
+ // If block is inside the loop then it is not a exit block.
+ continue;
+
+ pred_iterator PI = pred_begin(*I);
+ BasicBlock *firstPred = *PI;
+
+ // If current basic block is this exit block's first predecessor
+ // then only insert exit block in to the output ExitBlocks vector.
+ // This ensures that same exit block is not inserted twice into
+ // ExitBlocks vector.
+ if (current != firstPred)
+ continue;
+
+ // If a terminator has more then two successors, for example SwitchInst,
+ // then it is possible that there are multiple edges from current block
+ // to one exit block.
+ if (current->getTerminator()->getNumSuccessors() <= 2) {
+ ExitBlocks.push_back(*I);
+ continue;
+ }
+
+ // In case of multiple edges from current block to exit block, collect
+ // only one edge in ExitBlocks. Use switchExitBlocks to keep track of
+ // duplicate edges.
+ if (std::find(switchExitBlocks.begin(), switchExitBlocks.end(), *I)
+ == switchExitBlocks.end()) {
+ switchExitBlocks.push_back(*I);
+ ExitBlocks.push_back(*I);
+ }
+ }
+ }
+}
+
+
+/// getLoopPreheader - If there is a preheader for this loop, return it. A
+/// loop has a preheader if there is only one edge to the header of the loop
+/// from outside of the loop. If this is the case, the block branching to the
+/// header of the loop is the preheader node.
+///
+/// This method returns null if there is no preheader for the loop.
+///
+BasicBlock *Loop::getLoopPreheader() const {
+ // Keep track of nodes outside the loop branching to the header...
+ BasicBlock *Out = 0;
+
+ // Loop over the predecessors of the header node...
+ BasicBlock *Header = getHeader();
+ for (pred_iterator PI = pred_begin(Header), PE = pred_end(Header);
+ PI != PE; ++PI)
+ if (!contains(*PI)) { // If the block is not in the loop...
+ if (Out && Out != *PI)
+ return 0; // Multiple predecessors outside the loop
+ Out = *PI;
+ }
+
+ // Make sure there is only one exit out of the preheader.
+ assert(Out && "Header of loop has no predecessors from outside loop?");
+ succ_iterator SI = succ_begin(Out);
+ ++SI;
+ if (SI != succ_end(Out))
+ return 0; // Multiple exits from the block, must not be a preheader.
+
+ // If there is exactly one preheader, return it. If there was zero, then Out
+ // is still null.
+ return Out;
+}
+
+/// getLoopLatch - If there is a latch block for this loop, return it. A
+/// latch block is the canonical backedge for a loop. A loop header in normal
+/// form has two edges into it: one from a preheader and one from a latch
+/// block.
+BasicBlock *Loop::getLoopLatch() const {
+ BasicBlock *Header = getHeader();
+ pred_iterator PI = pred_begin(Header), PE = pred_end(Header);
+ if (PI == PE) return 0; // no preds?
+
+ BasicBlock *Latch = 0;
+ if (contains(*PI))
+ Latch = *PI;
+ ++PI;
+ if (PI == PE) return 0; // only one pred?
+
+ if (contains(*PI)) {
+ if (Latch) return 0; // multiple backedges
+ Latch = *PI;
+ }
+ ++PI;
+ if (PI != PE) return 0; // more than two preds
+
+ return Latch;
+}
+
+/// getCanonicalInductionVariable - Check to see if the loop has a canonical
+/// induction variable: an integer recurrence that starts at 0 and increments by
+/// one each time through the loop. If so, return the phi node that corresponds
+/// to it.
+///
+PHINode *Loop::getCanonicalInductionVariable() const {
+ BasicBlock *H = getHeader();
+
+ BasicBlock *Incoming = 0, *Backedge = 0;
+ pred_iterator PI = pred_begin(H);
+ assert(PI != pred_end(H) && "Loop must have at least one backedge!");
+ Backedge = *PI++;
+ if (PI == pred_end(H)) return 0; // dead loop
+ Incoming = *PI++;
+ if (PI != pred_end(H)) return 0; // multiple backedges?
+
+ if (contains(Incoming)) {
+ if (contains(Backedge))
+ return 0;
+ std::swap(Incoming, Backedge);
+ } else if (!contains(Backedge))
+ return 0;
+
+ // Loop over all of the PHI nodes, looking for a canonical indvar.
+ for (BasicBlock::iterator I = H->begin(); isa<PHINode>(I); ++I) {
+ PHINode *PN = cast<PHINode>(I);
+ if (Instruction *Inc =
+ dyn_cast<Instruction>(PN->getIncomingValueForBlock(Backedge)))
+ if (Inc->getOpcode() == Instruction::Add && Inc->getOperand(0) == PN)
+ if (ConstantInt *CI = dyn_cast<ConstantInt>(Inc->getOperand(1)))
+ if (CI->equalsInt(1))
+ return PN;
+ }
+ return 0;
+}
+
+/// getCanonicalInductionVariableIncrement - Return the LLVM value that holds
+/// the canonical induction variable value for the "next" iteration of the loop.
+/// This always succeeds if getCanonicalInductionVariable succeeds.
+///
+Instruction *Loop::getCanonicalInductionVariableIncrement() const {
+ if (PHINode *PN = getCanonicalInductionVariable()) {
+ bool P1InLoop = contains(PN->getIncomingBlock(1));
+ return cast<Instruction>(PN->getIncomingValue(P1InLoop));
+ }
+ return 0;
+}
+
+/// getTripCount - Return a loop-invariant LLVM value indicating the number of
+/// times the loop will be executed. Note that this means that the backedge of
+/// the loop executes N-1 times. If the trip-count cannot be determined, this
+/// returns null.
+///
+Value *Loop::getTripCount() const {
+ // Canonical loops will end with a 'cmp ne I, V', where I is the incremented
+ // canonical induction variable and V is the trip count of the loop.
+ Instruction *Inc = getCanonicalInductionVariableIncrement();
+ if (Inc == 0) return 0;
+ PHINode *IV = cast<PHINode>(Inc->getOperand(0));
+
+ BasicBlock *BackedgeBlock =
+ IV->getIncomingBlock(contains(IV->getIncomingBlock(1)));
+
+ if (BranchInst *BI = dyn_cast<BranchInst>(BackedgeBlock->getTerminator()))
+ if (BI->isConditional()) {
+ if (ICmpInst *ICI = dyn_cast<ICmpInst>(BI->getCondition())) {
+ if (ICI->getOperand(0) == Inc)
+ if (BI->getSuccessor(0) == getHeader()) {
+ if (ICI->getPredicate() == ICmpInst::ICMP_NE)
+ return ICI->getOperand(1);
+ } else if (ICI->getPredicate() == ICmpInst::ICMP_EQ) {
+ return ICI->getOperand(1);
+ }
+ }
+ }
+
+ return 0;
+}
+
+/// isLCSSAForm - Return true if the Loop is in LCSSA form
+bool Loop::isLCSSAForm() const {
+ // Sort the blocks vector so that we can use binary search to do quick
+ // lookups.
+ SmallPtrSet<BasicBlock*, 16> LoopBBs(block_begin(), block_end());
+
+ for (block_iterator BI = block_begin(), E = block_end(); BI != E; ++BI) {
+ BasicBlock *BB = *BI;
+ for (BasicBlock::iterator I = BB->begin(), E = BB->end(); I != E; ++I)
+ for (Value::use_iterator UI = I->use_begin(), E = I->use_end(); UI != E;
+ ++UI) {
+ BasicBlock *UserBB = cast<Instruction>(*UI)->getParent();
+ if (PHINode *P = dyn_cast<PHINode>(*UI)) {
+ unsigned OperandNo = UI.getOperandNo();
+ UserBB = P->getIncomingBlock(OperandNo/2);
+ }
+
+ // Check the current block, as a fast-path. Most values are used in the
+ // same block they are defined in.
+ if (UserBB != BB && !LoopBBs.count(UserBB))
+ return false;
+ }
+ }
+
+ return true;
+}
+
+//===-------------------------------------------------------------------===//
+// APIs for updating loop information after changing the CFG
+//
+
+/// addBasicBlockToLoop - This function is used by other analyses to update loop
+/// information. NewBB is set to be a new member of the current loop. Because
+/// of this, it is added as a member of all parent loops, and is added to the
+/// specified LoopInfo object as being in the current basic block. It is not
+/// valid to replace the loop header with this method.
+///
+void Loop::addBasicBlockToLoop(BasicBlock *NewBB, LoopInfo &LI) {
+ assert((Blocks.empty() || LI[getHeader()] == this) &&
+ "Incorrect LI specified for this loop!");
+ assert(NewBB && "Cannot add a null basic block to the loop!");
+ assert(LI[NewBB] == 0 && "BasicBlock already in the loop!");
+
+ // Add the loop mapping to the LoopInfo object...
+ LI.BBMap[NewBB] = this;
+
+ // Add the basic block to this loop and all parent loops...
+ Loop *L = this;
+ while (L) {
+ L->Blocks.push_back(NewBB);
+ L = L->getParentLoop();
+ }
+}
+
+/// replaceChildLoopWith - This is used when splitting loops up. It replaces
+/// the OldChild entry in our children list with NewChild, and updates the
+/// parent pointers of the two loops as appropriate.
+void Loop::replaceChildLoopWith(Loop *OldChild, Loop *NewChild) {
+ assert(OldChild->ParentLoop == this && "This loop is already broken!");
+ assert(NewChild->ParentLoop == 0 && "NewChild already has a parent!");
+ std::vector<Loop*>::iterator I = std::find(SubLoops.begin(), SubLoops.end(),
+ OldChild);
+ assert(I != SubLoops.end() && "OldChild not in loop!");
+ *I = NewChild;
+ OldChild->ParentLoop = 0;
+ NewChild->ParentLoop = this;
+}
+
+/// addChildLoop - Add the specified loop to be a child of this loop.
+///
+void Loop::addChildLoop(Loop *NewChild) {
+ assert(NewChild->ParentLoop == 0 && "NewChild already has a parent!");
+ NewChild->ParentLoop = this;
+ SubLoops.push_back(NewChild);
+}
+
+template<typename T>
+static void RemoveFromVector(std::vector<T*> &V, T *N) {
+ typename std::vector<T*>::iterator I = std::find(V.begin(), V.end(), N);
+ assert(I != V.end() && "N is not in this list!");
+ V.erase(I);
+}
+
+/// removeChildLoop - This removes the specified child from being a subloop of
+/// this loop. The loop is not deleted, as it will presumably be inserted
+/// into another loop.
+Loop *Loop::removeChildLoop(iterator I) {
+ assert(I != SubLoops.end() && "Cannot remove end iterator!");
+ Loop *Child = *I;
+ assert(Child->ParentLoop == this && "Child is not a child of this loop!");
+ SubLoops.erase(SubLoops.begin()+(I-begin()));
+ Child->ParentLoop = 0;
+ return Child;
+}
+
+
+/// removeBlockFromLoop - This removes the specified basic block from the
+/// current loop, updating the Blocks and ExitBlocks lists as appropriate. This
+/// does not update the mapping in the LoopInfo class.
+void Loop::removeBlockFromLoop(BasicBlock *BB) {
+ RemoveFromVector(Blocks, BB);
+}
+
+// Ensure this file gets linked when LoopInfo.h is used.
+DEFINING_FILE_FOR(LoopInfo)
diff --git a/lib/Analysis/LoopPass.cpp b/lib/Analysis/LoopPass.cpp
new file mode 100644
index 0000000..a5496a0
--- /dev/null
+++ b/lib/Analysis/LoopPass.cpp
@@ -0,0 +1,317 @@
+//===- LoopPass.cpp - Loop Pass and Loop Pass Manager ---------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by Devang Patel and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements LoopPass and LPPassManager. All loop optimization
+// and transformation passes are derived from LoopPass. LPPassManager is
+// responsible for managing LoopPasses.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Analysis/LoopPass.h"
+#include "llvm/Analysis/ScalarEvolutionExpander.h"
+using namespace llvm;
+
+//===----------------------------------------------------------------------===//
+// LPPassManager
+//
+
+char LPPassManager::ID = 0;
+/// LPPassManager manages FPPassManagers and CalLGraphSCCPasses.
+
+LPPassManager::LPPassManager(int Depth)
+ : FunctionPass((intptr_t)&ID), PMDataManager(Depth) {
+ skipThisLoop = false;
+ redoThisLoop = false;
+ LI = NULL;
+ CurrentLoop = NULL;
+}
+
+/// Delete loop from the loop queue and loop hierarcy (LoopInfo).
+void LPPassManager::deleteLoopFromQueue(Loop *L) {
+
+ if (Loop *ParentLoop = L->getParentLoop()) { // Not a top-level loop.
+ // Reparent all of the blocks in this loop. Since BBLoop had a parent,
+ // they are now all in it.
+ for (Loop::block_iterator I = L->block_begin(), E = L->block_end();
+ I != E; ++I)
+ if (LI->getLoopFor(*I) == L) // Don't change blocks in subloops.
+ LI->changeLoopFor(*I, ParentLoop);
+
+ // Remove the loop from its parent loop.
+ for (Loop::iterator I = ParentLoop->begin(), E = ParentLoop->end();;
+ ++I) {
+ assert(I != E && "Couldn't find loop");
+ if (*I == L) {
+ ParentLoop->removeChildLoop(I);
+ break;
+ }
+ }
+
+ // Move all subloops into the parent loop.
+ while (L->begin() != L->end())
+ ParentLoop->addChildLoop(L->removeChildLoop(L->end()-1));
+ } else {
+ // Reparent all of the blocks in this loop. Since BBLoop had no parent,
+ // they no longer in a loop at all.
+
+ for (unsigned i = 0; i != L->getBlocks().size(); ++i) {
+ // Don't change blocks in subloops.
+ if (LI->getLoopFor(L->getBlocks()[i]) == L) {
+ LI->removeBlock(L->getBlocks()[i]);
+ --i;
+ }
+ }
+
+ // Remove the loop from the top-level LoopInfo object.
+ for (LoopInfo::iterator I = LI->begin(), E = LI->end();; ++I) {
+ assert(I != E && "Couldn't find loop");
+ if (*I == L) {
+ LI->removeLoop(I);
+ break;
+ }
+ }
+
+ // Move all of the subloops to the top-level.
+ while (L->begin() != L->end())
+ LI->addTopLevelLoop(L->removeChildLoop(L->end()-1));
+ }
+
+ delete L;
+
+ // If L is current loop then skip rest of the passes and let
+ // runOnFunction remove L from LQ. Otherwise, remove L from LQ now
+ // and continue applying other passes on CurrentLoop.
+ if (CurrentLoop == L) {
+ skipThisLoop = true;
+ return;
+ }
+
+ for (std::deque<Loop *>::iterator I = LQ.begin(),
+ E = LQ.end(); I != E; ++I) {
+ if (*I == L) {
+ LQ.erase(I);
+ break;
+ }
+ }
+}
+
+// Inset loop into loop nest (LoopInfo) and loop queue (LQ).
+void LPPassManager::insertLoop(Loop *L, Loop *ParentLoop) {
+
+ assert (CurrentLoop != L && "Cannot insert CurrentLoop");
+
+ // Insert into loop nest
+ if (ParentLoop)
+ ParentLoop->addChildLoop(L);
+ else
+ LI->addTopLevelLoop(L);
+
+ // Insert L into loop queue
+ if (L == CurrentLoop)
+ redoLoop(L);
+ else if (!ParentLoop)
+ // This is top level loop.
+ LQ.push_front(L);
+ else {
+ // Insert L after ParentLoop
+ for (std::deque<Loop *>::iterator I = LQ.begin(),
+ E = LQ.end(); I != E; ++I) {
+ if (*I == ParentLoop) {
+ // deque does not support insert after.
+ ++I;
+ LQ.insert(I, 1, L);
+ break;
+ }
+ }
+ }
+}
+
+// Reoptimize this loop. LPPassManager will re-insert this loop into the
+// queue. This allows LoopPass to change loop nest for the loop. This
+// utility may send LPPassManager into infinite loops so use caution.
+void LPPassManager::redoLoop(Loop *L) {
+ assert (CurrentLoop == L && "Can redo only CurrentLoop");
+ redoThisLoop = true;
+}
+
+// Recurse through all subloops and all loops into LQ.
+static void addLoopIntoQueue(Loop *L, std::deque<Loop *> &LQ) {
+ LQ.push_back(L);
+ for (Loop::iterator I = L->begin(), E = L->end(); I != E; ++I)
+ addLoopIntoQueue(*I, LQ);
+}
+
+/// Pass Manager itself does not invalidate any analysis info.
+void LPPassManager::getAnalysisUsage(AnalysisUsage &Info) const {
+ // LPPassManager needs LoopInfo. In the long term LoopInfo class will
+ // become part of LPPassManager.
+ Info.addRequired<LoopInfo>();
+ // Used by IndVar doInitialization.
+ Info.addRequired<ScalarEvolution>();
+ Info.setPreservesAll();
+}
+
+/// verifyLoopInfo - Verify loop nest.
+void LPPassManager::verifyLoopInfo() {
+ assert (LI && "Loop Info is missing");
+
+ for (LoopInfo::iterator I = LI->begin(), E = LI->end(); I != E; ++I) {
+ Loop *L = *I;
+ assert (L->getHeader() && "Loop header is missing");
+ assert (L->getLoopPreheader() && "Loop preheader is missing");
+ assert (L->getLoopLatch() && "Loop latch is missing");
+ }
+}
+
+/// run - Execute all of the passes scheduled for execution. Keep track of
+/// whether any of the passes modifies the function, and if so, return true.
+bool LPPassManager::runOnFunction(Function &F) {
+ LI = &getAnalysis<LoopInfo>();
+ bool Changed = false;
+
+ // Populate Loop Queue
+ for (LoopInfo::iterator I = LI->begin(), E = LI->end(); I != E; ++I)
+ addLoopIntoQueue(*I, LQ);
+
+ // Initialization
+ for (std::deque<Loop *>::const_iterator I = LQ.begin(), E = LQ.end();
+ 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);
+ }
+ }
+
+ // Walk Loops
+ while (!LQ.empty()) {
+
+ CurrentLoop = LQ.back();
+ skipThisLoop = false;
+ redoThisLoop = false;
+
+ // Run all passes on current SCC
+ for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index) {
+
+ Pass *P = getContainedPass(Index);
+ AnalysisUsage AnUsage;
+ P->getAnalysisUsage(AnUsage);
+
+ dumpPassInfo(P, EXECUTION_MSG, ON_LOOP_MSG, "");
+ dumpAnalysisSetInfo("Required", P, AnUsage.getRequiredSet());
+
+ initializeAnalysisImpl(P);
+
+ StartPassTimer(P);
+ LoopPass *LP = dynamic_cast<LoopPass *>(P);
+ assert (LP && "Invalid LPPassManager member");
+ LP->runOnLoop(CurrentLoop, *this);
+ verifyLoopInfo();
+ StopPassTimer(P);
+
+ if (Changed)
+ dumpPassInfo(P, MODIFICATION_MSG, ON_LOOP_MSG, "");
+ dumpAnalysisSetInfo("Preserved", P, AnUsage.getPreservedSet());
+
+ removeNotPreservedAnalysis(P);
+ recordAvailableAnalysis(P);
+ removeDeadPasses(P, "", ON_LOOP_MSG);
+
+ if (skipThisLoop)
+ // Do not run other passes on this loop.
+ break;
+ }
+
+ // Pop the loop from queue after running all passes.
+ LQ.pop_back();
+
+ if (redoThisLoop)
+ LQ.push_back(CurrentLoop);
+ }
+
+ // Finalization
+ for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index) {
+ Pass *P = getContainedPass(Index);
+ LoopPass *LP = dynamic_cast <LoopPass *>(P);
+ if (LP)
+ Changed |= LP->doFinalization();
+ }
+
+ return Changed;
+}
+
+
+//===----------------------------------------------------------------------===//
+// LoopPass
+
+// Check if this pass is suitable for the current LPPassManager, if
+// available. This pass P is not suitable for a LPPassManager if P
+// is not preserving higher level analysis info used by other
+// LPPassManager passes. In such case, pop LPPassManager from the
+// stack. This will force assignPassManager() to create new
+// LPPassManger as expected.
+void LoopPass::preparePassManager(PMStack &PMS) {
+
+ // Find LPPassManager
+ while (!PMS.empty()) {
+ if (PMS.top()->getPassManagerType() > PMT_LoopPassManager)
+ PMS.pop();
+ else;
+ break;
+ }
+
+ 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))
+ PMS.pop();
+}
+
+/// Assign pass manager to manage this pass.
+void LoopPass::assignPassManager(PMStack &PMS,
+ PassManagerType PreferredType) {
+ // Find LPPassManager
+ while (!PMS.empty()) {
+ if (PMS.top()->getPassManagerType() > PMT_LoopPassManager)
+ PMS.pop();
+ else;
+ break;
+ }
+
+ LPPassManager *LPPM = dynamic_cast<LPPassManager *>(PMS.top());
+
+ // Create new Loop Pass Manager if it does not exist.
+ if (!LPPM) {
+
+ assert (!PMS.empty() && "Unable to create Loop Pass Manager");
+ PMDataManager *PMD = PMS.top();
+
+ // [1] Create new Call Graph Pass Manager
+ LPPM = new LPPassManager(PMD->getDepth() + 1);
+ LPPM->populateInheritedAnalysis(PMS);
+
+ // [2] Set up new manager's top level manager
+ PMTopLevelManager *TPM = PMD->getTopLevelManager();
+ TPM->addIndirectPassManager(LPPM);
+
+ // [3] Assign manager to manage this new manager. This may create
+ // and push new managers into PMS
+ Pass *P = dynamic_cast<Pass *>(LPPM);
+ TPM->schedulePass(P);
+
+ // [4] Push new manager into PMS
+ PMS.push(LPPM);
+ }
+
+ LPPM->add(this);
+}
diff --git a/lib/Analysis/Makefile b/lib/Analysis/Makefile
new file mode 100644
index 0000000..2efe8b8
--- /dev/null
+++ b/lib/Analysis/Makefile
@@ -0,0 +1,16 @@
+##===- lib/Analysis/Makefile -------------------------------*- Makefile -*-===##
+#
+# The LLVM Compiler Infrastructure
+#
+# This file was developed by the LLVM research group and is distributed under
+# the University of Illinois Open Source License. See LICENSE.TXT for details.
+#
+##===----------------------------------------------------------------------===##
+
+LEVEL = ../..
+LIBRARYNAME = LLVMAnalysis
+DIRS = IPA
+BUILD_ARCHIVE = 1
+
+include $(LEVEL)/Makefile.common
+
diff --git a/lib/Analysis/MemoryDependenceAnalysis.cpp b/lib/Analysis/MemoryDependenceAnalysis.cpp
new file mode 100644
index 0000000..498e54c
--- /dev/null
+++ b/lib/Analysis/MemoryDependenceAnalysis.cpp
@@ -0,0 +1,279 @@
+//===- MemoryDependenceAnalysis.cpp - Mem Deps Implementation --*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the Owen Anderson and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements an analysis that determines, for a given memory
+// operation, what preceding memory operations it depends on. It builds on
+// alias analysis information, and tries to provide a lazy, caching interface to
+// a common kind of alias information query.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Analysis/MemoryDependenceAnalysis.h"
+#include "llvm/Constants.h"
+#include "llvm/Instructions.h"
+#include "llvm/Function.h"
+#include "llvm/Analysis/AliasAnalysis.h"
+#include "llvm/Target/TargetData.h"
+
+using namespace llvm;
+
+char MemoryDependenceAnalysis::ID = 0;
+
+Instruction* MemoryDependenceAnalysis::NonLocal = (Instruction*)0;
+Instruction* MemoryDependenceAnalysis::None = (Instruction*)~0;
+
+// Register this pass...
+static RegisterPass<MemoryDependenceAnalysis> X("memdep",
+ "Memory Dependence Analysis");
+
+/// getAnalysisUsage - Does not modify anything. It uses Alias Analysis.
+///
+void MemoryDependenceAnalysis::getAnalysisUsage(AnalysisUsage &AU) const {
+ AU.setPreservesAll();
+ AU.addRequiredTransitive<AliasAnalysis>();
+ AU.addRequiredTransitive<TargetData>();
+}
+
+// Find the dependency of a CallSite
+Instruction* MemoryDependenceAnalysis::getCallSiteDependency(CallSite C, Instruction* start,
+ bool local) {
+ assert(local && "Non-local memory dependence analysis not yet implemented");
+
+ AliasAnalysis& AA = getAnalysis<AliasAnalysis>();
+ TargetData& TD = getAnalysis<TargetData>();
+ BasicBlock::iterator blockBegin = C.getInstruction()->getParent()->begin();
+ BasicBlock::iterator QI = C.getInstruction();
+
+ while (QI != blockBegin) {
+ --QI;
+
+ // If this inst is a memory op, get the pointer it accessed
+ Value* pointer = 0;
+ uint64_t pointerSize = 0;
+ if (StoreInst* S = dyn_cast<StoreInst>(QI)) {
+ pointer = S->getPointerOperand();
+ pointerSize = TD.getTypeSize(S->getOperand(0)->getType());
+ } else if (LoadInst* L = dyn_cast<LoadInst>(QI)) {
+ pointer = L->getPointerOperand();
+ pointerSize = TD.getTypeSize(L->getType());
+ } else if (AllocationInst* AI = dyn_cast<AllocationInst>(QI)) {
+ pointer = AI;
+ if (ConstantInt* C = dyn_cast<ConstantInt>(AI->getArraySize()))
+ pointerSize = C->getZExtValue() * TD.getTypeSize(AI->getAllocatedType());
+ else
+ pointerSize = ~0UL;
+ } else if (VAArgInst* V = dyn_cast<VAArgInst>(QI)) {
+ pointer = V->getOperand(0);
+ pointerSize = TD.getTypeSize(V->getType());
+ } else if (FreeInst* F = dyn_cast<FreeInst>(QI)) {
+ pointer = F->getPointerOperand();
+
+ // FreeInsts erase the entire structure
+ pointerSize = ~0UL;
+ } else if (CallSite::get(QI).getInstruction() != 0) {
+ if (AA.getModRefInfo(C, CallSite::get(QI)) != AliasAnalysis::NoModRef) {
+ depGraphLocal.insert(std::make_pair(C.getInstruction(), std::make_pair(QI, true)));
+ reverseDep.insert(std::make_pair(QI, C.getInstruction()));
+ return QI;
+ } else {
+ continue;
+ }
+ } else
+ continue;
+
+ if (AA.getModRefInfo(C, pointer, pointerSize) != AliasAnalysis::NoModRef) {
+ depGraphLocal.insert(std::make_pair(C.getInstruction(), std::make_pair(QI, true)));
+ reverseDep.insert(std::make_pair(QI, C.getInstruction()));
+ return QI;
+ }
+ }
+
+ // No dependence found
+ depGraphLocal.insert(std::make_pair(C.getInstruction(), std::make_pair(NonLocal, true)));
+ reverseDep.insert(std::make_pair(NonLocal, C.getInstruction()));
+ return NonLocal;
+}
+
+/// getDependency - Return the instruction on which a memory operation
+/// depends. The local paramter indicates if the query should only
+/// evaluate dependencies within the same basic block.
+Instruction* MemoryDependenceAnalysis::getDependency(Instruction* query,
+ Instruction* start,
+ bool local) {
+ if (!local)
+ assert(0 && "Non-local memory dependence is not yet supported.");
+
+ // Start looking for dependencies with the queried inst
+ BasicBlock::iterator QI = query;
+
+ // Check for a cached result
+ std::pair<Instruction*, bool> cachedResult = depGraphLocal[query];
+ // If we have a _confirmed_ cached entry, return it
+ if (cachedResult.second)
+ return cachedResult.first;
+ else if (cachedResult.first != NonLocal)
+ // If we have an unconfirmed cached entry, we can start our search from there
+ QI = cachedResult.first;
+
+ if (start)
+ QI = start;
+
+ AliasAnalysis& AA = getAnalysis<AliasAnalysis>();
+ TargetData& TD = getAnalysis<TargetData>();
+
+ // Get the pointer value for which dependence will be determined
+ Value* dependee = 0;
+ uint64_t dependeeSize = 0;
+ bool queryIsVolatile = false;
+ if (StoreInst* S = dyn_cast<StoreInst>(query)) {
+ dependee = S->getPointerOperand();
+ dependeeSize = TD.getTypeSize(S->getOperand(0)->getType());
+ queryIsVolatile = S->isVolatile();
+ } else if (LoadInst* L = dyn_cast<LoadInst>(query)) {
+ dependee = L->getPointerOperand();
+ dependeeSize = TD.getTypeSize(L->getType());
+ queryIsVolatile = L->isVolatile();
+ } else if (VAArgInst* V = dyn_cast<VAArgInst>(query)) {
+ dependee = V->getOperand(0);
+ dependeeSize = TD.getTypeSize(V->getType());
+ } else if (FreeInst* F = dyn_cast<FreeInst>(query)) {
+ dependee = F->getPointerOperand();
+
+ // FreeInsts erase the entire structure, not just a field
+ dependeeSize = ~0UL;
+ } else if (CallSite::get(query).getInstruction() != 0)
+ return getCallSiteDependency(CallSite::get(query), start);
+ else if (isa<AllocationInst>(query))
+ return None;
+ else
+ return None;
+
+ BasicBlock::iterator blockBegin = query->getParent()->begin();
+
+ while (QI != blockBegin) {
+ --QI;
+
+ // If this inst is a memory op, get the pointer it accessed
+ Value* pointer = 0;
+ uint64_t pointerSize = 0;
+ if (StoreInst* S = dyn_cast<StoreInst>(QI)) {
+ // All volatile loads/stores depend on each other
+ if (queryIsVolatile && S->isVolatile()) {
+ if (!start) {
+ depGraphLocal.insert(std::make_pair(query, std::make_pair(S, true)));
+ reverseDep.insert(std::make_pair(S, query));
+ }
+
+ return S;
+ }
+
+ pointer = S->getPointerOperand();
+ pointerSize = TD.getTypeSize(S->getOperand(0)->getType());
+ } else if (LoadInst* L = dyn_cast<LoadInst>(QI)) {
+ // All volatile loads/stores depend on each other
+ if (queryIsVolatile && L->isVolatile()) {
+ if (!start) {
+ depGraphLocal.insert(std::make_pair(query, std::make_pair(L, true)));
+ reverseDep.insert(std::make_pair(L, query));
+ }
+
+ return L;
+ }
+
+ pointer = L->getPointerOperand();
+ pointerSize = TD.getTypeSize(L->getType());
+ } else if (AllocationInst* AI = dyn_cast<AllocationInst>(QI)) {
+ pointer = AI;
+ if (ConstantInt* C = dyn_cast<ConstantInt>(AI->getArraySize()))
+ pointerSize = C->getZExtValue() * TD.getTypeSize(AI->getAllocatedType());
+ else
+ pointerSize = ~0UL;
+ } else if (VAArgInst* V = dyn_cast<VAArgInst>(QI)) {
+ pointer = V->getOperand(0);
+ pointerSize = TD.getTypeSize(V->getType());
+ } else if (FreeInst* F = dyn_cast<FreeInst>(QI)) {
+ pointer = F->getPointerOperand();
+
+ // FreeInsts erase the entire structure
+ pointerSize = ~0UL;
+ } else if (CallSite::get(QI).getInstruction() != 0) {
+ // Call insts need special handling. Check is they can modify our pointer
+ if (AA.getModRefInfo(CallSite::get(QI), dependee, dependeeSize) !=
+ AliasAnalysis::NoModRef) {
+ if (!start) {
+ depGraphLocal.insert(std::make_pair(query, std::make_pair(QI, true)));
+ reverseDep.insert(std::make_pair(QI, query));
+ }
+
+ return QI;
+ } else {
+ continue;
+ }
+ }
+
+ // If we found a pointer, check if it could be the same as our pointer
+ if (pointer) {
+ AliasAnalysis::AliasResult R = AA.alias(pointer, pointerSize,
+ dependee, dependeeSize);
+
+ if (R != AliasAnalysis::NoAlias) {
+ if (!start) {
+ depGraphLocal.insert(std::make_pair(query, std::make_pair(QI, true)));
+ reverseDep.insert(std::make_pair(QI, query));
+ }
+
+ return QI;
+ }
+ }
+ }
+
+ // If we found nothing, return the non-local flag
+ if (!start) {
+ depGraphLocal.insert(std::make_pair(query,
+ std::make_pair(NonLocal, true)));
+ reverseDep.insert(std::make_pair(NonLocal, query));
+ }
+
+ return NonLocal;
+}
+
+/// removeInstruction - Remove an instruction from the dependence analysis,
+/// updating the dependence of instructions that previously depended on it.
+void MemoryDependenceAnalysis::removeInstruction(Instruction* rem) {
+ // Figure out the new dep for things that currently depend on rem
+ Instruction* newDep = NonLocal;
+ if (depGraphLocal[rem].first != NonLocal) {
+ // If we have dep info for rem, set them to it
+ BasicBlock::iterator RI = depGraphLocal[rem].first;
+ RI++;
+ newDep = RI;
+ } else if (depGraphLocal[rem].first == NonLocal &&
+ depGraphLocal[rem].second ) {
+ // If we have a confirmed non-local flag, use it
+ newDep = NonLocal;
+ } else {
+ // Otherwise, use the immediate successor of rem
+ // NOTE: This is because, when getDependence is called, it will first check
+ // the immediate predecessor of what is in the cache.
+ BasicBlock::iterator RI = rem;
+ RI++;
+ newDep = RI;
+ }
+
+ std::multimap<Instruction*, Instruction*>::iterator I = reverseDep.find(rem);
+ while (I->first == rem) {
+ // Insert the new dependencies
+ // Mark it as unconfirmed as long as it is not the non-local flag
+ depGraphLocal[I->second] = std::make_pair(newDep, !newDep);
+ reverseDep.erase(I);
+ I = reverseDep.find(rem);
+ }
+
+ getAnalysis<AliasAnalysis>().deleteValue(rem);
+}
diff --git a/lib/Analysis/PostDominators.cpp b/lib/Analysis/PostDominators.cpp
new file mode 100644
index 0000000..48f7b30
--- /dev/null
+++ b/lib/Analysis/PostDominators.cpp
@@ -0,0 +1,262 @@
+//===- PostDominators.cpp - Post-Dominator Calculation --------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the post-dominator construction algorithms.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Analysis/PostDominators.h"
+#include "llvm/Instructions.h"
+#include "llvm/Support/CFG.h"
+#include "llvm/ADT/DepthFirstIterator.h"
+#include "llvm/ADT/SetOperations.h"
+using namespace llvm;
+
+//===----------------------------------------------------------------------===//
+// PostDominatorTree Implementation
+//===----------------------------------------------------------------------===//
+
+char PostDominatorTree::ID = 0;
+char PostDominanceFrontier::ID = 0;
+static RegisterPass<PostDominatorTree>
+F("postdomtree", "Post-Dominator Tree Construction", true);
+
+unsigned PostDominatorTree::DFSPass(BasicBlock *V, InfoRec &VInfo,
+ unsigned N) {
+ std::vector<std::pair<BasicBlock *, InfoRec *> > workStack;
+ std::set<BasicBlock *> visited;
+ workStack.push_back(std::make_pair(V, &VInfo));
+
+ do {
+ BasicBlock *currentBB = workStack.back().first;
+ InfoRec *currentVInfo = workStack.back().second;
+
+ // Visit each block only once.
+ if (visited.count(currentBB) == 0) {
+
+ visited.insert(currentBB);
+ currentVInfo->Semi = ++N;
+ currentVInfo->Label = currentBB;
+
+ Vertex.push_back(currentBB); // Vertex[n] = current;
+ // Info[currentBB].Ancestor = 0;
+ // Ancestor[n] = 0
+ // Child[currentBB] = 0;
+ currentVInfo->Size = 1; // Size[currentBB] = 1
+ }
+
+ // Visit children
+ bool visitChild = false;
+ for (pred_iterator PI = pred_begin(currentBB), PE = pred_end(currentBB);
+ PI != PE && !visitChild; ++PI) {
+ InfoRec &SuccVInfo = Info[*PI];
+ if (SuccVInfo.Semi == 0) {
+ SuccVInfo.Parent = currentBB;
+ if (visited.count (*PI) == 0) {
+ workStack.push_back(std::make_pair(*PI, &SuccVInfo));
+ visitChild = true;
+ }
+ }
+ }
+
+ // If all children are visited or if this block has no child then pop this
+ // block out of workStack.
+ if (!visitChild)
+ workStack.pop_back();
+
+ } while (!workStack.empty());
+
+ return N;
+}
+
+void PostDominatorTree::Compress(BasicBlock *V, InfoRec &VInfo) {
+ BasicBlock *VAncestor = VInfo.Ancestor;
+ InfoRec &VAInfo = Info[VAncestor];
+ if (VAInfo.Ancestor == 0)
+ return;
+
+ Compress(VAncestor, VAInfo);
+
+ BasicBlock *VAncestorLabel = VAInfo.Label;
+ BasicBlock *VLabel = VInfo.Label;
+ if (Info[VAncestorLabel].Semi < Info[VLabel].Semi)
+ VInfo.Label = VAncestorLabel;
+
+ VInfo.Ancestor = VAInfo.Ancestor;
+}
+
+BasicBlock *PostDominatorTree::Eval(BasicBlock *V) {
+ InfoRec &VInfo = Info[V];
+
+ // Higher-complexity but faster implementation
+ if (VInfo.Ancestor == 0)
+ return V;
+ Compress(V, VInfo);
+ return VInfo.Label;
+}
+
+void PostDominatorTree::Link(BasicBlock *V, BasicBlock *W,
+ InfoRec &WInfo) {
+ // Higher-complexity but faster implementation
+ WInfo.Ancestor = V;
+}
+
+void PostDominatorTree::calculate(Function &F) {
+ // Step #0: Scan the function looking for the root nodes of the post-dominance
+ // relationships. These blocks, which have no successors, end with return and
+ // unwind instructions.
+ for (Function::iterator I = F.begin(), E = F.end(); I != E; ++I)
+ if (succ_begin(I) == succ_end(I))
+ Roots.push_back(I);
+
+ Vertex.push_back(0);
+
+ // Step #1: Number blocks in depth-first order and initialize variables used
+ // in later stages of the algorithm.
+ unsigned N = 0;
+ for (unsigned i = 0, e = Roots.size(); i != e; ++i)
+ N = DFSPass(Roots[i], Info[Roots[i]], N);
+
+ for (unsigned i = N; i >= 2; --i) {
+ BasicBlock *W = Vertex[i];
+ InfoRec &WInfo = Info[W];
+
+ // Step #2: Calculate the semidominators of all vertices
+ for (succ_iterator SI = succ_begin(W), SE = succ_end(W); SI != SE; ++SI)
+ if (Info.count(*SI)) { // Only if this predecessor is reachable!
+ unsigned SemiU = Info[Eval(*SI)].Semi;
+ if (SemiU < WInfo.Semi)
+ WInfo.Semi = SemiU;
+ }
+
+ Info[Vertex[WInfo.Semi]].Bucket.push_back(W);
+
+ BasicBlock *WParent = WInfo.Parent;
+ Link(WParent, W, WInfo);
+
+ // Step #3: Implicitly define the immediate dominator of vertices
+ std::vector<BasicBlock*> &WParentBucket = Info[WParent].Bucket;
+ while (!WParentBucket.empty()) {
+ BasicBlock *V = WParentBucket.back();
+ WParentBucket.pop_back();
+ BasicBlock *U = Eval(V);
+ IDoms[V] = Info[U].Semi < Info[V].Semi ? U : WParent;
+ }
+ }
+
+ // Step #4: Explicitly define the immediate dominator of each vertex
+ for (unsigned i = 2; i <= N; ++i) {
+ BasicBlock *W = Vertex[i];
+ BasicBlock *&WIDom = IDoms[W];
+ if (WIDom != Vertex[Info[W].Semi])
+ WIDom = IDoms[WIDom];
+ }
+
+ if (Roots.empty()) return;
+
+ // Add a node for the root. This node might be the actual root, if there is
+ // one exit block, or it may be the virtual exit (denoted by (BasicBlock *)0)
+ // which postdominates all real exits if there are multiple exit blocks.
+ BasicBlock *Root = Roots.size() == 1 ? Roots[0] : 0;
+ DomTreeNodes[Root] = RootNode = new DomTreeNode(Root, 0);
+
+ // Loop over all of the reachable blocks in the function...
+ for (Function::iterator I = F.begin(), E = F.end(); I != E; ++I)
+ if (BasicBlock *ImmPostDom = getIDom(I)) { // Reachable block.
+ DomTreeNode *&BBNode = DomTreeNodes[I];
+ if (!BBNode) { // Haven't calculated this node yet?
+ // Get or calculate the node for the immediate dominator
+ DomTreeNode *IPDomNode = getNodeForBlock(ImmPostDom);
+
+ // Add a new tree node for this BasicBlock, and link it as a child of
+ // IDomNode
+ DomTreeNode *C = new DomTreeNode(I, IPDomNode);
+ DomTreeNodes[I] = C;
+ BBNode = IPDomNode->addChild(C);
+ }
+ }
+
+ // Free temporary memory used to construct idom's
+ IDoms.clear();
+ Info.clear();
+ std::vector<BasicBlock*>().swap(Vertex);
+
+ int dfsnum = 0;
+ // Iterate over all nodes in depth first order...
+ for (unsigned i = 0, e = Roots.size(); i != e; ++i)
+ for (idf_iterator<BasicBlock*> I = idf_begin(Roots[i]),
+ E = idf_end(Roots[i]); I != E; ++I) {
+ if (!getNodeForBlock(*I)->getIDom())
+ getNodeForBlock(*I)->assignDFSNumber(dfsnum);
+ }
+ DFSInfoValid = true;
+}
+
+
+DomTreeNode *PostDominatorTree::getNodeForBlock(BasicBlock *BB) {
+ DomTreeNode *&BBNode = DomTreeNodes[BB];
+ if (BBNode) return BBNode;
+
+ // Haven't calculated this node yet? Get or calculate the node for the
+ // immediate postdominator.
+ BasicBlock *IPDom = getIDom(BB);
+ DomTreeNode *IPDomNode = getNodeForBlock(IPDom);
+
+ // Add a new tree node for this BasicBlock, and link it as a child of
+ // IDomNode
+ DomTreeNode *C = new DomTreeNode(BB, IPDomNode);
+ DomTreeNodes[BB] = C;
+ return BBNode = IPDomNode->addChild(C);
+}
+
+//===----------------------------------------------------------------------===//
+// PostDominanceFrontier Implementation
+//===----------------------------------------------------------------------===//
+
+static RegisterPass<PostDominanceFrontier>
+H("postdomfrontier", "Post-Dominance Frontier Construction", true);
+
+const DominanceFrontier::DomSetType &
+PostDominanceFrontier::calculate(const PostDominatorTree &DT,
+ const DomTreeNode *Node) {
+ // Loop over CFG successors to calculate DFlocal[Node]
+ BasicBlock *BB = Node->getBlock();
+ DomSetType &S = Frontiers[BB]; // The new set to fill in...
+ if (getRoots().empty()) return S;
+
+ if (BB)
+ for (pred_iterator SI = pred_begin(BB), SE = pred_end(BB);
+ SI != SE; ++SI) {
+ // Does Node immediately dominate this predecessor?
+ DomTreeNode *SINode = DT[*SI];
+ if (SINode && SINode->getIDom() != Node)
+ S.insert(*SI);
+ }
+
+ // At this point, S is DFlocal. Now we union in DFup's of our children...
+ // Loop through and visit the nodes that Node immediately dominates (Node's
+ // children in the IDomTree)
+ //
+ for (DomTreeNode::const_iterator
+ NI = Node->begin(), NE = Node->end(); NI != NE; ++NI) {
+ DomTreeNode *IDominee = *NI;
+ const DomSetType &ChildDF = calculate(DT, IDominee);
+
+ DomSetType::const_iterator CDFI = ChildDF.begin(), CDFE = ChildDF.end();
+ for (; CDFI != CDFE; ++CDFI) {
+ if (!DT.properlyDominates(Node, DT[*CDFI]))
+ S.insert(*CDFI);
+ }
+ }
+
+ return S;
+}
+
+// Ensure that this .cpp file gets linked when PostDominators.h is used.
+DEFINING_FILE_FOR(PostDominanceFrontier)
diff --git a/lib/Analysis/ProfileInfo.cpp b/lib/Analysis/ProfileInfo.cpp
new file mode 100644
index 0000000..c8dad66
--- /dev/null
+++ b/lib/Analysis/ProfileInfo.cpp
@@ -0,0 +1,102 @@
+//===- ProfileInfo.cpp - Profile Info Interface ---------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the abstract ProfileInfo interface, and the default
+// "no profile" implementation.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Analysis/Passes.h"
+#include "llvm/Analysis/ProfileInfo.h"
+#include "llvm/Pass.h"
+#include "llvm/Support/CFG.h"
+#include "llvm/Support/Compiler.h"
+#include <set>
+using namespace llvm;
+
+// Register the ProfileInfo interface, providing a nice name to refer to.
+namespace {
+ RegisterAnalysisGroup<ProfileInfo> Z("Profile Information");
+}
+char ProfileInfo::ID = 0;
+
+ProfileInfo::~ProfileInfo() {}
+
+unsigned ProfileInfo::getExecutionCount(BasicBlock *BB) const {
+ pred_iterator PI = pred_begin(BB), PE = pred_end(BB);
+
+ // Are there zero predecessors of this block?
+ if (PI == PE) {
+ // If this is the entry block, look for the Null -> Entry edge.
+ if (BB == &BB->getParent()->getEntryBlock())
+ return getEdgeWeight(0, BB);
+ else
+ return 0; // Otherwise, this is a dead block.
+ }
+
+ // Otherwise, if there are predecessors, the execution count of this block is
+ // the sum of the edge frequencies from the incoming edges. Note that if
+ // there are multiple edges from a predecessor to this block that we don't
+ // want to count its weight multiple times. For this reason, we keep track of
+ // the predecessors we've seen and only count them if we haven't run into them
+ // yet.
+ //
+ // We don't want to create an std::set unless we are dealing with a block that
+ // has a LARGE number of in-edges. Handle the common case of having only a
+ // few in-edges with special code.
+ //
+ BasicBlock *FirstPred = *PI;
+ unsigned Count = getEdgeWeight(FirstPred, BB);
+ ++PI;
+ if (PI == PE) return Count; // Quick exit for single predecessor blocks
+
+ BasicBlock *SecondPred = *PI;
+ if (SecondPred != FirstPred) Count += getEdgeWeight(SecondPred, BB);
+ ++PI;
+ if (PI == PE) return Count; // Quick exit for two predecessor blocks
+
+ BasicBlock *ThirdPred = *PI;
+ if (ThirdPred != FirstPred && ThirdPred != SecondPred)
+ Count += getEdgeWeight(ThirdPred, BB);
+ ++PI;
+ if (PI == PE) return Count; // Quick exit for three predecessor blocks
+
+ std::set<BasicBlock*> ProcessedPreds;
+ ProcessedPreds.insert(FirstPred);
+ ProcessedPreds.insert(SecondPred);
+ ProcessedPreds.insert(ThirdPred);
+ for (; PI != PE; ++PI)
+ if (ProcessedPreds.insert(*PI).second)
+ Count += getEdgeWeight(*PI, BB);
+ return Count;
+}
+
+
+
+//===----------------------------------------------------------------------===//
+// NoProfile ProfileInfo implementation
+//
+
+namespace {
+ struct VISIBILITY_HIDDEN NoProfileInfo
+ : public ImmutablePass, public ProfileInfo {
+ static char ID; // Class identification, replacement for typeinfo
+ NoProfileInfo() : ImmutablePass((intptr_t)&ID) {}
+ };
+
+ char NoProfileInfo::ID = 0;
+ // Register this pass...
+ RegisterPass<NoProfileInfo>
+ X("no-profile", "No Profile Information");
+
+ // Declare that we implement the ProfileInfo interface
+ RegisterAnalysisGroup<ProfileInfo, true> Y(X);
+} // End of anonymous namespace
+
+ImmutablePass *llvm::createNoProfileInfoPass() { return new NoProfileInfo(); }
diff --git a/lib/Analysis/ProfileInfoLoader.cpp b/lib/Analysis/ProfileInfoLoader.cpp
new file mode 100644
index 0000000..dec29a4
--- /dev/null
+++ b/lib/Analysis/ProfileInfoLoader.cpp
@@ -0,0 +1,276 @@
+//===- ProfileInfoLoad.cpp - Load profile information from disk -----------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// The ProfileInfoLoader class is used to load and represent profiling
+// information read in from the dump file.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Analysis/ProfileInfoLoader.h"
+#include "llvm/Analysis/ProfileInfoTypes.h"
+#include "llvm/Module.h"
+#include "llvm/InstrTypes.h"
+#include "llvm/Support/Streams.h"
+#include <cstdio>
+#include <map>
+using namespace llvm;
+
+// ByteSwap - Byteswap 'Var' if 'Really' is true.
+//
+static inline unsigned ByteSwap(unsigned Var, bool Really) {
+ if (!Really) return Var;
+ return ((Var & (255<< 0)) << 24) |
+ ((Var & (255<< 8)) << 8) |
+ ((Var & (255<<16)) >> 8) |
+ ((Var & (255<<24)) >> 24);
+}
+
+static void ReadProfilingBlock(const char *ToolName, FILE *F,
+ bool ShouldByteSwap,
+ std::vector<unsigned> &Data) {
+ // Read the number of entries...
+ unsigned NumEntries;
+ if (fread(&NumEntries, sizeof(unsigned), 1, F) != 1) {
+ cerr << ToolName << ": data packet truncated!\n";
+ perror(0);
+ exit(1);
+ }
+ NumEntries = ByteSwap(NumEntries, ShouldByteSwap);
+
+ // Read the counts...
+ std::vector<unsigned> TempSpace(NumEntries);
+
+ // Read in the block of data...
+ if (fread(&TempSpace[0], sizeof(unsigned)*NumEntries, 1, F) != 1) {
+ cerr << ToolName << ": data packet truncated!\n";
+ perror(0);
+ exit(1);
+ }
+
+ // Make sure we have enough space...
+ if (Data.size() < NumEntries)
+ Data.resize(NumEntries);
+
+ // Accumulate the data we just read into the data.
+ if (!ShouldByteSwap) {
+ for (unsigned i = 0; i != NumEntries; ++i)
+ Data[i] += TempSpace[i];
+ } else {
+ for (unsigned i = 0; i != NumEntries; ++i)
+ Data[i] += ByteSwap(TempSpace[i], true);
+ }
+}
+
+// ProfileInfoLoader ctor - Read the specified profiling data file, exiting the
+// program if the file is invalid or broken.
+//
+ProfileInfoLoader::ProfileInfoLoader(const char *ToolName,
+ const std::string &Filename,
+ Module &TheModule) : M(TheModule) {
+ FILE *F = fopen(Filename.c_str(), "r");
+ if (F == 0) {
+ cerr << ToolName << ": Error opening '" << Filename << "': ";
+ perror(0);
+ exit(1);
+ }
+
+ // Keep reading packets until we run out of them.
+ unsigned PacketType;
+ while (fread(&PacketType, sizeof(unsigned), 1, F) == 1) {
+ // If the low eight bits of the packet are zero, we must be dealing with an
+ // endianness mismatch. Byteswap all words read from the profiling
+ // information.
+ bool ShouldByteSwap = (char)PacketType == 0;
+ PacketType = ByteSwap(PacketType, ShouldByteSwap);
+
+ switch (PacketType) {
+ case ArgumentInfo: {
+ unsigned ArgLength;
+ if (fread(&ArgLength, sizeof(unsigned), 1, F) != 1) {
+ cerr << ToolName << ": arguments packet truncated!\n";
+ perror(0);
+ exit(1);
+ }
+ ArgLength = ByteSwap(ArgLength, ShouldByteSwap);
+
+ // Read in the arguments...
+ std::vector<char> Chars(ArgLength+4);
+
+ if (ArgLength)
+ if (fread(&Chars[0], (ArgLength+3) & ~3, 1, F) != 1) {
+ cerr << ToolName << ": arguments packet truncated!\n";
+ perror(0);
+ exit(1);
+ }
+ CommandLines.push_back(std::string(&Chars[0], &Chars[ArgLength]));
+ break;
+ }
+
+ case FunctionInfo:
+ ReadProfilingBlock(ToolName, F, ShouldByteSwap, FunctionCounts);
+ break;
+
+ case BlockInfo:
+ ReadProfilingBlock(ToolName, F, ShouldByteSwap, BlockCounts);
+ break;
+
+ case EdgeInfo:
+ ReadProfilingBlock(ToolName, F, ShouldByteSwap, EdgeCounts);
+ break;
+
+ case BBTraceInfo:
+ ReadProfilingBlock(ToolName, F, ShouldByteSwap, BBTrace);
+ break;
+
+ default:
+ cerr << ToolName << ": Unknown packet type #" << PacketType << "!\n";
+ exit(1);
+ }
+ }
+
+ fclose(F);
+}
+
+
+// getFunctionCounts - This method is used by consumers of function counting
+// information. If we do not directly have function count information, we
+// compute it from other, more refined, types of profile information.
+//
+void ProfileInfoLoader::getFunctionCounts(std::vector<std::pair<Function*,
+ unsigned> > &Counts) {
+ if (FunctionCounts.empty()) {
+ if (hasAccurateBlockCounts()) {
+ // Synthesize function frequency information from the number of times
+ // their entry blocks were executed.
+ std::vector<std::pair<BasicBlock*, unsigned> > BlockCounts;
+ getBlockCounts(BlockCounts);
+
+ for (unsigned i = 0, e = BlockCounts.size(); i != e; ++i)
+ if (&BlockCounts[i].first->getParent()->getEntryBlock() ==
+ BlockCounts[i].first)
+ Counts.push_back(std::make_pair(BlockCounts[i].first->getParent(),
+ BlockCounts[i].second));
+ } else {
+ cerr << "Function counts are not available!\n";
+ }
+ return;
+ }
+
+ unsigned Counter = 0;
+ for (Module::iterator I = M.begin(), E = M.end();
+ I != E && Counter != FunctionCounts.size(); ++I)
+ if (!I->isDeclaration())
+ Counts.push_back(std::make_pair(I, FunctionCounts[Counter++]));
+}
+
+// getBlockCounts - This method is used by consumers of block counting
+// information. If we do not directly have block count information, we
+// compute it from other, more refined, types of profile information.
+//
+void ProfileInfoLoader::getBlockCounts(std::vector<std::pair<BasicBlock*,
+ unsigned> > &Counts) {
+ if (BlockCounts.empty()) {
+ if (hasAccurateEdgeCounts()) {
+ // Synthesize block count information from edge frequency information.
+ // The block execution frequency is equal to the sum of the execution
+ // frequency of all outgoing edges from a block.
+ //
+ // If a block has no successors, this will not be correct, so we have to
+ // special case it. :(
+ std::vector<std::pair<Edge, unsigned> > EdgeCounts;
+ getEdgeCounts(EdgeCounts);
+
+ std::map<BasicBlock*, unsigned> InEdgeFreqs;
+
+ BasicBlock *LastBlock = 0;
+ TerminatorInst *TI = 0;
+ for (unsigned i = 0, e = EdgeCounts.size(); i != e; ++i) {
+ if (EdgeCounts[i].first.first != LastBlock) {
+ LastBlock = EdgeCounts[i].first.first;
+ TI = LastBlock->getTerminator();
+ Counts.push_back(std::make_pair(LastBlock, 0));
+ }
+ Counts.back().second += EdgeCounts[i].second;
+ unsigned SuccNum = EdgeCounts[i].first.second;
+ if (SuccNum >= TI->getNumSuccessors()) {
+ static bool Warned = false;
+ if (!Warned) {
+ cerr << "WARNING: profile info doesn't seem to match"
+ << " the program!\n";
+ Warned = true;
+ }
+ } else {
+ // If this successor has no successors of its own, we will never
+ // compute an execution count for that block. Remember the incoming
+ // edge frequencies to add later.
+ BasicBlock *Succ = TI->getSuccessor(SuccNum);
+ if (Succ->getTerminator()->getNumSuccessors() == 0)
+ InEdgeFreqs[Succ] += EdgeCounts[i].second;
+ }
+ }
+
+ // Now we have to accumulate information for those blocks without
+ // successors into our table.
+ for (std::map<BasicBlock*, unsigned>::iterator I = InEdgeFreqs.begin(),
+ E = InEdgeFreqs.end(); I != E; ++I) {
+ unsigned i = 0;
+ for (; i != Counts.size() && Counts[i].first != I->first; ++i)
+ /*empty*/;
+ if (i == Counts.size()) Counts.push_back(std::make_pair(I->first, 0));
+ Counts[i].second += I->second;
+ }
+
+ } else {
+ cerr << "Block counts are not available!\n";
+ }
+ return;
+ }
+
+ unsigned Counter = 0;
+ for (Module::iterator F = M.begin(), E = M.end(); F != E; ++F)
+ for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB) {
+ Counts.push_back(std::make_pair(BB, BlockCounts[Counter++]));
+ if (Counter == BlockCounts.size())
+ return;
+ }
+}
+
+// getEdgeCounts - This method is used by consumers of edge counting
+// information. If we do not directly have edge count information, we compute
+// it from other, more refined, types of profile information.
+//
+void ProfileInfoLoader::getEdgeCounts(std::vector<std::pair<Edge,
+ unsigned> > &Counts) {
+ if (EdgeCounts.empty()) {
+ cerr << "Edge counts not available, and no synthesis "
+ << "is implemented yet!\n";
+ return;
+ }
+
+ unsigned Counter = 0;
+ for (Module::iterator F = M.begin(), E = M.end(); F != E; ++F)
+ for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB)
+ for (unsigned i = 0, e = BB->getTerminator()->getNumSuccessors();
+ i != e; ++i) {
+ Counts.push_back(std::make_pair(Edge(BB, i), EdgeCounts[Counter++]));
+ if (Counter == EdgeCounts.size())
+ return;
+ }
+}
+
+// getBBTrace - This method is used by consumers of basic-block trace
+// information.
+//
+void ProfileInfoLoader::getBBTrace(std::vector<BasicBlock *> &Trace) {
+ if (BBTrace.empty ()) {
+ cerr << "Basic block trace is not available!\n";
+ return;
+ }
+ cerr << "Basic block trace loading is not implemented yet!\n";
+}
diff --git a/lib/Analysis/ProfileInfoLoaderPass.cpp b/lib/Analysis/ProfileInfoLoaderPass.cpp
new file mode 100644
index 0000000..e749375
--- /dev/null
+++ b/lib/Analysis/ProfileInfoLoaderPass.cpp
@@ -0,0 +1,92 @@
+//===- ProfileInfoLoaderPass.cpp - LLVM Pass to load profile info ---------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements a concrete implementation of profiling information that
+// loads the information from a profile dump file.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/BasicBlock.h"
+#include "llvm/InstrTypes.h"
+#include "llvm/Pass.h"
+#include "llvm/Analysis/Passes.h"
+#include "llvm/Analysis/ProfileInfo.h"
+#include "llvm/Analysis/ProfileInfoLoader.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/Compiler.h"
+#include "llvm/Support/Streams.h"
+using namespace llvm;
+
+namespace {
+ cl::opt<std::string>
+ ProfileInfoFilename("profile-info-file", cl::init("llvmprof.out"),
+ cl::value_desc("filename"),
+ cl::desc("Profile file loaded by -profile-loader"));
+
+ class VISIBILITY_HIDDEN LoaderPass : public ModulePass, public ProfileInfo {
+ std::string Filename;
+ public:
+ static char ID; // Class identification, replacement for typeinfo
+ LoaderPass(const std::string &filename = "")
+ : ModulePass((intptr_t)&ID), Filename(filename) {
+ if (filename.empty()) Filename = ProfileInfoFilename;
+ }
+
+ virtual void getAnalysisUsage(AnalysisUsage &AU) const {
+ AU.setPreservesAll();
+ }
+
+ virtual const char *getPassName() const {
+ return "Profiling information loader";
+ }
+
+ /// run - Load the profile information from the specified file.
+ virtual bool runOnModule(Module &M);
+ };
+
+ char LoaderPass::ID = 0;
+ RegisterPass<LoaderPass>
+ X("profile-loader", "Load profile information from llvmprof.out");
+
+ RegisterAnalysisGroup<ProfileInfo> Y(X);
+} // End of anonymous namespace
+
+ModulePass *llvm::createProfileLoaderPass() { return new LoaderPass(); }
+
+/// createProfileLoaderPass - This function returns a Pass that loads the
+/// profiling information for the module from the specified filename, making it
+/// available to the optimizers.
+Pass *llvm::createProfileLoaderPass(const std::string &Filename) {
+ return new LoaderPass(Filename);
+}
+
+bool LoaderPass::runOnModule(Module &M) {
+ ProfileInfoLoader PIL("profile-loader", Filename, M);
+ EdgeCounts.clear();
+ bool PrintedWarning = false;
+
+ std::vector<std::pair<ProfileInfoLoader::Edge, unsigned> > ECs;
+ PIL.getEdgeCounts(ECs);
+ for (unsigned i = 0, e = ECs.size(); i != e; ++i) {
+ BasicBlock *BB = ECs[i].first.first;
+ unsigned SuccNum = ECs[i].first.second;
+ TerminatorInst *TI = BB->getTerminator();
+ if (SuccNum >= TI->getNumSuccessors()) {
+ if (!PrintedWarning) {
+ cerr << "WARNING: profile information is inconsistent with "
+ << "the current program!\n";
+ PrintedWarning = true;
+ }
+ } else {
+ EdgeCounts[std::make_pair(BB, TI->getSuccessor(SuccNum))]+= ECs[i].second;
+ }
+ }
+
+ return false;
+}
diff --git a/lib/Analysis/ScalarEvolution.cpp b/lib/Analysis/ScalarEvolution.cpp
new file mode 100644
index 0000000..0039144
--- /dev/null
+++ b/lib/Analysis/ScalarEvolution.cpp
@@ -0,0 +1,2656 @@
+//===- ScalarEvolution.cpp - Scalar Evolution Analysis ----------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains the implementation of the scalar evolution analysis
+// engine, which is used primarily to analyze expressions involving induction
+// variables in loops.
+//
+// There are several aspects to this library. First is the representation of
+// scalar expressions, which are represented as subclasses of the SCEV class.
+// These classes are used to represent certain types of subexpressions that we
+// can handle. These classes are reference counted, managed by the SCEVHandle
+// class. We only create one SCEV of a particular shape, so pointer-comparisons
+// for equality are legal.
+//
+// One important aspect of the SCEV objects is that they are never cyclic, even
+// if there is a cycle in the dataflow for an expression (ie, a PHI node). If
+// the PHI node is one of the idioms that we can represent (e.g., a polynomial
+// recurrence) then we represent it directly as a recurrence node, otherwise we
+// represent it as a SCEVUnknown node.
+//
+// In addition to being able to represent expressions of various types, we also
+// have folders that are used to build the *canonical* representation for a
+// particular expression. These folders are capable of using a variety of
+// rewrite rules to simplify the expressions.
+//
+// Once the folders are defined, we can implement the more interesting
+// higher-level code, such as the code that recognizes PHI nodes of various
+// types, computes the execution count of a loop, etc.
+//
+// TODO: We should use these routines and value representations to implement
+// dependence analysis!
+//
+//===----------------------------------------------------------------------===//
+//
+// There are several good references for the techniques used in this analysis.
+//
+// Chains of recurrences -- a method to expedite the evaluation
+// of closed-form functions
+// Olaf Bachmann, Paul S. Wang, Eugene V. Zima
+//
+// On computational properties of chains of recurrences
+// Eugene V. Zima
+//
+// Symbolic Evaluation of Chains of Recurrences for Loop Optimization
+// Robert A. van Engelen
+//
+// Efficient Symbolic Analysis for Optimizing Compilers
+// Robert A. van Engelen
+//
+// Using the chains of recurrences algebra for data dependence testing and
+// induction variable substitution
+// MS Thesis, Johnie Birch
+//
+//===----------------------------------------------------------------------===//
+
+#define DEBUG_TYPE "scalar-evolution"
+#include "llvm/Analysis/ScalarEvolutionExpressions.h"
+#include "llvm/Constants.h"
+#include "llvm/DerivedTypes.h"
+#include "llvm/GlobalVariable.h"
+#include "llvm/Instructions.h"
+#include "llvm/Analysis/ConstantFolding.h"
+#include "llvm/Analysis/LoopInfo.h"
+#include "llvm/Assembly/Writer.h"
+#include "llvm/Transforms/Scalar.h"
+#include "llvm/Support/CFG.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/Compiler.h"
+#include "llvm/Support/ConstantRange.h"
+#include "llvm/Support/InstIterator.h"
+#include "llvm/Support/ManagedStatic.h"
+#include "llvm/Support/MathExtras.h"
+#include "llvm/Support/Streams.h"
+#include "llvm/ADT/Statistic.h"
+#include <ostream>
+#include <algorithm>
+#include <cmath>
+using namespace llvm;
+
+STATISTIC(NumBruteForceEvaluations,
+ "Number of brute force evaluations needed to "
+ "calculate high-order polynomial exit values");
+STATISTIC(NumArrayLenItCounts,
+ "Number of trip counts computed with array length");
+STATISTIC(NumTripCountsComputed,
+ "Number of loops with predictable loop counts");
+STATISTIC(NumTripCountsNotComputed,
+ "Number of loops without predictable loop counts");
+STATISTIC(NumBruteForceTripCountsComputed,
+ "Number of loops with trip counts computed by force");
+
+cl::opt<unsigned>
+MaxBruteForceIterations("scalar-evolution-max-iterations", cl::ReallyHidden,
+ cl::desc("Maximum number of iterations SCEV will "
+ "symbolically execute a constant derived loop"),
+ cl::init(100));
+
+namespace {
+ RegisterPass<ScalarEvolution>
+ R("scalar-evolution", "Scalar Evolution Analysis");
+}
+char ScalarEvolution::ID = 0;
+
+//===----------------------------------------------------------------------===//
+// SCEV class definitions
+//===----------------------------------------------------------------------===//
+
+//===----------------------------------------------------------------------===//
+// Implementation of the SCEV class.
+//
+SCEV::~SCEV() {}
+void SCEV::dump() const {
+ print(cerr);
+}
+
+/// getValueRange - Return the tightest constant bounds that this value is
+/// known to have. This method is only valid on integer SCEV objects.
+ConstantRange SCEV::getValueRange() const {
+ const Type *Ty = getType();
+ assert(Ty->isInteger() && "Can't get range for a non-integer SCEV!");
+ // Default to a full range if no better information is available.
+ return ConstantRange(getBitWidth());
+}
+
+uint32_t SCEV::getBitWidth() const {
+ if (const IntegerType* ITy = dyn_cast<IntegerType>(getType()))
+ return ITy->getBitWidth();
+ return 0;
+}
+
+
+SCEVCouldNotCompute::SCEVCouldNotCompute() : SCEV(scCouldNotCompute) {}
+
+bool SCEVCouldNotCompute::isLoopInvariant(const Loop *L) const {
+ assert(0 && "Attempt to use a SCEVCouldNotCompute object!");
+ return false;
+}
+
+const Type *SCEVCouldNotCompute::getType() const {
+ assert(0 && "Attempt to use a SCEVCouldNotCompute object!");
+ return 0;
+}
+
+bool SCEVCouldNotCompute::hasComputableLoopEvolution(const Loop *L) const {
+ assert(0 && "Attempt to use a SCEVCouldNotCompute object!");
+ return false;
+}
+
+SCEVHandle SCEVCouldNotCompute::
+replaceSymbolicValuesWithConcrete(const SCEVHandle &Sym,
+ const SCEVHandle &Conc) const {
+ return this;
+}
+
+void SCEVCouldNotCompute::print(std::ostream &OS) const {
+ OS << "***COULDNOTCOMPUTE***";
+}
+
+bool SCEVCouldNotCompute::classof(const SCEV *S) {
+ return S->getSCEVType() == scCouldNotCompute;
+}
+
+
+// SCEVConstants - Only allow the creation of one SCEVConstant for any
+// particular value. Don't use a SCEVHandle here, or else the object will
+// never be deleted!
+static ManagedStatic<std::map<ConstantInt*, SCEVConstant*> > SCEVConstants;
+
+
+SCEVConstant::~SCEVConstant() {
+ SCEVConstants->erase(V);
+}
+
+SCEVHandle SCEVConstant::get(ConstantInt *V) {
+ SCEVConstant *&R = (*SCEVConstants)[V];
+ if (R == 0) R = new SCEVConstant(V);
+ return R;
+}
+
+SCEVHandle SCEVConstant::get(const APInt& Val) {
+ return get(ConstantInt::get(Val));
+}
+
+ConstantRange SCEVConstant::getValueRange() const {
+ return ConstantRange(V->getValue());
+}
+
+const Type *SCEVConstant::getType() const { return V->getType(); }
+
+void SCEVConstant::print(std::ostream &OS) const {
+ WriteAsOperand(OS, V, false);
+}
+
+// SCEVTruncates - Only allow the creation of one SCEVTruncateExpr for any
+// particular input. Don't use a SCEVHandle here, or else the object will
+// never be deleted!
+static ManagedStatic<std::map<std::pair<SCEV*, const Type*>,
+ SCEVTruncateExpr*> > SCEVTruncates;
+
+SCEVTruncateExpr::SCEVTruncateExpr(const SCEVHandle &op, const Type *ty)
+ : SCEV(scTruncate), Op(op), Ty(ty) {
+ assert(Op->getType()->isInteger() && Ty->isInteger() &&
+ "Cannot truncate non-integer value!");
+ assert(Op->getType()->getPrimitiveSizeInBits() > Ty->getPrimitiveSizeInBits()
+ && "This is not a truncating conversion!");
+}
+
+SCEVTruncateExpr::~SCEVTruncateExpr() {
+ SCEVTruncates->erase(std::make_pair(Op, Ty));
+}
+
+ConstantRange SCEVTruncateExpr::getValueRange() const {
+ return getOperand()->getValueRange().truncate(getBitWidth());
+}
+
+void SCEVTruncateExpr::print(std::ostream &OS) const {
+ OS << "(truncate " << *Op << " to " << *Ty << ")";
+}
+
+// SCEVZeroExtends - Only allow the creation of one SCEVZeroExtendExpr for any
+// particular input. Don't use a SCEVHandle here, or else the object will never
+// be deleted!
+static ManagedStatic<std::map<std::pair<SCEV*, const Type*>,
+ SCEVZeroExtendExpr*> > SCEVZeroExtends;
+
+SCEVZeroExtendExpr::SCEVZeroExtendExpr(const SCEVHandle &op, const Type *ty)
+ : SCEV(scZeroExtend), Op(op), Ty(ty) {
+ assert(Op->getType()->isInteger() && Ty->isInteger() &&
+ "Cannot zero extend non-integer value!");
+ assert(Op->getType()->getPrimitiveSizeInBits() < Ty->getPrimitiveSizeInBits()
+ && "This is not an extending conversion!");
+}
+
+SCEVZeroExtendExpr::~SCEVZeroExtendExpr() {
+ SCEVZeroExtends->erase(std::make_pair(Op, Ty));
+}
+
+ConstantRange SCEVZeroExtendExpr::getValueRange() const {
+ return getOperand()->getValueRange().zeroExtend(getBitWidth());
+}
+
+void SCEVZeroExtendExpr::print(std::ostream &OS) const {
+ OS << "(zeroextend " << *Op << " to " << *Ty << ")";
+}
+
+// SCEVSignExtends - Only allow the creation of one SCEVSignExtendExpr for any
+// particular input. Don't use a SCEVHandle here, or else the object will never
+// be deleted!
+static ManagedStatic<std::map<std::pair<SCEV*, const Type*>,
+ SCEVSignExtendExpr*> > SCEVSignExtends;
+
+SCEVSignExtendExpr::SCEVSignExtendExpr(const SCEVHandle &op, const Type *ty)
+ : SCEV(scSignExtend), Op(op), Ty(ty) {
+ assert(Op->getType()->isInteger() && Ty->isInteger() &&
+ "Cannot sign extend non-integer value!");
+ assert(Op->getType()->getPrimitiveSizeInBits() < Ty->getPrimitiveSizeInBits()
+ && "This is not an extending conversion!");
+}
+
+SCEVSignExtendExpr::~SCEVSignExtendExpr() {
+ SCEVSignExtends->erase(std::make_pair(Op, Ty));
+}
+
+ConstantRange SCEVSignExtendExpr::getValueRange() const {
+ return getOperand()->getValueRange().signExtend(getBitWidth());
+}
+
+void SCEVSignExtendExpr::print(std::ostream &OS) const {
+ OS << "(signextend " << *Op << " to " << *Ty << ")";
+}
+
+// SCEVCommExprs - Only allow the creation of one SCEVCommutativeExpr for any
+// particular input. Don't use a SCEVHandle here, or else the object will never
+// be deleted!
+static ManagedStatic<std::map<std::pair<unsigned, std::vector<SCEV*> >,
+ SCEVCommutativeExpr*> > SCEVCommExprs;
+
+SCEVCommutativeExpr::~SCEVCommutativeExpr() {
+ SCEVCommExprs->erase(std::make_pair(getSCEVType(),
+ std::vector<SCEV*>(Operands.begin(),
+ Operands.end())));
+}
+
+void SCEVCommutativeExpr::print(std::ostream &OS) const {
+ assert(Operands.size() > 1 && "This plus expr shouldn't exist!");
+ const char *OpStr = getOperationStr();
+ OS << "(" << *Operands[0];
+ for (unsigned i = 1, e = Operands.size(); i != e; ++i)
+ OS << OpStr << *Operands[i];
+ OS << ")";
+}
+
+SCEVHandle SCEVCommutativeExpr::
+replaceSymbolicValuesWithConcrete(const SCEVHandle &Sym,
+ const SCEVHandle &Conc) const {
+ for (unsigned i = 0, e = getNumOperands(); i != e; ++i) {
+ SCEVHandle H = getOperand(i)->replaceSymbolicValuesWithConcrete(Sym, Conc);
+ if (H != getOperand(i)) {
+ std::vector<SCEVHandle> NewOps;
+ NewOps.reserve(getNumOperands());
+ for (unsigned j = 0; j != i; ++j)
+ NewOps.push_back(getOperand(j));
+ NewOps.push_back(H);
+ for (++i; i != e; ++i)
+ NewOps.push_back(getOperand(i)->
+ replaceSymbolicValuesWithConcrete(Sym, Conc));
+
+ if (isa<SCEVAddExpr>(this))
+ return SCEVAddExpr::get(NewOps);
+ else if (isa<SCEVMulExpr>(this))
+ return SCEVMulExpr::get(NewOps);
+ else
+ assert(0 && "Unknown commutative expr!");
+ }
+ }
+ return this;
+}
+
+
+// SCEVSDivs - Only allow the creation of one SCEVSDivExpr for any particular
+// input. Don't use a SCEVHandle here, or else the object will never be
+// deleted!
+static ManagedStatic<std::map<std::pair<SCEV*, SCEV*>,
+ SCEVSDivExpr*> > SCEVSDivs;
+
+SCEVSDivExpr::~SCEVSDivExpr() {
+ SCEVSDivs->erase(std::make_pair(LHS, RHS));
+}
+
+void SCEVSDivExpr::print(std::ostream &OS) const {
+ OS << "(" << *LHS << " /s " << *RHS << ")";
+}
+
+const Type *SCEVSDivExpr::getType() const {
+ return LHS->getType();
+}
+
+// SCEVAddRecExprs - Only allow the creation of one SCEVAddRecExpr for any
+// particular input. Don't use a SCEVHandle here, or else the object will never
+// be deleted!
+static ManagedStatic<std::map<std::pair<const Loop *, std::vector<SCEV*> >,
+ SCEVAddRecExpr*> > SCEVAddRecExprs;
+
+SCEVAddRecExpr::~SCEVAddRecExpr() {
+ SCEVAddRecExprs->erase(std::make_pair(L,
+ std::vector<SCEV*>(Operands.begin(),
+ Operands.end())));
+}
+
+SCEVHandle SCEVAddRecExpr::
+replaceSymbolicValuesWithConcrete(const SCEVHandle &Sym,
+ const SCEVHandle &Conc) const {
+ for (unsigned i = 0, e = getNumOperands(); i != e; ++i) {
+ SCEVHandle H = getOperand(i)->replaceSymbolicValuesWithConcrete(Sym, Conc);
+ if (H != getOperand(i)) {
+ std::vector<SCEVHandle> NewOps;
+ NewOps.reserve(getNumOperands());
+ for (unsigned j = 0; j != i; ++j)
+ NewOps.push_back(getOperand(j));
+ NewOps.push_back(H);
+ for (++i; i != e; ++i)
+ NewOps.push_back(getOperand(i)->
+ replaceSymbolicValuesWithConcrete(Sym, Conc));
+
+ return get(NewOps, L);
+ }
+ }
+ return this;
+}
+
+
+bool SCEVAddRecExpr::isLoopInvariant(const Loop *QueryLoop) const {
+ // This recurrence is invariant w.r.t to QueryLoop iff QueryLoop doesn't
+ // contain L and if the start is invariant.
+ return !QueryLoop->contains(L->getHeader()) &&
+ getOperand(0)->isLoopInvariant(QueryLoop);
+}
+
+
+void SCEVAddRecExpr::print(std::ostream &OS) const {
+ OS << "{" << *Operands[0];
+ for (unsigned i = 1, e = Operands.size(); i != e; ++i)
+ OS << ",+," << *Operands[i];
+ OS << "}<" << L->getHeader()->getName() + ">";
+}
+
+// SCEVUnknowns - Only allow the creation of one SCEVUnknown for any particular
+// value. Don't use a SCEVHandle here, or else the object will never be
+// deleted!
+static ManagedStatic<std::map<Value*, SCEVUnknown*> > SCEVUnknowns;
+
+SCEVUnknown::~SCEVUnknown() { SCEVUnknowns->erase(V); }
+
+bool SCEVUnknown::isLoopInvariant(const Loop *L) const {
+ // All non-instruction values are loop invariant. All instructions are loop
+ // invariant if they are not contained in the specified loop.
+ if (Instruction *I = dyn_cast<Instruction>(V))
+ return !L->contains(I->getParent());
+ return true;
+}
+
+const Type *SCEVUnknown::getType() const {
+ return V->getType();
+}
+
+void SCEVUnknown::print(std::ostream &OS) const {
+ WriteAsOperand(OS, V, false);
+}
+
+//===----------------------------------------------------------------------===//
+// SCEV Utilities
+//===----------------------------------------------------------------------===//
+
+namespace {
+ /// SCEVComplexityCompare - Return true if the complexity of the LHS is less
+ /// than the complexity of the RHS. This comparator is used to canonicalize
+ /// expressions.
+ struct VISIBILITY_HIDDEN SCEVComplexityCompare {
+ bool operator()(SCEV *LHS, SCEV *RHS) {
+ return LHS->getSCEVType() < RHS->getSCEVType();
+ }
+ };
+}
+
+/// GroupByComplexity - Given a list of SCEV objects, order them by their
+/// complexity, and group objects of the same complexity together by value.
+/// When this routine is finished, we know that any duplicates in the vector are
+/// consecutive and that complexity is monotonically increasing.
+///
+/// Note that we go take special precautions to ensure that we get determinstic
+/// results from this routine. In other words, we don't want the results of
+/// this to depend on where the addresses of various SCEV objects happened to
+/// land in memory.
+///
+static void GroupByComplexity(std::vector<SCEVHandle> &Ops) {
+ if (Ops.size() < 2) return; // Noop
+ if (Ops.size() == 2) {
+ // This is the common case, which also happens to be trivially simple.
+ // Special case it.
+ if (Ops[0]->getSCEVType() > Ops[1]->getSCEVType())
+ std::swap(Ops[0], Ops[1]);
+ return;
+ }
+
+ // Do the rough sort by complexity.
+ std::sort(Ops.begin(), Ops.end(), SCEVComplexityCompare());
+
+ // Now that we are sorted by complexity, group elements of the same
+ // complexity. Note that this is, at worst, N^2, but the vector is likely to
+ // be extremely short in practice. Note that we take this approach because we
+ // do not want to depend on the addresses of the objects we are grouping.
+ for (unsigned i = 0, e = Ops.size(); i != e-2; ++i) {
+ SCEV *S = Ops[i];
+ unsigned Complexity = S->getSCEVType();
+
+ // If there are any objects of the same complexity and same value as this
+ // one, group them.
+ for (unsigned j = i+1; j != e && Ops[j]->getSCEVType() == Complexity; ++j) {
+ if (Ops[j] == S) { // Found a duplicate.
+ // Move it to immediately after i'th element.
+ std::swap(Ops[i+1], Ops[j]);
+ ++i; // no need to rescan it.
+ if (i == e-2) return; // Done!
+ }
+ }
+ }
+}
+
+
+
+//===----------------------------------------------------------------------===//
+// Simple SCEV method implementations
+//===----------------------------------------------------------------------===//
+
+/// getIntegerSCEV - Given an integer or FP type, create a constant for the
+/// specified signed integer value and return a SCEV for the constant.
+SCEVHandle SCEVUnknown::getIntegerSCEV(int Val, const Type *Ty) {
+ Constant *C;
+ if (Val == 0)
+ C = Constant::getNullValue(Ty);
+ else if (Ty->isFloatingPoint())
+ C = ConstantFP::get(Ty, Val);
+ else
+ C = ConstantInt::get(Ty, Val);
+ return SCEVUnknown::get(C);
+}
+
+/// getTruncateOrZeroExtend - Return a SCEV corresponding to a conversion of the
+/// input value to the specified type. If the type must be extended, it is zero
+/// extended.
+static SCEVHandle getTruncateOrZeroExtend(const SCEVHandle &V, const Type *Ty) {
+ const Type *SrcTy = V->getType();
+ assert(SrcTy->isInteger() && Ty->isInteger() &&
+ "Cannot truncate or zero extend with non-integer arguments!");
+ if (SrcTy->getPrimitiveSizeInBits() == Ty->getPrimitiveSizeInBits())
+ return V; // No conversion
+ if (SrcTy->getPrimitiveSizeInBits() > Ty->getPrimitiveSizeInBits())
+ return SCEVTruncateExpr::get(V, Ty);
+ return SCEVZeroExtendExpr::get(V, Ty);
+}
+
+/// getNegativeSCEV - Return a SCEV corresponding to -V = -1*V
+///
+SCEVHandle SCEV::getNegativeSCEV(const SCEVHandle &V) {
+ if (SCEVConstant *VC = dyn_cast<SCEVConstant>(V))
+ return SCEVUnknown::get(ConstantExpr::getNeg(VC->getValue()));
+
+ return SCEVMulExpr::get(V, SCEVUnknown::getIntegerSCEV(-1, V->getType()));
+}
+
+/// getMinusSCEV - Return a SCEV corresponding to LHS - RHS.
+///
+SCEVHandle SCEV::getMinusSCEV(const SCEVHandle &LHS, const SCEVHandle &RHS) {
+ // X - Y --> X + -Y
+ return SCEVAddExpr::get(LHS, SCEV::getNegativeSCEV(RHS));
+}
+
+
+/// PartialFact - Compute V!/(V-NumSteps)!
+static SCEVHandle PartialFact(SCEVHandle V, unsigned NumSteps) {
+ // Handle this case efficiently, it is common to have constant iteration
+ // counts while computing loop exit values.
+ if (SCEVConstant *SC = dyn_cast<SCEVConstant>(V)) {
+ const APInt& Val = SC->getValue()->getValue();
+ APInt Result(Val.getBitWidth(), 1);
+ for (; NumSteps; --NumSteps)
+ Result *= Val-(NumSteps-1);
+ return SCEVConstant::get(Result);
+ }
+
+ const Type *Ty = V->getType();
+ if (NumSteps == 0)
+ return SCEVUnknown::getIntegerSCEV(1, Ty);
+
+ SCEVHandle Result = V;
+ for (unsigned i = 1; i != NumSteps; ++i)
+ Result = SCEVMulExpr::get(Result, SCEV::getMinusSCEV(V,
+ SCEVUnknown::getIntegerSCEV(i, Ty)));
+ return Result;
+}
+
+
+/// evaluateAtIteration - Return the value of this chain of recurrences at
+/// the specified iteration number. We can evaluate this recurrence by
+/// multiplying each element in the chain by the binomial coefficient
+/// corresponding to it. In other words, we can evaluate {A,+,B,+,C,+,D} as:
+///
+/// A*choose(It, 0) + B*choose(It, 1) + C*choose(It, 2) + D*choose(It, 3)
+///
+/// FIXME/VERIFY: I don't trust that this is correct in the face of overflow.
+/// Is the binomial equation safe using modular arithmetic??
+///
+SCEVHandle SCEVAddRecExpr::evaluateAtIteration(SCEVHandle It) const {
+ SCEVHandle Result = getStart();
+ int Divisor = 1;
+ const Type *Ty = It->getType();
+ for (unsigned i = 1, e = getNumOperands(); i != e; ++i) {
+ SCEVHandle BC = PartialFact(It, i);
+ Divisor *= i;
+ SCEVHandle Val = SCEVSDivExpr::get(SCEVMulExpr::get(BC, getOperand(i)),
+ SCEVUnknown::getIntegerSCEV(Divisor,Ty));
+ Result = SCEVAddExpr::get(Result, Val);
+ }
+ return Result;
+}
+
+
+//===----------------------------------------------------------------------===//
+// SCEV Expression folder implementations
+//===----------------------------------------------------------------------===//
+
+SCEVHandle SCEVTruncateExpr::get(const SCEVHandle &Op, const Type *Ty) {
+ if (SCEVConstant *SC = dyn_cast<SCEVConstant>(Op))
+ return SCEVUnknown::get(
+ ConstantExpr::getTrunc(SC->getValue(), Ty));
+
+ // If the input value is a chrec scev made out of constants, truncate
+ // all of the constants.
+ if (SCEVAddRecExpr *AddRec = dyn_cast<SCEVAddRecExpr>(Op)) {
+ std::vector<SCEVHandle> Operands;
+ for (unsigned i = 0, e = AddRec->getNumOperands(); i != e; ++i)
+ // FIXME: This should allow truncation of other expression types!
+ if (isa<SCEVConstant>(AddRec->getOperand(i)))
+ Operands.push_back(get(AddRec->getOperand(i), Ty));
+ else
+ break;
+ if (Operands.size() == AddRec->getNumOperands())
+ return SCEVAddRecExpr::get(Operands, AddRec->getLoop());
+ }
+
+ SCEVTruncateExpr *&Result = (*SCEVTruncates)[std::make_pair(Op, Ty)];
+ if (Result == 0) Result = new SCEVTruncateExpr(Op, Ty);
+ return Result;
+}
+
+SCEVHandle SCEVZeroExtendExpr::get(const SCEVHandle &Op, const Type *Ty) {
+ if (SCEVConstant *SC = dyn_cast<SCEVConstant>(Op))
+ return SCEVUnknown::get(
+ ConstantExpr::getZExt(SC->getValue(), Ty));
+
+ // FIXME: If the input value is a chrec scev, and we can prove that the value
+ // did not overflow the old, smaller, value, we can zero extend all of the
+ // operands (often constants). This would allow analysis of something like
+ // this: for (unsigned char X = 0; X < 100; ++X) { int Y = X; }
+
+ SCEVZeroExtendExpr *&Result = (*SCEVZeroExtends)[std::make_pair(Op, Ty)];
+ if (Result == 0) Result = new SCEVZeroExtendExpr(Op, Ty);
+ return Result;
+}
+
+SCEVHandle SCEVSignExtendExpr::get(const SCEVHandle &Op, const Type *Ty) {
+ if (SCEVConstant *SC = dyn_cast<SCEVConstant>(Op))
+ return SCEVUnknown::get(
+ ConstantExpr::getSExt(SC->getValue(), Ty));
+
+ // FIXME: If the input value is a chrec scev, and we can prove that the value
+ // did not overflow the old, smaller, value, we can sign extend all of the
+ // operands (often constants). This would allow analysis of something like
+ // this: for (signed char X = 0; X < 100; ++X) { int Y = X; }
+
+ SCEVSignExtendExpr *&Result = (*SCEVSignExtends)[std::make_pair(Op, Ty)];
+ if (Result == 0) Result = new SCEVSignExtendExpr(Op, Ty);
+ return Result;
+}
+
+// get - Get a canonical add expression, or something simpler if possible.
+SCEVHandle SCEVAddExpr::get(std::vector<SCEVHandle> &Ops) {
+ assert(!Ops.empty() && "Cannot get empty add!");
+ if (Ops.size() == 1) return Ops[0];
+
+ // Sort by complexity, this groups all similar expression types together.
+ GroupByComplexity(Ops);
+
+ // If there are any constants, fold them together.
+ unsigned Idx = 0;
+ if (SCEVConstant *LHSC = dyn_cast<SCEVConstant>(Ops[0])) {
+ ++Idx;
+ assert(Idx < Ops.size());
+ while (SCEVConstant *RHSC = dyn_cast<SCEVConstant>(Ops[Idx])) {
+ // We found two constants, fold them together!
+ Constant *Fold = ConstantInt::get(LHSC->getValue()->getValue() +
+ RHSC->getValue()->getValue());
+ if (ConstantInt *CI = dyn_cast<ConstantInt>(Fold)) {
+ Ops[0] = SCEVConstant::get(CI);
+ Ops.erase(Ops.begin()+1); // Erase the folded element
+ if (Ops.size() == 1) return Ops[0];
+ LHSC = cast<SCEVConstant>(Ops[0]);
+ } else {
+ // If we couldn't fold the expression, move to the next constant. Note
+ // that this is impossible to happen in practice because we always
+ // constant fold constant ints to constant ints.
+ ++Idx;
+ }
+ }
+
+ // If we are left with a constant zero being added, strip it off.
+ if (cast<SCEVConstant>(Ops[0])->getValue()->isZero()) {
+ Ops.erase(Ops.begin());
+ --Idx;
+ }
+ }
+
+ if (Ops.size() == 1) return Ops[0];
+
+ // Okay, check to see if the same value occurs in the operand list twice. If
+ // so, merge them together into an multiply expression. Since we sorted the
+ // list, these values are required to be adjacent.
+ const Type *Ty = Ops[0]->getType();
+ for (unsigned i = 0, e = Ops.size()-1; i != e; ++i)
+ if (Ops[i] == Ops[i+1]) { // X + Y + Y --> X + Y*2
+ // Found a match, merge the two values into a multiply, and add any
+ // remaining values to the result.
+ SCEVHandle Two = SCEVUnknown::getIntegerSCEV(2, Ty);
+ SCEVHandle Mul = SCEVMulExpr::get(Ops[i], Two);
+ if (Ops.size() == 2)
+ return Mul;
+ Ops.erase(Ops.begin()+i, Ops.begin()+i+2);
+ Ops.push_back(Mul);
+ return SCEVAddExpr::get(Ops);
+ }
+
+ // Now we know the first non-constant operand. Skip past any cast SCEVs.
+ while (Idx < Ops.size() && Ops[Idx]->getSCEVType() < scAddExpr)
+ ++Idx;
+
+ // If there are add operands they would be next.
+ if (Idx < Ops.size()) {
+ bool DeletedAdd = false;
+ while (SCEVAddExpr *Add = dyn_cast<SCEVAddExpr>(Ops[Idx])) {
+ // If we have an add, expand the add operands onto the end of the operands
+ // list.
+ Ops.insert(Ops.end(), Add->op_begin(), Add->op_end());
+ Ops.erase(Ops.begin()+Idx);
+ DeletedAdd = true;
+ }
+
+ // If we deleted at least one add, we added operands to the end of the list,
+ // and they are not necessarily sorted. Recurse to resort and resimplify
+ // any operands we just aquired.
+ if (DeletedAdd)
+ return get(Ops);
+ }
+
+ // Skip over the add expression until we get to a multiply.
+ while (Idx < Ops.size() && Ops[Idx]->getSCEVType() < scMulExpr)
+ ++Idx;
+
+ // If we are adding something to a multiply expression, make sure the
+ // something is not already an operand of the multiply. If so, merge it into
+ // the multiply.
+ for (; Idx < Ops.size() && isa<SCEVMulExpr>(Ops[Idx]); ++Idx) {
+ SCEVMulExpr *Mul = cast<SCEVMulExpr>(Ops[Idx]);
+ for (unsigned MulOp = 0, e = Mul->getNumOperands(); MulOp != e; ++MulOp) {
+ SCEV *MulOpSCEV = Mul->getOperand(MulOp);
+ for (unsigned AddOp = 0, e = Ops.size(); AddOp != e; ++AddOp)
+ if (MulOpSCEV == Ops[AddOp] && !isa<SCEVConstant>(MulOpSCEV)) {
+ // Fold W + X + (X * Y * Z) --> W + (X * ((Y*Z)+1))
+ SCEVHandle InnerMul = Mul->getOperand(MulOp == 0);
+ if (Mul->getNumOperands() != 2) {
+ // If the multiply has more than two operands, we must get the
+ // Y*Z term.
+ std::vector<SCEVHandle> MulOps(Mul->op_begin(), Mul->op_end());
+ MulOps.erase(MulOps.begin()+MulOp);
+ InnerMul = SCEVMulExpr::get(MulOps);
+ }
+ SCEVHandle One = SCEVUnknown::getIntegerSCEV(1, Ty);
+ SCEVHandle AddOne = SCEVAddExpr::get(InnerMul, One);
+ SCEVHandle OuterMul = SCEVMulExpr::get(AddOne, Ops[AddOp]);
+ if (Ops.size() == 2) return OuterMul;
+ if (AddOp < Idx) {
+ Ops.erase(Ops.begin()+AddOp);
+ Ops.erase(Ops.begin()+Idx-1);
+ } else {
+ Ops.erase(Ops.begin()+Idx);
+ Ops.erase(Ops.begin()+AddOp-1);
+ }
+ Ops.push_back(OuterMul);
+ return SCEVAddExpr::get(Ops);
+ }
+
+ // Check this multiply against other multiplies being added together.
+ for (unsigned OtherMulIdx = Idx+1;
+ OtherMulIdx < Ops.size() && isa<SCEVMulExpr>(Ops[OtherMulIdx]);
+ ++OtherMulIdx) {
+ SCEVMulExpr *OtherMul = cast<SCEVMulExpr>(Ops[OtherMulIdx]);
+ // If MulOp occurs in OtherMul, we can fold the two multiplies
+ // together.
+ for (unsigned OMulOp = 0, e = OtherMul->getNumOperands();
+ OMulOp != e; ++OMulOp)
+ if (OtherMul->getOperand(OMulOp) == MulOpSCEV) {
+ // Fold X + (A*B*C) + (A*D*E) --> X + (A*(B*C+D*E))
+ SCEVHandle InnerMul1 = Mul->getOperand(MulOp == 0);
+ if (Mul->getNumOperands() != 2) {
+ std::vector<SCEVHandle> MulOps(Mul->op_begin(), Mul->op_end());
+ MulOps.erase(MulOps.begin()+MulOp);
+ InnerMul1 = SCEVMulExpr::get(MulOps);
+ }
+ SCEVHandle InnerMul2 = OtherMul->getOperand(OMulOp == 0);
+ if (OtherMul->getNumOperands() != 2) {
+ std::vector<SCEVHandle> MulOps(OtherMul->op_begin(),
+ OtherMul->op_end());
+ MulOps.erase(MulOps.begin()+OMulOp);
+ InnerMul2 = SCEVMulExpr::get(MulOps);
+ }
+ SCEVHandle InnerMulSum = SCEVAddExpr::get(InnerMul1,InnerMul2);
+ SCEVHandle OuterMul = SCEVMulExpr::get(MulOpSCEV, InnerMulSum);
+ if (Ops.size() == 2) return OuterMul;
+ Ops.erase(Ops.begin()+Idx);
+ Ops.erase(Ops.begin()+OtherMulIdx-1);
+ Ops.push_back(OuterMul);
+ return SCEVAddExpr::get(Ops);
+ }
+ }
+ }
+ }
+
+ // If there are any add recurrences in the operands list, see if any other
+ // added values are loop invariant. If so, we can fold them into the
+ // recurrence.
+ while (Idx < Ops.size() && Ops[Idx]->getSCEVType() < scAddRecExpr)
+ ++Idx;
+
+ // Scan over all recurrences, trying to fold loop invariants into them.
+ for (; Idx < Ops.size() && isa<SCEVAddRecExpr>(Ops[Idx]); ++Idx) {
+ // Scan all of the other operands to this add and add them to the vector if
+ // they are loop invariant w.r.t. the recurrence.
+ std::vector<SCEVHandle> LIOps;
+ SCEVAddRecExpr *AddRec = cast<SCEVAddRecExpr>(Ops[Idx]);
+ for (unsigned i = 0, e = Ops.size(); i != e; ++i)
+ if (Ops[i]->isLoopInvariant(AddRec->getLoop())) {
+ LIOps.push_back(Ops[i]);
+ Ops.erase(Ops.begin()+i);
+ --i; --e;
+ }
+
+ // If we found some loop invariants, fold them into the recurrence.
+ if (!LIOps.empty()) {
+ // NLI + LI + { Start,+,Step} --> NLI + { LI+Start,+,Step }
+ LIOps.push_back(AddRec->getStart());
+
+ std::vector<SCEVHandle> AddRecOps(AddRec->op_begin(), AddRec->op_end());
+ AddRecOps[0] = SCEVAddExpr::get(LIOps);
+
+ SCEVHandle NewRec = SCEVAddRecExpr::get(AddRecOps, AddRec->getLoop());
+ // If all of the other operands were loop invariant, we are done.
+ if (Ops.size() == 1) return NewRec;
+
+ // Otherwise, add the folded AddRec by the non-liv parts.
+ for (unsigned i = 0;; ++i)
+ if (Ops[i] == AddRec) {
+ Ops[i] = NewRec;
+ break;
+ }
+ return SCEVAddExpr::get(Ops);
+ }
+
+ // Okay, if there weren't any loop invariants to be folded, check to see if
+ // there are multiple AddRec's with the same loop induction variable being
+ // added together. If so, we can fold them.
+ for (unsigned OtherIdx = Idx+1;
+ OtherIdx < Ops.size() && isa<SCEVAddRecExpr>(Ops[OtherIdx]);++OtherIdx)
+ if (OtherIdx != Idx) {
+ SCEVAddRecExpr *OtherAddRec = cast<SCEVAddRecExpr>(Ops[OtherIdx]);
+ if (AddRec->getLoop() == OtherAddRec->getLoop()) {
+ // Other + {A,+,B} + {C,+,D} --> Other + {A+C,+,B+D}
+ std::vector<SCEVHandle> NewOps(AddRec->op_begin(), AddRec->op_end());
+ for (unsigned i = 0, e = OtherAddRec->getNumOperands(); i != e; ++i) {
+ if (i >= NewOps.size()) {
+ NewOps.insert(NewOps.end(), OtherAddRec->op_begin()+i,
+ OtherAddRec->op_end());
+ break;
+ }
+ NewOps[i] = SCEVAddExpr::get(NewOps[i], OtherAddRec->getOperand(i));
+ }
+ SCEVHandle NewAddRec = SCEVAddRecExpr::get(NewOps, AddRec->getLoop());
+
+ if (Ops.size() == 2) return NewAddRec;
+
+ Ops.erase(Ops.begin()+Idx);
+ Ops.erase(Ops.begin()+OtherIdx-1);
+ Ops.push_back(NewAddRec);
+ return SCEVAddExpr::get(Ops);
+ }
+ }
+
+ // Otherwise couldn't fold anything into this recurrence. Move onto the
+ // next one.
+ }
+
+ // Okay, it looks like we really DO need an add expr. Check to see if we
+ // already have one, otherwise create a new one.
+ std::vector<SCEV*> SCEVOps(Ops.begin(), Ops.end());
+ SCEVCommutativeExpr *&Result = (*SCEVCommExprs)[std::make_pair(scAddExpr,
+ SCEVOps)];
+ if (Result == 0) Result = new SCEVAddExpr(Ops);
+ return Result;
+}
+
+
+SCEVHandle SCEVMulExpr::get(std::vector<SCEVHandle> &Ops) {
+ assert(!Ops.empty() && "Cannot get empty mul!");
+
+ // Sort by complexity, this groups all similar expression types together.
+ GroupByComplexity(Ops);
+
+ // If there are any constants, fold them together.
+ unsigned Idx = 0;
+ if (SCEVConstant *LHSC = dyn_cast<SCEVConstant>(Ops[0])) {
+
+ // C1*(C2+V) -> C1*C2 + C1*V
+ if (Ops.size() == 2)
+ if (SCEVAddExpr *Add = dyn_cast<SCEVAddExpr>(Ops[1]))
+ if (Add->getNumOperands() == 2 &&
+ isa<SCEVConstant>(Add->getOperand(0)))
+ return SCEVAddExpr::get(SCEVMulExpr::get(LHSC, Add->getOperand(0)),
+ SCEVMulExpr::get(LHSC, Add->getOperand(1)));
+
+
+ ++Idx;
+ while (SCEVConstant *RHSC = dyn_cast<SCEVConstant>(Ops[Idx])) {
+ // We found two constants, fold them together!
+ Constant *Fold = ConstantInt::get(LHSC->getValue()->getValue() *
+ RHSC->getValue()->getValue());
+ if (ConstantInt *CI = dyn_cast<ConstantInt>(Fold)) {
+ Ops[0] = SCEVConstant::get(CI);
+ Ops.erase(Ops.begin()+1); // Erase the folded element
+ if (Ops.size() == 1) return Ops[0];
+ LHSC = cast<SCEVConstant>(Ops[0]);
+ } else {
+ // If we couldn't fold the expression, move to the next constant. Note
+ // that this is impossible to happen in practice because we always
+ // constant fold constant ints to constant ints.
+ ++Idx;
+ }
+ }
+
+ // If we are left with a constant one being multiplied, strip it off.
+ if (cast<SCEVConstant>(Ops[0])->getValue()->equalsInt(1)) {
+ Ops.erase(Ops.begin());
+ --Idx;
+ } else if (cast<SCEVConstant>(Ops[0])->getValue()->isZero()) {
+ // If we have a multiply of zero, it will always be zero.
+ return Ops[0];
+ }
+ }
+
+ // Skip over the add expression until we get to a multiply.
+ while (Idx < Ops.size() && Ops[Idx]->getSCEVType() < scMulExpr)
+ ++Idx;
+
+ if (Ops.size() == 1)
+ return Ops[0];
+
+ // If there are mul operands inline them all into this expression.
+ if (Idx < Ops.size()) {
+ bool DeletedMul = false;
+ while (SCEVMulExpr *Mul = dyn_cast<SCEVMulExpr>(Ops[Idx])) {
+ // If we have an mul, expand the mul operands onto the end of the operands
+ // list.
+ Ops.insert(Ops.end(), Mul->op_begin(), Mul->op_end());
+ Ops.erase(Ops.begin()+Idx);
+ DeletedMul = true;
+ }
+
+ // If we deleted at least one mul, we added operands to the end of the list,
+ // and they are not necessarily sorted. Recurse to resort and resimplify
+ // any operands we just aquired.
+ if (DeletedMul)
+ return get(Ops);
+ }
+
+ // If there are any add recurrences in the operands list, see if any other
+ // added values are loop invariant. If so, we can fold them into the
+ // recurrence.
+ while (Idx < Ops.size() && Ops[Idx]->getSCEVType() < scAddRecExpr)
+ ++Idx;
+
+ // Scan over all recurrences, trying to fold loop invariants into them.
+ for (; Idx < Ops.size() && isa<SCEVAddRecExpr>(Ops[Idx]); ++Idx) {
+ // Scan all of the other operands to this mul and add them to the vector if
+ // they are loop invariant w.r.t. the recurrence.
+ std::vector<SCEVHandle> LIOps;
+ SCEVAddRecExpr *AddRec = cast<SCEVAddRecExpr>(Ops[Idx]);
+ for (unsigned i = 0, e = Ops.size(); i != e; ++i)
+ if (Ops[i]->isLoopInvariant(AddRec->getLoop())) {
+ LIOps.push_back(Ops[i]);
+ Ops.erase(Ops.begin()+i);
+ --i; --e;
+ }
+
+ // If we found some loop invariants, fold them into the recurrence.
+ if (!LIOps.empty()) {
+ // NLI * LI * { Start,+,Step} --> NLI * { LI*Start,+,LI*Step }
+ std::vector<SCEVHandle> NewOps;
+ NewOps.reserve(AddRec->getNumOperands());
+ if (LIOps.size() == 1) {
+ SCEV *Scale = LIOps[0];
+ for (unsigned i = 0, e = AddRec->getNumOperands(); i != e; ++i)
+ NewOps.push_back(SCEVMulExpr::get(Scale, AddRec->getOperand(i)));
+ } else {
+ for (unsigned i = 0, e = AddRec->getNumOperands(); i != e; ++i) {
+ std::vector<SCEVHandle> MulOps(LIOps);
+ MulOps.push_back(AddRec->getOperand(i));
+ NewOps.push_back(SCEVMulExpr::get(MulOps));
+ }
+ }
+
+ SCEVHandle NewRec = SCEVAddRecExpr::get(NewOps, AddRec->getLoop());
+
+ // If all of the other operands were loop invariant, we are done.
+ if (Ops.size() == 1) return NewRec;
+
+ // Otherwise, multiply the folded AddRec by the non-liv parts.
+ for (unsigned i = 0;; ++i)
+ if (Ops[i] == AddRec) {
+ Ops[i] = NewRec;
+ break;
+ }
+ return SCEVMulExpr::get(Ops);
+ }
+
+ // Okay, if there weren't any loop invariants to be folded, check to see if
+ // there are multiple AddRec's with the same loop induction variable being
+ // multiplied together. If so, we can fold them.
+ for (unsigned OtherIdx = Idx+1;
+ OtherIdx < Ops.size() && isa<SCEVAddRecExpr>(Ops[OtherIdx]);++OtherIdx)
+ if (OtherIdx != Idx) {
+ SCEVAddRecExpr *OtherAddRec = cast<SCEVAddRecExpr>(Ops[OtherIdx]);
+ if (AddRec->getLoop() == OtherAddRec->getLoop()) {
+ // F * G --> {A,+,B} * {C,+,D} --> {A*C,+,F*D + G*B + B*D}
+ SCEVAddRecExpr *F = AddRec, *G = OtherAddRec;
+ SCEVHandle NewStart = SCEVMulExpr::get(F->getStart(),
+ G->getStart());
+ SCEVHandle B = F->getStepRecurrence();
+ SCEVHandle D = G->getStepRecurrence();
+ SCEVHandle NewStep = SCEVAddExpr::get(SCEVMulExpr::get(F, D),
+ SCEVMulExpr::get(G, B),
+ SCEVMulExpr::get(B, D));
+ SCEVHandle NewAddRec = SCEVAddRecExpr::get(NewStart, NewStep,
+ F->getLoop());
+ if (Ops.size() == 2) return NewAddRec;
+
+ Ops.erase(Ops.begin()+Idx);
+ Ops.erase(Ops.begin()+OtherIdx-1);
+ Ops.push_back(NewAddRec);
+ return SCEVMulExpr::get(Ops);
+ }
+ }
+
+ // Otherwise couldn't fold anything into this recurrence. Move onto the
+ // next one.
+ }
+
+ // Okay, it looks like we really DO need an mul expr. Check to see if we
+ // already have one, otherwise create a new one.
+ std::vector<SCEV*> SCEVOps(Ops.begin(), Ops.end());
+ SCEVCommutativeExpr *&Result = (*SCEVCommExprs)[std::make_pair(scMulExpr,
+ SCEVOps)];
+ if (Result == 0)
+ Result = new SCEVMulExpr(Ops);
+ return Result;
+}
+
+SCEVHandle SCEVSDivExpr::get(const SCEVHandle &LHS, const SCEVHandle &RHS) {
+ if (SCEVConstant *RHSC = dyn_cast<SCEVConstant>(RHS)) {
+ if (RHSC->getValue()->equalsInt(1))
+ return LHS; // X sdiv 1 --> x
+ if (RHSC->getValue()->isAllOnesValue())
+ return SCEV::getNegativeSCEV(LHS); // X sdiv -1 --> -x
+
+ if (SCEVConstant *LHSC = dyn_cast<SCEVConstant>(LHS)) {
+ Constant *LHSCV = LHSC->getValue();
+ Constant *RHSCV = RHSC->getValue();
+ return SCEVUnknown::get(ConstantExpr::getSDiv(LHSCV, RHSCV));
+ }
+ }
+
+ // FIXME: implement folding of (X*4)/4 when we know X*4 doesn't overflow.
+
+ SCEVSDivExpr *&Result = (*SCEVSDivs)[std::make_pair(LHS, RHS)];
+ if (Result == 0) Result = new SCEVSDivExpr(LHS, RHS);
+ return Result;
+}
+
+
+/// SCEVAddRecExpr::get - Get a add recurrence expression for the
+/// specified loop. Simplify the expression as much as possible.
+SCEVHandle SCEVAddRecExpr::get(const SCEVHandle &Start,
+ const SCEVHandle &Step, const Loop *L) {
+ std::vector<SCEVHandle> Operands;
+ Operands.push_back(Start);
+ if (SCEVAddRecExpr *StepChrec = dyn_cast<SCEVAddRecExpr>(Step))
+ if (StepChrec->getLoop() == L) {
+ Operands.insert(Operands.end(), StepChrec->op_begin(),
+ StepChrec->op_end());
+ return get(Operands, L);
+ }
+
+ Operands.push_back(Step);
+ return get(Operands, L);
+}
+
+/// SCEVAddRecExpr::get - Get a add recurrence expression for the
+/// specified loop. Simplify the expression as much as possible.
+SCEVHandle SCEVAddRecExpr::get(std::vector<SCEVHandle> &Operands,
+ const Loop *L) {
+ if (Operands.size() == 1) return Operands[0];
+
+ if (SCEVConstant *StepC = dyn_cast<SCEVConstant>(Operands.back()))
+ if (StepC->getValue()->isZero()) {
+ Operands.pop_back();
+ return get(Operands, L); // { X,+,0 } --> X
+ }
+
+ SCEVAddRecExpr *&Result =
+ (*SCEVAddRecExprs)[std::make_pair(L, std::vector<SCEV*>(Operands.begin(),
+ Operands.end()))];
+ if (Result == 0) Result = new SCEVAddRecExpr(Operands, L);
+ return Result;
+}
+
+SCEVHandle SCEVUnknown::get(Value *V) {
+ if (ConstantInt *CI = dyn_cast<ConstantInt>(V))
+ return SCEVConstant::get(CI);
+ SCEVUnknown *&Result = (*SCEVUnknowns)[V];
+ if (Result == 0) Result = new SCEVUnknown(V);
+ return Result;
+}
+
+
+//===----------------------------------------------------------------------===//
+// ScalarEvolutionsImpl Definition and Implementation
+//===----------------------------------------------------------------------===//
+//
+/// ScalarEvolutionsImpl - This class implements the main driver for the scalar
+/// evolution code.
+///
+namespace {
+ struct VISIBILITY_HIDDEN ScalarEvolutionsImpl {
+ /// F - The function we are analyzing.
+ ///
+ Function &F;
+
+ /// LI - The loop information for the function we are currently analyzing.
+ ///
+ LoopInfo &LI;
+
+ /// UnknownValue - This SCEV is used to represent unknown trip counts and
+ /// things.
+ SCEVHandle UnknownValue;
+
+ /// Scalars - This is a cache of the scalars we have analyzed so far.
+ ///
+ std::map<Value*, SCEVHandle> Scalars;
+
+ /// IterationCounts - Cache the iteration count of the loops for this
+ /// function as they are computed.
+ std::map<const Loop*, SCEVHandle> IterationCounts;
+
+ /// ConstantEvolutionLoopExitValue - This map contains entries for all of
+ /// the PHI instructions that we attempt to compute constant evolutions for.
+ /// This allows us to avoid potentially expensive recomputation of these
+ /// properties. An instruction maps to null if we are unable to compute its
+ /// exit value.
+ std::map<PHINode*, Constant*> ConstantEvolutionLoopExitValue;
+
+ public:
+ ScalarEvolutionsImpl(Function &f, LoopInfo &li)
+ : F(f), LI(li), UnknownValue(new SCEVCouldNotCompute()) {}
+
+ /// getSCEV - Return an existing SCEV if it exists, otherwise analyze the
+ /// expression and create a new one.
+ SCEVHandle getSCEV(Value *V);
+
+ /// hasSCEV - Return true if the SCEV for this value has already been
+ /// computed.
+ bool hasSCEV(Value *V) const {
+ return Scalars.count(V);
+ }
+
+ /// setSCEV - Insert the specified SCEV into the map of current SCEVs for
+ /// the specified value.
+ void setSCEV(Value *V, const SCEVHandle &H) {
+ bool isNew = Scalars.insert(std::make_pair(V, H)).second;
+ assert(isNew && "This entry already existed!");
+ }
+
+
+ /// getSCEVAtScope - Compute the value of the specified expression within
+ /// the indicated loop (which may be null to indicate in no loop). If the
+ /// expression cannot be evaluated, return UnknownValue itself.
+ SCEVHandle getSCEVAtScope(SCEV *V, const Loop *L);
+
+
+ /// hasLoopInvariantIterationCount - Return true if the specified loop has
+ /// an analyzable loop-invariant iteration count.
+ bool hasLoopInvariantIterationCount(const Loop *L);
+
+ /// getIterationCount - If the specified loop has a predictable iteration
+ /// count, return it. Note that it is not valid to call this method on a
+ /// loop without a loop-invariant iteration count.
+ SCEVHandle getIterationCount(const Loop *L);
+
+ /// deleteValueFromRecords - This method should be called by the
+ /// client before it removes a value from the program, to make sure
+ /// that no dangling references are left around.
+ void deleteValueFromRecords(Value *V);
+
+ private:
+ /// createSCEV - We know that there is no SCEV for the specified value.
+ /// Analyze the expression.
+ SCEVHandle createSCEV(Value *V);
+
+ /// createNodeForPHI - Provide the special handling we need to analyze PHI
+ /// SCEVs.
+ SCEVHandle createNodeForPHI(PHINode *PN);
+
+ /// ReplaceSymbolicValueWithConcrete - This looks up the computed SCEV value
+ /// for the specified instruction and replaces any references to the
+ /// symbolic value SymName with the specified value. This is used during
+ /// PHI resolution.
+ void ReplaceSymbolicValueWithConcrete(Instruction *I,
+ const SCEVHandle &SymName,
+ const SCEVHandle &NewVal);
+
+ /// ComputeIterationCount - Compute the number of times the specified loop
+ /// will iterate.
+ SCEVHandle ComputeIterationCount(const Loop *L);
+
+ /// ComputeLoadConstantCompareIterationCount - Given an exit condition of
+ /// 'setcc load X, cst', try to see if we can compute the trip count.
+ SCEVHandle ComputeLoadConstantCompareIterationCount(LoadInst *LI,
+ Constant *RHS,
+ const Loop *L,
+ ICmpInst::Predicate p);
+
+ /// ComputeIterationCountExhaustively - If the trip is known to execute a
+ /// constant number of times (the condition evolves only from constants),
+ /// try to evaluate a few iterations of the loop until we get the exit
+ /// condition gets a value of ExitWhen (true or false). If we cannot
+ /// evaluate the trip count of the loop, return UnknownValue.
+ SCEVHandle ComputeIterationCountExhaustively(const Loop *L, Value *Cond,
+ bool ExitWhen);
+
+ /// HowFarToZero - Return the number of times a backedge comparing the
+ /// specified value to zero will execute. If not computable, return
+ /// UnknownValue.
+ SCEVHandle HowFarToZero(SCEV *V, const Loop *L);
+
+ /// HowFarToNonZero - Return the number of times a backedge checking the
+ /// specified value for nonzero will execute. If not computable, return
+ /// UnknownValue.
+ SCEVHandle HowFarToNonZero(SCEV *V, const Loop *L);
+
+ /// HowManyLessThans - Return the number of times a backedge containing the
+ /// specified less-than comparison will execute. If not computable, return
+ /// UnknownValue.
+ SCEVHandle HowManyLessThans(SCEV *LHS, SCEV *RHS, const Loop *L);
+
+ /// getConstantEvolutionLoopExitValue - If we know that the specified Phi is
+ /// in the header of its containing loop, we know the loop executes a
+ /// constant number of times, and the PHI node is just a recurrence
+ /// involving constants, fold it.
+ Constant *getConstantEvolutionLoopExitValue(PHINode *PN, const APInt& Its,
+ const Loop *L);
+ };
+}
+
+//===----------------------------------------------------------------------===//
+// Basic SCEV Analysis and PHI Idiom Recognition Code
+//
+
+/// deleteValueFromRecords - This method should be called by the
+/// client before it removes an instruction from the program, to make sure
+/// that no dangling references are left around.
+void ScalarEvolutionsImpl::deleteValueFromRecords(Value *V) {
+ SmallVector<Value *, 16> Worklist;
+
+ if (Scalars.erase(V)) {
+ if (PHINode *PN = dyn_cast<PHINode>(V))
+ ConstantEvolutionLoopExitValue.erase(PN);
+ Worklist.push_back(V);
+ }
+
+ while (!Worklist.empty()) {
+ Value *VV = Worklist.back();
+ Worklist.pop_back();
+
+ for (Instruction::use_iterator UI = VV->use_begin(), UE = VV->use_end();
+ UI != UE; ++UI) {
+ Instruction *Inst = cast<Instruction>(*UI);
+ if (Scalars.erase(Inst)) {
+ if (PHINode *PN = dyn_cast<PHINode>(VV))
+ ConstantEvolutionLoopExitValue.erase(PN);
+ Worklist.push_back(Inst);
+ }
+ }
+ }
+}
+
+
+/// getSCEV - Return an existing SCEV if it exists, otherwise analyze the
+/// expression and create a new one.
+SCEVHandle ScalarEvolutionsImpl::getSCEV(Value *V) {
+ assert(V->getType() != Type::VoidTy && "Can't analyze void expressions!");
+
+ std::map<Value*, SCEVHandle>::iterator I = Scalars.find(V);
+ if (I != Scalars.end()) return I->second;
+ SCEVHandle S = createSCEV(V);
+ Scalars.insert(std::make_pair(V, S));
+ return S;
+}
+
+/// ReplaceSymbolicValueWithConcrete - This looks up the computed SCEV value for
+/// the specified instruction and replaces any references to the symbolic value
+/// SymName with the specified value. This is used during PHI resolution.
+void ScalarEvolutionsImpl::
+ReplaceSymbolicValueWithConcrete(Instruction *I, const SCEVHandle &SymName,
+ const SCEVHandle &NewVal) {
+ std::map<Value*, SCEVHandle>::iterator SI = Scalars.find(I);
+ if (SI == Scalars.end()) return;
+
+ SCEVHandle NV =
+ SI->second->replaceSymbolicValuesWithConcrete(SymName, NewVal);
+ if (NV == SI->second) return; // No change.
+
+ SI->second = NV; // Update the scalars map!
+
+ // Any instruction values that use this instruction might also need to be
+ // updated!
+ for (Value::use_iterator UI = I->use_begin(), E = I->use_end();
+ UI != E; ++UI)
+ ReplaceSymbolicValueWithConcrete(cast<Instruction>(*UI), SymName, NewVal);
+}
+
+/// createNodeForPHI - PHI nodes have two cases. Either the PHI node exists in
+/// a loop header, making it a potential recurrence, or it doesn't.
+///
+SCEVHandle ScalarEvolutionsImpl::createNodeForPHI(PHINode *PN) {
+ if (PN->getNumIncomingValues() == 2) // The loops have been canonicalized.
+ if (const Loop *L = LI.getLoopFor(PN->getParent()))
+ if (L->getHeader() == PN->getParent()) {
+ // If it lives in the loop header, it has two incoming values, one
+ // from outside the loop, and one from inside.
+ unsigned IncomingEdge = L->contains(PN->getIncomingBlock(0));
+ unsigned BackEdge = IncomingEdge^1;
+
+ // While we are analyzing this PHI node, handle its value symbolically.
+ SCEVHandle SymbolicName = SCEVUnknown::get(PN);
+ assert(Scalars.find(PN) == Scalars.end() &&
+ "PHI node already processed?");
+ Scalars.insert(std::make_pair(PN, SymbolicName));
+
+ // Using this symbolic name for the PHI, analyze the value coming around
+ // the back-edge.
+ SCEVHandle BEValue = getSCEV(PN->getIncomingValue(BackEdge));
+
+ // NOTE: If BEValue is loop invariant, we know that the PHI node just
+ // has a special value for the first iteration of the loop.
+
+ // If the value coming around the backedge is an add with the symbolic
+ // value we just inserted, then we found a simple induction variable!
+ if (SCEVAddExpr *Add = dyn_cast<SCEVAddExpr>(BEValue)) {
+ // If there is a single occurrence of the symbolic value, replace it
+ // with a recurrence.
+ unsigned FoundIndex = Add->getNumOperands();
+ for (unsigned i = 0, e = Add->getNumOperands(); i != e; ++i)
+ if (Add->getOperand(i) == SymbolicName)
+ if (FoundIndex == e) {
+ FoundIndex = i;
+ break;
+ }
+
+ if (FoundIndex != Add->getNumOperands()) {
+ // Create an add with everything but the specified operand.
+ std::vector<SCEVHandle> Ops;
+ for (unsigned i = 0, e = Add->getNumOperands(); i != e; ++i)
+ if (i != FoundIndex)
+ Ops.push_back(Add->getOperand(i));
+ SCEVHandle Accum = SCEVAddExpr::get(Ops);
+
+ // This is not a valid addrec if the step amount is varying each
+ // loop iteration, but is not itself an addrec in this loop.
+ if (Accum->isLoopInvariant(L) ||
+ (isa<SCEVAddRecExpr>(Accum) &&
+ cast<SCEVAddRecExpr>(Accum)->getLoop() == L)) {
+ SCEVHandle StartVal = getSCEV(PN->getIncomingValue(IncomingEdge));
+ SCEVHandle PHISCEV = SCEVAddRecExpr::get(StartVal, Accum, L);
+
+ // Okay, for the entire analysis of this edge we assumed the PHI
+ // to be symbolic. We now need to go back and update all of the
+ // entries for the scalars that use the PHI (except for the PHI
+ // itself) to use the new analyzed value instead of the "symbolic"
+ // value.
+ ReplaceSymbolicValueWithConcrete(PN, SymbolicName, PHISCEV);
+ return PHISCEV;
+ }
+ }
+ } else if (SCEVAddRecExpr *AddRec = dyn_cast<SCEVAddRecExpr>(BEValue)) {
+ // Otherwise, this could be a loop like this:
+ // i = 0; for (j = 1; ..; ++j) { .... i = j; }
+ // In this case, j = {1,+,1} and BEValue is j.
+ // Because the other in-value of i (0) fits the evolution of BEValue
+ // i really is an addrec evolution.
+ if (AddRec->getLoop() == L && AddRec->isAffine()) {
+ SCEVHandle StartVal = getSCEV(PN->getIncomingValue(IncomingEdge));
+
+ // If StartVal = j.start - j.stride, we can use StartVal as the
+ // initial step of the addrec evolution.
+ if (StartVal == SCEV::getMinusSCEV(AddRec->getOperand(0),
+ AddRec->getOperand(1))) {
+ SCEVHandle PHISCEV =
+ SCEVAddRecExpr::get(StartVal, AddRec->getOperand(1), L);
+
+ // Okay, for the entire analysis of this edge we assumed the PHI
+ // to be symbolic. We now need to go back and update all of the
+ // entries for the scalars that use the PHI (except for the PHI
+ // itself) to use the new analyzed value instead of the "symbolic"
+ // value.
+ ReplaceSymbolicValueWithConcrete(PN, SymbolicName, PHISCEV);
+ return PHISCEV;
+ }
+ }
+ }
+
+ return SymbolicName;
+ }
+
+ // If it's not a loop phi, we can't handle it yet.
+ return SCEVUnknown::get(PN);
+}
+
+/// GetConstantFactor - Determine the largest constant factor that S has. For
+/// example, turn {4,+,8} -> 4. (S umod result) should always equal zero.
+static APInt GetConstantFactor(SCEVHandle S) {
+ if (SCEVConstant *C = dyn_cast<SCEVConstant>(S)) {
+ const APInt& V = C->getValue()->getValue();
+ if (!V.isMinValue())
+ return V;
+ else // Zero is a multiple of everything.
+ return APInt(C->getBitWidth(), 1).shl(C->getBitWidth()-1);
+ }
+
+ if (SCEVTruncateExpr *T = dyn_cast<SCEVTruncateExpr>(S)) {
+ return GetConstantFactor(T->getOperand()).trunc(
+ cast<IntegerType>(T->getType())->getBitWidth());
+ }
+ if (SCEVZeroExtendExpr *E = dyn_cast<SCEVZeroExtendExpr>(S))
+ return GetConstantFactor(E->getOperand()).zext(
+ cast<IntegerType>(E->getType())->getBitWidth());
+ if (SCEVSignExtendExpr *E = dyn_cast<SCEVSignExtendExpr>(S))
+ return GetConstantFactor(E->getOperand()).sext(
+ cast<IntegerType>(E->getType())->getBitWidth());
+
+ if (SCEVAddExpr *A = dyn_cast<SCEVAddExpr>(S)) {
+ // The result is the min of all operands.
+ APInt Res(GetConstantFactor(A->getOperand(0)));
+ for (unsigned i = 1, e = A->getNumOperands();
+ i != e && Res.ugt(APInt(Res.getBitWidth(),1)); ++i) {
+ APInt Tmp(GetConstantFactor(A->getOperand(i)));
+ Res = APIntOps::umin(Res, Tmp);
+ }
+ return Res;
+ }
+
+ if (SCEVMulExpr *M = dyn_cast<SCEVMulExpr>(S)) {
+ // The result is the product of all the operands.
+ APInt Res(GetConstantFactor(M->getOperand(0)));
+ for (unsigned i = 1, e = M->getNumOperands(); i != e; ++i) {
+ APInt Tmp(GetConstantFactor(M->getOperand(i)));
+ Res *= Tmp;
+ }
+ return Res;
+ }
+
+ if (SCEVAddRecExpr *A = dyn_cast<SCEVAddRecExpr>(S)) {
+ // For now, we just handle linear expressions.
+ if (A->getNumOperands() == 2) {
+ // We want the GCD between the start and the stride value.
+ APInt Start(GetConstantFactor(A->getOperand(0)));
+ if (Start == 1)
+ return Start;
+ APInt Stride(GetConstantFactor(A->getOperand(1)));
+ return APIntOps::GreatestCommonDivisor(Start, Stride);
+ }
+ }
+
+ // SCEVSDivExpr, SCEVUnknown.
+ return APInt(S->getBitWidth(), 1);
+}
+
+/// createSCEV - We know that there is no SCEV for the specified value.
+/// Analyze the expression.
+///
+SCEVHandle ScalarEvolutionsImpl::createSCEV(Value *V) {
+ if (Instruction *I = dyn_cast<Instruction>(V)) {
+ switch (I->getOpcode()) {
+ case Instruction::Add:
+ return SCEVAddExpr::get(getSCEV(I->getOperand(0)),
+ getSCEV(I->getOperand(1)));
+ case Instruction::Mul:
+ return SCEVMulExpr::get(getSCEV(I->getOperand(0)),
+ getSCEV(I->getOperand(1)));
+ case Instruction::SDiv:
+ return SCEVSDivExpr::get(getSCEV(I->getOperand(0)),
+ getSCEV(I->getOperand(1)));
+ break;
+
+ case Instruction::Sub:
+ return SCEV::getMinusSCEV(getSCEV(I->getOperand(0)),
+ getSCEV(I->getOperand(1)));
+ case Instruction::Or:
+ // If the RHS of the Or is a constant, we may have something like:
+ // X*4+1 which got turned into X*4|1. Handle this as an add so loop
+ // optimizations will transparently handle this case.
+ if (ConstantInt *CI = dyn_cast<ConstantInt>(I->getOperand(1))) {
+ SCEVHandle LHS = getSCEV(I->getOperand(0));
+ APInt CommonFact(GetConstantFactor(LHS));
+ assert(!CommonFact.isMinValue() &&
+ "Common factor should at least be 1!");
+ if (CommonFact.ugt(CI->getValue())) {
+ // If the LHS is a multiple that is larger than the RHS, use +.
+ return SCEVAddExpr::get(LHS,
+ getSCEV(I->getOperand(1)));
+ }
+ }
+ break;
+ case Instruction::Xor:
+ // If the RHS of the xor is a signbit, then this is just an add.
+ // Instcombine turns add of signbit into xor as a strength reduction step.
+ if (ConstantInt *CI = dyn_cast<ConstantInt>(I->getOperand(1))) {
+ if (CI->getValue().isSignBit())
+ return SCEVAddExpr::get(getSCEV(I->getOperand(0)),
+ getSCEV(I->getOperand(1)));
+ }
+ break;
+
+ case Instruction::Shl:
+ // Turn shift left of a constant amount into a multiply.
+ if (ConstantInt *SA = dyn_cast<ConstantInt>(I->getOperand(1))) {
+ uint32_t BitWidth = cast<IntegerType>(V->getType())->getBitWidth();
+ Constant *X = ConstantInt::get(
+ APInt(BitWidth, 1).shl(SA->getLimitedValue(BitWidth)));
+ return SCEVMulExpr::get(getSCEV(I->getOperand(0)), getSCEV(X));
+ }
+ break;
+
+ case Instruction::Trunc:
+ return SCEVTruncateExpr::get(getSCEV(I->getOperand(0)), I->getType());
+
+ case Instruction::ZExt:
+ return SCEVZeroExtendExpr::get(getSCEV(I->getOperand(0)), I->getType());
+
+ case Instruction::SExt:
+ return SCEVSignExtendExpr::get(getSCEV(I->getOperand(0)), I->getType());
+
+ case Instruction::BitCast:
+ // BitCasts are no-op casts so we just eliminate the cast.
+ if (I->getType()->isInteger() &&
+ I->getOperand(0)->getType()->isInteger())
+ return getSCEV(I->getOperand(0));
+ break;
+
+ case Instruction::PHI:
+ return createNodeForPHI(cast<PHINode>(I));
+
+ default: // We cannot analyze this expression.
+ break;
+ }
+ }
+
+ return SCEVUnknown::get(V);
+}
+
+
+
+//===----------------------------------------------------------------------===//
+// Iteration Count Computation Code
+//
+
+/// getIterationCount - If the specified loop has a predictable iteration
+/// count, return it. Note that it is not valid to call this method on a
+/// loop without a loop-invariant iteration count.
+SCEVHandle ScalarEvolutionsImpl::getIterationCount(const Loop *L) {
+ std::map<const Loop*, SCEVHandle>::iterator I = IterationCounts.find(L);
+ if (I == IterationCounts.end()) {
+ SCEVHandle ItCount = ComputeIterationCount(L);
+ I = IterationCounts.insert(std::make_pair(L, ItCount)).first;
+ if (ItCount != UnknownValue) {
+ assert(ItCount->isLoopInvariant(L) &&
+ "Computed trip count isn't loop invariant for loop!");
+ ++NumTripCountsComputed;
+ } else if (isa<PHINode>(L->getHeader()->begin())) {
+ // Only count loops that have phi nodes as not being computable.
+ ++NumTripCountsNotComputed;
+ }
+ }
+ return I->second;
+}
+
+/// ComputeIterationCount - Compute the number of times the specified loop
+/// will iterate.
+SCEVHandle ScalarEvolutionsImpl::ComputeIterationCount(const Loop *L) {
+ // If the loop has a non-one exit block count, we can't analyze it.
+ std::vector<BasicBlock*> ExitBlocks;
+ L->getExitBlocks(ExitBlocks);
+ if (ExitBlocks.size() != 1) return UnknownValue;
+
+ // Okay, there is one exit block. Try to find the condition that causes the
+ // loop to be exited.
+ BasicBlock *ExitBlock = ExitBlocks[0];
+
+ BasicBlock *ExitingBlock = 0;
+ for (pred_iterator PI = pred_begin(ExitBlock), E = pred_end(ExitBlock);
+ PI != E; ++PI)
+ if (L->contains(*PI)) {
+ if (ExitingBlock == 0)
+ ExitingBlock = *PI;
+ else
+ return UnknownValue; // More than one block exiting!
+ }
+ assert(ExitingBlock && "No exits from loop, something is broken!");
+
+ // Okay, we've computed the exiting block. See what condition causes us to
+ // exit.
+ //
+ // FIXME: we should be able to handle switch instructions (with a single exit)
+ BranchInst *ExitBr = dyn_cast<BranchInst>(ExitingBlock->getTerminator());
+ if (ExitBr == 0) return UnknownValue;
+ assert(ExitBr->isConditional() && "If unconditional, it can't be in loop!");
+
+ // At this point, we know we have a conditional branch that determines whether
+ // the loop is exited. However, we don't know if the branch is executed each
+ // time through the loop. If not, then the execution count of the branch will
+ // not be equal to the trip count of the loop.
+ //
+ // Currently we check for this by checking to see if the Exit branch goes to
+ // the loop header. If so, we know it will always execute the same number of
+ // times as the loop. We also handle the case where the exit block *is* the
+ // loop header. This is common for un-rotated loops. More extensive analysis
+ // could be done to handle more cases here.
+ if (ExitBr->getSuccessor(0) != L->getHeader() &&
+ ExitBr->getSuccessor(1) != L->getHeader() &&
+ ExitBr->getParent() != L->getHeader())
+ return UnknownValue;
+
+ ICmpInst *ExitCond = dyn_cast<ICmpInst>(ExitBr->getCondition());
+
+ // If its not an integer comparison then compute it the hard way.
+ // Note that ICmpInst deals with pointer comparisons too so we must check
+ // the type of the operand.
+ if (ExitCond == 0 || isa<PointerType>(ExitCond->getOperand(0)->getType()))
+ return ComputeIterationCountExhaustively(L, ExitBr->getCondition(),
+ ExitBr->getSuccessor(0) == ExitBlock);
+
+ // If the condition was exit on true, convert the condition to exit on false
+ ICmpInst::Predicate Cond;
+ if (ExitBr->getSuccessor(1) == ExitBlock)
+ Cond = ExitCond->getPredicate();
+ else
+ Cond = ExitCond->getInversePredicate();
+
+ // Handle common loops like: for (X = "string"; *X; ++X)
+ if (LoadInst *LI = dyn_cast<LoadInst>(ExitCond->getOperand(0)))
+ if (Constant *RHS = dyn_cast<Constant>(ExitCond->getOperand(1))) {
+ SCEVHandle ItCnt =
+ ComputeLoadConstantCompareIterationCount(LI, RHS, L, Cond);
+ if (!isa<SCEVCouldNotCompute>(ItCnt)) return ItCnt;
+ }
+
+ SCEVHandle LHS = getSCEV(ExitCond->getOperand(0));
+ SCEVHandle RHS = getSCEV(ExitCond->getOperand(1));
+
+ // Try to evaluate any dependencies out of the loop.
+ SCEVHandle Tmp = getSCEVAtScope(LHS, L);
+ if (!isa<SCEVCouldNotCompute>(Tmp)) LHS = Tmp;
+ Tmp = getSCEVAtScope(RHS, L);
+ if (!isa<SCEVCouldNotCompute>(Tmp)) RHS = Tmp;
+
+ // At this point, we would like to compute how many iterations of the
+ // loop the predicate will return true for these inputs.
+ if (isa<SCEVConstant>(LHS) && !isa<SCEVConstant>(RHS)) {
+ // If there is a constant, force it into the RHS.
+ std::swap(LHS, RHS);
+ Cond = ICmpInst::getSwappedPredicate(Cond);
+ }
+
+ // FIXME: think about handling pointer comparisons! i.e.:
+ // while (P != P+100) ++P;
+
+ // If we have a comparison of a chrec against a constant, try to use value
+ // ranges to answer this query.
+ if (SCEVConstant *RHSC = dyn_cast<SCEVConstant>(RHS))
+ if (SCEVAddRecExpr *AddRec = dyn_cast<SCEVAddRecExpr>(LHS))
+ if (AddRec->getLoop() == L) {
+ // Form the comparison range using the constant of the correct type so
+ // that the ConstantRange class knows to do a signed or unsigned
+ // comparison.
+ ConstantInt *CompVal = RHSC->getValue();
+ const Type *RealTy = ExitCond->getOperand(0)->getType();
+ CompVal = dyn_cast<ConstantInt>(
+ ConstantExpr::getBitCast(CompVal, RealTy));
+ if (CompVal) {
+ // Form the constant range.
+ ConstantRange CompRange(
+ ICmpInst::makeConstantRange(Cond, CompVal->getValue()));
+
+ SCEVHandle Ret = AddRec->getNumIterationsInRange(CompRange);
+ if (!isa<SCEVCouldNotCompute>(Ret)) return Ret;
+ }
+ }
+
+ switch (Cond) {
+ case ICmpInst::ICMP_NE: { // while (X != Y)
+ // Convert to: while (X-Y != 0)
+ SCEVHandle TC = HowFarToZero(SCEV::getMinusSCEV(LHS, RHS), L);
+ if (!isa<SCEVCouldNotCompute>(TC)) return TC;
+ break;
+ }
+ case ICmpInst::ICMP_EQ: {
+ // Convert to: while (X-Y == 0) // while (X == Y)
+ SCEVHandle TC = HowFarToNonZero(SCEV::getMinusSCEV(LHS, RHS), L);
+ if (!isa<SCEVCouldNotCompute>(TC)) return TC;
+ break;
+ }
+ case ICmpInst::ICMP_SLT: {
+ SCEVHandle TC = HowManyLessThans(LHS, RHS, L);
+ if (!isa<SCEVCouldNotCompute>(TC)) return TC;
+ break;
+ }
+ case ICmpInst::ICMP_SGT: {
+ SCEVHandle TC = HowManyLessThans(SCEV::getNegativeSCEV(LHS),
+ SCEV::getNegativeSCEV(RHS), L);
+ if (!isa<SCEVCouldNotCompute>(TC)) return TC;
+ break;
+ }
+ default:
+#if 0
+ cerr << "ComputeIterationCount ";
+ if (ExitCond->getOperand(0)->getType()->isUnsigned())
+ cerr << "[unsigned] ";
+ cerr << *LHS << " "
+ << Instruction::getOpcodeName(Instruction::ICmp)
+ << " " << *RHS << "\n";
+#endif
+ break;
+ }
+ return ComputeIterationCountExhaustively(L, ExitCond,
+ ExitBr->getSuccessor(0) == ExitBlock);
+}
+
+static ConstantInt *
+EvaluateConstantChrecAtConstant(const SCEVAddRecExpr *AddRec, ConstantInt *C) {
+ SCEVHandle InVal = SCEVConstant::get(C);
+ SCEVHandle Val = AddRec->evaluateAtIteration(InVal);
+ assert(isa<SCEVConstant>(Val) &&
+ "Evaluation of SCEV at constant didn't fold correctly?");
+ return cast<SCEVConstant>(Val)->getValue();
+}
+
+/// GetAddressedElementFromGlobal - Given a global variable with an initializer
+/// and a GEP expression (missing the pointer index) indexing into it, return
+/// the addressed element of the initializer or null if the index expression is
+/// invalid.
+static Constant *
+GetAddressedElementFromGlobal(GlobalVariable *GV,
+ const std::vector<ConstantInt*> &Indices) {
+ Constant *Init = GV->getInitializer();
+ for (unsigned i = 0, e = Indices.size(); i != e; ++i) {
+ uint64_t Idx = Indices[i]->getZExtValue();
+ if (ConstantStruct *CS = dyn_cast<ConstantStruct>(Init)) {
+ assert(Idx < CS->getNumOperands() && "Bad struct index!");
+ Init = cast<Constant>(CS->getOperand(Idx));
+ } else if (ConstantArray *CA = dyn_cast<ConstantArray>(Init)) {
+ if (Idx >= CA->getNumOperands()) return 0; // Bogus program
+ Init = cast<Constant>(CA->getOperand(Idx));
+ } else if (isa<ConstantAggregateZero>(Init)) {
+ if (const StructType *STy = dyn_cast<StructType>(Init->getType())) {
+ assert(Idx < STy->getNumElements() && "Bad struct index!");
+ Init = Constant::getNullValue(STy->getElementType(Idx));
+ } else if (const ArrayType *ATy = dyn_cast<ArrayType>(Init->getType())) {
+ if (Idx >= ATy->getNumElements()) return 0; // Bogus program
+ Init = Constant::getNullValue(ATy->getElementType());
+ } else {
+ assert(0 && "Unknown constant aggregate type!");
+ }
+ return 0;
+ } else {
+ return 0; // Unknown initializer type
+ }
+ }
+ return Init;
+}
+
+/// ComputeLoadConstantCompareIterationCount - Given an exit condition of
+/// 'setcc load X, cst', try to se if we can compute the trip count.
+SCEVHandle ScalarEvolutionsImpl::
+ComputeLoadConstantCompareIterationCount(LoadInst *LI, Constant *RHS,
+ const Loop *L,
+ ICmpInst::Predicate predicate) {
+ if (LI->isVolatile()) return UnknownValue;
+
+ // Check to see if the loaded pointer is a getelementptr of a global.
+ GetElementPtrInst *GEP = dyn_cast<GetElementPtrInst>(LI->getOperand(0));
+ if (!GEP) return UnknownValue;
+
+ // Make sure that it is really a constant global we are gepping, with an
+ // initializer, and make sure the first IDX is really 0.
+ GlobalVariable *GV = dyn_cast<GlobalVariable>(GEP->getOperand(0));
+ if (!GV || !GV->isConstant() || !GV->hasInitializer() ||
+ GEP->getNumOperands() < 3 || !isa<Constant>(GEP->getOperand(1)) ||
+ !cast<Constant>(GEP->getOperand(1))->isNullValue())
+ return UnknownValue;
+
+ // Okay, we allow one non-constant index into the GEP instruction.
+ Value *VarIdx = 0;
+ std::vector<ConstantInt*> Indexes;
+ unsigned VarIdxNum = 0;
+ for (unsigned i = 2, e = GEP->getNumOperands(); i != e; ++i)
+ if (ConstantInt *CI = dyn_cast<ConstantInt>(GEP->getOperand(i))) {
+ Indexes.push_back(CI);
+ } else if (!isa<ConstantInt>(GEP->getOperand(i))) {
+ if (VarIdx) return UnknownValue; // Multiple non-constant idx's.
+ VarIdx = GEP->getOperand(i);
+ VarIdxNum = i-2;
+ Indexes.push_back(0);
+ }
+
+ // Okay, we know we have a (load (gep GV, 0, X)) comparison with a constant.
+ // Check to see if X is a loop variant variable value now.
+ SCEVHandle Idx = getSCEV(VarIdx);
+ SCEVHandle Tmp = getSCEVAtScope(Idx, L);
+ if (!isa<SCEVCouldNotCompute>(Tmp)) Idx = Tmp;
+
+ // We can only recognize very limited forms of loop index expressions, in
+ // particular, only affine AddRec's like {C1,+,C2}.
+ SCEVAddRecExpr *IdxExpr = dyn_cast<SCEVAddRecExpr>(Idx);
+ if (!IdxExpr || !IdxExpr->isAffine() || IdxExpr->isLoopInvariant(L) ||
+ !isa<SCEVConstant>(IdxExpr->getOperand(0)) ||
+ !isa<SCEVConstant>(IdxExpr->getOperand(1)))
+ return UnknownValue;
+
+ unsigned MaxSteps = MaxBruteForceIterations;
+ for (unsigned IterationNum = 0; IterationNum != MaxSteps; ++IterationNum) {
+ ConstantInt *ItCst =
+ ConstantInt::get(IdxExpr->getType(), IterationNum);
+ ConstantInt *Val = EvaluateConstantChrecAtConstant(IdxExpr, ItCst);
+
+ // Form the GEP offset.
+ Indexes[VarIdxNum] = Val;
+
+ Constant *Result = GetAddressedElementFromGlobal(GV, Indexes);
+ if (Result == 0) break; // Cannot compute!
+
+ // Evaluate the condition for this iteration.
+ Result = ConstantExpr::getICmp(predicate, Result, RHS);
+ if (!isa<ConstantInt>(Result)) break; // Couldn't decide for sure
+ if (cast<ConstantInt>(Result)->getValue().isMinValue()) {
+#if 0
+ cerr << "\n***\n*** Computed loop count " << *ItCst
+ << "\n*** From global " << *GV << "*** BB: " << *L->getHeader()
+ << "***\n";
+#endif
+ ++NumArrayLenItCounts;
+ return SCEVConstant::get(ItCst); // Found terminating iteration!
+ }
+ }
+ return UnknownValue;
+}
+
+
+/// CanConstantFold - Return true if we can constant fold an instruction of the
+/// specified type, assuming that all operands were constants.
+static bool CanConstantFold(const Instruction *I) {
+ if (isa<BinaryOperator>(I) || isa<CmpInst>(I) ||
+ isa<SelectInst>(I) || isa<CastInst>(I) || isa<GetElementPtrInst>(I))
+ return true;
+
+ if (const CallInst *CI = dyn_cast<CallInst>(I))
+ if (const Function *F = CI->getCalledFunction())
+ return canConstantFoldCallTo((Function*)F); // FIXME: elim cast
+ return false;
+}
+
+/// getConstantEvolvingPHI - Given an LLVM value and a loop, return a PHI node
+/// in the loop that V is derived from. We allow arbitrary operations along the
+/// way, but the operands of an operation must either be constants or a value
+/// derived from a constant PHI. If this expression does not fit with these
+/// constraints, return null.
+static PHINode *getConstantEvolvingPHI(Value *V, const Loop *L) {
+ // If this is not an instruction, or if this is an instruction outside of the
+ // loop, it can't be derived from a loop PHI.
+ Instruction *I = dyn_cast<Instruction>(V);
+ if (I == 0 || !L->contains(I->getParent())) return 0;
+
+ if (PHINode *PN = dyn_cast<PHINode>(I))
+ if (L->getHeader() == I->getParent())
+ return PN;
+ else
+ // We don't currently keep track of the control flow needed to evaluate
+ // PHIs, so we cannot handle PHIs inside of loops.
+ return 0;
+
+ // If we won't be able to constant fold this expression even if the operands
+ // are constants, return early.
+ if (!CanConstantFold(I)) return 0;
+
+ // Otherwise, we can evaluate this instruction if all of its operands are
+ // constant or derived from a PHI node themselves.
+ PHINode *PHI = 0;
+ for (unsigned Op = 0, e = I->getNumOperands(); Op != e; ++Op)
+ if (!(isa<Constant>(I->getOperand(Op)) ||
+ isa<GlobalValue>(I->getOperand(Op)))) {
+ PHINode *P = getConstantEvolvingPHI(I->getOperand(Op), L);
+ if (P == 0) return 0; // Not evolving from PHI
+ if (PHI == 0)
+ PHI = P;
+ else if (PHI != P)
+ return 0; // Evolving from multiple different PHIs.
+ }
+
+ // This is a expression evolving from a constant PHI!
+ return PHI;
+}
+
+/// EvaluateExpression - Given an expression that passes the
+/// getConstantEvolvingPHI predicate, evaluate its value assuming the PHI node
+/// in the loop has the value PHIVal. If we can't fold this expression for some
+/// reason, return null.
+static Constant *EvaluateExpression(Value *V, Constant *PHIVal) {
+ if (isa<PHINode>(V)) return PHIVal;
+ if (GlobalValue *GV = dyn_cast<GlobalValue>(V))
+ return GV;
+ if (Constant *C = dyn_cast<Constant>(V)) return C;
+ Instruction *I = cast<Instruction>(V);
+
+ std::vector<Constant*> Operands;
+ Operands.resize(I->getNumOperands());
+
+ for (unsigned i = 0, e = I->getNumOperands(); i != e; ++i) {
+ Operands[i] = EvaluateExpression(I->getOperand(i), PHIVal);
+ if (Operands[i] == 0) return 0;
+ }
+
+ return ConstantFoldInstOperands(I, &Operands[0], Operands.size());
+}
+
+/// getConstantEvolutionLoopExitValue - If we know that the specified Phi is
+/// in the header of its containing loop, we know the loop executes a
+/// constant number of times, and the PHI node is just a recurrence
+/// involving constants, fold it.
+Constant *ScalarEvolutionsImpl::
+getConstantEvolutionLoopExitValue(PHINode *PN, const APInt& Its, const Loop *L){
+ std::map<PHINode*, Constant*>::iterator I =
+ ConstantEvolutionLoopExitValue.find(PN);
+ if (I != ConstantEvolutionLoopExitValue.end())
+ return I->second;
+
+ if (Its.ugt(APInt(Its.getBitWidth(),MaxBruteForceIterations)))
+ return ConstantEvolutionLoopExitValue[PN] = 0; // Not going to evaluate it.
+
+ Constant *&RetVal = ConstantEvolutionLoopExitValue[PN];
+
+ // Since the loop is canonicalized, the PHI node must have two entries. One
+ // entry must be a constant (coming in from outside of the loop), and the
+ // second must be derived from the same PHI.
+ bool SecondIsBackedge = L->contains(PN->getIncomingBlock(1));
+ Constant *StartCST =
+ dyn_cast<Constant>(PN->getIncomingValue(!SecondIsBackedge));
+ if (StartCST == 0)
+ return RetVal = 0; // Must be a constant.
+
+ Value *BEValue = PN->getIncomingValue(SecondIsBackedge);
+ PHINode *PN2 = getConstantEvolvingPHI(BEValue, L);
+ if (PN2 != PN)
+ return RetVal = 0; // Not derived from same PHI.
+
+ // Execute the loop symbolically to determine the exit value.
+ if (Its.getActiveBits() >= 32)
+ return RetVal = 0; // More than 2^32-1 iterations?? Not doing it!
+
+ unsigned NumIterations = Its.getZExtValue(); // must be in range
+ unsigned IterationNum = 0;
+ for (Constant *PHIVal = StartCST; ; ++IterationNum) {
+ if (IterationNum == NumIterations)
+ return RetVal = PHIVal; // Got exit value!
+
+ // Compute the value of the PHI node for the next iteration.
+ Constant *NextPHI = EvaluateExpression(BEValue, PHIVal);
+ if (NextPHI == PHIVal)
+ return RetVal = NextPHI; // Stopped evolving!
+ if (NextPHI == 0)
+ return 0; // Couldn't evaluate!
+ PHIVal = NextPHI;
+ }
+}
+
+/// ComputeIterationCountExhaustively - If the trip is known to execute a
+/// constant number of times (the condition evolves only from constants),
+/// try to evaluate a few iterations of the loop until we get the exit
+/// condition gets a value of ExitWhen (true or false). If we cannot
+/// evaluate the trip count of the loop, return UnknownValue.
+SCEVHandle ScalarEvolutionsImpl::
+ComputeIterationCountExhaustively(const Loop *L, Value *Cond, bool ExitWhen) {
+ PHINode *PN = getConstantEvolvingPHI(Cond, L);
+ if (PN == 0) return UnknownValue;
+
+ // Since the loop is canonicalized, the PHI node must have two entries. One
+ // entry must be a constant (coming in from outside of the loop), and the
+ // second must be derived from the same PHI.
+ bool SecondIsBackedge = L->contains(PN->getIncomingBlock(1));
+ Constant *StartCST =
+ dyn_cast<Constant>(PN->getIncomingValue(!SecondIsBackedge));
+ if (StartCST == 0) return UnknownValue; // Must be a constant.
+
+ Value *BEValue = PN->getIncomingValue(SecondIsBackedge);
+ PHINode *PN2 = getConstantEvolvingPHI(BEValue, L);
+ if (PN2 != PN) return UnknownValue; // Not derived from same PHI.
+
+ // Okay, we find a PHI node that defines the trip count of this loop. Execute
+ // the loop symbolically to determine when the condition gets a value of
+ // "ExitWhen".
+ unsigned IterationNum = 0;
+ unsigned MaxIterations = MaxBruteForceIterations; // Limit analysis.
+ for (Constant *PHIVal = StartCST;
+ IterationNum != MaxIterations; ++IterationNum) {
+ ConstantInt *CondVal =
+ dyn_cast_or_null<ConstantInt>(EvaluateExpression(Cond, PHIVal));
+
+ // Couldn't symbolically evaluate.
+ if (!CondVal) return UnknownValue;
+
+ if (CondVal->getValue() == uint64_t(ExitWhen)) {
+ ConstantEvolutionLoopExitValue[PN] = PHIVal;
+ ++NumBruteForceTripCountsComputed;
+ return SCEVConstant::get(ConstantInt::get(Type::Int32Ty, IterationNum));
+ }
+
+ // Compute the value of the PHI node for the next iteration.
+ Constant *NextPHI = EvaluateExpression(BEValue, PHIVal);
+ if (NextPHI == 0 || NextPHI == PHIVal)
+ return UnknownValue; // Couldn't evaluate or not making progress...
+ PHIVal = NextPHI;
+ }
+
+ // Too many iterations were needed to evaluate.
+ return UnknownValue;
+}
+
+/// getSCEVAtScope - Compute the value of the specified expression within the
+/// indicated loop (which may be null to indicate in no loop). If the
+/// expression cannot be evaluated, return UnknownValue.
+SCEVHandle ScalarEvolutionsImpl::getSCEVAtScope(SCEV *V, const Loop *L) {
+ // FIXME: this should be turned into a virtual method on SCEV!
+
+ if (isa<SCEVConstant>(V)) return V;
+
+ // If this instruction is evolves from a constant-evolving PHI, compute the
+ // exit value from the loop without using SCEVs.
+ if (SCEVUnknown *SU = dyn_cast<SCEVUnknown>(V)) {
+ if (Instruction *I = dyn_cast<Instruction>(SU->getValue())) {
+ const Loop *LI = this->LI[I->getParent()];
+ if (LI && LI->getParentLoop() == L) // Looking for loop exit value.
+ if (PHINode *PN = dyn_cast<PHINode>(I))
+ if (PN->getParent() == LI->getHeader()) {
+ // Okay, there is no closed form solution for the PHI node. Check
+ // to see if the loop that contains it has a known iteration count.
+ // If so, we may be able to force computation of the exit value.
+ SCEVHandle IterationCount = getIterationCount(LI);
+ if (SCEVConstant *ICC = dyn_cast<SCEVConstant>(IterationCount)) {
+ // Okay, we know how many times the containing loop executes. If
+ // this is a constant evolving PHI node, get the final value at
+ // the specified iteration number.
+ Constant *RV = getConstantEvolutionLoopExitValue(PN,
+ ICC->getValue()->getValue(),
+ LI);
+ if (RV) return SCEVUnknown::get(RV);
+ }
+ }
+
+ // Okay, this is an expression that we cannot symbolically evaluate
+ // into a SCEV. Check to see if it's possible to symbolically evaluate
+ // the arguments into constants, and if so, try to constant propagate the
+ // result. This is particularly useful for computing loop exit values.
+ if (CanConstantFold(I)) {
+ std::vector<Constant*> Operands;
+ Operands.reserve(I->getNumOperands());
+ for (unsigned i = 0, e = I->getNumOperands(); i != e; ++i) {
+ Value *Op = I->getOperand(i);
+ if (Constant *C = dyn_cast<Constant>(Op)) {
+ Operands.push_back(C);
+ } else {
+ SCEVHandle OpV = getSCEVAtScope(getSCEV(Op), L);
+ if (SCEVConstant *SC = dyn_cast<SCEVConstant>(OpV))
+ Operands.push_back(ConstantExpr::getIntegerCast(SC->getValue(),
+ Op->getType(),
+ false));
+ else if (SCEVUnknown *SU = dyn_cast<SCEVUnknown>(OpV)) {
+ if (Constant *C = dyn_cast<Constant>(SU->getValue()))
+ Operands.push_back(ConstantExpr::getIntegerCast(C,
+ Op->getType(),
+ false));
+ else
+ return V;
+ } else {
+ return V;
+ }
+ }
+ }
+ Constant *C =ConstantFoldInstOperands(I, &Operands[0], Operands.size());
+ return SCEVUnknown::get(C);
+ }
+ }
+
+ // This is some other type of SCEVUnknown, just return it.
+ return V;
+ }
+
+ if (SCEVCommutativeExpr *Comm = dyn_cast<SCEVCommutativeExpr>(V)) {
+ // Avoid performing the look-up in the common case where the specified
+ // expression has no loop-variant portions.
+ for (unsigned i = 0, e = Comm->getNumOperands(); i != e; ++i) {
+ SCEVHandle OpAtScope = getSCEVAtScope(Comm->getOperand(i), L);
+ if (OpAtScope != Comm->getOperand(i)) {
+ if (OpAtScope == UnknownValue) return UnknownValue;
+ // Okay, at least one of these operands is loop variant but might be
+ // foldable. Build a new instance of the folded commutative expression.
+ std::vector<SCEVHandle> NewOps(Comm->op_begin(), Comm->op_begin()+i);
+ NewOps.push_back(OpAtScope);
+
+ for (++i; i != e; ++i) {
+ OpAtScope = getSCEVAtScope(Comm->getOperand(i), L);
+ if (OpAtScope == UnknownValue) return UnknownValue;
+ NewOps.push_back(OpAtScope);
+ }
+ if (isa<SCEVAddExpr>(Comm))
+ return SCEVAddExpr::get(NewOps);
+ assert(isa<SCEVMulExpr>(Comm) && "Only know about add and mul!");
+ return SCEVMulExpr::get(NewOps);
+ }
+ }
+ // If we got here, all operands are loop invariant.
+ return Comm;
+ }
+
+ if (SCEVSDivExpr *Div = dyn_cast<SCEVSDivExpr>(V)) {
+ SCEVHandle LHS = getSCEVAtScope(Div->getLHS(), L);
+ if (LHS == UnknownValue) return LHS;
+ SCEVHandle RHS = getSCEVAtScope(Div->getRHS(), L);
+ if (RHS == UnknownValue) return RHS;
+ if (LHS == Div->getLHS() && RHS == Div->getRHS())
+ return Div; // must be loop invariant
+ return SCEVSDivExpr::get(LHS, RHS);
+ }
+
+ // If this is a loop recurrence for a loop that does not contain L, then we
+ // are dealing with the final value computed by the loop.
+ if (SCEVAddRecExpr *AddRec = dyn_cast<SCEVAddRecExpr>(V)) {
+ if (!L || !AddRec->getLoop()->contains(L->getHeader())) {
+ // To evaluate this recurrence, we need to know how many times the AddRec
+ // loop iterates. Compute this now.
+ SCEVHandle IterationCount = getIterationCount(AddRec->getLoop());
+ if (IterationCount == UnknownValue) return UnknownValue;
+ IterationCount = getTruncateOrZeroExtend(IterationCount,
+ AddRec->getType());
+
+ // If the value is affine, simplify the expression evaluation to just
+ // Start + Step*IterationCount.
+ if (AddRec->isAffine())
+ return SCEVAddExpr::get(AddRec->getStart(),
+ SCEVMulExpr::get(IterationCount,
+ AddRec->getOperand(1)));
+
+ // Otherwise, evaluate it the hard way.
+ return AddRec->evaluateAtIteration(IterationCount);
+ }
+ return UnknownValue;
+ }
+
+ //assert(0 && "Unknown SCEV type!");
+ return UnknownValue;
+}
+
+
+/// SolveQuadraticEquation - Find the roots of the quadratic equation for the
+/// given quadratic chrec {L,+,M,+,N}. This returns either the two roots (which
+/// might be the same) or two SCEVCouldNotCompute objects.
+///
+static std::pair<SCEVHandle,SCEVHandle>
+SolveQuadraticEquation(const SCEVAddRecExpr *AddRec) {
+ assert(AddRec->getNumOperands() == 3 && "This is not a quadratic chrec!");
+ SCEVConstant *LC = dyn_cast<SCEVConstant>(AddRec->getOperand(0));
+ SCEVConstant *MC = dyn_cast<SCEVConstant>(AddRec->getOperand(1));
+ SCEVConstant *NC = dyn_cast<SCEVConstant>(AddRec->getOperand(2));
+
+ // We currently can only solve this if the coefficients are constants.
+ if (!LC || !MC || !NC) {
+ SCEV *CNC = new SCEVCouldNotCompute();
+ return std::make_pair(CNC, CNC);
+ }
+
+ uint32_t BitWidth = LC->getValue()->getValue().getBitWidth();
+ const APInt &L = LC->getValue()->getValue();
+ const APInt &M = MC->getValue()->getValue();
+ const APInt &N = NC->getValue()->getValue();
+ APInt Two(BitWidth, 2);
+ APInt Four(BitWidth, 4);
+
+ {
+ using namespace APIntOps;
+ const APInt& C = L;
+ // Convert from chrec coefficients to polynomial coefficients AX^2+BX+C
+ // The B coefficient is M-N/2
+ APInt B(M);
+ B -= sdiv(N,Two);
+
+ // The A coefficient is N/2
+ APInt A(N.sdiv(Two));
+
+ // Compute the B^2-4ac term.
+ APInt SqrtTerm(B);
+ SqrtTerm *= B;
+ SqrtTerm -= Four * (A * C);
+
+ // Compute sqrt(B^2-4ac). This is guaranteed to be the nearest
+ // integer value or else APInt::sqrt() will assert.
+ APInt SqrtVal(SqrtTerm.sqrt());
+
+ // Compute the two solutions for the quadratic formula.
+ // The divisions must be performed as signed divisions.
+ APInt NegB(-B);
+ APInt TwoA( A << 1 );
+ ConstantInt *Solution1 = ConstantInt::get((NegB + SqrtVal).sdiv(TwoA));
+ ConstantInt *Solution2 = ConstantInt::get((NegB - SqrtVal).sdiv(TwoA));
+
+ return std::make_pair(SCEVConstant::get(Solution1),
+ SCEVConstant::get(Solution2));
+ } // end APIntOps namespace
+}
+
+/// HowFarToZero - Return the number of times a backedge comparing the specified
+/// value to zero will execute. If not computable, return UnknownValue
+SCEVHandle ScalarEvolutionsImpl::HowFarToZero(SCEV *V, const Loop *L) {
+ // If the value is a constant
+ if (SCEVConstant *C = dyn_cast<SCEVConstant>(V)) {
+ // If the value is already zero, the branch will execute zero times.
+ if (C->getValue()->isZero()) return C;
+ return UnknownValue; // Otherwise it will loop infinitely.
+ }
+
+ SCEVAddRecExpr *AddRec = dyn_cast<SCEVAddRecExpr>(V);
+ if (!AddRec || AddRec->getLoop() != L)
+ return UnknownValue;
+
+ if (AddRec->isAffine()) {
+ // If this is an affine expression the execution count of this branch is
+ // equal to:
+ //
+ // (0 - Start/Step) iff Start % Step == 0
+ //
+ // Get the initial value for the loop.
+ SCEVHandle Start = getSCEVAtScope(AddRec->getStart(), L->getParentLoop());
+ if (isa<SCEVCouldNotCompute>(Start)) return UnknownValue;
+ SCEVHandle Step = AddRec->getOperand(1);
+
+ Step = getSCEVAtScope(Step, L->getParentLoop());
+
+ // Figure out if Start % Step == 0.
+ // FIXME: We should add DivExpr and RemExpr operations to our AST.
+ if (SCEVConstant *StepC = dyn_cast<SCEVConstant>(Step)) {
+ if (StepC->getValue()->equalsInt(1)) // N % 1 == 0
+ return SCEV::getNegativeSCEV(Start); // 0 - Start/1 == -Start
+ if (StepC->getValue()->isAllOnesValue()) // N % -1 == 0
+ return Start; // 0 - Start/-1 == Start
+
+ // Check to see if Start is divisible by SC with no remainder.
+ if (SCEVConstant *StartC = dyn_cast<SCEVConstant>(Start)) {
+ ConstantInt *StartCC = StartC->getValue();
+ Constant *StartNegC = ConstantExpr::getNeg(StartCC);
+ Constant *Rem = ConstantExpr::getSRem(StartNegC, StepC->getValue());
+ if (Rem->isNullValue()) {
+ Constant *Result =ConstantExpr::getSDiv(StartNegC,StepC->getValue());
+ return SCEVUnknown::get(Result);
+ }
+ }
+ }
+ } else if (AddRec->isQuadratic() && AddRec->getType()->isInteger()) {
+ // If this is a quadratic (3-term) AddRec {L,+,M,+,N}, find the roots of
+ // the quadratic equation to solve it.
+ std::pair<SCEVHandle,SCEVHandle> Roots = SolveQuadraticEquation(AddRec);
+ SCEVConstant *R1 = dyn_cast<SCEVConstant>(Roots.first);
+ SCEVConstant *R2 = dyn_cast<SCEVConstant>(Roots.second);
+ if (R1) {
+#if 0
+ cerr << "HFTZ: " << *V << " - sol#1: " << *R1
+ << " sol#2: " << *R2 << "\n";
+#endif
+ // Pick the smallest positive root value.
+ if (ConstantInt *CB =
+ dyn_cast<ConstantInt>(ConstantExpr::getICmp(ICmpInst::ICMP_ULT,
+ R1->getValue(), R2->getValue()))) {
+ if (CB->getZExtValue() == false)
+ std::swap(R1, R2); // R1 is the minimum root now.
+
+ // We can only use this value if the chrec ends up with an exact zero
+ // value at this index. When solving for "X*X != 5", for example, we
+ // should not accept a root of 2.
+ SCEVHandle Val = AddRec->evaluateAtIteration(R1);
+ if (SCEVConstant *EvalVal = dyn_cast<SCEVConstant>(Val))
+ if (EvalVal->getValue()->isZero())
+ return R1; // We found a quadratic root!
+ }
+ }
+ }
+
+ return UnknownValue;
+}
+
+/// HowFarToNonZero - Return the number of times a backedge checking the
+/// specified value for nonzero will execute. If not computable, return
+/// UnknownValue
+SCEVHandle ScalarEvolutionsImpl::HowFarToNonZero(SCEV *V, const Loop *L) {
+ // Loops that look like: while (X == 0) are very strange indeed. We don't
+ // handle them yet except for the trivial case. This could be expanded in the
+ // future as needed.
+
+ // If the value is a constant, check to see if it is known to be non-zero
+ // already. If so, the backedge will execute zero times.
+ if (SCEVConstant *C = dyn_cast<SCEVConstant>(V)) {
+ Constant *Zero = Constant::getNullValue(C->getValue()->getType());
+ Constant *NonZero =
+ ConstantExpr::getICmp(ICmpInst::ICMP_NE, C->getValue(), Zero);
+ if (NonZero == ConstantInt::getTrue())
+ return getSCEV(Zero);
+ return UnknownValue; // Otherwise it will loop infinitely.
+ }
+
+ // We could implement others, but I really doubt anyone writes loops like
+ // this, and if they did, they would already be constant folded.
+ return UnknownValue;
+}
+
+/// HowManyLessThans - Return the number of times a backedge containing the
+/// specified less-than comparison will execute. If not computable, return
+/// UnknownValue.
+SCEVHandle ScalarEvolutionsImpl::
+HowManyLessThans(SCEV *LHS, SCEV *RHS, const Loop *L) {
+ // Only handle: "ADDREC < LoopInvariant".
+ if (!RHS->isLoopInvariant(L)) return UnknownValue;
+
+ SCEVAddRecExpr *AddRec = dyn_cast<SCEVAddRecExpr>(LHS);
+ if (!AddRec || AddRec->getLoop() != L)
+ return UnknownValue;
+
+ if (AddRec->isAffine()) {
+ // FORNOW: We only support unit strides.
+ SCEVHandle One = SCEVUnknown::getIntegerSCEV(1, RHS->getType());
+ if (AddRec->getOperand(1) != One)
+ return UnknownValue;
+
+ // The number of iterations for "[n,+,1] < m", is m-n. However, we don't
+ // know that m is >= n on input to the loop. If it is, the condition return
+ // true zero times. What we really should return, for full generality, is
+ // SMAX(0, m-n). Since we cannot check this, we will instead check for a
+ // canonical loop form: most do-loops will have a check that dominates the
+ // loop, that only enters the loop if [n-1]<m. If we can find this check,
+ // we know that the SMAX will evaluate to m-n, because we know that m >= n.
+
+ // Search for the check.
+ BasicBlock *Preheader = L->getLoopPreheader();
+ BasicBlock *PreheaderDest = L->getHeader();
+ if (Preheader == 0) return UnknownValue;
+
+ BranchInst *LoopEntryPredicate =
+ dyn_cast<BranchInst>(Preheader->getTerminator());
+ if (!LoopEntryPredicate) return UnknownValue;
+
+ // This might be a critical edge broken out. If the loop preheader ends in
+ // an unconditional branch to the loop, check to see if the preheader has a
+ // single predecessor, and if so, look for its terminator.
+ while (LoopEntryPredicate->isUnconditional()) {
+ PreheaderDest = Preheader;
+ Preheader = Preheader->getSinglePredecessor();
+ if (!Preheader) return UnknownValue; // Multiple preds.
+
+ LoopEntryPredicate =
+ dyn_cast<BranchInst>(Preheader->getTerminator());
+ if (!LoopEntryPredicate) return UnknownValue;
+ }
+
+ // Now that we found a conditional branch that dominates the loop, check to
+ // see if it is the comparison we are looking for.
+ if (ICmpInst *ICI = dyn_cast<ICmpInst>(LoopEntryPredicate->getCondition())){
+ Value *PreCondLHS = ICI->getOperand(0);
+ Value *PreCondRHS = ICI->getOperand(1);
+ ICmpInst::Predicate Cond;
+ if (LoopEntryPredicate->getSuccessor(0) == PreheaderDest)
+ Cond = ICI->getPredicate();
+ else
+ Cond = ICI->getInversePredicate();
+
+ switch (Cond) {
+ case ICmpInst::ICMP_UGT:
+ std::swap(PreCondLHS, PreCondRHS);
+ Cond = ICmpInst::ICMP_ULT;
+ break;
+ case ICmpInst::ICMP_SGT:
+ std::swap(PreCondLHS, PreCondRHS);
+ Cond = ICmpInst::ICMP_SLT;
+ break;
+ default: break;
+ }
+
+ if (Cond == ICmpInst::ICMP_SLT) {
+ if (PreCondLHS->getType()->isInteger()) {
+ if (RHS != getSCEV(PreCondRHS))
+ return UnknownValue; // Not a comparison against 'm'.
+
+ if (SCEV::getMinusSCEV(AddRec->getOperand(0), One)
+ != getSCEV(PreCondLHS))
+ return UnknownValue; // Not a comparison against 'n-1'.
+ }
+ else return UnknownValue;
+ } else if (Cond == ICmpInst::ICMP_ULT)
+ return UnknownValue;
+
+ // cerr << "Computed Loop Trip Count as: "
+ // << // *SCEV::getMinusSCEV(RHS, AddRec->getOperand(0)) << "\n";
+ return SCEV::getMinusSCEV(RHS, AddRec->getOperand(0));
+ }
+ else
+ return UnknownValue;
+ }
+
+ return UnknownValue;
+}
+
+/// getNumIterationsInRange - Return the number of iterations of this loop that
+/// produce values in the specified constant range. Another way of looking at
+/// this is that it returns the first iteration number where the value is not in
+/// the condition, thus computing the exit count. If the iteration count can't
+/// be computed, an instance of SCEVCouldNotCompute is returned.
+SCEVHandle SCEVAddRecExpr::getNumIterationsInRange(ConstantRange Range) const {
+ if (Range.isFullSet()) // Infinite loop.
+ return new SCEVCouldNotCompute();
+
+ // If the start is a non-zero constant, shift the range to simplify things.
+ if (SCEVConstant *SC = dyn_cast<SCEVConstant>(getStart()))
+ if (!SC->getValue()->isZero()) {
+ std::vector<SCEVHandle> Operands(op_begin(), op_end());
+ Operands[0] = SCEVUnknown::getIntegerSCEV(0, SC->getType());
+ SCEVHandle Shifted = SCEVAddRecExpr::get(Operands, getLoop());
+ if (SCEVAddRecExpr *ShiftedAddRec = dyn_cast<SCEVAddRecExpr>(Shifted))
+ return ShiftedAddRec->getNumIterationsInRange(
+ Range.subtract(SC->getValue()->getValue()));
+ // This is strange and shouldn't happen.
+ return new SCEVCouldNotCompute();
+ }
+
+ // The only time we can solve this is when we have all constant indices.
+ // Otherwise, we cannot determine the overflow conditions.
+ for (unsigned i = 0, e = getNumOperands(); i != e; ++i)
+ if (!isa<SCEVConstant>(getOperand(i)))
+ return new SCEVCouldNotCompute();
+
+
+ // Okay at this point we know that all elements of the chrec are constants and
+ // that the start element is zero.
+
+ // First check to see if the range contains zero. If not, the first
+ // iteration exits.
+ if (!Range.contains(APInt(getBitWidth(),0)))
+ return SCEVConstant::get(ConstantInt::get(getType(),0));
+
+ if (isAffine()) {
+ // If this is an affine expression then we have this situation:
+ // Solve {0,+,A} in Range === Ax in Range
+
+ // We know that zero is in the range. If A is positive then we know that
+ // the upper value of the range must be the first possible exit value.
+ // If A is negative then the lower of the range is the last possible loop
+ // value. Also note that we already checked for a full range.
+ APInt One(getBitWidth(),1);
+ APInt A = cast<SCEVConstant>(getOperand(1))->getValue()->getValue();
+ APInt End = A.sge(One) ? (Range.getUpper() - One) : Range.getLower();
+
+ // The exit value should be (End+A)/A.
+ APInt ExitVal = (End + A).sdiv(A);
+ ConstantInt *ExitValue = ConstantInt::get(ExitVal);
+
+ // Evaluate at the exit value. If we really did fall out of the valid
+ // range, then we computed our trip count, otherwise wrap around or other
+ // things must have happened.
+ ConstantInt *Val = EvaluateConstantChrecAtConstant(this, ExitValue);
+ if (Range.contains(Val->getValue()))
+ return new SCEVCouldNotCompute(); // Something strange happened
+
+ // Ensure that the previous value is in the range. This is a sanity check.
+ assert(Range.contains(
+ EvaluateConstantChrecAtConstant(this,
+ ConstantInt::get(ExitVal - One))->getValue()) &&
+ "Linear scev computation is off in a bad way!");
+ return SCEVConstant::get(ExitValue);
+ } else if (isQuadratic()) {
+ // If this is a quadratic (3-term) AddRec {L,+,M,+,N}, find the roots of the
+ // quadratic equation to solve it. To do this, we must frame our problem in
+ // terms of figuring out when zero is crossed, instead of when
+ // Range.getUpper() is crossed.
+ std::vector<SCEVHandle> NewOps(op_begin(), op_end());
+ NewOps[0] = SCEV::getNegativeSCEV(SCEVConstant::get(Range.getUpper()));
+ SCEVHandle NewAddRec = SCEVAddRecExpr::get(NewOps, getLoop());
+
+ // Next, solve the constructed addrec
+ std::pair<SCEVHandle,SCEVHandle> Roots =
+ SolveQuadraticEquation(cast<SCEVAddRecExpr>(NewAddRec));
+ SCEVConstant *R1 = dyn_cast<SCEVConstant>(Roots.first);
+ SCEVConstant *R2 = dyn_cast<SCEVConstant>(Roots.second);
+ if (R1) {
+ // Pick the smallest positive root value.
+ if (ConstantInt *CB =
+ dyn_cast<ConstantInt>(ConstantExpr::getICmp(ICmpInst::ICMP_ULT,
+ R1->getValue(), R2->getValue()))) {
+ if (CB->getZExtValue() == false)
+ std::swap(R1, R2); // R1 is the minimum root now.
+
+ // Make sure the root is not off by one. The returned iteration should
+ // not be in the range, but the previous one should be. When solving
+ // for "X*X < 5", for example, we should not return a root of 2.
+ ConstantInt *R1Val = EvaluateConstantChrecAtConstant(this,
+ R1->getValue());
+ if (Range.contains(R1Val->getValue())) {
+ // The next iteration must be out of the range...
+ ConstantInt *NextVal = ConstantInt::get(R1->getValue()->getValue()+1);
+
+ R1Val = EvaluateConstantChrecAtConstant(this, NextVal);
+ if (!Range.contains(R1Val->getValue()))
+ return SCEVConstant::get(NextVal);
+ return new SCEVCouldNotCompute(); // Something strange happened
+ }
+
+ // If R1 was not in the range, then it is a good return value. Make
+ // sure that R1-1 WAS in the range though, just in case.
+ ConstantInt *NextVal = ConstantInt::get(R1->getValue()->getValue()-1);
+ R1Val = EvaluateConstantChrecAtConstant(this, NextVal);
+ if (Range.contains(R1Val->getValue()))
+ return R1;
+ return new SCEVCouldNotCompute(); // Something strange happened
+ }
+ }
+ }
+
+ // Fallback, if this is a general polynomial, figure out the progression
+ // through brute force: evaluate until we find an iteration that fails the
+ // test. This is likely to be slow, but getting an accurate trip count is
+ // incredibly important, we will be able to simplify the exit test a lot, and
+ // we are almost guaranteed to get a trip count in this case.
+ ConstantInt *TestVal = ConstantInt::get(getType(), 0);
+ ConstantInt *EndVal = TestVal; // Stop when we wrap around.
+ do {
+ ++NumBruteForceEvaluations;
+ SCEVHandle Val = evaluateAtIteration(SCEVConstant::get(TestVal));
+ if (!isa<SCEVConstant>(Val)) // This shouldn't happen.
+ return new SCEVCouldNotCompute();
+
+ // Check to see if we found the value!
+ if (!Range.contains(cast<SCEVConstant>(Val)->getValue()->getValue()))
+ return SCEVConstant::get(TestVal);
+
+ // Increment to test the next index.
+ TestVal = ConstantInt::get(TestVal->getValue()+1);
+ } while (TestVal != EndVal);
+
+ return new SCEVCouldNotCompute();
+}
+
+
+
+//===----------------------------------------------------------------------===//
+// ScalarEvolution Class Implementation
+//===----------------------------------------------------------------------===//
+
+bool ScalarEvolution::runOnFunction(Function &F) {
+ Impl = new ScalarEvolutionsImpl(F, getAnalysis<LoopInfo>());
+ return false;
+}
+
+void ScalarEvolution::releaseMemory() {
+ delete (ScalarEvolutionsImpl*)Impl;
+ Impl = 0;
+}
+
+void ScalarEvolution::getAnalysisUsage(AnalysisUsage &AU) const {
+ AU.setPreservesAll();
+ AU.addRequiredTransitive<LoopInfo>();
+}
+
+SCEVHandle ScalarEvolution::getSCEV(Value *V) const {
+ return ((ScalarEvolutionsImpl*)Impl)->getSCEV(V);
+}
+
+/// hasSCEV - Return true if the SCEV for this value has already been
+/// computed.
+bool ScalarEvolution::hasSCEV(Value *V) const {
+ return ((ScalarEvolutionsImpl*)Impl)->hasSCEV(V);
+}
+
+
+/// setSCEV - Insert the specified SCEV into the map of current SCEVs for
+/// the specified value.
+void ScalarEvolution::setSCEV(Value *V, const SCEVHandle &H) {
+ ((ScalarEvolutionsImpl*)Impl)->setSCEV(V, H);
+}
+
+
+SCEVHandle ScalarEvolution::getIterationCount(const Loop *L) const {
+ return ((ScalarEvolutionsImpl*)Impl)->getIterationCount(L);
+}
+
+bool ScalarEvolution::hasLoopInvariantIterationCount(const Loop *L) const {
+ return !isa<SCEVCouldNotCompute>(getIterationCount(L));
+}
+
+SCEVHandle ScalarEvolution::getSCEVAtScope(Value *V, const Loop *L) const {
+ return ((ScalarEvolutionsImpl*)Impl)->getSCEVAtScope(getSCEV(V), L);
+}
+
+void ScalarEvolution::deleteValueFromRecords(Value *V) const {
+ return ((ScalarEvolutionsImpl*)Impl)->deleteValueFromRecords(V);
+}
+
+static void PrintLoopInfo(std::ostream &OS, const ScalarEvolution *SE,
+ const Loop *L) {
+ // Print all inner loops first
+ for (Loop::iterator I = L->begin(), E = L->end(); I != E; ++I)
+ PrintLoopInfo(OS, SE, *I);
+
+ cerr << "Loop " << L->getHeader()->getName() << ": ";
+
+ std::vector<BasicBlock*> ExitBlocks;
+ L->getExitBlocks(ExitBlocks);
+ if (ExitBlocks.size() != 1)
+ cerr << "<multiple exits> ";
+
+ if (SE->hasLoopInvariantIterationCount(L)) {
+ cerr << *SE->getIterationCount(L) << " iterations! ";
+ } else {
+ cerr << "Unpredictable iteration count. ";
+ }
+
+ cerr << "\n";
+}
+
+void ScalarEvolution::print(std::ostream &OS, const Module* ) const {
+ Function &F = ((ScalarEvolutionsImpl*)Impl)->F;
+ LoopInfo &LI = ((ScalarEvolutionsImpl*)Impl)->LI;
+
+ OS << "Classifying expressions for: " << F.getName() << "\n";
+ for (inst_iterator I = inst_begin(F), E = inst_end(F); I != E; ++I)
+ if (I->getType()->isInteger()) {
+ OS << *I;
+ OS << " --> ";
+ SCEVHandle SV = getSCEV(&*I);
+ SV->print(OS);
+ OS << "\t\t";
+
+ if ((*I).getType()->isInteger()) {
+ ConstantRange Bounds = SV->getValueRange();
+ if (!Bounds.isFullSet())
+ OS << "Bounds: " << Bounds << " ";
+ }
+
+ if (const Loop *L = LI.getLoopFor((*I).getParent())) {
+ OS << "Exits: ";
+ SCEVHandle ExitValue = getSCEVAtScope(&*I, L->getParentLoop());
+ if (isa<SCEVCouldNotCompute>(ExitValue)) {
+ OS << "<<Unknown>>";
+ } else {
+ OS << *ExitValue;
+ }
+ }
+
+
+ OS << "\n";
+ }
+
+ OS << "Determining loop execution counts for: " << F.getName() << "\n";
+ for (LoopInfo::iterator I = LI.begin(), E = LI.end(); I != E; ++I)
+ PrintLoopInfo(OS, this, *I);
+}
+
diff --git a/lib/Analysis/ScalarEvolutionExpander.cpp b/lib/Analysis/ScalarEvolutionExpander.cpp
new file mode 100644
index 0000000..3e590d6
--- /dev/null
+++ b/lib/Analysis/ScalarEvolutionExpander.cpp
@@ -0,0 +1,209 @@
+//===- ScalarEvolutionExpander.cpp - Scalar Evolution Analysis --*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains the implementation of the scalar evolution expander,
+// which is used to generate the code corresponding to a given scalar evolution
+// expression.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Analysis/ScalarEvolutionExpander.h"
+#include "llvm/Analysis/LoopInfo.h"
+using namespace llvm;
+
+/// InsertCastOfTo - Insert a cast of V to the specified type, doing what
+/// we can to share the casts.
+Value *SCEVExpander::InsertCastOfTo(Instruction::CastOps opcode, Value *V,
+ const Type *Ty) {
+ // FIXME: keep track of the cast instruction.
+ if (Constant *C = dyn_cast<Constant>(V))
+ return ConstantExpr::getCast(opcode, C, Ty);
+
+ if (Argument *A = dyn_cast<Argument>(V)) {
+ // Check to see if there is already a cast!
+ for (Value::use_iterator UI = A->use_begin(), E = A->use_end();
+ UI != E; ++UI) {
+ if ((*UI)->getType() == Ty)
+ if (CastInst *CI = dyn_cast<CastInst>(cast<Instruction>(*UI))) {
+ // If the cast isn't the first instruction of the function, move it.
+ if (BasicBlock::iterator(CI) !=
+ A->getParent()->getEntryBlock().begin()) {
+ CI->moveBefore(A->getParent()->getEntryBlock().begin());
+ }
+ return CI;
+ }
+ }
+ return CastInst::create(opcode, V, Ty, V->getName(),
+ A->getParent()->getEntryBlock().begin());
+ }
+
+ Instruction *I = cast<Instruction>(V);
+
+ // Check to see if there is already a cast. If there is, use it.
+ for (Value::use_iterator UI = I->use_begin(), E = I->use_end();
+ UI != E; ++UI) {
+ if ((*UI)->getType() == Ty)
+ if (CastInst *CI = dyn_cast<CastInst>(cast<Instruction>(*UI))) {
+ BasicBlock::iterator It = I; ++It;
+ if (isa<InvokeInst>(I))
+ It = cast<InvokeInst>(I)->getNormalDest()->begin();
+ while (isa<PHINode>(It)) ++It;
+ if (It != BasicBlock::iterator(CI)) {
+ // Splice the cast immediately after the operand in question.
+ CI->moveBefore(It);
+ }
+ return CI;
+ }
+ }
+ BasicBlock::iterator IP = I; ++IP;
+ if (InvokeInst *II = dyn_cast<InvokeInst>(I))
+ IP = II->getNormalDest()->begin();
+ while (isa<PHINode>(IP)) ++IP;
+ return CastInst::create(opcode, V, Ty, V->getName(), IP);
+}
+
+/// InsertBinop - Insert the specified binary operator, doing a small amount
+/// of work to avoid inserting an obviously redundant operation.
+Value *SCEVExpander::InsertBinop(Instruction::BinaryOps Opcode, Value *LHS,
+ Value *RHS, Instruction *&InsertPt) {
+ // Fold a binop with constant operands.
+ if (Constant *CLHS = dyn_cast<Constant>(LHS))
+ if (Constant *CRHS = dyn_cast<Constant>(RHS))
+ return ConstantExpr::get(Opcode, CLHS, CRHS);
+
+ // Do a quick scan to see if we have this binop nearby. If so, reuse it.
+ unsigned ScanLimit = 6;
+ for (BasicBlock::iterator IP = InsertPt, E = InsertPt->getParent()->begin();
+ ScanLimit; --IP, --ScanLimit) {
+ if (BinaryOperator *BinOp = dyn_cast<BinaryOperator>(IP))
+ if (BinOp->getOpcode() == Opcode && BinOp->getOperand(0) == LHS &&
+ BinOp->getOperand(1) == RHS) {
+ // If we found the instruction *at* the insert point, insert later
+ // instructions after it.
+ if (BinOp == InsertPt)
+ InsertPt = ++IP;
+ return BinOp;
+ }
+ if (IP == E) break;
+ }
+
+ // If we don't have
+ return BinaryOperator::create(Opcode, LHS, RHS, "tmp.", InsertPt);
+}
+
+Value *SCEVExpander::visitMulExpr(SCEVMulExpr *S) {
+ int FirstOp = 0; // Set if we should emit a subtract.
+ if (SCEVConstant *SC = dyn_cast<SCEVConstant>(S->getOperand(0)))
+ if (SC->getValue()->isAllOnesValue())
+ FirstOp = 1;
+
+ int i = S->getNumOperands()-2;
+ Value *V = expand(S->getOperand(i+1));
+
+ // Emit a bunch of multiply instructions
+ for (; i >= FirstOp; --i)
+ V = InsertBinop(Instruction::Mul, V, expand(S->getOperand(i)),
+ InsertPt);
+ // -1 * ... ---> 0 - ...
+ if (FirstOp == 1)
+ V = InsertBinop(Instruction::Sub, Constant::getNullValue(V->getType()), V,
+ InsertPt);
+ return V;
+}
+
+Value *SCEVExpander::visitAddRecExpr(SCEVAddRecExpr *S) {
+ const Type *Ty = S->getType();
+ const Loop *L = S->getLoop();
+ // We cannot yet do fp recurrences, e.g. the xform of {X,+,F} --> X+{0,+,F}
+ assert(Ty->isInteger() && "Cannot expand fp recurrences yet!");
+
+ // {X,+,F} --> X + {0,+,F}
+ if (!isa<SCEVConstant>(S->getStart()) ||
+ !cast<SCEVConstant>(S->getStart())->getValue()->isZero()) {
+ Value *Start = expand(S->getStart());
+ std::vector<SCEVHandle> NewOps(S->op_begin(), S->op_end());
+ NewOps[0] = SCEVUnknown::getIntegerSCEV(0, Ty);
+ Value *Rest = expand(SCEVAddRecExpr::get(NewOps, L));
+
+ // FIXME: look for an existing add to use.
+ return InsertBinop(Instruction::Add, Rest, Start, InsertPt);
+ }
+
+ // {0,+,1} --> Insert a canonical induction variable into the loop!
+ if (S->getNumOperands() == 2 &&
+ S->getOperand(1) == SCEVUnknown::getIntegerSCEV(1, Ty)) {
+ // Create and insert the PHI node for the induction variable in the
+ // specified loop.
+ BasicBlock *Header = L->getHeader();
+ PHINode *PN = new PHINode(Ty, "indvar", Header->begin());
+ PN->addIncoming(Constant::getNullValue(Ty), L->getLoopPreheader());
+
+ pred_iterator HPI = pred_begin(Header);
+ assert(HPI != pred_end(Header) && "Loop with zero preds???");
+ if (!L->contains(*HPI)) ++HPI;
+ assert(HPI != pred_end(Header) && L->contains(*HPI) &&
+ "No backedge in loop?");
+
+ // Insert a unit add instruction right before the terminator corresponding
+ // to the back-edge.
+ Constant *One = ConstantInt::get(Ty, 1);
+ Instruction *Add = BinaryOperator::createAdd(PN, One, "indvar.next",
+ (*HPI)->getTerminator());
+
+ pred_iterator PI = pred_begin(Header);
+ if (*PI == L->getLoopPreheader())
+ ++PI;
+ PN->addIncoming(Add, *PI);
+ return PN;
+ }
+
+ // Get the canonical induction variable I for this loop.
+ Value *I = getOrInsertCanonicalInductionVariable(L, Ty);
+
+ // If this is a simple linear addrec, emit it now as a special case.
+ if (S->getNumOperands() == 2) { // {0,+,F} --> i*F
+ Value *F = expand(S->getOperand(1));
+
+ // IF the step is by one, just return the inserted IV.
+ if (ConstantInt *CI = dyn_cast<ConstantInt>(F))
+ if (CI->getValue() == 1)
+ return I;
+
+ // If the insert point is directly inside of the loop, emit the multiply at
+ // the insert point. Otherwise, L is a loop that is a parent of the insert
+ // point loop. If we can, move the multiply to the outer most loop that it
+ // is safe to be in.
+ Instruction *MulInsertPt = InsertPt;
+ Loop *InsertPtLoop = LI.getLoopFor(MulInsertPt->getParent());
+ if (InsertPtLoop != L && InsertPtLoop &&
+ L->contains(InsertPtLoop->getHeader())) {
+ while (InsertPtLoop != L) {
+ // If we cannot hoist the multiply out of this loop, don't.
+ if (!InsertPtLoop->isLoopInvariant(F)) break;
+
+ // Otherwise, move the insert point to the preheader of the loop.
+ MulInsertPt = InsertPtLoop->getLoopPreheader()->getTerminator();
+ InsertPtLoop = InsertPtLoop->getParentLoop();
+ }
+ }
+
+ return InsertBinop(Instruction::Mul, I, F, MulInsertPt);
+ }
+
+ // If this is a chain of recurrences, turn it into a closed form, using the
+ // folders, then expandCodeFor the closed form. This allows the folders to
+ // simplify the expression without having to build a bunch of special code
+ // into this folder.
+ SCEVHandle IH = SCEVUnknown::get(I); // Get I as a "symbolic" SCEV.
+
+ SCEVHandle V = S->evaluateAtIteration(IH);
+ //cerr << "Evaluated: " << *this << "\n to: " << *V << "\n";
+
+ return expand(V);
+}
diff --git a/lib/Analysis/Trace.cpp b/lib/Analysis/Trace.cpp
new file mode 100644
index 0000000..3e3b1b9
--- /dev/null
+++ b/lib/Analysis/Trace.cpp
@@ -0,0 +1,50 @@
+//===- Trace.cpp - Implementation of Trace class --------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This class represents a single trace of LLVM basic blocks. A trace is a
+// single entry, multiple exit, region of code that is often hot. Trace-based
+// optimizations treat traces almost like they are a large, strange, basic
+// block: because the trace path is assumed to be hot, optimizations for the
+// fall-through path are made at the expense of the non-fall-through paths.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Analysis/Trace.h"
+#include "llvm/Function.h"
+#include "llvm/Assembly/Writer.h"
+#include "llvm/Support/Streams.h"
+using namespace llvm;
+
+Function *Trace::getFunction() const {
+ return getEntryBasicBlock()->getParent();
+}
+
+Module *Trace::getModule() const {
+ return getFunction()->getParent();
+}
+
+/// print - Write trace to output stream.
+///
+void Trace::print(std::ostream &O) const {
+ Function *F = getFunction ();
+ O << "; Trace from function " << F->getName() << ", blocks:\n";
+ for (const_iterator i = begin(), e = end(); i != e; ++i) {
+ O << "; ";
+ WriteAsOperand(O, *i, true, getModule());
+ O << "\n";
+ }
+ O << "; Trace parent function: \n" << *F;
+}
+
+/// dump - Debugger convenience method; writes trace to standard error
+/// output stream.
+///
+void Trace::dump() const {
+ print(cerr);
+}
diff --git a/lib/Analysis/ValueNumbering.cpp b/lib/Analysis/ValueNumbering.cpp
new file mode 100644
index 0000000..bdb9422
--- /dev/null
+++ b/lib/Analysis/ValueNumbering.cpp
@@ -0,0 +1,280 @@
+//===- ValueNumbering.cpp - Value #'ing Implementation ----------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by the LLVM research group and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the non-abstract Value Numbering methods as well as a
+// default implementation for the analysis group.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Analysis/Passes.h"
+#include "llvm/Analysis/ValueNumbering.h"
+#include "llvm/Support/InstVisitor.h"
+#include "llvm/BasicBlock.h"
+#include "llvm/Instructions.h"
+#include "llvm/Pass.h"
+#include "llvm/Type.h"
+#include "llvm/Support/Compiler.h"
+using namespace llvm;
+
+char ValueNumbering::ID = 0;
+// Register the ValueNumbering interface, providing a nice name to refer to.
+static RegisterAnalysisGroup<ValueNumbering> X("Value Numbering");
+
+/// ValueNumbering destructor: DO NOT move this to the header file for
+/// ValueNumbering or else clients of the ValueNumbering class may not depend on
+/// the ValueNumbering.o file in the current .a file, causing alias analysis
+/// support to not be included in the tool correctly!
+///
+ValueNumbering::~ValueNumbering() {}
+
+//===----------------------------------------------------------------------===//
+// Basic ValueNumbering Pass Implementation
+//===----------------------------------------------------------------------===//
+//
+// Because of the way .a files work, the implementation of the BasicVN class
+// MUST be in the ValueNumbering file itself, or else we run the risk of
+// ValueNumbering being used, but the default implementation not being linked
+// into the tool that uses it. As such, we register and implement the class
+// here.
+//
+
+namespace {
+ /// BasicVN - This class is the default implementation of the ValueNumbering
+ /// interface. It walks the SSA def-use chains to trivially identify
+ /// lexically identical expressions. This does not require any ahead of time
+ /// analysis, so it is a very fast default implementation.
+ ///
+ struct VISIBILITY_HIDDEN BasicVN
+ : public ImmutablePass, public ValueNumbering {
+ static char ID; // Class identification, replacement for typeinfo
+ BasicVN() : ImmutablePass((intptr_t)&ID) {}
+
+ /// getEqualNumberNodes - Return nodes with the same value number as the
+ /// specified Value. This fills in the argument vector with any equal
+ /// values.
+ ///
+ /// This is where our implementation is.
+ ///
+ virtual void getEqualNumberNodes(Value *V1,
+ std::vector<Value*> &RetVals) const;
+ };
+
+ char BasicVN::ID = 0;
+ // Register this pass...
+ RegisterPass<BasicVN>
+ X("basicvn", "Basic Value Numbering (default GVN impl)");
+
+ // Declare that we implement the ValueNumbering interface
+ RegisterAnalysisGroup<ValueNumbering, true> Y(X);
+
+ /// BVNImpl - Implement BasicVN in terms of a visitor class that
+ /// handles the different types of instructions as appropriate.
+ ///
+ struct VISIBILITY_HIDDEN BVNImpl : public InstVisitor<BVNImpl> {
+ std::vector<Value*> &RetVals;
+ BVNImpl(std::vector<Value*> &RV) : RetVals(RV) {}
+
+ void visitCastInst(CastInst &I);
+ void visitGetElementPtrInst(GetElementPtrInst &I);
+ void visitCmpInst(CmpInst &I);
+
+ void handleBinaryInst(Instruction &I);
+ void visitBinaryOperator(Instruction &I) { handleBinaryInst(I); }
+ void visitShiftInst(Instruction &I) { handleBinaryInst(I); }
+ void visitExtractElementInst(Instruction &I) { handleBinaryInst(I); }
+
+ void handleTernaryInst(Instruction &I);
+ void visitSelectInst(Instruction &I) { handleTernaryInst(I); }
+ void visitInsertElementInst(Instruction &I) { handleTernaryInst(I); }
+ void visitShuffleVectorInst(Instruction &I) { handleTernaryInst(I); }
+ void visitInstruction(Instruction &) {
+ // Cannot value number calls or terminator instructions.
+ }
+ };
+}
+
+ImmutablePass *llvm::createBasicVNPass() { return new BasicVN(); }
+
+// getEqualNumberNodes - Return nodes with the same value number as the
+// specified Value. This fills in the argument vector with any equal values.
+//
+void BasicVN::getEqualNumberNodes(Value *V, std::vector<Value*> &RetVals) const{
+ assert(V->getType() != Type::VoidTy &&
+ "Can only value number non-void values!");
+ // We can only handle the case where I is an instruction!
+ if (Instruction *I = dyn_cast<Instruction>(V))
+ BVNImpl(RetVals).visit(I);
+}
+
+void BVNImpl::visitCastInst(CastInst &CI) {
+ Instruction &I = (Instruction&)CI;
+ Value *Op = I.getOperand(0);
+ Function *F = I.getParent()->getParent();
+
+ for (Value::use_iterator UI = Op->use_begin(), UE = Op->use_end();
+ UI != UE; ++UI)
+ if (CastInst *Other = dyn_cast<CastInst>(*UI))
+ // Check that the opcode is the same
+ if (Other->getOpcode() == Instruction::CastOps(I.getOpcode()) &&
+ // Check that the destination types are the same
+ Other->getType() == I.getType() &&
+ // Is it embedded in the same function? (This could be false if LHS
+ // is a constant or global!)
+ Other->getParent()->getParent() == F &&
+ // Check to see if this new cast is not I.
+ Other != &I) {
+ // These instructions are identical. Add to list...
+ RetVals.push_back(Other);
+ }
+}
+
+void BVNImpl::visitCmpInst(CmpInst &CI1) {
+ Value *LHS = CI1.getOperand(0);
+ for (Value::use_iterator UI = LHS->use_begin(), UE = LHS->use_end();
+ UI != UE; ++UI)
+ if (CmpInst *CI2 = dyn_cast<CmpInst>(*UI))
+ // Check to see if this compare instruction is not CI, but same opcode,
+ // same predicate, and in the same function.
+ if (CI2 != &CI1 && CI2->getOpcode() == CI1.getOpcode() &&
+ CI2->getPredicate() == CI1.getPredicate() &&
+ CI2->getParent()->getParent() == CI1.getParent()->getParent())
+ // If the operands are the same
+ if ((CI2->getOperand(0) == CI1.getOperand(0) &&
+ CI2->getOperand(1) == CI1.getOperand(1)) ||
+ // Or the compare is commutative and the operands are reversed
+ (CI1.isCommutative() &&
+ CI2->getOperand(0) == CI1.getOperand(1) &&
+ CI2->getOperand(1) == CI1.getOperand(0)))
+ // Then the instructiosn are identical, add to list.
+ RetVals.push_back(CI2);
+}
+
+
+
+// isIdenticalBinaryInst - Return true if the two binary instructions are
+// identical.
+//
+static inline bool isIdenticalBinaryInst(const Instruction &I1,
+ const Instruction *I2) {
+ // Is it embedded in the same function? (This could be false if LHS
+ // is a constant or global!)
+ if (I1.getOpcode() != I2->getOpcode() ||
+ I1.getParent()->getParent() != I2->getParent()->getParent())
+ return false;
+
+ // If they are CmpInst instructions, check their predicates
+ if (CmpInst *CI1 = dyn_cast<CmpInst>(&const_cast<Instruction&>(I1)))
+ if (CI1->getPredicate() != cast<CmpInst>(I2)->getPredicate())
+ return false;
+
+ // They are identical if both operands are the same!
+ if (I1.getOperand(0) == I2->getOperand(0) &&
+ I1.getOperand(1) == I2->getOperand(1))
+ return true;
+
+ // If the instruction is commutative, the instruction can match if the
+ // operands are swapped!
+ //
+ if ((I1.getOperand(0) == I2->getOperand(1) &&
+ I1.getOperand(1) == I2->getOperand(0)) &&
+ I1.isCommutative())
+ return true;
+
+ return false;
+}
+
+// isIdenticalTernaryInst - Return true if the two ternary instructions are
+// identical.
+//
+static inline bool isIdenticalTernaryInst(const Instruction &I1,
+ const Instruction *I2) {
+ // Is it embedded in the same function? (This could be false if LHS
+ // is a constant or global!)
+ if (I1.getParent()->getParent() != I2->getParent()->getParent())
+ return false;
+
+ // They are identical if all operands are the same!
+ return I1.getOperand(0) == I2->getOperand(0) &&
+ I1.getOperand(1) == I2->getOperand(1) &&
+ I1.getOperand(2) == I2->getOperand(2);
+}
+
+
+
+void BVNImpl::handleBinaryInst(Instruction &I) {
+ Value *LHS = I.getOperand(0);
+
+ for (Value::use_iterator UI = LHS->use_begin(), UE = LHS->use_end();
+ UI != UE; ++UI)
+ if (Instruction *Other = dyn_cast<Instruction>(*UI))
+ // Check to see if this new binary operator is not I, but same operand...
+ if (Other != &I && isIdenticalBinaryInst(I, Other)) {
+ // These instructions are identical. Handle the situation.
+ RetVals.push_back(Other);
+ }
+}
+
+// IdenticalComplexInst - Return true if the two instructions are the same, by
+// using a brute force comparison. This is useful for instructions with an
+// arbitrary number of arguments.
+//
+static inline bool IdenticalComplexInst(const Instruction *I1,
+ const Instruction *I2) {
+ assert(I1->getOpcode() == I2->getOpcode());
+ // Equal if they are in the same function...
+ return I1->getParent()->getParent() == I2->getParent()->getParent() &&
+ // And return the same type...
+ I1->getType() == I2->getType() &&
+ // And have the same number of operands...
+ I1->getNumOperands() == I2->getNumOperands() &&
+ // And all of the operands are equal.
+ std::equal(I1->op_begin(), I1->op_end(), I2->op_begin());
+}
+
+void BVNImpl::visitGetElementPtrInst(GetElementPtrInst &I) {
+ Value *Op = I.getOperand(0);
+
+ // Try to pick a local operand if possible instead of a constant or a global
+ // that might have a lot of uses.
+ for (unsigned i = 1, e = I.getNumOperands(); i != e; ++i)
+ if (isa<Instruction>(I.getOperand(i)) || isa<Argument>(I.getOperand(i))) {
+ Op = I.getOperand(i);
+ break;
+ }
+
+ for (Value::use_iterator UI = Op->use_begin(), UE = Op->use_end();
+ UI != UE; ++UI)
+ if (GetElementPtrInst *Other = dyn_cast<GetElementPtrInst>(*UI))
+ // Check to see if this new getelementptr is not I, but same operand...
+ if (Other != &I && IdenticalComplexInst(&I, Other)) {
+ // These instructions are identical. Handle the situation.
+ RetVals.push_back(Other);
+ }
+}
+
+void BVNImpl::handleTernaryInst(Instruction &I) {
+ Value *Op0 = I.getOperand(0);
+ Instruction *OtherInst;
+
+ for (Value::use_iterator UI = Op0->use_begin(), UE = Op0->use_end();
+ UI != UE; ++UI)
+ if ((OtherInst = dyn_cast<Instruction>(*UI)) &&
+ OtherInst->getOpcode() == I.getOpcode()) {
+ // Check to see if this new select is not I, but has the same operands.
+ if (OtherInst != &I && isIdenticalTernaryInst(I, OtherInst)) {
+ // These instructions are identical. Handle the situation.
+ RetVals.push_back(OtherInst);
+ }
+
+ }
+}
+
+
+// Ensure that users of ValueNumbering.h will link with this file
+DEFINING_FILE_FOR(BasicValueNumbering)