[llvm-commits] [llvm] r53941 - in /llvm/trunk: include/llvm/ include/llvm/Bitcode/ include/llvm/Support/ lib/AsmParser/ lib/Bitcode/Reader/ lib/Bitcode/Writer/ lib/CodeGen/SelectionDAG/ lib/Target/CBackend/ lib/Transforms/IPO/ lib/Transforms/Scalar/ lib/Transforms/Utils/ lib/VMCore/ test/Transforms/SCCP/

Dan Gohman gohman at apple.com
Tue Jul 22 17:34:11 PDT 2008


Author: djg
Date: Tue Jul 22 19:34:11 2008
New Revision: 53941

URL: http://llvm.org/viewvc/llvm-project?rev=53941&view=rev
Log:
Enable first-class aggregates support.

Remove the GetResultInst instruction. It is still accepted in LLVM assembly
and bitcode, where it is now auto-upgraded to ExtractValueInst. Also, remove
support for return instructions with multiple values. These are auto-upgraded
to use InsertValueInst instructions.

The IRBuilder still accepts multiple-value returns, and auto-upgrades them
to InsertValueInst instructions.

Modified:
    llvm/trunk/include/llvm/AutoUpgrade.h
    llvm/trunk/include/llvm/Bitcode/LLVMBitCodes.h
    llvm/trunk/include/llvm/InstrTypes.h
    llvm/trunk/include/llvm/Instruction.def
    llvm/trunk/include/llvm/Instructions.h
    llvm/trunk/include/llvm/Support/IRBuilder.h
    llvm/trunk/include/llvm/Support/InstVisitor.h
    llvm/trunk/lib/AsmParser/LLLexer.cpp
    llvm/trunk/lib/AsmParser/llvmAsmParser.y
    llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp
    llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp
    llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
    llvm/trunk/lib/Target/CBackend/CBackend.cpp
    llvm/trunk/lib/Transforms/IPO/IPConstantPropagation.cpp
    llvm/trunk/lib/Transforms/IPO/StructRetPromotion.cpp
    llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp
    llvm/trunk/lib/Transforms/Scalar/JumpThreading.cpp
    llvm/trunk/lib/Transforms/Scalar/LoopRotation.cpp
    llvm/trunk/lib/Transforms/Scalar/SCCP.cpp
    llvm/trunk/lib/Transforms/Utils/InlineFunction.cpp
    llvm/trunk/lib/Transforms/Utils/LCSSA.cpp
    llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp
    llvm/trunk/lib/Transforms/Utils/UnifyFunctionExitNodes.cpp
    llvm/trunk/lib/VMCore/AsmWriter.cpp
    llvm/trunk/lib/VMCore/AutoUpgrade.cpp
    llvm/trunk/lib/VMCore/Instruction.cpp
    llvm/trunk/lib/VMCore/Instructions.cpp
    llvm/trunk/lib/VMCore/Verifier.cpp
    llvm/trunk/test/Transforms/SCCP/2008-03-10-sret.ll

Modified: llvm/trunk/include/llvm/AutoUpgrade.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/AutoUpgrade.h?rev=53941&r1=53940&r2=53941&view=diff

==============================================================================
--- llvm/trunk/include/llvm/AutoUpgrade.h (original)
+++ llvm/trunk/include/llvm/AutoUpgrade.h Tue Jul 22 19:34:11 2008
@@ -35,12 +35,6 @@
   /// so that it can update all calls to the old function.
   void UpgradeCallsToIntrinsic(Function* F);
 
-  /// This is an auto-upgrade hook for mutiple-value return statements.
-  /// This function auto-upgrades all such return statements in the given
-  /// function to use aggregate return values built with insertvalue
-  /// instructions.
-  void UpgradeMultipleReturnValues(Function *F);
-
 } // End llvm namespace
 
 #endif

Modified: llvm/trunk/include/llvm/Bitcode/LLVMBitCodes.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Bitcode/LLVMBitCodes.h?rev=53941&r1=53940&r2=53941&view=diff

==============================================================================
--- llvm/trunk/include/llvm/Bitcode/LLVMBitCodes.h (original)
+++ llvm/trunk/include/llvm/Bitcode/LLVMBitCodes.h Tue Jul 22 19:34:11 2008
@@ -202,6 +202,7 @@
     // this is so information only available in the pointer type (e.g. address
     // spaces) is retained.
     FUNC_CODE_INST_STORE2      = 24, // STORE:      [ptrty,ptr,val, align, vol]
+    // FIXME: Remove GETRESULT in favor of EXTRACTVAL in LLVM 3.0
     FUNC_CODE_INST_GETRESULT   = 25, // GETRESULT:  [ty, opval, n]
     FUNC_CODE_INST_EXTRACTVAL  = 26, // EXTRACTVAL: [n x operands]
     FUNC_CODE_INST_INSERTVAL   = 27  // INSERTVAL:  [n x operands]

Modified: llvm/trunk/include/llvm/InstrTypes.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/InstrTypes.h?rev=53941&r1=53940&r2=53941&view=diff

==============================================================================
--- llvm/trunk/include/llvm/InstrTypes.h (original)
+++ llvm/trunk/include/llvm/InstrTypes.h Tue Jul 22 19:34:11 2008
@@ -117,7 +117,6 @@
            I->getOpcode() == Instruction::Free ||
            I->getOpcode() == Instruction::Load ||
            I->getOpcode() == Instruction::VAArg ||
-           I->getOpcode() == Instruction::GetResult ||
            I->getOpcode() == Instruction::ExtractValue ||
            (I->getOpcode() >= CastOpsBegin && I->getOpcode() < CastOpsEnd);
   }

Modified: llvm/trunk/include/llvm/Instruction.def
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Instruction.def?rev=53941&r1=53940&r2=53941&view=diff

==============================================================================
--- llvm/trunk/include/llvm/Instruction.def (original)
+++ llvm/trunk/include/llvm/Instruction.def Tue Jul 22 19:34:11 2008
@@ -164,12 +164,10 @@
 HANDLE_OTHER_INST(48, ExtractElement, ExtractElementInst)// extract from vector
 HANDLE_OTHER_INST(49, InsertElement, InsertElementInst)  // insert into vector
 HANDLE_OTHER_INST(50, ShuffleVector, ShuffleVectorInst)  // shuffle two vectors.
-HANDLE_OTHER_INST(51, GetResult, GetResultInst) // Extract individual value 
-                                                //from aggregate result
-HANDLE_OTHER_INST(52, ExtractValue, ExtractValueInst)// extract from aggregate
-HANDLE_OTHER_INST(53, InsertValue, InsertValueInst)  // insert into aggregate
-HANDLE_OTHER_INST(54, VICmp  , VICmpInst  )  // Vec Int comparison instruction.
-HANDLE_OTHER_INST(55, VFCmp  , VFCmpInst  )  // Vec FP point comparison instr.
+HANDLE_OTHER_INST(51, ExtractValue, ExtractValueInst)// extract from aggregate
+HANDLE_OTHER_INST(52, InsertValue, InsertValueInst)  // insert into aggregate
+HANDLE_OTHER_INST(53, VICmp  , VICmpInst  )  // Vec Int comparison instruction.
+HANDLE_OTHER_INST(54, VFCmp  , VFCmpInst  )  // Vec FP point comparison instr.
 
   LAST_OTHER_INST(55)
 

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

==============================================================================
--- llvm/trunk/include/llvm/Instructions.h (original)
+++ llvm/trunk/include/llvm/Instructions.h Tue Jul 22 19:34:11 2008
@@ -2000,7 +2000,6 @@
 ///
 class ReturnInst : public TerminatorInst {
   ReturnInst(const ReturnInst &RI);
-  void init(Value * const* retVals, unsigned N);
 
 private:
   // ReturnInst constructors:
@@ -2011,16 +2010,11 @@
   // ReturnInst(Value* X, Inst *I) - 'ret X'    instruction, insert before I
   // ReturnInst(    null, BB *B)   - 'ret void' instruction, insert @ end of B
   // ReturnInst(Value* X, BB *B)   - 'ret X'    instruction, insert @ end of B
-  // ReturnInst(Value* X, N)          - 'ret X,X+1...X+N-1' instruction
-  // ReturnInst(Value* X, N, Inst *I) - 'ret X,X+1...X+N-1', insert before I
-  // ReturnInst(Value* X, N, BB *B)   - 'ret X,X+1...X+N-1', insert @ end of B
   //
   // NOTE: If the Value* passed is of type void then the constructor behaves as
   // if it was passed NULL.
   explicit ReturnInst(Value *retVal = 0, Instruction *InsertBefore = 0);
   ReturnInst(Value *retVal, BasicBlock *InsertAtEnd);
-  ReturnInst(Value * const* retVals, unsigned N, Instruction *InsertBefore = 0);
-  ReturnInst(Value * const* retVals, unsigned N, BasicBlock *InsertAtEnd);
   explicit ReturnInst(BasicBlock *InsertAtEnd);
 public:
   static ReturnInst* Create(Value *retVal = 0, Instruction *InsertBefore = 0) {
@@ -2029,19 +2023,10 @@
   static ReturnInst* Create(Value *retVal, BasicBlock *InsertAtEnd) {
     return new(!!retVal) ReturnInst(retVal, InsertAtEnd);
   }
-  static ReturnInst* Create(Value * const* retVals, unsigned N,
-                            Instruction *InsertBefore = 0) {
-    return new(N) ReturnInst(retVals, N, InsertBefore);
-  }
-  static ReturnInst* Create(Value * const* retVals, unsigned N,
-                            BasicBlock *InsertAtEnd) {
-    return new(N) ReturnInst(retVals, N, InsertAtEnd);
-  }
   static ReturnInst* Create(BasicBlock *InsertAtEnd) {
     return new(0) ReturnInst(InsertAtEnd);
   }
   virtual ~ReturnInst();
-  inline void operator delete(void*);
 
   virtual ReturnInst *clone() const;
 
@@ -2072,16 +2057,10 @@
 };
 
 template <>
-struct OperandTraits<ReturnInst> : VariadicOperandTraits<> {
+struct OperandTraits<ReturnInst> : OptionalOperandTraits<> {
 };
 
 DEFINE_TRANSPARENT_OPERAND_ACCESSORS(ReturnInst, Value)
-void ReturnInst::operator delete(void *it) {
-  ReturnInst* me(static_cast<ReturnInst*>(it));
-  Use::zap(OperandTraits<ReturnInst>::op_begin(me),
-           OperandTraits<ReturnInst>::op_end(me),
-           true);
-}
 
 //===----------------------------------------------------------------------===//
 //                               BranchInst Class
@@ -3126,53 +3105,6 @@
   }
 };
 
-//===----------------------------------------------------------------------===//
-//                             GetResultInst Class
-//===----------------------------------------------------------------------===//
-
-/// GetResultInst - This instruction extracts individual result value from
-/// aggregate value, where aggregate value is returned by CallInst.
-///
-class GetResultInst : public UnaryInstruction {
-  unsigned Idx;
-  GetResultInst(const GetResultInst &GRI) :
-    UnaryInstruction(GRI.getType(), Instruction::GetResult, GRI.getOperand(0)),
-    Idx(GRI.Idx) {
-  }
-
-public:
-  GetResultInst(Value *Aggr, unsigned index,
-                const std::string &Name = "",
-                Instruction *InsertBefore = 0);
-
-  /// isValidOperands - Return true if an getresult instruction can be
-  /// formed with the specified operands.
-  static bool isValidOperands(const Value *Aggr, unsigned index);
-  
-  virtual GetResultInst *clone() const;
-  
-  Value *getAggregateValue() {
-    return getOperand(0);
-  }
-
-  const Value *getAggregateValue() const {
-    return getOperand(0);
-  }
-
-  unsigned getIndex() const {
-    return Idx;
-  }
-
-  // Methods for support type inquiry through isa, cast, and dyn_cast:
-  static inline bool classof(const GetResultInst *) { return true; }
-  static inline bool classof(const Instruction *I) {
-    return (I->getOpcode() == Instruction::GetResult);
-  }
-  static inline bool classof(const Value *V) {
-    return isa<Instruction>(V) && classof(cast<Instruction>(V));
-  }
-};
-
 } // End llvm namespace
 
 #endif

Modified: llvm/trunk/include/llvm/Support/IRBuilder.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/IRBuilder.h?rev=53941&r1=53940&r2=53941&view=diff

==============================================================================
--- llvm/trunk/include/llvm/Support/IRBuilder.h (original)
+++ llvm/trunk/include/llvm/Support/IRBuilder.h Tue Jul 22 19:34:11 2008
@@ -102,7 +102,15 @@
   }
 
   ReturnInst *CreateRet(Value * const* retVals, unsigned N) {
-    return Insert(ReturnInst::Create(retVals, N));
+    const Type *RetType = BB->getParent()->getReturnType();
+    if (N == 0 && RetType == Type::VoidTy)
+      return CreateRetVoid();
+    if (N == 1 && retVals[0]->getType() == RetType)
+      return Insert(ReturnInst::Create(retVals[0]));
+    Value *V = UndefValue::get(RetType);
+    for (unsigned i = 0; i != N; ++i)
+      V = CreateInsertValue(V, retVals[i], i, "mrv");
+    return Insert(ReturnInst::Create(V));
   }
   
   /// CreateBr - Create an unconditional 'br label X' instruction.
@@ -568,11 +576,6 @@
     return Insert(new ShuffleVectorInst(V1, V2, Mask), Name);
   }
 
-  GetResultInst *CreateGetResult(Value *V, unsigned Index, 
-                                 const char *Name = "") {
-    return Insert(new GetResultInst(V, Index), Name);
-  }
-    
   Value *CreateExtractValue(Value *Agg, unsigned Idx,
                             const char *Name = "") {
     if (Constant *AggC = dyn_cast<Constant>(Agg))

Modified: llvm/trunk/include/llvm/Support/InstVisitor.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/InstVisitor.h?rev=53941&r1=53940&r2=53941&view=diff

==============================================================================
--- llvm/trunk/include/llvm/Support/InstVisitor.h (original)
+++ llvm/trunk/include/llvm/Support/InstVisitor.h Tue Jul 22 19:34:11 2008
@@ -196,7 +196,6 @@
   RetTy visitExtractElementInst(ExtractElementInst &I) { DELEGATE(Instruction);}
   RetTy visitInsertElementInst(InsertElementInst &I) { DELEGATE(Instruction); }
   RetTy visitShuffleVectorInst(ShuffleVectorInst &I) { DELEGATE(Instruction); }
-  RetTy visitGetResultInst(GetResultInst &I) { DELEGATE(Instruction); }
   RetTy visitExtractValueInst(ExtractValueInst &I)  { DELEGATE(Instruction);}
   RetTy visitInsertValueInst(InsertValueInst &I)    { DELEGATE(Instruction); }
 

Modified: llvm/trunk/lib/AsmParser/LLLexer.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/AsmParser/LLLexer.cpp?rev=53941&r1=53940&r2=53941&view=diff

==============================================================================
--- llvm/trunk/lib/AsmParser/LLLexer.cpp (original)
+++ llvm/trunk/lib/AsmParser/LLLexer.cpp Tue Jul 22 19:34:11 2008
@@ -604,7 +604,7 @@
   INSTKEYWORD("extractelement", OtherOpVal, ExtractElement, EXTRACTELEMENT);
   INSTKEYWORD("insertelement", OtherOpVal, InsertElement, INSERTELEMENT);
   INSTKEYWORD("shufflevector", OtherOpVal, ShuffleVector, SHUFFLEVECTOR);
-  INSTKEYWORD("getresult", OtherOpVal, GetResult, GETRESULT);
+  INSTKEYWORD("getresult", OtherOpVal, ExtractValue, GETRESULT);
   INSTKEYWORD("extractvalue", OtherOpVal, ExtractValue, EXTRACTVALUE);
   INSTKEYWORD("insertvalue", OtherOpVal, InsertValue, INSERTVALUE);
 #undef INSTKEYWORD

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

==============================================================================
--- llvm/trunk/lib/AsmParser/llvmAsmParser.y (original)
+++ llvm/trunk/lib/AsmParser/llvmAsmParser.y Tue Jul 22 19:34:11 2008
@@ -2704,7 +2704,20 @@
   RET ReturnedVal  { // Return with a result...
     ValueList &VL = *$2;
     assert(!VL.empty() && "Invalid ret operands!");
-    $$ = ReturnInst::Create(&VL[0], VL.size());
+    const Type *ReturnType = CurFun.CurrentFunction->getReturnType();
+    if (VL.size() > 1 ||
+        (isa<StructType>(ReturnType) &&
+         (VL.empty() || VL[0]->getType() != ReturnType))) {
+      Value *RV = UndefValue::get(ReturnType);
+      for (unsigned i = 0, e = VL.size(); i != e; ++i) {
+        Instruction *I = InsertValueInst::Create(RV, VL[i], i, "mrv");
+        ($<BasicBlockVal>-1)->getInstList().push_back(I);
+        RV = I;
+      }
+      $$ = ReturnInst::Create(RV);
+    } else {
+      $$ = ReturnInst::Create(VL[0]);
+    }
     delete $2;
     CHECK_FOR_ERROR
   }
@@ -3309,12 +3322,18 @@
     delete $5;
   }
   | GETRESULT Types ValueRef ',' EUINT64VAL  {
-  Value *TmpVal = getVal($2->get(), $3);
-  if (!GetResultInst::isValidOperands(TmpVal, $5))
-      GEN_ERROR("Invalid getresult operands");
-    $$ = new GetResultInst(TmpVal, $5);
-    delete $2;
+    if (!UpRefs.empty())
+      GEN_ERROR("Invalid upreference in type: " + (*$2)->getDescription());
+    if (!isa<StructType>($2->get()) && !isa<ArrayType>($2->get()))
+      GEN_ERROR("getresult insn requires an aggregate operand");
+    if (!ExtractValueInst::getIndexedType(*$2, $5))
+      GEN_ERROR("Invalid getresult index for type '" +
+                     (*$2)->getDescription()+ "'");
+
+    Value *tmpVal = getVal(*$2, $3);
     CHECK_FOR_ERROR
+    $$ = ExtractValueInst::Create(tmpVal, $5);
+    delete $2;
   }
   | GETELEMENTPTR Types ValueRef IndexList {
     if (!UpRefs.empty())

Modified: llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp?rev=53941&r1=53940&r2=53941&view=diff

==============================================================================
--- llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp (original)
+++ llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp Tue Jul 22 19:34:11 2008
@@ -1472,7 +1472,7 @@
       Value *Op;
       getValueTypePair(Record, OpNum, NextValueNo, Op);
       unsigned Index = Record[1];
-      I = new GetResultInst(Op, Index);
+      I = ExtractValueInst::Create(Op, Index);
       break;
     }
     
@@ -1482,20 +1482,34 @@
         if (Size == 0) {
           I = ReturnInst::Create();
           break;
-        } else {
-          unsigned OpNum = 0;
-          SmallVector<Value *,4> Vs;
-          do {
-            Value *Op = NULL;
-            if (getValueTypePair(Record, OpNum, NextValueNo, Op))
-              return Error("Invalid RET record");
-            Vs.push_back(Op);
-          } while(OpNum != Record.size());
+        }
 
-          // SmallVector Vs has at least one element.
-          I = ReturnInst::Create(&Vs[0], Vs.size());
+        unsigned OpNum = 0;
+        SmallVector<Value *,4> Vs;
+        do {
+          Value *Op = NULL;
+          if (getValueTypePair(Record, OpNum, NextValueNo, Op))
+            return Error("Invalid RET record");
+          Vs.push_back(Op);
+        } while(OpNum != Record.size());
+
+        const Type *ReturnType = F->getReturnType();
+        if (Vs.size() > 1 ||
+            (isa<StructType>(ReturnType) &&
+             (Vs.empty() || Vs[0]->getType() != ReturnType))) {
+          Value *RV = UndefValue::get(ReturnType);
+          for (unsigned i = 0, e = Vs.size(); i != e; ++i) {
+            I = InsertValueInst::Create(RV, Vs[i], i, "mrv");
+            CurBB->getInstList().push_back(I);
+            ValueList.AssignValue(I, NextValueNo++);
+            RV = I;
+          }
+          I = ReturnInst::Create(RV);
           break;
         }
+
+        I = ReturnInst::Create(Vs[0]);
+        break;
       }
     case bitc::FUNC_CODE_INST_BR: { // BR: [bb#, bb#, opval] or [bb#]
       if (Record.size() != 1 && Record.size() != 3)

Modified: llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp?rev=53941&r1=53940&r2=53941&view=diff

==============================================================================
--- llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp (original)
+++ llvm/trunk/lib/Bitcode/Writer/BitcodeWriter.cpp Tue Jul 22 19:34:11 2008
@@ -768,11 +768,6 @@
     Vals.push_back(VE.getValueID(I.getOperand(1)));
     Vals.push_back(cast<CmpInst>(I).getPredicate());
     break;
-  case Instruction::GetResult:
-    Code = bitc::FUNC_CODE_INST_GETRESULT;
-    PushValueAndType(I.getOperand(0), InstID, Vals, VE);
-    Vals.push_back(cast<GetResultInst>(I).getIndex());
-    break;
 
   case Instruction::Ret: 
     {

Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp?rev=53941&r1=53940&r2=53941&view=diff

==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp Tue Jul 22 19:34:11 2008
@@ -806,8 +806,6 @@
   void visitVAEnd(CallInst &I);
   void visitVACopy(CallInst &I);
 
-  void visitGetResult(GetResultInst &I);
-
   void visitUserOp1(Instruction &I) {
     assert(0 && "UserOp1 should not exist at instruction selection time!");
     abort();
@@ -3688,24 +3686,6 @@
 }
 
 
-void SelectionDAGLowering::visitGetResult(GetResultInst &I) {
-  if (isa<UndefValue>(I.getOperand(0))) {
-    SDOperand Undef = DAG.getNode(ISD::UNDEF, TLI.getValueType(I.getType()));
-    setValue(&I, Undef);
-    return;
-  }
-  
-  // To add support for individual return values with aggregate types,
-  // we'd need a way to take a getresult index and determine which
-  // values of the Call SDNode are associated with it.
-  assert(TLI.getValueType(I.getType(), true) != MVT::Other &&
-         "Individual return values must not be aggregates!");
-
-  SDOperand Call = getValue(I.getOperand(0));
-  setValue(&I, SDOperand(Call.Val, I.getIndex()));
-}
-
-
 /// getCopyFromRegs - Emit a series of CopyFromReg nodes that copies from
 /// this value and returns the result as a ValueVT value.  This uses 
 /// Chain/Flag as the input and updates them for the output Chain/Flag.

Modified: llvm/trunk/lib/Target/CBackend/CBackend.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/CBackend/CBackend.cpp?rev=53941&r1=53940&r2=53941&view=diff

==============================================================================
--- llvm/trunk/lib/Target/CBackend/CBackend.cpp (original)
+++ llvm/trunk/lib/Target/CBackend/CBackend.cpp Tue Jul 22 19:34:11 2008
@@ -285,7 +285,6 @@
     void visitInsertElementInst(InsertElementInst &I);
     void visitExtractElementInst(ExtractElementInst &I);
     void visitShuffleVectorInst(ShuffleVectorInst &SVI);
-    void visitGetResultInst(GetResultInst &GRI);
 
     void visitInsertValueInst(InsertValueInst &I);
     void visitExtractValueInst(ExtractValueInst &I);
@@ -3325,18 +3324,6 @@
   Out << "}";
 }
 
-void CWriter::visitGetResultInst(GetResultInst &GRI) {
-  Out << "(";
-  if (isa<UndefValue>(GRI.getOperand(0))) {
-    Out << "(";
-    printType(Out, GRI.getType());
-    Out << ") 0/*UNDEF*/";
-  } else {
-    Out << GetValueName(GRI.getOperand(0)) << ".field" << GRI.getIndex();
-  }
-  Out << ")";
-}
-
 void CWriter::visitInsertValueInst(InsertValueInst &IVI) {
   // Start by copying the entire aggregate value into the result variable.
   writeOperand(IVI.getOperand(0));

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

==============================================================================
--- llvm/trunk/lib/Transforms/IPO/IPConstantPropagation.cpp (original)
+++ llvm/trunk/lib/Transforms/IPO/IPConstantPropagation.cpp Tue Jul 22 19:34:11 2008
@@ -255,9 +255,7 @@
 
       // Find the index of the retval to replace with
       int index = -1;
-      if (GetResultInst *GR = dyn_cast<GetResultInst>(Ins))
-        index = GR->getIndex();
-      else if (ExtractValueInst *EV = dyn_cast<ExtractValueInst>(Ins))
+      if (ExtractValueInst *EV = dyn_cast<ExtractValueInst>(Ins))
         if (EV->hasIndices())
           index = *EV->idx_begin();
 

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

==============================================================================
--- llvm/trunk/lib/Transforms/IPO/StructRetPromotion.cpp (original)
+++ llvm/trunk/lib/Transforms/IPO/StructRetPromotion.cpp Tue Jul 22 19:34:11 2008
@@ -97,9 +97,6 @@
     dyn_cast<StructType>(FArgType->getElementType());
   assert (STy && "Invalid sret parameter element type");
 
-  if (nestedStructType(STy))
-    return false;
-
   // Check if it is ok to perform this promotion.
   if (isSafeToUpdateAllCallers(F) == false) {
     NumRejectedSRETUses++;
@@ -114,25 +111,13 @@
   NFirstArg->replaceAllUsesWith(TheAlloca);
 
   // [2] Find and replace ret instructions
-  SmallVector<Value *,4> RetVals;
   for (Function::iterator FI = F->begin(), FE = F->end();  FI != FE; ++FI) 
     for(BasicBlock::iterator BI = FI->begin(), BE = FI->end(); BI != BE; ) {
       Instruction *I = BI;
       ++BI;
       if (isa<ReturnInst>(I)) {
-        RetVals.clear();
-        for (unsigned idx = 0; idx < STy->getNumElements(); ++idx) {
-          SmallVector<Value*, 2> GEPIdx;
-          GEPIdx.push_back(ConstantInt::get(Type::Int32Ty, 0));
-          GEPIdx.push_back(ConstantInt::get(Type::Int32Ty, idx));
-          Value *NGEPI = GetElementPtrInst::Create(TheAlloca, GEPIdx.begin(),
-                                                   GEPIdx.end(),
-                                                   "mrv.gep", I);
-          Value *NV = new LoadInst(NGEPI, "mrv.ld", I);
-          RetVals.push_back(NV);
-        }
-    
-        ReturnInst *NR = ReturnInst::Create(&RetVals[0], RetVals.size(), I);
+        Value *NV = new LoadInst(TheAlloca, "mrv.ld", I);
+        ReturnInst *NR = ReturnInst::Create(NV);
         I->replaceAllUsesWith(NR);
         I->eraseFromParent();
       }
@@ -315,7 +300,7 @@
     ArgAttrsVec.clear();
     New->takeName(Call);
 
-    // Update all users of sret parameter to extract value using getresult.
+    // Update all users of sret parameter to extract value using extractvalue.
     for (Value::use_iterator UI = FirstCArg->use_begin(), 
            UE = FirstCArg->use_end(); UI != UE; ) {
       User *U2 = *UI++;
@@ -325,7 +310,8 @@
       else if (GetElementPtrInst *UGEP = dyn_cast<GetElementPtrInst>(U2)) {
         ConstantInt *Idx = dyn_cast<ConstantInt>(UGEP->getOperand(2));
         assert (Idx && "Unexpected getelementptr index!");
-        Value *GR = new GetResultInst(New, Idx->getZExtValue(), "gr", UGEP);
+        Value *GR = ExtractValueInst::Create(New, Idx->getZExtValue(),
+                                             "evi", UGEP);
         for (Value::use_iterator GI = UGEP->use_begin(),
                GE = UGEP->use_end(); GI != GE; ++GI) {
           if (LoadInst *L = dyn_cast<LoadInst>(*GI)) {

Modified: llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp?rev=53941&r1=53940&r2=53941&view=diff

==============================================================================
--- llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp (original)
+++ llvm/trunk/lib/Transforms/Scalar/InstructionCombining.cpp Tue Jul 22 19:34:11 2008
@@ -11476,9 +11476,7 @@
     }
 
     // See if we can trivially sink this instruction to a successor basic block.
-    // FIXME: Remove GetResultInst test when first class support for aggregates
-    // is implemented.
-    if (I->hasOneUse() && !isa<GetResultInst>(I)) {
+    if (I->hasOneUse()) {
       BasicBlock *BB = I->getParent();
       BasicBlock *UserParent = cast<Instruction>(I->use_back())->getParent();
       if (UserParent != BB) {

Modified: llvm/trunk/lib/Transforms/Scalar/JumpThreading.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/JumpThreading.cpp?rev=53941&r1=53940&r2=53941&view=diff

==============================================================================
--- llvm/trunk/lib/Transforms/Scalar/JumpThreading.cpp (original)
+++ llvm/trunk/lib/Transforms/Scalar/JumpThreading.cpp Tue Jul 22 19:34:11 2008
@@ -440,20 +440,7 @@
     
     // We found a use of I outside of BB.  Create a new stack slot to
     // break this inter-block usage pattern.
-    if (!isa<StructType>(I->getType())) {
-      DemoteRegToStack(*I);
-      continue;
-    }
-    
-    // Alternatively, I must be a call or invoke that returns multiple retvals.
-    // We can't use 'DemoteRegToStack' because that will create loads and
-    // stores of aggregates which is not valid yet.  If I is a call, we can just
-    // pull all the getresult instructions up to this block.  If I is an invoke,
-    // we are out of luck.
-    BasicBlock::iterator IP = I; ++IP;
-    for (Value::use_iterator UI = I->use_begin(), E = I->use_end();
-         UI != E; ++UI)
-      cast<GetResultInst>(UI)->moveBefore(IP);
+    DemoteRegToStack(*I);
   }
  
   // We are going to have to map operands from the original BB block to the new

Modified: llvm/trunk/lib/Transforms/Scalar/LoopRotation.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/LoopRotation.cpp?rev=53941&r1=53940&r2=53941&view=diff

==============================================================================
--- llvm/trunk/lib/Transforms/Scalar/LoopRotation.cpp (original)
+++ llvm/trunk/lib/Transforms/Scalar/LoopRotation.cpp Tue Jul 22 19:34:11 2008
@@ -249,35 +249,11 @@
     // create new PHINode for this instruction.
     Instruction *NewHeaderReplacement = NULL;
     if (usedOutsideOriginalHeader(In)) {
-      // FIXME: remove this when we have first-class aggregates.
-      if (isa<StructType>(In->getType())) {
-        // Can't create PHI nodes for this type.  If there are any getResults
-        // not defined in this block, move them back to this block.  PHI
-        // nodes will be created for all getResults later.
-        BasicBlock::iterator InsertPoint;
-        if (InvokeInst *II = dyn_cast<InvokeInst>(In)) {
-          InsertPoint = II->getNormalDest()->getFirstNonPHI();
-        } else {
-          InsertPoint = I;  // call
-          ++InsertPoint;
-        }
-        for (Value::use_iterator UI = In->use_begin(), UE = In->use_end();
-             UI != UE; ++UI) {
-          GetResultInst *InGR = cast<GetResultInst>(UI);
-          if (InGR->getParent() != OrigHeader) {
-            // Move InGR to immediately after the call or in the normal dest of
-            // the invoke.  It will be picked up, cloned and PHI'd on the next
-            // iteration.
-            InGR->moveBefore(InsertPoint);
-          }
-        }
-      } else {
-        PHINode *PN = PHINode::Create(In->getType(), In->getName(),
-                                      NewHeader->begin());
-        PN->addIncoming(In, OrigHeader);
-        PN->addIncoming(C, OrigPreHeader);
-        NewHeaderReplacement = PN;
-      }
+      PHINode *PN = PHINode::Create(In->getType(), In->getName(),
+                                    NewHeader->begin());
+      PN->addIncoming(In, OrigHeader);
+      PN->addIncoming(C, OrigPreHeader);
+      NewHeaderReplacement = PN;
     }
     LoopHeaderInfo.push_back(RenameData(In, C, NewHeaderReplacement));
   }

Modified: llvm/trunk/lib/Transforms/Scalar/SCCP.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/SCCP.cpp?rev=53941&r1=53940&r2=53941&view=diff

==============================================================================
--- llvm/trunk/lib/Transforms/Scalar/SCCP.cpp (original)
+++ llvm/trunk/lib/Transforms/Scalar/SCCP.cpp Tue Jul 22 19:34:11 2008
@@ -384,7 +384,6 @@
   void visitTerminatorInst(TerminatorInst &TI);
 
   void visitCastInst(CastInst &I);
-  void visitGetResultInst(GetResultInst &GRI);
   void visitSelectInst(SelectInst &I);
   void visitBinaryOperator(Instruction &I);
   void visitCmpInst(CmpInst &I);
@@ -669,41 +668,6 @@
                                            VState.getConstant(), I.getType()));
 }
 
-void SCCPSolver::visitGetResultInst(GetResultInst &GRI) {
-  Value *Aggr = GRI.getOperand(0);
-
-  // If the operand to the getresult is an undef, the result is undef.
-  if (isa<UndefValue>(Aggr))
-    return;
-  
-  Function *F;
-  if (CallInst *CI = dyn_cast<CallInst>(Aggr))
-    F = CI->getCalledFunction();
-  else
-    F = cast<InvokeInst>(Aggr)->getCalledFunction();
-
-  // TODO: If IPSCCP resolves the callee of this function, we could propagate a
-  // result back!
-  if (F == 0 || TrackedMultipleRetVals.empty()) {
-    markOverdefined(&GRI);
-    return;
-  }
-  
-  // See if we are tracking the result of the callee.
-  std::map<std::pair<Function*, unsigned>, LatticeVal>::iterator
-    It = TrackedMultipleRetVals.find(std::make_pair(F, GRI.getIndex()));
-
-  // If not tracking this function (for example, it is a declaration) just move
-  // to overdefined.
-  if (It == TrackedMultipleRetVals.end()) {
-    markOverdefined(&GRI);
-    return;
-  }
-  
-  // Otherwise, the value will be merged in here as a result of CallSite
-  // handling.
-}
-
 void SCCPSolver::visitExtractValueInst(ExtractValueInst &EVI) {
   Value *Aggr = EVI.getAggregateOperand();
 
@@ -1267,11 +1231,6 @@
     // currently handled conservatively.
     for (Value::use_iterator UI = I->use_begin(), E = I->use_end();
          UI != E; ++UI) {
-      if (GetResultInst *GRI = dyn_cast<GetResultInst>(*UI)) {
-        mergeInValue(GRI, 
-                TrackedMultipleRetVals[std::make_pair(F, GRI->getIndex())]);
-        continue;
-      }
       if (ExtractValueInst *EVI = dyn_cast<ExtractValueInst>(*UI)) {
         if (EVI->getNumIndices() == 1) {
           mergeInValue(EVI, 

Modified: llvm/trunk/lib/Transforms/Utils/InlineFunction.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/InlineFunction.cpp?rev=53941&r1=53940&r2=53941&view=diff

==============================================================================
--- llvm/trunk/lib/Transforms/Utils/InlineFunction.cpp (original)
+++ llvm/trunk/lib/Transforms/Utils/InlineFunction.cpp Tue Jul 22 19:34:11 2008
@@ -442,17 +442,7 @@
     // uses of the returned value.
     if (!TheCall->use_empty()) {
       ReturnInst *R = Returns[0];
-      if (isa<StructType>(TheCall->getType()) &&
-          TheCall->getType() != R->getOperand(0)->getType()) {
-        // Multiple-value return statements.
-        while (!TheCall->use_empty()) {
-          GetResultInst *GR = cast<GetResultInst>(TheCall->use_back());
-          Value *RV = R->getOperand(GR->getIndex());
-          GR->replaceAllUsesWith(RV);
-          GR->eraseFromParent();
-        }
-      } else
-        TheCall->replaceAllUsesWith(R->getReturnValue());
+      TheCall->replaceAllUsesWith(R->getReturnValue());
     }
     // Since we are now done with the Call/Invoke, we can delete it.
     TheCall->eraseFromParent();
@@ -508,63 +498,27 @@
   // Handle all of the return instructions that we just cloned in, and eliminate
   // any users of the original call/invoke instruction.
   const Type *RTy = CalledFunc->getReturnType();
-  const StructType *STy = dyn_cast<StructType>(RTy);
 
-  // We do special handling for multiple-value return statements. If this is
-  // a plain aggregate return, don't do the special handling.
-  if (!Returns.empty() && Returns[0]->getNumOperands() != 0 &&
-      Returns[0]->getOperand(0)->getType() == STy)
-    STy = 0;
-
-  if (Returns.size() > 1 || STy) {
+  if (Returns.size() > 1) {
     // The PHI node should go at the front of the new basic block to merge all
     // possible incoming values.
-    SmallVector<PHINode *, 4> PHIs;
+    PHINode *PHI = 0;
     if (!TheCall->use_empty()) {
-      if (STy) {
-        unsigned NumRetVals = STy->getNumElements();
-        // Create new phi nodes such that phi node number in the PHIs vector
-        // match corresponding return value operand number.
-        Instruction *InsertPt = AfterCallBB->begin();
-        for (unsigned i = 0; i < NumRetVals; ++i) {
-            PHINode *PHI = PHINode::Create(STy->getElementType(i),
-                                           TheCall->getName() + "." + utostr(i), 
-                                           InsertPt);
-          PHIs.push_back(PHI);
-        }
-        // TheCall results are used by GetResult instructions. 
-        while (!TheCall->use_empty()) {
-          GetResultInst *GR = cast<GetResultInst>(TheCall->use_back());
-          GR->replaceAllUsesWith(PHIs[GR->getIndex()]);
-          GR->eraseFromParent();
-        }
-      } else {
-        PHINode *PHI = PHINode::Create(RTy, TheCall->getName(),
-                                       AfterCallBB->begin());
-        PHIs.push_back(PHI);
-        // Anything that used the result of the function call should now use the
-        // PHI node as their operand.
-        TheCall->replaceAllUsesWith(PHI); 
-      } 
+      PHI = PHINode::Create(RTy, TheCall->getName(),
+                            AfterCallBB->begin());
+      // Anything that used the result of the function call should now use the
+      // PHI node as their operand.
+      TheCall->replaceAllUsesWith(PHI); 
     }
 
     // Loop over all of the return instructions adding entries to the PHI node as
     // appropriate.
-    if (!PHIs.empty()) {
-      // There is atleast one return value.
-      unsigned NumRetVals = 1; 
-      if (STy)
-        NumRetVals = STy->getNumElements();
-      for (unsigned j = 0; j < NumRetVals; ++j) {
-        PHINode *PHI = PHIs[j];
-        // Each PHI node will receive one value from each return instruction.
-        for(unsigned i = 0, e = Returns.size(); i != e; ++i) {
-          ReturnInst *RI = Returns[i];
-          assert(RI->getReturnValue(j)->getType() == PHI->getType() &&
-                 "Ret value not consistent in function!");
-          PHI->addIncoming(RI->getReturnValue(j /*PHI number matches operand number*/), 
-                           RI->getParent());
-        }
+    if (PHI) {
+      for (unsigned i = 0, e = Returns.size(); i != e; ++i) {
+        ReturnInst *RI = Returns[i];
+        assert(RI->getReturnValue()->getType() == PHI->getType() &&
+               "Ret value not consistent in function!");
+        PHI->addIncoming(RI->getReturnValue(), RI->getParent());
       }
     }
 

Modified: llvm/trunk/lib/Transforms/Utils/LCSSA.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/LCSSA.cpp?rev=53941&r1=53940&r2=53941&view=diff

==============================================================================
--- llvm/trunk/lib/Transforms/Utils/LCSSA.cpp (original)
+++ llvm/trunk/lib/Transforms/Utils/LCSSA.cpp Tue Jul 22 19:34:11 2008
@@ -217,27 +217,7 @@
         }
         
         if (*BB != UserBB && !inLoop(UserBB)) {
-          const StructType *STy = dyn_cast<StructType>(I->getType());
-          if (STy) {
-            // I is a call or an invoke that returns multiple values.
-            // These values are accessible through getresult only.
-            // If the getresult value is not in the BB then move it
-            // immediately here. It will be processed in next iteration.
-            BasicBlock::iterator InsertPoint;
-            if (InvokeInst *II = dyn_cast<InvokeInst>(I)) {
-              InsertPoint = II->getNormalDest()->getFirstNonPHI();
-            } else {
-              InsertPoint = I;
-              InsertPoint++;
-            }
-            for (Value::use_iterator TmpI = I->use_begin(), 
-                   TmpE = I->use_end(); TmpI != TmpE; ++TmpI) {
-              GetResultInst *GR = cast<GetResultInst>(TmpI);
-              if (GR->getParent() != *BB)
-                GR->moveBefore(InsertPoint);
-            }
-          } else
-            AffectedValues.insert(I);
+          AffectedValues.insert(I);
           break;
         }
       }

Modified: llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp?rev=53941&r1=53940&r2=53941&view=diff

==============================================================================
--- llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp (original)
+++ llvm/trunk/lib/Transforms/Utils/SimplifyCFG.cpp Tue Jul 22 19:34:11 2008
@@ -1357,40 +1357,31 @@
     return true;
   }
     
-  // Otherwise, build up the result values for the new return.
-  SmallVector<Value*, 4> TrueResult;
-  SmallVector<Value*, 4> FalseResult;
-  
-  for (unsigned i = 0, e = TrueRet->getNumOperands(); i != e; ++i) {
-    // Otherwise, figure out what the true and false return values are
-    // so we can insert a new select instruction.
-    Value *TrueValue = TrueRet->getOperand(i);
-    Value *FalseValue = FalseRet->getOperand(i);
-    
-    // Unwrap any PHI nodes in the return blocks.
-    if (PHINode *TVPN = dyn_cast<PHINode>(TrueValue))
-      if (TVPN->getParent() == TrueSucc)
-        TrueValue = TVPN->getIncomingValueForBlock(BI->getParent());
-    if (PHINode *FVPN = dyn_cast<PHINode>(FalseValue))
-      if (FVPN->getParent() == FalseSucc)
-        FalseValue = FVPN->getIncomingValueForBlock(BI->getParent());
-    
-    // In order for this transformation to be safe, we must be able to
-    // unconditionally execute both operands to the return.  This is
-    // normally the case, but we could have a potentially-trapping
-    // constant expression that prevents this transformation from being
-    // safe.
-    if (ConstantExpr *TCV = dyn_cast<ConstantExpr>(TrueValue))
-      if (TCV->canTrap())
-        return false;
-    if (ConstantExpr *FCV = dyn_cast<ConstantExpr>(FalseValue))
-      if (FCV->canTrap())
-        return false;
-    
-    TrueResult.push_back(TrueValue);
-    FalseResult.push_back(FalseValue);
-  }
-
+  // Otherwise, figure out what the true and false return values are
+  // so we can insert a new select instruction.
+  Value *TrueValue = TrueRet->getReturnValue();
+  Value *FalseValue = FalseRet->getReturnValue();
+  
+  // Unwrap any PHI nodes in the return blocks.
+  if (PHINode *TVPN = dyn_cast_or_null<PHINode>(TrueValue))
+    if (TVPN->getParent() == TrueSucc)
+      TrueValue = TVPN->getIncomingValueForBlock(BI->getParent());
+  if (PHINode *FVPN = dyn_cast_or_null<PHINode>(FalseValue))
+    if (FVPN->getParent() == FalseSucc)
+      FalseValue = FVPN->getIncomingValueForBlock(BI->getParent());
+  
+  // In order for this transformation to be safe, we must be able to
+  // unconditionally execute both operands to the return.  This is
+  // normally the case, but we could have a potentially-trapping
+  // constant expression that prevents this transformation from being
+  // safe.
+  if (ConstantExpr *TCV = dyn_cast_or_null<ConstantExpr>(TrueValue))
+    if (TCV->canTrap())
+      return false;
+  if (ConstantExpr *FCV = dyn_cast_or_null<ConstantExpr>(FalseValue))
+    if (FCV->canTrap())
+      return false;
+  
   // Okay, we collected all the mapped values and checked them for sanity, and
   // defined to really do this transformation.  First, update the CFG.
   TrueSucc->removePredecessor(BI->getParent());
@@ -1398,20 +1389,20 @@
   
   // Insert select instructions where needed.
   Value *BrCond = BI->getCondition();
-  for (unsigned i = 0, e = TrueRet->getNumOperands(); i != e; ++i) {
+  if (TrueValue) {
     // Insert a select if the results differ.
-    if (TrueResult[i] == FalseResult[i] || isa<UndefValue>(FalseResult[i]))
-      continue;
-    if (isa<UndefValue>(TrueResult[i])) {
-      TrueResult[i] = FalseResult[i];
-      continue;
+    if (TrueValue == FalseValue || isa<UndefValue>(FalseValue)) {
+    } else if (isa<UndefValue>(TrueValue)) {
+      TrueValue = FalseValue;
+    } else {
+      TrueValue = SelectInst::Create(BrCond, TrueValue,
+                                     FalseValue, "retval", BI);
     }
-    
-    TrueResult[i] = SelectInst::Create(BrCond, TrueResult[i],
-                                       FalseResult[i], "retval", BI);
   }
 
-  Value *RI = ReturnInst::Create(&TrueResult[0], TrueResult.size(), BI);
+  Value *RI = !TrueValue ?
+              ReturnInst::Create(BI) :
+              ReturnInst::Create(TrueValue, BI);
       
   DOUT << "\nCHANGING BRANCH TO TWO RETURNS INTO SELECT:"
        << "\n  " << *BI << "NewRet = " << *RI

Modified: llvm/trunk/lib/Transforms/Utils/UnifyFunctionExitNodes.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/UnifyFunctionExitNodes.cpp?rev=53941&r1=53940&r2=53941&view=diff

==============================================================================
--- llvm/trunk/lib/Transforms/Utils/UnifyFunctionExitNodes.cpp (original)
+++ llvm/trunk/lib/Transforms/Utils/UnifyFunctionExitNodes.cpp Tue Jul 22 19:34:11 2008
@@ -110,32 +110,13 @@
   //
   BasicBlock *NewRetBlock = BasicBlock::Create("UnifiedReturnBlock", &F);
 
-  SmallVector<Value *, 4> Phis;
-  unsigned NumRetVals = ReturningBlocks[0]->getTerminator()->getNumOperands();
-  if (NumRetVals == 0)
+  PHINode *PN = 0;
+  if (F.getReturnType() == Type::VoidTy) {
     ReturnInst::Create(NULL, NewRetBlock);
-  else if (const StructType *STy = dyn_cast<StructType>(F.getReturnType())) {
-    Instruction *InsertPt = NULL;
-    if (NumRetVals == 0)
-      InsertPt = NewRetBlock->getFirstNonPHI();
-    PHINode *PN = NULL;
-    for (unsigned i = 0; i < NumRetVals; ++i) {
-      if (InsertPt)
-        PN = PHINode::Create(STy->getElementType(i), "UnifiedRetVal." 
-                         + utostr(i), InsertPt);
-      else
-        PN = PHINode::Create(STy->getElementType(i), "UnifiedRetVal." 
-                         + utostr(i), NewRetBlock);
-      Phis.push_back(PN);
-      InsertPt = PN;
-    }
-    ReturnInst::Create(&Phis[0], NumRetVals, NewRetBlock);
-  }
-  else {
+  } else {
     // If the function doesn't return void... add a PHI node to the block...
-    PHINode *PN = PHINode::Create(F.getReturnType(), "UnifiedRetVal");
+    PN = PHINode::Create(F.getReturnType(), "UnifiedRetVal");
     NewRetBlock->getInstList().push_back(PN);
-    Phis.push_back(PN);
     ReturnInst::Create(PN, NewRetBlock);
   }
 
@@ -148,11 +129,8 @@
 
     // Add an incoming element to the PHI node for every return instruction that
     // is merging into this new block...
-    if (!Phis.empty()) {
-      for (unsigned i = 0; i < NumRetVals; ++i) 
-        cast<PHINode>(Phis[i])->addIncoming(BB->getTerminator()->getOperand(i), 
-                                            BB);
-    }
+    if (PN)
+      PN->addIncoming(BB->getTerminator()->getOperand(0), BB);
 
     BB->getInstList().pop_back();  // Remove the return insn
     BranchInst::Create(NewRetBlock, BB);

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

==============================================================================
--- llvm/trunk/lib/VMCore/AsmWriter.cpp (original)
+++ llvm/trunk/lib/VMCore/AsmWriter.cpp Tue Jul 22 19:34:11 2008
@@ -1299,9 +1299,6 @@
       writeOperand(I.getOperand(op  ), false); Out << ',';
       writeOperand(I.getOperand(op+1), false); Out << " ]";
     }
-  } else if (const GetResultInst *GRI = dyn_cast<GetResultInst>(&I)) {
-    writeOperand(I.getOperand(0), true);
-    Out << ", " << GRI->getIndex();
   } else if (const ExtractValueInst *EVI = dyn_cast<ExtractValueInst>(&I)) {
     writeOperand(I.getOperand(0), true);
     for (const unsigned *i = EVI->idx_begin(), *e = EVI->idx_end(); i != e; ++i)

Modified: llvm/trunk/lib/VMCore/AutoUpgrade.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/AutoUpgrade.cpp?rev=53941&r1=53940&r2=53941&view=diff

==============================================================================
--- llvm/trunk/lib/VMCore/AutoUpgrade.cpp (original)
+++ llvm/trunk/lib/VMCore/AutoUpgrade.cpp Tue Jul 22 19:34:11 2008
@@ -414,31 +414,3 @@
     }
   }
 }
-
-/// This is an auto-upgrade hook for mutiple-value return statements.
-/// This function auto-upgrades all such return statements in the given
-/// function to use aggregate return values built with insertvalue
-/// instructions.
-void llvm::UpgradeMultipleReturnValues(Function *CurrentFunction) {
-  const Type *ReturnType = CurrentFunction->getReturnType();
-  for (Function::iterator I = CurrentFunction->begin(),
-       E = CurrentFunction->end(); I != E; ++I) {
-    BasicBlock *BB = I;
-    if (ReturnInst *RI = dyn_cast<ReturnInst>(BB->getTerminator())) {
-      unsigned NumVals = RI->getNumOperands();
-      if (NumVals > 1 ||
-          (isa<StructType>(ReturnType) &&
-           (NumVals == 0 || RI->getOperand(0)->getType() != ReturnType))) {
-        std::vector<const Type *> Types(NumVals);
-        for (unsigned i = 0; i != NumVals; ++i)
-          Types[i] = RI->getOperand(i)->getType();
-        const Type *ReturnType = StructType::get(Types);
-        Value *RV = UndefValue::get(ReturnType);
-        for (unsigned i = 0; i != NumVals; ++i)
-          RV = InsertValueInst::Create(RV, RI->getOperand(i), i, "mrv", RI);
-        ReturnInst::Create(RV, RI);
-        RI->eraseFromParent();
-      }
-    }
-  }
-}

Modified: llvm/trunk/lib/VMCore/Instruction.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/Instruction.cpp?rev=53941&r1=53940&r2=53941&view=diff

==============================================================================
--- llvm/trunk/lib/VMCore/Instruction.cpp (original)
+++ llvm/trunk/lib/VMCore/Instruction.cpp Tue Jul 22 19:34:11 2008
@@ -146,7 +146,6 @@
   case ExtractElement: return "extractelement";
   case InsertElement:  return "insertelement";
   case ShuffleVector:  return "shufflevector";
-  case GetResult:      return "getresult";
   case ExtractValue:   return "extractvalue";
   case InsertValue:    return "insertvalue";
 

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

==============================================================================
--- llvm/trunk/lib/VMCore/Instructions.cpp (original)
+++ llvm/trunk/lib/VMCore/Instructions.cpp Tue Jul 22 19:34:11 2008
@@ -500,75 +500,30 @@
 
 ReturnInst::ReturnInst(const ReturnInst &RI)
   : TerminatorInst(Type::VoidTy, Instruction::Ret,
-                   OperandTraits<ReturnInst>::op_end(this)
-                   - RI.getNumOperands(),
+                   OperandTraits<ReturnInst>::op_end(this) -
+                     RI.getNumOperands(),
                    RI.getNumOperands()) {
-  unsigned N = RI.getNumOperands();
-  if (N == 1)
+  if (RI.getNumOperands())
     Op<0>() = RI.Op<0>();
-  else if (N) {
-    Use *OL = OperandList;
-    for (unsigned i = 0; i < N; ++i)
-      OL[i] = RI.getOperand(i);
-  }
 }
 
 ReturnInst::ReturnInst(Value *retVal, Instruction *InsertBefore)
   : TerminatorInst(Type::VoidTy, Instruction::Ret,
-                   OperandTraits<ReturnInst>::op_end(this) - (retVal != 0),
-                   retVal != 0, InsertBefore) {
+                   OperandTraits<ReturnInst>::op_end(this) - !!retVal, !!retVal,
+                   InsertBefore) {
   if (retVal)
-    init(&retVal, 1);
+    Op<0>() = retVal;
 }
 ReturnInst::ReturnInst(Value *retVal, BasicBlock *InsertAtEnd)
   : TerminatorInst(Type::VoidTy, Instruction::Ret,
-                   OperandTraits<ReturnInst>::op_end(this) - (retVal != 0),
-                   retVal != 0, InsertAtEnd) {
+                   OperandTraits<ReturnInst>::op_end(this) - !!retVal, !!retVal,
+                   InsertAtEnd) {
   if (retVal)
-    init(&retVal, 1);
+    Op<0>() = retVal;
 }
 ReturnInst::ReturnInst(BasicBlock *InsertAtEnd)
   : TerminatorInst(Type::VoidTy, Instruction::Ret,
-                   OperandTraits<ReturnInst>::op_end(this),
-                   0, InsertAtEnd) {
-}
-
-ReturnInst::ReturnInst(Value * const* retVals, unsigned N,
-                       Instruction *InsertBefore)
-  : TerminatorInst(Type::VoidTy, Instruction::Ret,
-                   OperandTraits<ReturnInst>::op_end(this) - N,
-                   N, InsertBefore) {
-  if (N != 0)
-    init(retVals, N);
-}
-ReturnInst::ReturnInst(Value * const* retVals, unsigned N,
-                       BasicBlock *InsertAtEnd)
-  : TerminatorInst(Type::VoidTy, Instruction::Ret,
-                   OperandTraits<ReturnInst>::op_end(this) - N,
-                   N, InsertAtEnd) {
-  if (N != 0)
-    init(retVals, N);
-}
-
-void ReturnInst::init(Value * const* retVals, unsigned N) {
-  assert (N > 0 && "Invalid operands numbers in ReturnInst init");
-
-  NumOperands = N;
-  if (NumOperands == 1) {
-    Value *V = *retVals;
-    if (V->getType() == Type::VoidTy)
-      return;
-    Op<0>() = V;
-    return;
-  }
-
-  Use *OL = OperandList;
-  for (unsigned i = 0; i < NumOperands; ++i) {
-    Value *V = *retVals++;
-    assert(!isa<BasicBlock>(V) &&
-           "Cannot return basic block.  Probably using the incorrect ctor");
-    OL[i] = V;
-  }
+                   OperandTraits<ReturnInst>::op_end(this), 0, InsertAtEnd) {
 }
 
 unsigned ReturnInst::getNumSuccessorsV() const {
@@ -2855,43 +2810,6 @@
   setSuccessor(idx, B);
 }
 
-//===----------------------------------------------------------------------===//
-//                           GetResultInst Implementation
-//===----------------------------------------------------------------------===//
-
-GetResultInst::GetResultInst(Value *Aggregate, unsigned Index,
-                             const std::string &Name,
-                             Instruction *InsertBef)
-  : UnaryInstruction(cast<StructType>(Aggregate->getType())
-                       ->getElementType(Index),
-                     GetResult, Aggregate, InsertBef),
-    Idx(Index) {
-  assert(isValidOperands(Aggregate, Index)
-         && "Invalid GetResultInst operands!");
-  setName(Name);
-}
-
-bool GetResultInst::isValidOperands(const Value *Aggregate, unsigned Index) {
-  if (!Aggregate)
-    return false;
-
-  if (const StructType *STy = dyn_cast<StructType>(Aggregate->getType())) {
-    unsigned NumElements = STy->getNumElements();
-    if (Index >= NumElements || NumElements == 0)
-      return false;
-
-    // getresult aggregate value's element types are restricted to
-    // avoid nested aggregates.
-    for (unsigned i = 0; i < NumElements; ++i)
-      if (!STy->getElementType(i)->isFirstClassType())
-        return false;
-
-    // Otherwise, Aggregate is valid.
-    return true;
-  }
-  return false;
-}
-
 // Define these methods here so vtables don't get emitted into every translation
 // unit that uses these classes.
 
@@ -2972,4 +2890,3 @@
 }
 UnwindInst *UnwindInst::clone() const { return new UnwindInst(); }
 UnreachableInst *UnreachableInst::clone() const { return new UnreachableInst();}
-GetResultInst *GetResultInst::clone() const { return new GetResultInst(*this); }

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

==============================================================================
--- llvm/trunk/lib/VMCore/Verifier.cpp (original)
+++ llvm/trunk/lib/VMCore/Verifier.cpp Tue Jul 22 19:34:11 2008
@@ -259,7 +259,8 @@
     void visitUserOp2(Instruction &I) { visitUserOp1(I); }
     void visitIntrinsicFunctionCall(Intrinsic::ID ID, CallInst &CI);
     void visitAllocationInst(AllocationInst &AI);
-    void visitGetResultInst(GetResultInst &GRI);
+    void visitExtractValueInst(ExtractValueInst &EVI);
+    void visitInsertValueInst(InsertValueInst &IVI);
 
     void VerifyCallSite(CallSite CS);
     void VerifyIntrinsicPrototype(Intrinsic::ID ID, Function *F,
@@ -1090,18 +1091,23 @@
   visitInstruction(AI);
 }
 
-void Verifier::visitGetResultInst(GetResultInst &GRI) {
-  Assert1(GetResultInst::isValidOperands(GRI.getAggregateValue(),
-                                         GRI.getIndex()),
-          "Invalid GetResultInst operands!", &GRI);
-  Assert1(isa<CallInst>(GRI.getAggregateValue()) ||
-          isa<InvokeInst>(GRI.getAggregateValue()) ||
-          isa<UndefValue>(GRI.getAggregateValue()),
-          "GetResultInst operand must be a call/invoke/undef!", &GRI);
+void Verifier::visitExtractValueInst(ExtractValueInst &EVI) {
+  Assert1(ExtractValueInst::getIndexedType(EVI.getAggregateOperand()->getType(),
+                                           EVI.idx_begin(), EVI.idx_end()) ==
+          EVI.getType(),
+          "Invalid ExtractValueInst operands!", &EVI);
   
-  visitInstruction(GRI);
+  visitInstruction(EVI);
 }
 
+void Verifier::visitInsertValueInst(InsertValueInst &IVI) {
+  Assert1(ExtractValueInst::getIndexedType(IVI.getAggregateOperand()->getType(),
+                                           IVI.idx_begin(), IVI.idx_end()) ==
+          IVI.getOperand(1)->getType(),
+          "Invalid InsertValueInst operands!", &IVI);
+  
+  visitInstruction(IVI);
+}
 
 /// verifyInstruction - Verify that an instruction is well formed.
 ///
@@ -1151,20 +1157,7 @@
     // Check to make sure that only first-class-values are operands to
     // instructions.
     if (!I.getOperand(i)->getType()->isFirstClassType()) {
-      if (isa<ReturnInst>(I) || isa<GetResultInst>(I))
-        Assert1(isa<StructType>(I.getOperand(i)->getType()),
-                "Invalid ReturnInst operands!", &I);
-      else if (isa<CallInst>(I) || isa<InvokeInst>(I)) {
-        if (const PointerType *PT = dyn_cast<PointerType>
-            (I.getOperand(i)->getType())) {
-          const Type *ETy = PT->getElementType();
-          Assert1(isa<StructType>(ETy), "Invalid CallInst operands!", &I);
-        }
-        else
-          Assert1(0, "Invalid CallInst operands!", &I);
-      }
-      else
-        Assert1(0, "Instruction operands must be first-class values!", &I);
+      Assert1(0, "Instruction operands must be first-class values!", &I);
     }
     
     if (Function *F = dyn_cast<Function>(I.getOperand(i))) {

Modified: llvm/trunk/test/Transforms/SCCP/2008-03-10-sret.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/SCCP/2008-03-10-sret.ll?rev=53941&r1=53940&r2=53941&view=diff

==============================================================================
--- llvm/trunk/test/Transforms/SCCP/2008-03-10-sret.ll (original)
+++ llvm/trunk/test/Transforms/SCCP/2008-03-10-sret.ll Tue Jul 22 19:34:11 2008
@@ -1,5 +1,8 @@
-; RUN: llvm-as < %s  | opt -ipsccp | llvm-dis | grep {ret i32 36}
-; RUN: llvm-as < %s  | opt -ipsccp | llvm-dis | grep {ret i32 18, i32 17}
+; RUN: llvm-as < %s  | opt -ipsccp | llvm-dis > %t
+; RUN: grep {ret i32 36} %t
+; RUN: grep {%mrv = insertvalue \{ i32, i32 \} undef, i32 18, 0} %t
+; RUN: grep {%mrv1 = insertvalue \{ i32, i32 \} %mrv, i32 17, 1} %t
+; RUN: grep {ret \{ i32, i32 \} %mrv1} %t
 
 define internal {i32, i32} @bar(i32 %A) {
 	%X = add i32 1, %A





More information about the llvm-commits mailing list