[llvm-commits] [llvm] r48254 - in /llvm/trunk: lib/Transforms/IPO/IPConstantPropagation.cpp test/Transforms/IPConstantProp/return-constants.ll

Devang Patel dpatel at apple.com
Tue Mar 11 15:24:29 PDT 2008


Author: dpatel
Date: Tue Mar 11 17:24:29 2008
New Revision: 48254

URL: http://llvm.org/viewvc/llvm-project?rev=48254&view=rev
Log:
Handle multiple ret values.

Added:
    llvm/trunk/test/Transforms/IPConstantProp/return-constants.ll
Modified:
    llvm/trunk/lib/Transforms/IPO/IPConstantPropagation.cpp

Modified: llvm/trunk/lib/Transforms/IPO/IPConstantPropagation.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/IPO/IPConstantPropagation.cpp?rev=48254&r1=48253&r2=48254&view=diff

==============================================================================
--- llvm/trunk/lib/Transforms/IPO/IPConstantPropagation.cpp (original)
+++ llvm/trunk/lib/Transforms/IPO/IPConstantPropagation.cpp Tue Mar 11 17:24:29 2008
@@ -24,6 +24,7 @@
 #include "llvm/Support/CallSite.h"
 #include "llvm/Support/Compiler.h"
 #include "llvm/ADT/Statistic.h"
+#include "llvm/ADT/SmallVector.h"
 using namespace llvm;
 
 STATISTIC(NumArgumentsProped, "Number of args turned into constants");
@@ -142,22 +143,44 @@
     return false; // No return value.
 
   // Check to see if this function returns a constant.
-  Value *RetVal = 0;
+  SmallVector<Value *,4> RetVals;
+  unsigned N = 0;
+  const StructType *STy = dyn_cast<StructType>(F.getReturnType());
+  if (STy)
+    N = STy->getNumElements();
+  else
+    N = 1;
+  for (unsigned i = 0; i < N; ++i)
+    RetVals.push_back(0);
+
   for (Function::iterator BB = F.begin(), E = F.end(); BB != E; ++BB)
     if (ReturnInst *RI = dyn_cast<ReturnInst>(BB->getTerminator())) {
-      if (isa<UndefValue>(RI->getOperand(0))) {
-        // Ignore.
-      } else if (Constant *C = dyn_cast<Constant>(RI->getOperand(0))) {
-        if (RetVal == 0)
-          RetVal = C;
-        else if (RetVal != C)
-          return false;  // Does not return the same constant.
-      } else {
-        return false;  // Does not return a constant.
+      assert (N == RI->getNumOperands() && "Invalid ReturnInst operands!");
+      for (unsigned i = 0; i < N; ++i) {
+        if (isa<UndefValue>(RI->getOperand(i))) {
+          // Ignore
+        } else if (Constant *C = dyn_cast<Constant>(RI->getOperand(i))) { 
+          Value *RV = RetVals[i];
+          if (RV == 0)
+            RetVals[i] = C;
+          else if (RV != C)
+            return false; // Does not return the same constant.
+        } else {
+          return false; // Does not return a constant.
+        }
       }
     }
 
-  if (RetVal == 0) RetVal = UndefValue::get(F.getReturnType());
+  if (N == 1) {
+    if (RetVals[0] == 0)
+      RetVals[0] = UndefValue::get(F.getReturnType());
+  } else {
+    for (unsigned i = 0; i < N; ++i) {
+      Value *RetVal = RetVals[i];
+      if (RetVal == 0) 
+        RetVals[i] = UndefValue::get(STy->getElementType(i));
+    }
+  }
 
   // If we got here, the function returns a constant value.  Loop over all
   // users, replacing any uses of the return value with the returned constant.
@@ -172,8 +195,18 @@
           CS.getCalledFunction() != &F) {
         ReplacedAllUsers = false;
       } else {
-        if (!CS.getInstruction()->use_empty()) {
-          CS.getInstruction()->replaceAllUsesWith(RetVal);
+        Instruction *Call = CS.getInstruction();
+        if (!Call->use_empty()) {
+          if (N == 1)
+            Call->replaceAllUsesWith(RetVals[0]);
+          else {
+            for(Value::use_iterator CUI = Call->use_begin(), CUE = Call->use_end();
+                CUI != CUE; ++CUI) {
+              GetResultInst *GR = cast<GetResultInst>(CUI);
+              GR->replaceAllUsesWith(RetVals[GR->getIndex()]);
+              GR->eraseFromParent();
+            }
+          }
           MadeChange = true;
         }
       }
@@ -182,15 +215,20 @@
   // If we replace all users with the returned constant, and there can be no
   // other callers of the function, replace the constant being returned in the
   // function with an undef value.
-  if (ReplacedAllUsers && F.hasInternalLinkage() && !isa<UndefValue>(RetVal)) {
-    Value *RV = UndefValue::get(RetVal->getType());
-    for (Function::iterator BB = F.begin(), E = F.end(); BB != E; ++BB)
-      if (ReturnInst *RI = dyn_cast<ReturnInst>(BB->getTerminator())) {
-        if (RI->getOperand(0) != RV) {
-          RI->setOperand(0, RV);
-          MadeChange = true;
+  if (ReplacedAllUsers && F.hasInternalLinkage()) {
+    for (unsigned i = 0; i < N; ++i) {
+      Value *RetVal = RetVals[i];
+      if (isa<UndefValue>(RetVal))
+        continue;
+      Value *RV = UndefValue::get(RetVal->getType());
+      for (Function::iterator BB = F.begin(), E = F.end(); BB != E; ++BB)
+        if (ReturnInst *RI = dyn_cast<ReturnInst>(BB->getTerminator())) {
+          if (RI->getOperand(i) != RV) {
+            RI->setOperand(i, RV);
+            MadeChange = true;
+          }
         }
-      }
+    }
   }
 
   if (MadeChange) ++NumReturnValProped;

Added: llvm/trunk/test/Transforms/IPConstantProp/return-constants.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/IPConstantProp/return-constants.ll?rev=48254&view=auto

==============================================================================
--- llvm/trunk/test/Transforms/IPConstantProp/return-constants.ll (added)
+++ llvm/trunk/test/Transforms/IPConstantProp/return-constants.ll Tue Mar 11 17:24:29 2008
@@ -0,0 +1,20 @@
+; RUN: llvm-as < %s | opt -ipconstprop | llvm-dis | grep {add i32 21, 21}
+
+define internal {i32, i32} @foo(i1 %C) {
+        br i1 %C, label %T, label %F
+
+T:              ; preds = %0
+        ret i32 21, i32 21
+
+F:              ; preds = %0
+        ret i32 21, i32 21
+}
+
+define i32 @caller(i1 %C) {
+        %X = call {i32, i32} @foo( i1 %C )
+        %A = getresult {i32, i32} %X, 0
+        %B = getresult {i32, i32} %X, 1
+        %Y = add i32 %A, %B
+        ret i32 %Y
+}
+





More information about the llvm-commits mailing list