Add comment.
[oota-llvm.git] / lib / VMCore / Instructions.cpp
index c1e583375a2cc9a90856df9e20d08cd1cde0e4cf..c0b3413da33782870832f11d011181ba3ab69485 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();
@@ -384,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);
@@ -508,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 {
@@ -552,30 +574,66 @@ bool InvokeInst::isStructReturn() const {
 ReturnInst::ReturnInst(const ReturnInst &RI)
   : TerminatorInst(Type::VoidTy, Instruction::Ret,
                    &RetVal, RI.getNumOperands()) {
-  if (RI.getNumOperands())
+  unsigned N = RI.getNumOperands();
+  if (N == 1) 
     RetVal.init(RI.RetVal, this);
+  else if (N) {
+    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) {
-  init(retVal);
+  if (retVal)
+    init(&retVal, 1);
 }
 ReturnInst::ReturnInst(Value *retVal, BasicBlock *InsertAtEnd)
   : TerminatorInst(Type::VoidTy, Instruction::Ret, &RetVal, 0, InsertAtEnd) {
-  init(retVal);
+  if (retVal)
+    init(&retVal, 1);
 }
 ReturnInst::ReturnInst(BasicBlock *InsertAtEnd)
   : TerminatorInst(Type::VoidTy, Instruction::Ret, &RetVal, 0, InsertAtEnd) {
 }
 
+ReturnInst::ReturnInst(Value * const* retVals, unsigned N,
+                       Instruction *InsertBefore)
+  : TerminatorInst(Type::VoidTy, Instruction::Ret, &RetVal, N, InsertBefore) {
+  if (N != 0)
+    init(retVals, N);
+}
+ReturnInst::ReturnInst(Value * const* retVals, unsigned N,
+                       BasicBlock *InsertAtEnd)
+  : TerminatorInst(Type::VoidTy, Instruction::Ret, &RetVal, N, InsertAtEnd) {
+  if (N != 0)
+    init(retVals, N);
+}
+ReturnInst::ReturnInst(Value * const* retVals, unsigned N)
+  : TerminatorInst(Type::VoidTy, Instruction::Ret, &RetVal, N) {
+  if (N != 0)
+    init(retVals, N);
+}
 
+void ReturnInst::init(Value * const* retVals, unsigned N) {
+  assert (N > 0 && "Invalid operands numbers in ReturnInst init");
 
-void ReturnInst::init(Value *retVal) {
-  if (retVal && retVal->getType() != Type::VoidTy) {
-    assert(!isa<BasicBlock>(retVal) &&
+  NumOperands = N;
+  if (NumOperands == 1) {
+    Value *V = *retVals;
+    if (V->getType() == Type::VoidTy)
+      return;
+    RetVal.init(V, this);
+    return;
+  }
+
+  Use *OL = OperandList = new Use[NumOperands];
+  for (unsigned i = 0; i < NumOperands; ++i) {
+    Value *V = *retVals++;
+    assert(!isa<BasicBlock>(V) &&
            "Cannot return basic block.  Probably using the incorrect ctor");
-    NumOperands = 1;
-    RetVal.init(retVal, this);
+    OL[i].init(V, this);
   }
 }
 
@@ -583,8 +641,8 @@ unsigned ReturnInst::getNumSuccessorsV() const {
   return getNumSuccessors();
 }
 
-// Out-of-line ReturnInst method, put here so the C++ compiler can choose to
-// emit the vtable for the class in this translation unit.
+/// Out-of-line ReturnInst method, put here so the C++ compiler can choose to
+/// emit the vtable for the class in this translation unit.
 void ReturnInst::setSuccessorV(unsigned idx, BasicBlock *NewSucc) {
   assert(0 && "ReturnInst has no successors!");
 }
@@ -595,6 +653,10 @@ BasicBlock *ReturnInst::getSuccessorV(unsigned idx) const {
   return 0;
 }
 
+ReturnInst::~ReturnInst() {
+  if (NumOperands > 1)
+    delete [] OperandList;
+}
 
 //===----------------------------------------------------------------------===//
 //                        UnwindInst Implementation
@@ -2719,14 +2781,24 @@ GetResultInst::GetResultInst(Value *Aggregate, unsigned Index,
 bool GetResultInst::isValidOperands(const Value *Aggregate, unsigned Index) {
   if (!Aggregate)
     return false;
-  if (const StructType *STy = dyn_cast<StructType>(Aggregate->getType())) 
-    if (Index < STy->getNumElements())
-      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.