Add GetResultInst. First step for multiple return value support.
authorDevang Patel <dpatel@apple.com>
Tue, 19 Feb 2008 22:15:16 +0000 (22:15 +0000)
committerDevang Patel <dpatel@apple.com>
Tue, 19 Feb 2008 22:15:16 +0000 (22:15 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@47348 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/Instruction.def
include/llvm/Instructions.h
include/llvm/Support/InstVisitor.h
lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
lib/VMCore/Instructions.cpp
lib/VMCore/Verifier.cpp

index fff9ad7358c7f0ffd71ba618dcde53c273d373f0..b8e16da1aca32a8247de7e6770a2a9f7f2254cec 100644 (file)
@@ -164,7 +164,9 @@ HANDLE_OTHER_INST(47, VAArg  , VAArgInst  )  // vaarg instruction
 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
index 2de8c57d8ed86deb4c86e1eb7dcd37d61a1bcafb..54b67ffaad7a2096290804ba37584a07ef38456e 100644 (file)
@@ -2340,6 +2340,56 @@ public:
   }
 };
 
+//===----------------------------------------------------------------------===//
+//                             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
index ba98cd5896b328a1b2cc79143cacbf6678dd8e32..720b32d2bfca0fe284e576d091de9bf73bc2679a 100644 (file)
@@ -194,6 +194,7 @@ public:
   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
index 7b01d6390301d82ad1fffc8726d7081b95a375bd..1ee93d7bba103877f670d14585ea21d43b02d945 100644 (file)
@@ -608,6 +608,10 @@ public:
 
   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();
index 863f011cd07b9e65de76bd938cca3657d9d7128e..959ac9b61740e2f2ea24d456d34cdb9ad81d0df9 100644 (file)
@@ -2698,6 +2698,29 @@ void SwitchInst::setSuccessorV(unsigned idx, BasicBlock *B) {
   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 @@ SwitchInst *SwitchInst::clone() const { return new SwitchInst(*this); }
 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); }
index 98f421e95ea55190856e908647609cdc5086dd4e..a96f39c2c23708385c05cd0cfcabb08e429827a1 100644 (file)
@@ -257,6 +257,7 @@ namespace {  // Anonymous namespace for class
     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 @@ void Verifier::visitAllocationInst(AllocationInst &AI) {
   visitInstruction(AI);
 }
 
+void Verifier::visitGetResultInst(GetResultInst &GRI) {
+  // FIXME : Check operands.
+  visitInstruction(GRI);
+}
+
 
 /// verifyInstruction - Verify that an instruction is well formed.
 ///