Add GetResultInst. First step for multiple return value support.



git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@47348 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/include/llvm/Instruction.def b/include/llvm/Instruction.def
index fff9ad7..b8e16da 100644
--- a/include/llvm/Instruction.def
+++ b/include/llvm/Instruction.def
@@ -164,7 +164,9 @@
 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.
-  LAST_OTHER_INST(50)
+HANDLE_OTHER_INST(51, GetResult, GetResultInst) // Extract individual value 
+                                                //from aggregate result
+  LAST_OTHER_INST(51)
 
 #undef  FIRST_TERM_INST
 #undef HANDLE_TERM_INST
diff --git a/include/llvm/Instructions.h b/include/llvm/Instructions.h
index 2de8c57..54b67ff 100644
--- a/include/llvm/Instructions.h
+++ b/include/llvm/Instructions.h
@@ -2340,6 +2340,56 @@
   }
 };
 
+//===----------------------------------------------------------------------===//
+//                             GetResultInst Class
+//===----------------------------------------------------------------------===//
+
+/// GetResultInst - This instruction extracts individual result value from
+/// aggregate value, where aggregate value is returned by CallInst.
+///
+class GetResultInst : public Instruction {
+  Use Ops[2];
+  GetResultInst(const GetResultInst &GRI) :
+    Instruction(GRI.getType(), Instruction::GetResult, Ops, 2) {
+    Ops[0].init(GRI.Ops[0], this);
+    Ops[1].init(GRI.Ops[1], this);
+  }
+
+public:
+  explicit GetResultInst(Value *Aggr, Value *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, const Value *Idx);
+  
+  virtual GetResultInst *clone() const;
+  
+  // getType - Get aggregate value element type
+  inline const Type *getType() const {
+    return Ops[0]->getType();
+  }
+  
+  Value *getAggregateValue() {
+    return getOperand(0);
+  }
+  const Value *geIndex() {
+    return getOperand(1);
+  }
+
+  unsigned getNumOperands() const { return 2; }
+
+  // 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
diff --git a/include/llvm/Support/InstVisitor.h b/include/llvm/Support/InstVisitor.h
index ba98cd5..720b32d 100644
--- a/include/llvm/Support/InstVisitor.h
+++ b/include/llvm/Support/InstVisitor.h
@@ -194,6 +194,7 @@
   RetTy visitExtractElementInst(ExtractElementInst &I) { DELEGATE(Instruction);}
   RetTy visitInsertElementInst(InsertElementInst &I) { DELEGATE(Instruction); }
   RetTy visitShuffleVectorInst(ShuffleVectorInst &I) { DELEGATE(Instruction); }
+  RetTy visitGetResultInst(GetResultInst &I) { DELEGATE(Instruction); }
 
   // Next level propagators... if the user does not overload a specific
   // instruction type, they can overload one of these to get the whole class
diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
index 7b01d63..1ee93d7 100644
--- a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
+++ b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
@@ -608,6 +608,10 @@
 
   void visitMemIntrinsic(CallInst &I, unsigned Op);
 
+  void visitGetResult(GetResultInst &I) {
+    // FIXME
+  }
+
   void visitUserOp1(Instruction &I) {
     assert(0 && "UserOp1 should not exist at instruction selection time!");
     abort();
diff --git a/lib/VMCore/Instructions.cpp b/lib/VMCore/Instructions.cpp
index 863f011..959ac9b 100644
--- a/lib/VMCore/Instructions.cpp
+++ b/lib/VMCore/Instructions.cpp
@@ -2698,6 +2698,29 @@
   setSuccessor(idx, B);
 }
 
+//===----------------------------------------------------------------------===//
+//                           GetResultInst Implementation
+//===----------------------------------------------------------------------===//
+
+GetResultInst::GetResultInst(Value *Aggr, Value *Index,
+                             const std::string &Name,
+                             Instruction *InsertBef)
+  : Instruction(Aggr->getType(),
+                GetResult, Ops, 2, InsertBef) {
+  assert(isValidOperands(Aggr, Index) && "Invalid GetResultInst operands!");
+  Ops[0].init(Aggr, this);
+  Ops[1].init(Index, this);
+  setName(Name);
+}
+
+bool GetResultInst::isValidOperands(const Value *Aggr, const Value *Index) {
+  if (!Aggr || !Index)
+    return false;
+  if (!isa<StructType>(Aggr->getType()) || Index->getType() != Type::Int32Ty)
+    return false;
+  return true;
+}
+
 
 // Define these methods here so vtables don't get emitted into every translation
 // unit that uses these classes.
@@ -2754,3 +2777,4 @@
 InvokeInst *InvokeInst::clone() const { return new InvokeInst(*this); }
 UnwindInst *UnwindInst::clone() const { return new UnwindInst(); }
 UnreachableInst *UnreachableInst::clone() const { return new UnreachableInst();}
+GetResultInst *GetResultInst::clone() const { return new GetResultInst(*this); }
diff --git a/lib/VMCore/Verifier.cpp b/lib/VMCore/Verifier.cpp
index 98f421e..a96f39c 100644
--- a/lib/VMCore/Verifier.cpp
+++ b/lib/VMCore/Verifier.cpp
@@ -257,6 +257,7 @@
     void visitUserOp2(Instruction &I) { visitUserOp1(I); }
     void visitIntrinsicFunctionCall(Intrinsic::ID ID, CallInst &CI);
     void visitAllocationInst(AllocationInst &AI);
+    void visitGetResultInst(GetResultInst &GRI);
 
     void VerifyCallSite(CallSite CS);
     void VerifyIntrinsicPrototype(Intrinsic::ID ID, Function *F,
@@ -1037,6 +1038,11 @@
   visitInstruction(AI);
 }
 
+void Verifier::visitGetResultInst(GetResultInst &GRI) {
+  // FIXME : Check operands.
+  visitInstruction(GRI);
+}
+
 
 /// verifyInstruction - Verify that an instruction is well formed.
 ///