To support multiple return values, now ret instruction supports multiple operands...
[oota-llvm.git] / lib / VMCore / Instructions.cpp
index 959ac9b61740e2f2ea24d456d34cdb9ad81d0df9..d1df30b10330b8eef796ec6cf9ba0b2aea1aae8d 100644 (file)
@@ -17,7 +17,7 @@
 #include "llvm/DerivedTypes.h"
 #include "llvm/Function.h"
 #include "llvm/Instructions.h"
-#include "llvm/ParameterAttributes.h"
+#include "llvm/ParamAttrsList.h"
 #include "llvm/Support/CallSite.h"
 #include "llvm/Support/ConstantRange.h"
 #include "llvm/Support/MathExtras.h"
@@ -61,6 +61,13 @@ bool CallSite::paramHasAttr(uint16_t i, ParameterAttributes attr) const {
   else
     return cast<InvokeInst>(I)->paramHasAttr(i, attr);
 }
+uint16_t CallSite::getParamAlignment(uint16_t i) const {
+  if (CallInst *CI = dyn_cast<CallInst>(I))
+    return CI->getParamAlignment(i);
+  else
+    return cast<InvokeInst>(I)->getParamAlignment(i);
+}
+
 bool CallSite::doesNotAccessMemory() const {
   if (CallInst *CI = dyn_cast<CallInst>(I))
     return CI->doesNotAccessMemory();
@@ -186,11 +193,12 @@ void PHINode::resizeOperands(unsigned NumOps) {
 ///
 Value *PHINode::hasConstantValue(bool AllowNonDominatingInstruction) const {
   // If the PHI node only has one incoming value, eliminate the PHI node...
-  if (getNumIncomingValues() == 1)
+  if (getNumIncomingValues() == 1) {
     if (getIncomingValue(0) != this)   // not  X = phi X
       return getIncomingValue(0);
     else
       return UndefValue::get(getType());  // Self cycle is dead.
+  }
       
   // Otherwise if all of the incoming values are the same for the PHI, replace
   // the PHI node with the incoming value.
@@ -198,13 +206,14 @@ Value *PHINode::hasConstantValue(bool AllowNonDominatingInstruction) const {
   Value *InVal = 0;
   bool HasUndefInput = false;
   for (unsigned i = 0, e = getNumIncomingValues(); i != e; ++i)
-    if (isa<UndefValue>(getIncomingValue(i)))
+    if (isa<UndefValue>(getIncomingValue(i))) {
       HasUndefInput = true;
-    else if (getIncomingValue(i) != this)  // Not the PHI node itself...
+    } else if (getIncomingValue(i) != this) { // Not the PHI node itself...
       if (InVal && getIncomingValue(i) != InVal)
         return 0;  // Not the same, bail out.
       else
         InVal = getIncomingValue(i);
+    }
   
   // The only case that could cause InVal to be null is if we have a PHI node
   // that only has entries for itself.  In this case, there is no entry into the
@@ -382,6 +391,14 @@ bool CallInst::paramHasAttr(uint16_t i, ParameterAttributes attr) const {
   return false;
 }
 
+uint16_t CallInst::getParamAlignment(uint16_t i) const {
+  if (ParamAttrs && ParamAttrs->getParamAlignment(i))
+    return ParamAttrs->getParamAlignment(i);
+  if (const Function *F = getCalledFunction())
+    return F->getParamAlignment(i);
+  return 0;
+}
+
 /// @brief Determine if the call does not access memory.
 bool CallInst::doesNotAccessMemory() const {
   return paramHasAttr(0, ParamAttr::ReadNone);
@@ -451,8 +468,8 @@ void InvokeInst::init(Value *Fn, BasicBlock *IfNormal, BasicBlock *IfException,
     cast<FunctionType>(cast<PointerType>(Fn->getType())->getElementType());
   FTy = FTy;  // silence warning.
 
-  assert((NumArgs == FTy->getNumParams()) ||
-         (FTy->isVarArg() && NumArgs > FTy->getNumParams()) &&
+  assert(((NumArgs == FTy->getNumParams()) ||
+          (FTy->isVarArg() && NumArgs > FTy->getNumParams())) &&
          "Calling a function with bad signature");
 
   for (unsigned i = 0, e = NumArgs; i != e; i++) {
@@ -506,6 +523,13 @@ bool InvokeInst::paramHasAttr(uint16_t i, ParameterAttributes attr) const {
   return false;
 }
 
+uint16_t InvokeInst::getParamAlignment(uint16_t i) const {
+  if (ParamAttrs && ParamAttrs->getParamAlignment(i))
+    return ParamAttrs->getParamAlignment(i);
+  if (const Function *F = getCalledFunction())
+    return F->getParamAlignment(i);
+  return 0;
+}
 
 /// @brief Determine if the call does not access memory.
 bool InvokeInst::doesNotAccessMemory() const {
@@ -549,34 +573,75 @@ bool InvokeInst::isStructReturn() const {
 
 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();
 }
@@ -593,6 +658,10 @@ BasicBlock *ReturnInst::getSuccessorV(unsigned idx) const {
   return 0;
 }
 
+ReturnInst::~ReturnInst() {
+  if (NumOperands)
+    delete [] OperandList;
+}
 
 //===----------------------------------------------------------------------===//
 //                        UnwindInst Implementation
@@ -1037,12 +1106,13 @@ const Type* GetElementPtrInst::getIndexedType(const Type *Ptr,
   if (!isa<PointerType>(Ptr)) return 0;   // Type isn't a pointer type!
 
   // Handle the special case of the empty set index set...
-  if (NumIdx == 0)
+  if (NumIdx == 0) {
     if (AllowCompositeLeaf ||
         cast<PointerType>(Ptr)->getElementType()->isFirstClassType())
       return cast<PointerType>(Ptr)->getElementType();
     else
       return 0;
+  }
 
   unsigned CurIdx = 0;
   while (const CompositeType *CT = dyn_cast<CompositeType>(Ptr)) {
@@ -2329,7 +2399,7 @@ CmpInst::CmpInst(OtherOps op, unsigned short predicate, Value *LHS, Value *RHS,
     assert(Op0Ty == Op1Ty &&
           "Both operands to ICmp instruction are not of the same type!");
     // Check that the operands are the right type
-    assert(Op0Ty->isInteger() || isa<PointerType>(Op0Ty) &&
+    assert((Op0Ty->isInteger() || isa<PointerType>(Op0Ty)) &&
            "Invalid operand types for ICmp instruction");
     return;
   }
@@ -2702,25 +2772,37 @@ void SwitchInst::setSuccessorV(unsigned idx, BasicBlock *B) {
 //                           GetResultInst Implementation
 //===----------------------------------------------------------------------===//
 
-GetResultInst::GetResultInst(Value *Aggr, Value *Index,
+GetResultInst::GetResultInst(Value *Aggregate, unsigned 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);
+  : Instruction(cast<StructType>(Aggregate->getType())->getElementType(Index),
+                GetResult, &Aggr, 1, InsertBef) {
+  assert(isValidOperands(Aggregate, Index) && "Invalid GetResultInst operands!");
+  Aggr.init(Aggregate, this);
+  Idx = Index;
   setName(Name);
 }
 
-bool GetResultInst::isValidOperands(const Value *Aggr, const Value *Index) {
-  if (!Aggr || !Index)
+bool GetResultInst::isValidOperands(const Value *Aggregate, unsigned Index) {
+  if (!Aggregate)
     return false;
-  if (!isa<StructType>(Aggr->getType()) || Index->getType() != Type::Int32Ty)
-    return false;
-  return true;
-}
 
+  if (const StructType *STy = dyn_cast<StructType>(Aggregate->getType())) {
+    unsigned NumElements = STy->getNumElements();
+    if (Index >= NumElements)
+      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.