#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"
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();
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);
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 {
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);
}
}
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!");
}
return 0;
}
+ReturnInst::~ReturnInst() {
+ if (NumOperands > 1)
+ delete [] OperandList;
+}
//===----------------------------------------------------------------------===//
// UnwindInst Implementation
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.