STATISTIC(NumUnified , "Number of variables unified");
STATISTIC(NumErased , "Number of redundant constraints erased");
-namespace {
- const unsigned SelfRep = (unsigned)-1;
- const unsigned Unvisited = (unsigned)-1;
- // Position of the function return node relative to the function node.
- const unsigned CallReturnPos = 1;
- // Position of the function call node relative to the function node.
- const unsigned CallFirstArgPos = 2;
+static const unsigned SelfRep = (unsigned)-1;
+static const unsigned Unvisited = (unsigned)-1;
+// Position of the function return node relative to the function node.
+static const unsigned CallReturnPos = 1;
+// Position of the function call node relative to the function node.
+static const unsigned CallFirstArgPos = 2;
+namespace {
struct BitmapKeyInfo {
static inline SparseBitVector<> *getEmptyKey() {
return reinterpret_cast<SparseBitVector<> *>(-1);
public:
static char ID;
- Andersens() : ModulePass((intptr_t)&ID) {}
+ Andersens() : ModulePass(&ID) {}
bool runOnModule(Module &M) {
InitializeAliasAnalysis(this);
PrintPointsToGraph();
}
};
+}
- char Andersens::ID = 0;
- RegisterPass<Andersens> X("anders-aa",
- "Andersen's Interprocedural Alias Analysis", false,
- true);
- RegisterAnalysisGroup<AliasAnalysis> Y(X);
+char Andersens::ID = 0;
+static RegisterPass<Andersens>
+X("anders-aa", "Andersen's Interprocedural Alias Analysis", false, true);
+static RegisterAnalysisGroup<AliasAnalysis> Y(X);
- // Initialize Timestamp Counter (static).
- unsigned Andersens::Node::Counter = 0;
-}
+// Initialize Timestamp Counter (static).
+unsigned Andersens::Node::Counter = 0;
ModulePass *llvm::createAndersensPass() { return new Andersens(); }
/// object N, which contains values indicated by C.
void Andersens::AddGlobalInitializerConstraints(unsigned NodeIndex,
Constant *C) {
- if (C->getType()->isFirstClassType()) {
+ if (C->getType()->isSingleValueType()) {
if (isa<PointerType>(C->getType()))
Constraints.push_back(Constraint(Constraint::Copy, NodeIndex,
getNodeForConstantPointer(C)));
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() == "llvm.memset" ||
F->getName() == "strcmp" || F->getName() == "strncmp" ||
F->getName() == "execl" || F->getName() == "execlp" ||
F->getName() == "execle" || F->getName() == "execv" ||
// 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" ||
+ if (F->getName() == "llvm.memcpy" ||
+ F->getName() == "llvm.memmove" ||
F->getName() == "memmove") {
- // *Dest = *Src, which requires an artificial graph node to represent the
- // constraint. It is broken up into *Dest = temp, temp = *Src
- unsigned FirstArg = getNode(CS.getArgument(0));
- unsigned SecondArg = getNode(CS.getArgument(1));
- unsigned TempArg = GraphNodes.size();
- GraphNodes.push_back(Node());
- Constraints.push_back(Constraint(Constraint::Store,
- FirstArg, TempArg));
- Constraints.push_back(Constraint(Constraint::Load,
- TempArg, SecondArg));
- // In addition, Dest = Src
- Constraints.push_back(Constraint(Constraint::Copy,
- FirstArg, SecondArg));
- return true;
+ const FunctionType *FTy = F->getFunctionType();
+ if (FTy->getNumParams() > 1 &&
+ isa<PointerType>(FTy->getParamType(0)) &&
+ isa<PointerType>(FTy->getParamType(1))) {
+
+ // *Dest = *Src, which requires an artificial graph node to represent the
+ // constraint. It is broken up into *Dest = temp, temp = *Src
+ unsigned FirstArg = getNode(CS.getArgument(0));
+ unsigned SecondArg = getNode(CS.getArgument(1));
+ unsigned TempArg = GraphNodes.size();
+ GraphNodes.push_back(Node());
+ Constraints.push_back(Constraint(Constraint::Store,
+ FirstArg, TempArg));
+ Constraints.push_back(Constraint(Constraint::Load,
+ TempArg, SecondArg));
+ // In addition, Dest = Src
+ Constraints.push_back(Constraint(Constraint::Copy,
+ FirstArg, SecondArg));
+ 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;
+ const FunctionType *FTy = F->getFunctionType();
+ if (FTy->getNumParams() > 0 &&
+ isa<PointerType>(FTy->getParamType(0))) {
+ Constraints.push_back(Constraint(Constraint::Copy,
+ getNode(CS.getInstruction()),
+ getNode(CS.getArgument(0))));
+ return true;
+ }
}
return false;
// At some point we should just add constraints for the escaping functions
// at solve time, but this slows down solving. For now, we simply mark
// address taken functions as escaping and treat them as external.
- if (!F->hasInternalLinkage() || AnalyzeUsesOfFunction(F))
+ if (!F->hasLocalLinkage() || AnalyzeUsesOfFunction(F))
AddConstraintsForNonInternalLinkage(F);
if (!F->isDeclaration()) {
DOUT << "\n";
if (SDTActive)
- if (SDT[Second] >= 0)
+ if (SDT[Second] >= 0) {
if (SDT[First] < 0)
SDT[First] = SDT[Second];
else {
UniteNodes( FindNode(SDT[First]), FindNode(SDT[Second]) );
First = FindNode(First);
}
+ }
return First;
}