#include "llvm/Support/Debug.h"
#include "llvm/ADT/Statistic.h"
#include <set>
-#include <iostream>
using namespace llvm;
-namespace {
- Statistic<>
- NumIters("anders-aa", "Number of iterations to reach convergence");
- Statistic<>
- NumConstraints("anders-aa", "Number of constraints");
- Statistic<>
- NumNodes("anders-aa", "Number of nodes");
- Statistic<>
- NumEscapingFunctions("anders-aa", "Number of internal functions that escape");
- Statistic<>
- NumIndirectCallees("anders-aa", "Number of indirect callees found");
+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 Andersens : public ModulePass, public AliasAnalysis,
private InstVisitor<Andersens> {
/// Node class - This class is used to represent a memory object in the
void visitGetElementPtrInst(GetElementPtrInst &GEP);
void visitPHINode(PHINode &PN);
void visitCastInst(CastInst &CI);
- void visitSetCondInst(SetCondInst &SCI) {} // NOOP!
+ void visitICmpInst(ICmpInst &ICI) {} // NOOP!
+ void visitFCmpInst(FCmpInst &ICI) {} // NOOP!
void visitSelectInst(SelectInst &SI);
void visitVAArg(VAArgInst &I);
void visitInstruction(Instruction &I);
if (Function *F = CS.getCalledFunction())
if (F->isExternal()) {
Node *N1 = getNode(P);
- bool PointsToUniversalSet = false;
if (N1->begin() == N1->end())
return NoModRef; // P doesn't point to anything.
switch (CE->getOpcode()) {
case Instruction::GetElementPtr:
return getNodeForConstantPointer(CE->getOperand(0));
- case Instruction::Cast:
- if (isa<PointerType>(CE->getOperand(0)->getType()))
- return getNodeForConstantPointer(CE->getOperand(0));
- else
- return &GraphNodes[UniversalSet];
+ case Instruction::IntToPtr:
+ return &GraphNodes[UniversalSet];
+ case Instruction::BitCast:
+ return getNodeForConstantPointer(CE->getOperand(0));
default:
- std::cerr << "Constant Expr not yet handled: " << *CE << "\n";
+ cerr << "Constant Expr not yet handled: " << *CE << "\n";
assert(0);
}
} else {
switch (CE->getOpcode()) {
case Instruction::GetElementPtr:
return getNodeForConstantPointerTarget(CE->getOperand(0));
- case Instruction::Cast:
- if (isa<PointerType>(CE->getOperand(0)->getType()))
- return getNodeForConstantPointerTarget(CE->getOperand(0));
- else
- return &GraphNodes[UniversalSet];
+ case Instruction::IntToPtr:
+ return &GraphNodes[UniversalSet];
+ case Instruction::BitCast:
+ return getNodeForConstantPointerTarget(CE->getOperand(0));
default:
- std::cerr << "Constant Expr not yet handled: " << *CE << "\n";
+ cerr << "Constant Expr not yet handled: " << *CE << "\n";
assert(0);
}
} else {
case Instruction::Unreachable:
case Instruction::Free:
case Instruction::Shl:
- case Instruction::Shr:
+ case Instruction::LShr:
+ case Instruction::AShr:
+ case Instruction::ICmp:
+ case Instruction::FCmp:
return;
default:
// Is this something we aren't handling yet?
- std::cerr << "Unknown instruction: " << I;
+ cerr << "Unknown instruction: " << I;
abort();
}
}
while (Changed) {
Changed = false;
++NumIters;
- DEBUG(std::cerr << "Starting iteration #" << Iteration++ << "!\n");
+ 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) {
// We found a function that is just now escaping. Mark it as if it
// didn't have internal linkage.
AddConstraintsForNonInternalLinkage(F);
- DEBUG(std::cerr << "Found escaping internal function: "
- << F->getName() << "\n");
+ DOUT << "Found escaping internal function: " << F->getName() <<"\n";
++NumEscapingFunctions;
}
if (IP == KnownCallees.end() || *IP != F) {
// Add the constraints for the call now.
AddConstraintsForCall(CS, F);
- DEBUG(std::cerr << "Found actual callee '"
- << F->getName() << "' for call: "
- << *CS.getInstruction() << "\n");
+ DOUT << "Found actual callee '"
+ << F->getName() << "' for call: "
+ << *CS.getInstruction() << "\n";
++NumIndirectCallees;
KnownCallees.insert(IP, F);
}
void Andersens::PrintNode(Node *N) {
if (N == &GraphNodes[UniversalSet]) {
- std::cerr << "<universal>";
+ cerr << "<universal>";
return;
} else if (N == &GraphNodes[NullPtr]) {
- std::cerr << "<nullptr>";
+ cerr << "<nullptr>";
return;
} else if (N == &GraphNodes[NullObject]) {
- std::cerr << "<null>";
+ cerr << "<null>";
return;
}
if (Function *F = dyn_cast<Function>(V)) {
if (isa<PointerType>(F->getFunctionType()->getReturnType()) &&
N == getReturnNode(F)) {
- std::cerr << F->getName() << ":retval";
+ cerr << F->getName() << ":retval";
return;
} else if (F->getFunctionType()->isVarArg() && N == getVarargNode(F)) {
- std::cerr << F->getName() << ":vararg";
+ cerr << F->getName() << ":vararg";
return;
}
}
if (Instruction *I = dyn_cast<Instruction>(V))
- std::cerr << I->getParent()->getParent()->getName() << ":";
+ cerr << I->getParent()->getParent()->getName() << ":";
else if (Argument *Arg = dyn_cast<Argument>(V))
- std::cerr << Arg->getParent()->getName() << ":";
+ cerr << Arg->getParent()->getName() << ":";
if (V->hasName())
- std::cerr << V->getName();
+ cerr << V->getName();
else
- std::cerr << "(unnamed)";
+ cerr << "(unnamed)";
if (isa<GlobalValue>(V) || isa<AllocationInst>(V))
if (N == getObject(V))
- std::cerr << "<mem>";
+ cerr << "<mem>";
}
void Andersens::PrintConstraints() {
- std::cerr << "Constraints:\n";
+ cerr << "Constraints:\n";
for (unsigned i = 0, e = Constraints.size(); i != e; ++i) {
- std::cerr << " #" << i << ": ";
+ cerr << " #" << i << ": ";
Constraint &C = Constraints[i];
if (C.Type == Constraint::Store)
- std::cerr << "*";
+ cerr << "*";
PrintNode(C.Dest);
- std::cerr << " = ";
+ cerr << " = ";
if (C.Type == Constraint::Load)
- std::cerr << "*";
+ cerr << "*";
PrintNode(C.Src);
- std::cerr << "\n";
+ cerr << "\n";
}
}
void Andersens::PrintPointsToGraph() {
- std::cerr << "Points-to graph:\n";
+ cerr << "Points-to graph:\n";
for (unsigned i = 0, e = GraphNodes.size(); i != e; ++i) {
Node *N = &GraphNodes[i];
- std::cerr << "[" << (N->end() - N->begin()) << "] ";
+ cerr << "[" << (N->end() - N->begin()) << "] ";
PrintNode(N);
- std::cerr << "\t--> ";
+ cerr << "\t--> ";
for (Node::iterator I = N->begin(), E = N->end(); I != E; ++I) {
- if (I != N->begin()) std::cerr << ", ";
+ if (I != N->begin()) cerr << ", ";
PrintNode(*I);
}
- std::cerr << "\n";
+ cerr << "\n";
}
}