summaryrefslogtreecommitdiff
path: root/lib/Analysis/IPA
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2005-03-29 06:09:07 +0000
committerChris Lattner <sabre@nondot.org>2005-03-29 06:09:07 +0000
commit8a44643d613c5f01209ac147d7fc9432b0ced901 (patch)
tree55bf7fea14081760ec05c62aa1284dffd201a1f6 /lib/Analysis/IPA
parentf3d08f31b37fd9c6610c5894e93c698f00a440e9 (diff)
downloadllvm-8a44643d613c5f01209ac147d7fc9432b0ced901.tar.gz
llvm-8a44643d613c5f01209ac147d7fc9432b0ced901.tar.bz2
llvm-8a44643d613c5f01209ac147d7fc9432b0ced901.tar.xz
Handle "known" external calls context sensitively, add support for realloc
and a couple of other functions that are important. Handle aggregate undef values for gv initializers git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@20914 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Analysis/IPA')
-rw-r--r--lib/Analysis/IPA/Andersens.cpp46
1 files changed, 29 insertions, 17 deletions
diff --git a/lib/Analysis/IPA/Andersens.cpp b/lib/Analysis/IPA/Andersens.cpp
index f1ad3b44cf..c665038aa1 100644
--- a/lib/Analysis/IPA/Andersens.cpp
+++ b/lib/Analysis/IPA/Andersens.cpp
@@ -306,8 +306,8 @@ namespace {
void AddGlobalInitializerConstraints(Node *N, Constant *C);
void AddConstraintsForNonInternalLinkage(Function *F);
- bool AddConstraintsForExternalFunction(Function *F);
void AddConstraintsForCall(CallSite CS, Function *F);
+ bool AddConstraintsForExternalCall(CallSite CS, Function *F);
void PrintNode(Node *N);
@@ -581,7 +581,7 @@ void Andersens::AddGlobalInitializerConstraints(Node *N, Constant *C) {
} else if (C->isNullValue()) {
N->addPointerTo(&GraphNodes[NullObject]);
return;
- } else {
+ } 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)
@@ -601,32 +601,41 @@ void Andersens::AddConstraintsForNonInternalLinkage(Function *F) {
&GraphNodes[UniversalSet]));
}
-/// AddConstraintsForExternalFunction - If this is a call to a "known" function,
-/// add the constraints and return false. If this is a call to an unknown
-/// function, return true.
-bool Andersens::AddConstraintsForExternalFunction(Function *F) {
+/// 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->isExternal() && "Not an external function!");
// These functions don't induce any points-to constraints.
if (F->getName() == "printf" || F->getName() == "fprintf" ||
+ F->getName() == "fgets" ||
F->getName() == "open" || F->getName() == "fopen" ||
- F->getName() == "atoi" ||
+ F->getName() == "fclose" || F->getName() == "fflush" ||
+ F->getName() == "atoi" || F->getName() == "sscanf" ||
F->getName() == "llvm.memset" || F->getName() == "memcmp" ||
F->getName() == "read" || F->getName() == "write")
- return false;
+ return true;
// These functions do induce points-to edges.
if (F->getName() == "llvm.memcpy" || F->getName() == "llvm.memmove") {
- Function::arg_iterator Dst = F->arg_begin(), Src = Dst;
// Note: this is a poor approximation, this says Dest = Src, instead of
// *Dest = *Src.
- ++Src;
- Constraints.push_back(Constraint(Constraint::Copy, getNode(Dst),
- getNode(Src)));
- return false;
+ Constraints.push_back(Constraint(Constraint::Copy,
+ getNode(CS.getArgument(0)),
+ getNode(CS.getArgument(1))));
+ return true;
}
- return true;
+ if (F->getName() == "realloc") {
+ // Result = Arg
+ Constraints.push_back(Constraint(Constraint::Copy,
+ getNode(CS.getInstruction()),
+ getNode(CS.getArgument(0))));
+ return true;
+ }
+
+ return false;
}
@@ -689,9 +698,7 @@ void Andersens::CollectConstraints(Module &M) {
// 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 if (AddConstraintsForExternalFunction(F)) {
- // If we don't "know" about this function, assume the worst.
-
+ } else {
// External functions that return pointers return the universal set.
if (isa<PointerType>(F->getFunctionType()->getReturnType()))
Constraints.push_back(Constraint(Constraint::Copy,
@@ -836,6 +843,11 @@ void Andersens::visitVAArg(VAArgInst &I) {
/// 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->isExternal() && AddConstraintsForExternalCall(CS, F))
+ return;
+
if (isa<PointerType>(CS.getType())) {
Node *CSN = getNode(CS.getInstruction());
if (isa<PointerType>(F->getFunctionType()->getReturnType())) {