[llvm-commits] [llvm] r47508 - in /llvm/trunk: include/llvm/Instructions.h include/llvm/User.h lib/AsmParser/llvmAsmParser.y lib/VMCore/AsmWriter.cpp lib/VMCore/Instructions.cpp lib/VMCore/Verifier.cpp

Devang Patel dpatel at apple.com
Fri Feb 22 16:35:18 PST 2008


Author: dpatel
Date: Fri Feb 22 18:35:18 2008
New Revision: 47508

URL: http://llvm.org/viewvc/llvm-project?rev=47508&view=rev
Log:
To support multiple return values, now ret instruction supports multiple operands instead of one aggregate operand.


Modified:
    llvm/trunk/include/llvm/Instructions.h
    llvm/trunk/include/llvm/User.h
    llvm/trunk/lib/AsmParser/llvmAsmParser.y
    llvm/trunk/lib/VMCore/AsmWriter.cpp
    llvm/trunk/lib/VMCore/Instructions.cpp
    llvm/trunk/lib/VMCore/Verifier.cpp

Modified: llvm/trunk/include/llvm/Instructions.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Instructions.h?rev=47508&r1=47507&r2=47508&view=diff

==============================================================================
--- llvm/trunk/include/llvm/Instructions.h (original)
+++ llvm/trunk/include/llvm/Instructions.h Fri Feb 22 18:35:18 2008
@@ -1379,9 +1379,9 @@
 /// does not continue in this function any longer.
 ///
 class ReturnInst : public TerminatorInst {
-  Use RetVal;  // Return Value: null if 'void'.
   ReturnInst(const ReturnInst &RI);
   void init(Value *RetVal);
+  void init(std::vector<Value *> &RetVals);
 
 public:
   // ReturnInst constructors:
@@ -1397,21 +1397,15 @@
   // if it was passed NULL.
   explicit ReturnInst(Value *retVal = 0, Instruction *InsertBefore = 0);
   ReturnInst(Value *retVal, BasicBlock *InsertAtEnd);
+  ReturnInst(std::vector<Value *> &retVals);
+  ReturnInst(std::vector<Value *> &retVals, Instruction *InsertBefore);
+  ReturnInst(std::vector<Value *> &retVals, BasicBlock *InsertAtEnd);
   explicit ReturnInst(BasicBlock *InsertAtEnd);
+  virtual ~ReturnInst();
 
   virtual ReturnInst *clone() const;
 
-  // Transparently provide more efficient getOperand methods.
-  Value *getOperand(unsigned i) const {
-    assert(i < getNumOperands() && "getOperand() out of range!");
-    return RetVal;
-  }
-  void setOperand(unsigned i, Value *Val) {
-    assert(i < getNumOperands() && "setOperand() out of range!");
-    RetVal = Val;
-  }
-
-  Value *getReturnValue() const { return RetVal; }
+  Value *getReturnValue(unsigned n = 0) const;
 
   unsigned getNumSuccessors() const { return 0; }
 

Modified: llvm/trunk/include/llvm/User.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/User.h?rev=47508&r1=47507&r2=47508&view=diff

==============================================================================
--- llvm/trunk/include/llvm/User.h (original)
+++ llvm/trunk/include/llvm/User.h Fri Feb 22 18:35:18 2008
@@ -29,8 +29,9 @@
   /// OperandList - This is a pointer to the array of Users for this operand.
   /// For nodes of fixed arity (e.g. a binary operator) this array will live
   /// embedded into the derived class.  For nodes of variable arity
-  /// (e.g. ConstantArrays, CallInst, PHINodes, etc), this memory will be
-  /// dynamically allocated and should be destroyed by the classes virtual dtor.
+  /// (e.g. ConstantArrays, CallInst, PHINodes, ReturnInst etc), this memory 
+  /// will be dynamically allocated and should be destroyed by the classes 
+  /// virtual dtor.
   Use *OperandList;
 
   /// NumOperands - The number of values used by this User.

Modified: llvm/trunk/lib/AsmParser/llvmAsmParser.y
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/AsmParser/llvmAsmParser.y?rev=47508&r1=47507&r2=47508&view=diff

==============================================================================
--- llvm/trunk/lib/AsmParser/llvmAsmParser.y (original)
+++ llvm/trunk/lib/AsmParser/llvmAsmParser.y Fri Feb 22 18:35:18 2008
@@ -2531,7 +2531,7 @@
     $$->push_back($1); 
     CHECK_FOR_ERROR
   }
-  | ReturnedVal ',' ConstVal {
+  | ReturnedVal ',' ResolvedVal {
     ($$=$1)->push_back($3); 
     CHECK_FOR_ERROR
   };
@@ -2580,28 +2580,7 @@
 
 BBTerminatorInst : 
   RET ReturnedVal  { // Return with a result...
-    if($2->size() == 1) 
-      $$ = new ReturnInst($2->back());
-    else {
-
-      std::vector<const Type*> Elements;
-      std::vector<Constant*> Vals;
-      for (std::vector<Value *>::iterator I = $2->begin(),
-             E = $2->end(); I != E; ++I) {
-        Value *V = *I;
-        Constant *C = cast<Constant>(V);
-        Elements.push_back(V->getType());
-        Vals.push_back(C);
-      }
-
-      const StructType *STy = StructType::get(Elements);
-      PATypeHolder *PTy = 
-        new PATypeHolder(HandleUpRefs(StructType::get(Elements)));
-
-      Constant *CS = ConstantStruct::get(STy, Vals); // *$2);
-      $$ = new ReturnInst(CS);
-      delete PTy;
-    }
+    $$ = new ReturnInst(*$2);
     delete $2;
     CHECK_FOR_ERROR
   }
@@ -3174,6 +3153,7 @@
   if (!GetResultInst::isValidOperands(TmpVal, $5))
       GEN_ERROR("Invalid getresult operands");
     $$ = new GetResultInst(TmpVal, $5);
+    delete $2;
     CHECK_FOR_ERROR
   }
   | GETELEMENTPTR Types ValueRef IndexList {

Modified: llvm/trunk/lib/VMCore/AsmWriter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/AsmWriter.cpp?rev=47508&r1=47507&r2=47508&view=diff

==============================================================================
--- llvm/trunk/lib/VMCore/AsmWriter.cpp (original)
+++ llvm/trunk/lib/VMCore/AsmWriter.cpp Fri Feb 22 18:35:18 2008
@@ -1304,23 +1304,8 @@
     Out << " }";
     writeOperand(I.getOperand(0), false);
     Out << ", " << cast<GetResultInst>(I).getIndex();
-  } else if (isa<ReturnInst>(I)) {
-    if (!Operand)
-      Out << " void";
-    else {
-      if (I.getOperand(0)->getType()->isFirstClassType())
-        writeOperand(I.getOperand(0), true);
-      else {
-        Constant *ROp = cast<Constant>(I.getOperand(0));
-        const StructType *STy = cast<StructType>(ROp->getType());
-        unsigned NumElems = STy->getNumElements();
-        for (unsigned i = 0; i < NumElems; ++i) {
-          if (i)
-            Out << ",";
-          writeOperand(ROp->getOperand(i), true);
-        }
-      }
-    }
+  } else if (isa<ReturnInst>(I) && !Operand) {
+    Out << " void";
   } else if (const CallInst *CI = dyn_cast<CallInst>(&I)) {
     // Print the calling convention being used.
     switch (CI->getCallingConv()) {

Modified: llvm/trunk/lib/VMCore/Instructions.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/Instructions.cpp?rev=47508&r1=47507&r2=47508&view=diff

==============================================================================
--- llvm/trunk/lib/VMCore/Instructions.cpp (original)
+++ llvm/trunk/lib/VMCore/Instructions.cpp Fri Feb 22 18:35:18 2008
@@ -573,34 +573,75 @@
 
 ReturnInst::ReturnInst(const ReturnInst &RI)
   : TerminatorInst(Type::VoidTy, Instruction::Ret,
-                   &RetVal, RI.getNumOperands()) {
-  if (RI.getNumOperands())
-    RetVal.init(RI.RetVal, this);
+                   OperandList, RI.getNumOperands()) {
+  unsigned N = RI.getNumOperands();
+  Use *OL = OperandList = new Use[N];
+  for (unsigned i = 0; i < N; ++i)
+    OL[i].init(RI.getOperand(i), this);
 }
 
 ReturnInst::ReturnInst(Value *retVal, Instruction *InsertBefore)
-  : TerminatorInst(Type::VoidTy, Instruction::Ret, &RetVal, 0, InsertBefore) {
+  : TerminatorInst(Type::VoidTy, Instruction::Ret, OperandList, 0, InsertBefore) {
   init(retVal);
 }
 ReturnInst::ReturnInst(Value *retVal, BasicBlock *InsertAtEnd)
-  : TerminatorInst(Type::VoidTy, Instruction::Ret, &RetVal, 0, InsertAtEnd) {
+  : TerminatorInst(Type::VoidTy, Instruction::Ret, OperandList, 0, InsertAtEnd) {
   init(retVal);
 }
 ReturnInst::ReturnInst(BasicBlock *InsertAtEnd)
-  : TerminatorInst(Type::VoidTy, Instruction::Ret, &RetVal, 0, InsertAtEnd) {
+  : TerminatorInst(Type::VoidTy, Instruction::Ret, OperandList, 0, InsertAtEnd) {
 }
 
-
+ReturnInst::ReturnInst(std::vector<Value *> &retVals, Instruction *InsertBefore)
+  : TerminatorInst(Type::VoidTy, Instruction::Ret, OperandList, retVals.size(), InsertBefore) {
+  init(retVals);
+}
+ReturnInst::ReturnInst(std::vector<Value *> &retVals, BasicBlock *InsertAtEnd)
+  : TerminatorInst(Type::VoidTy, Instruction::Ret, OperandList, retVals.size(), InsertAtEnd) {
+  init(retVals);
+}
+ReturnInst::ReturnInst(std::vector<Value *> &retVals)
+  : TerminatorInst(Type::VoidTy, Instruction::Ret, OperandList, retVals.size()) {
+  init(retVals);
+}
 
 void ReturnInst::init(Value *retVal) {
   if (retVal && retVal->getType() != Type::VoidTy) {
     assert(!isa<BasicBlock>(retVal) &&
            "Cannot return basic block.  Probably using the incorrect ctor");
     NumOperands = 1;
-    RetVal.init(retVal, this);
+    Use *OL = OperandList = new Use[1];
+    OL[0].init(retVal, this);
+  }
+}
+
+void ReturnInst::init(std::vector<Value *> &retVals) {
+  if (retVals.empty())
+    return;
+
+  NumOperands = retVals.size();
+  if (NumOperands == 1) {
+    Value *V = retVals[0];
+    if (V->getType() == Type::VoidTy)
+      return;
+  }
+
+  Use *OL = OperandList = new Use[NumOperands];
+  for (unsigned i = 0; i < NumOperands; ++i) {
+    Value *V = retVals[i];
+    assert(!isa<BasicBlock>(V) &&
+           "Cannot return basic block.  Probably using the incorrect ctor");
+    OL[i].init(V, this);
   }
 }
 
+Value *ReturnInst::getReturnValue(unsigned n) const {
+  if (NumOperands)
+    return OperandList[n];
+  else
+    return 0;
+}
+
 unsigned ReturnInst::getNumSuccessorsV() const {
   return getNumSuccessors();
 }
@@ -617,6 +658,10 @@
   return 0;
 }
 
+ReturnInst::~ReturnInst() {
+  if (NumOperands)
+    delete [] OperandList;
+}
 
 //===----------------------------------------------------------------------===//
 //                        UnwindInst Implementation
@@ -2759,7 +2804,6 @@
   return false;
 }
 
-
 // Define these methods here so vtables don't get emitted into every translation
 // unit that uses these classes.
 

Modified: llvm/trunk/lib/VMCore/Verifier.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/Verifier.cpp?rev=47508&r1=47507&r2=47508&view=diff

==============================================================================
--- llvm/trunk/lib/VMCore/Verifier.cpp (original)
+++ llvm/trunk/lib/VMCore/Verifier.cpp Fri Feb 22 18:35:18 2008
@@ -576,14 +576,22 @@
 
 void Verifier::visitReturnInst(ReturnInst &RI) {
   Function *F = RI.getParent()->getParent();
-  if (RI.getNumOperands() == 0)
+  unsigned N = RI.getNumOperands();
+  if (N == 0) 
     Assert2(F->getReturnType() == Type::VoidTy,
             "Found return instr that returns void in Function of non-void "
             "return type!", &RI, F->getReturnType());
-  else
+  else if (N == 1)
     Assert2(F->getReturnType() == RI.getOperand(0)->getType(),
             "Function return type does not match operand "
             "type of return inst!", &RI, F->getReturnType());
+  else {
+    const StructType *STy = cast<StructType>(F->getReturnType());
+    for (unsigned i = 0; i < N; i++)
+      Assert2(STy->getElementType(i) == RI.getOperand(i)->getType(),
+            "Function return type does not match operand "
+            "type of return inst!", &RI, F->getReturnType());
+  }
 
   // Check to make sure that the return value has necessary properties for
   // terminators...





More information about the llvm-commits mailing list