aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2005-09-27 05:02:43 +0000
committerChris Lattner <sabre@nondot.org>2005-09-27 05:02:43 +0000
commita9ec8ab32bce9021c9501b45eea6bbc76ffeb207 (patch)
treea5021a8743c49d0e8a1eb91fb6bf64b2c3fa299d
parentdbe298571f72bde7caf7712a173e16cc996973f7 (diff)
Add support for external calls that we know how to constant fold. This implements
ctor-list-opt.ll:CTOR8 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@23465 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Transforms/IPO/GlobalOpt.cpp31
1 files changed, 20 insertions, 11 deletions
diff --git a/lib/Transforms/IPO/GlobalOpt.cpp b/lib/Transforms/IPO/GlobalOpt.cpp
index a3cd8d4f15..3b2eee0531 100644
--- a/lib/Transforms/IPO/GlobalOpt.cpp
+++ b/lib/Transforms/IPO/GlobalOpt.cpp
@@ -1450,21 +1450,30 @@ static bool EvaluateFunction(Function *F, Constant *&RetVal,
// Resolve function pointers.
Function *Callee = dyn_cast<Function>(getVal(Values, CI->getOperand(0)));
if (!Callee) return false; // Cannot resolve.
-
- if (Callee->isExternal() || Callee->getFunctionType()->isVarArg()) {
- return false; // TODO: Constant fold calls.
- }
-
+
std::vector<Constant*> Formals;
for (unsigned i = 1, e = CI->getNumOperands(); i != e; ++i)
Formals.push_back(getVal(Values, CI->getOperand(i)));
- Constant *RetVal;
- // Execute the call, if successful, use the return value.
- if (!EvaluateFunction(Callee, RetVal, Formals, CallStack,
- MutatedMemory, AllocaTmps))
- return false;
- InstResult = RetVal;
+ if (Callee->isExternal()) {
+ // If this is a function we can constant fold, do it.
+ if (Constant *C = ConstantFoldCall(Callee, Formals)) {
+ InstResult = C;
+ } else {
+ return false;
+ }
+ } else {
+ if (Callee->getFunctionType()->isVarArg())
+ return false;
+
+ Constant *RetVal;
+
+ // Execute the call, if successful, use the return value.
+ if (!EvaluateFunction(Callee, RetVal, Formals, CallStack,
+ MutatedMemory, AllocaTmps))
+ return false;
+ InstResult = RetVal;
+ }
} else if (TerminatorInst *TI = dyn_cast<TerminatorInst>(CurInst)) {
BasicBlock *NewBB = 0;
if (BranchInst *BI = dyn_cast<BranchInst>(CurInst)) {