Add SCCP support for constant folding calls, implementing:
authorChris Lattner <sabre@nondot.org>
Tue, 13 Apr 2004 19:43:54 +0000 (19:43 +0000)
committerChris Lattner <sabre@nondot.org>
Tue, 13 Apr 2004 19:43:54 +0000 (19:43 +0000)
test/Regression/Transforms/SCCP/calltest.ll

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@12921 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Transforms/Scalar/SCCP.cpp

index 8d550b82797816a2d41b25b738b8d1f2149f54a5..38a403b1a5d0b3c51fcaa31157f351c23d83022c 100644 (file)
@@ -29,6 +29,7 @@
 #include "llvm/Pass.h"
 #include "llvm/Type.h"
 #include "llvm/Support/InstVisitor.h"
+#include "llvm/Transforms/Utils/Local.h"
 #include "Support/Debug.h"
 #include "Support/Statistic.h"
 #include "Support/STLExtras.h"
@@ -220,7 +221,7 @@ private:
   void visitStoreInst     (Instruction &I) { /*returns void*/ }
   void visitLoadInst      (LoadInst &I);
   void visitGetElementPtrInst(GetElementPtrInst &I);
-  void visitCallInst      (Instruction &I) { markOverdefined(&I); }
+  void visitCallInst      (CallInst &I);
   void visitInvokeInst    (TerminatorInst &I) {
     if (I.getType() != Type::VoidTy) markOverdefined(&I);
     visitTerminatorInst(I);
@@ -777,3 +778,34 @@ void SCCP::visitLoadInst(LoadInst &I) {
   // Bail out.
   markOverdefined(IV, &I);
 }
+
+void SCCP::visitCallInst(CallInst &I) {
+  InstVal &IV = ValueState[&I];
+  if (IV.isOverdefined()) return;
+
+  Function *F = I.getCalledFunction();
+  if (F == 0 || !canConstantFoldCallTo(F)) {
+    markOverdefined(IV, &I);
+    return;
+  }
+
+  std::vector<Constant*> Operands;
+  Operands.reserve(I.getNumOperands()-1);
+
+  for (unsigned i = 1, e = I.getNumOperands(); i != e; ++i) {
+    InstVal &State = getValueState(I.getOperand(i));
+    if (State.isUndefined())
+      return;  // Operands are not resolved yet...
+    else if (State.isOverdefined()) {
+      markOverdefined(IV, &I);
+      return;
+    }
+    assert(State.isConstant() && "Unknown state!");
+    Operands.push_back(State.getConstant());
+  }
+
+  if (Constant *C = ConstantFoldCall(F, Operands))
+    markConstant(IV, &I, C);
+  else
+    markOverdefined(IV, &I);
+}