diff options
author | Chris Lattner <sabre@nondot.org> | 2008-03-12 17:45:29 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2008-03-12 17:45:29 +0000 |
commit | 1c8733e1fd69e634daaa7fefd0d1436b846a8eb3 (patch) | |
tree | f04d1ab294b3379bf97d9f727d4ade9e7079ca48 /lib/VMCore | |
parent | b532d64c6e829cf1d0ee3508f2cfb798c776a5e2 (diff) | |
download | external_llvm-1c8733e1fd69e634daaa7fefd0d1436b846a8eb3.zip external_llvm-1c8733e1fd69e634daaa7fefd0d1436b846a8eb3.tar.gz external_llvm-1c8733e1fd69e634daaa7fefd0d1436b846a8eb3.tar.bz2 |
Reimplement the parameter attributes support, phase #1. hilights:
1. There is now a "PAListPtr" class, which is a smart pointer around
the underlying uniqued parameter attribute list object, and manages
its refcount. It is now impossible to mess up the refcount.
2. PAListPtr is now the main interface to the underlying object, and
the underlying object is now completely opaque.
3. Implementation details like SmallVector and FoldingSet are now no
longer part of the interface.
4. You can create a PAListPtr with an arbitrary sequence of
ParamAttrsWithIndex's, no need to make a SmallVector of a specific
size (you can just use an array or scalar or vector if you wish).
5. All the client code that had to check for a null pointer before
dereferencing the pointer is simplified to just access the
PAListPtr directly.
6. The interfaces for adding attrs to a list and removing them is a
bit simpler.
Phase #2 will rename some stuff (e.g. PAListPtr) and do other less
invasive changes.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@48289 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/VMCore')
-rw-r--r-- | lib/VMCore/AsmWriter.cpp | 50 | ||||
-rw-r--r-- | lib/VMCore/AutoUpgrade.cpp | 18 | ||||
-rw-r--r-- | lib/VMCore/Function.cpp | 37 | ||||
-rw-r--r-- | lib/VMCore/Instructions.cpp | 79 | ||||
-rw-r--r-- | lib/VMCore/ParameterAttributes.cpp | 343 | ||||
-rw-r--r-- | lib/VMCore/Verifier.cpp | 125 |
6 files changed, 322 insertions, 330 deletions
diff --git a/lib/VMCore/AsmWriter.cpp b/lib/VMCore/AsmWriter.cpp index 438bdad..aba66c8 100644 --- a/lib/VMCore/AsmWriter.cpp +++ b/lib/VMCore/AsmWriter.cpp @@ -20,7 +20,6 @@ #include "llvm/CallingConv.h" #include "llvm/Constants.h" #include "llvm/DerivedTypes.h" -#include "llvm/ParamAttrsList.h" #include "llvm/InlineAsm.h" #include "llvm/Instruction.h" #include "llvm/Instructions.h" @@ -849,7 +848,7 @@ void AssemblyWriter::writeParamOperand(const Value *Operand, printType(Operand->getType()); // Print parameter attributes list if (Attrs != ParamAttr::None) - Out << ' ' << ParamAttrsList::getParamAttrsText(Attrs); + Out << ' ' << ParamAttr::getAsString(Attrs); // Print the operand WriteAsOperandInternal(Out, Operand, TypeNames, &Machine); } @@ -1074,7 +1073,7 @@ void AssemblyWriter::printFunction(const Function *F) { } const FunctionType *FT = F->getFunctionType(); - const ParamAttrsList *Attrs = F->getParamAttrs(); + const PAListPtr &Attrs = F->getParamAttrs(); printType(F->getReturnType()) << ' '; if (!F->getName().empty()) Out << getLLVMName(F->getName(), GlobalPrefix); @@ -1092,8 +1091,7 @@ void AssemblyWriter::printFunction(const Function *F) { I != E; ++I) { // Insert commas as we go... the first arg doesn't get a comma if (I != F->arg_begin()) Out << ", "; - printArgument(I, (Attrs ? Attrs->getParamAttrs(Idx) - : ParamAttr::None)); + printArgument(I, Attrs.getParamAttrs(Idx)); Idx++; } } else { @@ -1105,10 +1103,9 @@ void AssemblyWriter::printFunction(const Function *F) { // Output type... printType(FT->getParamType(i)); - ParameterAttributes ArgAttrs = ParamAttr::None; - if (Attrs) ArgAttrs = Attrs->getParamAttrs(i+1); + ParameterAttributes ArgAttrs = Attrs.getParamAttrs(i+1); if (ArgAttrs != ParamAttr::None) - Out << ' ' << ParamAttrsList::getParamAttrsText(ArgAttrs); + Out << ' ' << ParamAttr::getAsString(ArgAttrs); } } @@ -1118,8 +1115,9 @@ void AssemblyWriter::printFunction(const Function *F) { Out << "..."; // Output varargs portion of signature! } Out << ')'; - if (Attrs && Attrs->getParamAttrs(0) != ParamAttr::None) - Out << ' ' << Attrs->getParamAttrsTextByIndex(0); + ParameterAttributes RetAttrs = Attrs.getParamAttrs(0); + if (RetAttrs != ParamAttr::None) + Out << ' ' << ParamAttr::getAsString(Attrs.getParamAttrs(0)); if (F->hasSection()) Out << " section \"" << F->getSection() << '"'; if (F->getAlignment()) @@ -1152,7 +1150,7 @@ void AssemblyWriter::printArgument(const Argument *Arg, // Output parameter attributes list if (Attrs != ParamAttr::None) - Out << ' ' << ParamAttrsList::getParamAttrsText(Attrs); + Out << ' ' << ParamAttr::getAsString(Attrs); // Output name, if available... if (Arg->hasName()) @@ -1321,7 +1319,7 @@ void AssemblyWriter::printInstruction(const Instruction &I) { const PointerType *PTy = cast<PointerType>(Operand->getType()); const FunctionType *FTy = cast<FunctionType>(PTy->getElementType()); const Type *RetTy = FTy->getReturnType(); - const ParamAttrsList *PAL = CI->getParamAttrs(); + const PAListPtr &PAL = CI->getParamAttrs(); // If possible, print out the short form of the call instruction. We can // only do this if the first argument is a pointer to a nonvararg function, @@ -1339,17 +1337,16 @@ void AssemblyWriter::printInstruction(const Instruction &I) { for (unsigned op = 1, Eop = I.getNumOperands(); op < Eop; ++op) { if (op > 1) Out << ','; - writeParamOperand(I.getOperand(op), PAL ? PAL->getParamAttrs(op) : - ParamAttr::None); + writeParamOperand(I.getOperand(op), PAL.getParamAttrs(op)); } Out << " )"; - if (PAL && PAL->getParamAttrs(0) != ParamAttr::None) - Out << ' ' << PAL->getParamAttrsTextByIndex(0); + if (PAL.getParamAttrs(0) != ParamAttr::None) + Out << ' ' << ParamAttr::getAsString(PAL.getParamAttrs(0)); } else if (const InvokeInst *II = dyn_cast<InvokeInst>(&I)) { const PointerType *PTy = cast<PointerType>(Operand->getType()); const FunctionType *FTy = cast<FunctionType>(PTy->getElementType()); const Type *RetTy = FTy->getReturnType(); - const ParamAttrsList *PAL = II->getParamAttrs(); + const PAListPtr &PAL = II->getParamAttrs(); // Print the calling convention being used. switch (II->getCallingConv()) { @@ -1378,13 +1375,12 @@ void AssemblyWriter::printInstruction(const Instruction &I) { for (unsigned op = 3, Eop = I.getNumOperands(); op < Eop; ++op) { if (op > 3) Out << ','; - writeParamOperand(I.getOperand(op), PAL ? PAL->getParamAttrs(op-2) : - ParamAttr::None); + writeParamOperand(I.getOperand(op), PAL.getParamAttrs(op-2)); } Out << " )"; - if (PAL && PAL->getParamAttrs(0) != ParamAttr::None) - Out << " " << PAL->getParamAttrsTextByIndex(0); + if (PAL.getParamAttrs(0) != ParamAttr::None) + Out << " " << ParamAttr::getAsString(PAL.getParamAttrs(0)); Out << "\n\t\t\tto"; writeOperand(II->getNormalDest(), true); Out << " unwind"; @@ -1529,18 +1525,6 @@ void Value::dump() const { print(*cerr.stream()); cerr << '\n'; } // Located here because so much of the needed functionality is here. void Type::dump() const { print(*cerr.stream()); cerr << '\n'; } -void -ParamAttrsList::dump() const { - cerr << "PAL[ "; - for (unsigned i = 0; i < attrs.size(); ++i) { - uint16_t index = getParamIndex(i); - ParameterAttributes attrs = getParamAttrs(index); - cerr << "{" << index << "," << attrs << "} "; - } - - cerr << "]\n"; -} - //===----------------------------------------------------------------------===// // SlotMachine Implementation //===----------------------------------------------------------------------===// diff --git a/lib/VMCore/AutoUpgrade.cpp b/lib/VMCore/AutoUpgrade.cpp index f322e69..343a4b6 100644 --- a/lib/VMCore/AutoUpgrade.cpp +++ b/lib/VMCore/AutoUpgrade.cpp @@ -17,7 +17,7 @@ #include "llvm/Module.h" #include "llvm/Instructions.h" #include "llvm/Intrinsics.h" -#include "llvm/ParamAttrsList.h" +#include "llvm/ADT/SmallVector.h" #include <cstring> using namespace llvm; @@ -226,18 +226,18 @@ void llvm::UpgradeIntrinsicCall(CallInst *CI, Function *NewFn) { case Intrinsic::x86_mmx_psrl_d: case Intrinsic::x86_mmx_psrl_q: case Intrinsic::x86_mmx_psrl_w: { - SmallVector<Value*, 2> Operands; + Value *Operands[2]; - Operands.push_back(CI->getOperand(1)); + Operands[0] = CI->getOperand(1); // Cast the second parameter to the correct type. BitCastInst *BC = new BitCastInst(CI->getOperand(2), NewFn->getFunctionType()->getParamType(1), "upgraded", CI); - Operands.push_back(BC); + Operands[1] = BC; // Construct a new CallInst - CallInst *NewCI = new CallInst(NewFn, Operands.begin(), Operands.end(), + CallInst *NewCI = new CallInst(NewFn, Operands, Operands+2, "upgraded."+CI->getName(), CI); NewCI->setTailCall(CI->isTailCall()); NewCI->setCallingConv(CI->getCallingConv()); @@ -257,7 +257,7 @@ void llvm::UpgradeIntrinsicCall(CallInst *CI, Function *NewFn) { case Intrinsic::cttz: // Build a small vector of the 1..(N-1) operands, which are the // parameters. - SmallVector<Value*, 8> Operands(CI->op_begin()+1, CI->op_end()); + SmallVector<Value*, 8> Operands(CI->op_begin()+1, CI->op_end()); // Construct a new CallInst CallInst *NewCI = new CallInst(NewFn, Operands.begin(), Operands.end(), @@ -268,10 +268,8 @@ void llvm::UpgradeIntrinsicCall(CallInst *CI, Function *NewFn) { // Handle any uses of the old CallInst. if (!CI->use_empty()) { // Check for sign extend parameter attributes on the return values. - bool SrcSExt = NewFn->getParamAttrs() && - NewFn->getParamAttrs()->paramHasAttr(0,ParamAttr::SExt); - bool DestSExt = F->getParamAttrs() && - F->getParamAttrs()->paramHasAttr(0,ParamAttr::SExt); + bool SrcSExt = NewFn->getParamAttrs().paramHasAttr(0, ParamAttr::SExt); + bool DestSExt = F->getParamAttrs().paramHasAttr(0, ParamAttr::SExt); // Construct an appropriate cast from the new return type to the old. CastInst *RetCast = CastInst::create( diff --git a/lib/VMCore/Function.cpp b/lib/VMCore/Function.cpp index f5712e7..5a69c09 100644 --- a/lib/VMCore/Function.cpp +++ b/lib/VMCore/Function.cpp @@ -14,7 +14,6 @@ #include "llvm/Module.h" #include "llvm/DerivedTypes.h" #include "llvm/IntrinsicInst.h" -#include "llvm/ParamAttrsList.h" #include "llvm/CodeGen/ValueTypes.h" #include "llvm/Support/LeakDetector.h" #include "llvm/Support/StringPool.h" @@ -140,12 +139,12 @@ void Function::eraseFromParent() { /// @brief Determine whether the function has the given attribute. bool Function::paramHasAttr(uint16_t i, ParameterAttributes attr) const { - return ParamAttrs && ParamAttrs->paramHasAttr(i, attr); + return ParamAttrs.paramHasAttr(i, attr); } /// @brief Extract the alignment for a call or parameter (0=unknown). uint16_t Function::getParamAlignment(uint16_t i) const { - return ParamAttrs ? ParamAttrs->getParamAlignment(i) : 0; + return ParamAttrs.getParamAlignment(i); } /// @brief Determine if the function cannot return. @@ -181,8 +180,7 @@ bool Function::hasStructRetAttr() const { Function::Function(const FunctionType *Ty, LinkageTypes Linkage, const std::string &name, Module *ParentModule) : GlobalValue(PointerType::getUnqual(Ty), - Value::FunctionVal, 0, 0, Linkage, name), - ParamAttrs(0) { + Value::FunctionVal, 0, 0, Linkage, name) { SymTab = new ValueSymbolTable(); assert((getReturnType()->isFirstClassType() ||getReturnType() == Type::VoidTy @@ -207,10 +205,6 @@ Function::~Function() { ArgumentList.clear(); delete SymTab; - // Drop our reference to the parameter attributes, if any. - if (ParamAttrs) - ParamAttrs->dropRef(); - // Remove the function from the on-the-side collector table. clearCollector(); } @@ -243,24 +237,6 @@ void Function::setParent(Module *parent) { LeakDetector::removeGarbageObject(this); } -void Function::setParamAttrs(const ParamAttrsList *attrs) { - // Avoid deleting the ParamAttrsList if they are setting the - // attributes to the same list. - if (ParamAttrs == attrs) - return; - - // Drop reference on the old ParamAttrsList - if (ParamAttrs) - ParamAttrs->dropRef(); - - // Add reference to the new ParamAttrsList - if (attrs) - attrs->addRef(); - - // Set the new ParamAttrsList. - ParamAttrs = attrs; -} - // dropAllReferences() - This function causes all the subinstructions to "let // go" of all references that they are maintaining. This allows one to // 'delete' a whole class at a time, even though there may be circular @@ -370,8 +346,7 @@ const FunctionType *Intrinsic::getType(ID id, const Type **Tys, return FunctionType::get(ResultTy, ArgTys, IsVarArg); } -const ParamAttrsList *Intrinsic::getParamAttrs(ID id) { - ParamAttrsVector Attrs; +PAListPtr Intrinsic::getParamAttrs(ID id) { ParameterAttributes Attr = ParamAttr::None; #define GET_INTRINSIC_ATTRIBUTES @@ -381,8 +356,8 @@ const ParamAttrsList *Intrinsic::getParamAttrs(ID id) { // Intrinsics cannot throw exceptions. Attr |= ParamAttr::NoUnwind; - Attrs.push_back(ParamAttrsWithIndex::get(0, Attr)); - return ParamAttrsList::get(Attrs); + ParamAttrsWithIndex PAWI = ParamAttrsWithIndex::get(0, Attr); + return PAListPtr::get(&PAWI, 1); } Function *Intrinsic::getDeclaration(Module *M, ID id, const Type **Tys, diff --git a/lib/VMCore/Instructions.cpp b/lib/VMCore/Instructions.cpp index f7401ec..ee9a02e 100644 --- a/lib/VMCore/Instructions.cpp +++ b/lib/VMCore/Instructions.cpp @@ -17,7 +17,6 @@ #include "llvm/DerivedTypes.h" #include "llvm/Function.h" #include "llvm/Instructions.h" -#include "llvm/ParamAttrsList.h" #include "llvm/Support/CallSite.h" #include "llvm/Support/ConstantRange.h" #include "llvm/Support/MathExtras.h" @@ -43,13 +42,13 @@ void CallSite::setCallingConv(unsigned CC) { else cast<InvokeInst>(I)->setCallingConv(CC); } -const ParamAttrsList* CallSite::getParamAttrs() const { +const PAListPtr &CallSite::getParamAttrs() const { if (CallInst *CI = dyn_cast<CallInst>(I)) return CI->getParamAttrs(); else return cast<InvokeInst>(I)->getParamAttrs(); } -void CallSite::setParamAttrs(const ParamAttrsList *PAL) { +void CallSite::setParamAttrs(const PAListPtr &PAL) { if (CallInst *CI = dyn_cast<CallInst>(I)) CI->setParamAttrs(PAL); else @@ -243,12 +242,9 @@ Value *PHINode::hasConstantValue(bool AllowNonDominatingInstruction) const { CallInst::~CallInst() { delete [] OperandList; - if (ParamAttrs) - ParamAttrs->dropRef(); } void CallInst::init(Value *Func, Value* const *Params, unsigned NumParams) { - ParamAttrs = 0; NumOperands = NumParams+1; Use *OL = OperandList = new Use[NumParams+1]; OL[0].init(Func, this); @@ -269,7 +265,6 @@ void CallInst::init(Value *Func, Value* const *Params, unsigned NumParams) { } void CallInst::init(Value *Func, Value *Actual1, Value *Actual2) { - ParamAttrs = 0; NumOperands = 3; Use *OL = OperandList = new Use[3]; OL[0].init(Func, this); @@ -292,7 +287,6 @@ void CallInst::init(Value *Func, Value *Actual1, Value *Actual2) { } void CallInst::init(Value *Func, Value *Actual) { - ParamAttrs = 0; NumOperands = 2; Use *OL = OperandList = new Use[2]; OL[0].init(Func, this); @@ -311,7 +305,6 @@ void CallInst::init(Value *Func, Value *Actual) { } void CallInst::init(Value *Func) { - ParamAttrs = 0; NumOperands = 1; Use *OL = OperandList = new Use[1]; OL[0].init(Func, this); @@ -360,8 +353,7 @@ CallInst::CallInst(Value *Func, const std::string &Name, CallInst::CallInst(const CallInst &CI) : Instruction(CI.getType(), Instruction::Call, new Use[CI.getNumOperands()], - CI.getNumOperands()), - ParamAttrs(0) { + CI.getNumOperands()) { setParamAttrs(CI.getParamAttrs()); SubclassData = CI.SubclassData; Use *OL = OperandList; @@ -370,21 +362,8 @@ CallInst::CallInst(const CallInst &CI) OL[i].init(InOL[i], this); } -void CallInst::setParamAttrs(const ParamAttrsList *newAttrs) { - if (ParamAttrs == newAttrs) - return; - - if (ParamAttrs) - ParamAttrs->dropRef(); - - if (newAttrs) - newAttrs->addRef(); - - ParamAttrs = newAttrs; -} - bool CallInst::paramHasAttr(uint16_t i, ParameterAttributes attr) const { - if (ParamAttrs && ParamAttrs->paramHasAttr(i, attr)) + if (ParamAttrs.paramHasAttr(i, attr)) return true; if (const Function *F = getCalledFunction()) return F->paramHasAttr(i, attr); @@ -392,11 +371,7 @@ bool CallInst::paramHasAttr(uint16_t i, ParameterAttributes attr) const { } 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; + return ParamAttrs.getParamAlignment(i); } /// @brief Determine if the call does not access memory. @@ -428,21 +403,20 @@ bool CallInst::hasStructRetAttr() const { /// @brief Determine if any call argument is an aggregate passed by value. bool CallInst::hasByValArgument() const { - if (ParamAttrs && ParamAttrs->hasAttrSomewhere(ParamAttr::ByVal)) + if (ParamAttrs.hasAttrSomewhere(ParamAttr::ByVal)) return true; // Be consistent with other methods and check the callee too. if (const Function *F = getCalledFunction()) - if (const ParamAttrsList *PAL = F->getParamAttrs()) - return PAL->hasAttrSomewhere(ParamAttr::ByVal); + return F->getParamAttrs().hasAttrSomewhere(ParamAttr::ByVal); return false; } void CallInst::setDoesNotThrow(bool doesNotThrow) { - const ParamAttrsList *PAL = getParamAttrs(); + PAListPtr PAL = getParamAttrs(); if (doesNotThrow) - PAL = ParamAttrsList::includeAttrs(PAL, 0, ParamAttr::NoUnwind); + PAL = PAL.addAttr(0, ParamAttr::NoUnwind); else - PAL = ParamAttrsList::excludeAttrs(PAL, 0, ParamAttr::NoUnwind); + PAL = PAL.removeAttr(0, ParamAttr::NoUnwind); setParamAttrs(PAL); } @@ -453,13 +427,10 @@ void CallInst::setDoesNotThrow(bool doesNotThrow) { InvokeInst::~InvokeInst() { delete [] OperandList; - if (ParamAttrs) - ParamAttrs->dropRef(); } void InvokeInst::init(Value *Fn, BasicBlock *IfNormal, BasicBlock *IfException, Value* const *Args, unsigned NumArgs) { - ParamAttrs = 0; NumOperands = 3+NumArgs; Use *OL = OperandList = new Use[3+NumArgs]; OL[0].init(Fn, this); @@ -484,8 +455,7 @@ void InvokeInst::init(Value *Fn, BasicBlock *IfNormal, BasicBlock *IfException, InvokeInst::InvokeInst(const InvokeInst &II) : TerminatorInst(II.getType(), Instruction::Invoke, - new Use[II.getNumOperands()], II.getNumOperands()), - ParamAttrs(0) { + new Use[II.getNumOperands()], II.getNumOperands()) { setParamAttrs(II.getParamAttrs()); SubclassData = II.SubclassData; Use *OL = OperandList, *InOL = II.OperandList; @@ -503,21 +473,8 @@ void InvokeInst::setSuccessorV(unsigned idx, BasicBlock *B) { return setSuccessor(idx, B); } -void InvokeInst::setParamAttrs(const ParamAttrsList *newAttrs) { - if (ParamAttrs == newAttrs) - return; - - if (ParamAttrs) - ParamAttrs->dropRef(); - - if (newAttrs) - newAttrs->addRef(); - - ParamAttrs = newAttrs; -} - bool InvokeInst::paramHasAttr(uint16_t i, ParameterAttributes attr) const { - if (ParamAttrs && ParamAttrs->paramHasAttr(i, attr)) + if (ParamAttrs.paramHasAttr(i, attr)) return true; if (const Function *F = getCalledFunction()) return F->paramHasAttr(i, attr); @@ -525,11 +482,7 @@ bool InvokeInst::paramHasAttr(uint16_t i, ParameterAttributes attr) const { } 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; + return ParamAttrs.getParamAlignment(i); } /// @brief Determine if the call does not access memory. @@ -553,11 +506,11 @@ bool InvokeInst::doesNotThrow() const { } void InvokeInst::setDoesNotThrow(bool doesNotThrow) { - const ParamAttrsList *PAL = getParamAttrs(); + PAListPtr PAL = getParamAttrs(); if (doesNotThrow) - PAL = ParamAttrsList::includeAttrs(PAL, 0, ParamAttr::NoUnwind); + PAL = PAL.addAttr(0, ParamAttr::NoUnwind); else - PAL = ParamAttrsList::excludeAttrs(PAL, 0, ParamAttr::NoUnwind); + PAL = PAL.removeAttr(0, ParamAttr::NoUnwind); setParamAttrs(PAL); } diff --git a/lib/VMCore/ParameterAttributes.cpp b/lib/VMCore/ParameterAttributes.cpp index bebee3e..7501a35 100644 --- a/lib/VMCore/ParameterAttributes.cpp +++ b/lib/VMCore/ParameterAttributes.cpp @@ -11,41 +11,19 @@ // //===----------------------------------------------------------------------===// -#include "llvm/ParamAttrsList.h" -#include "llvm/DerivedTypes.h" +#include "llvm/ParameterAttributes.h" +#include "llvm/Type.h" #include "llvm/ADT/StringExtras.h" +#include "llvm/ADT/FoldingSet.h" +#include "llvm/Support/Streams.h" #include "llvm/Support/ManagedStatic.h" - using namespace llvm; -static ManagedStatic<FoldingSet<ParamAttrsList> > ParamAttrsLists; - -ParamAttrsList::ParamAttrsList(const ParamAttrsVector &attrVec) - : attrs(attrVec), refCount(0) { -} - -ParamAttrsList::~ParamAttrsList() { - ParamAttrsLists->RemoveNode(this); -} - -ParameterAttributes -ParamAttrsList::getParamAttrs(uint16_t Index) const { - unsigned limit = attrs.size(); - for (unsigned i = 0; i < limit && attrs[i].index <= Index; ++i) - if (attrs[i].index == Index) - return attrs[i].attrs; - return ParamAttr::None; -} - -bool ParamAttrsList::hasAttrSomewhere(ParameterAttributes attr) const { - for (unsigned i = 0, e = attrs.size(); i < e; ++i) - if (attrs[i].attrs & attr) - return true; - return false; -} +//===----------------------------------------------------------------------===// +// ParamAttr Function Definitions +//===----------------------------------------------------------------------===// -std::string -ParamAttrsList::getParamAttrsText(ParameterAttributes Attrs) { +std::string ParamAttr::getAsString(ParameterAttributes Attrs) { std::string Result; if (Attrs & ParamAttr::ZExt) Result += "zeroext "; @@ -77,155 +55,240 @@ ParamAttrsList::getParamAttrsText(ParameterAttributes Attrs) { return Result; } -void ParamAttrsList::Profile(FoldingSetNodeID &ID, - const ParamAttrsVector &Attrs) { - for (unsigned i = 0; i < Attrs.size(); ++i) - ID.AddInteger(uint64_t(Attrs[i].attrs) << 16 | unsigned(Attrs[i].index)); +ParameterAttributes ParamAttr::typeIncompatible(const Type *Ty) { + ParameterAttributes Incompatible = None; + + if (!Ty->isInteger()) + // Attributes that only apply to integers. + Incompatible |= SExt | ZExt; + + if (!isa<PointerType>(Ty)) + // Attributes that only apply to pointers. + Incompatible |= ByVal | Nest | NoAlias | StructRet; + + return Incompatible; } -const ParamAttrsList * -ParamAttrsList::get(const ParamAttrsVector &attrVec) { - // If there are no attributes then return a null ParamAttrsList pointer. - if (attrVec.empty()) - return 0; +//===----------------------------------------------------------------------===// +// ParamAttributeListImpl Definition +//===----------------------------------------------------------------------===// + +namespace llvm { +class ParamAttributeListImpl : public FoldingSetNode { + unsigned RefCount; + + // ParamAttrsList is uniqued, these should not be publicly available + void operator=(const ParamAttributeListImpl &); // Do not implement + ParamAttributeListImpl(const ParamAttributeListImpl &); // Do not implement + ~ParamAttributeListImpl(); // Private implementation +public: + SmallVector<ParamAttrsWithIndex, 4> Attrs; + + ParamAttributeListImpl(const ParamAttrsWithIndex *Attr, unsigned NumAttrs) + : Attrs(Attr, Attr+NumAttrs) { + RefCount = 0; + } + + void AddRef() { ++RefCount; } + void DropRef() { if (--RefCount == 0) delete this; } + + void Profile(FoldingSetNodeID &ID) const { + Profile(ID, &Attrs[0], Attrs.size()); + } + static void Profile(FoldingSetNodeID &ID, const ParamAttrsWithIndex *Attr, + unsigned NumAttrs) { + for (unsigned i = 0; i != NumAttrs; ++i) + ID.AddInteger(uint64_t(Attr[i].Attrs) << 32 | unsigned(Attr[i].Index)); + } +}; +} +static ManagedStatic<FoldingSet<ParamAttributeListImpl> > ParamAttrsLists; + +ParamAttributeListImpl::~ParamAttributeListImpl() { + ParamAttrsLists->RemoveNode(this); +} + + +PAListPtr PAListPtr::get(const ParamAttrsWithIndex *Attrs, unsigned NumAttrs) { + // If there are no attributes then return a null ParamAttrsList pointer. + if (NumAttrs == 0) + return PAListPtr(); + #ifndef NDEBUG - for (unsigned i = 0, e = attrVec.size(); i < e; ++i) { - assert(attrVec[i].attrs != ParamAttr::None - && "Pointless parameter attribute!"); - assert((!i || attrVec[i-1].index < attrVec[i].index) - && "Misordered ParamAttrsList!"); + for (unsigned i = 0; i != NumAttrs; ++i) { + assert(Attrs[i].Attrs != ParamAttr::None && + "Pointless parameter attribute!"); + assert((!i || Attrs[i-1].Index < Attrs[i].Index) && + "Misordered ParamAttrsList!"); } #endif - + // Otherwise, build a key to look up the existing attributes. FoldingSetNodeID ID; - ParamAttrsList::Profile(ID, attrVec); + ParamAttributeListImpl::Profile(ID, Attrs, NumAttrs); void *InsertPos; - ParamAttrsList *PAL = ParamAttrsLists->FindNodeOrInsertPos(ID, InsertPos); - + ParamAttributeListImpl *PAL = + ParamAttrsLists->FindNodeOrInsertPos(ID, InsertPos); + // If we didn't find any existing attributes of the same shape then // create a new one and insert it. if (!PAL) { - PAL = new ParamAttrsList(attrVec); + PAL = new ParamAttributeListImpl(Attrs, NumAttrs); ParamAttrsLists->InsertNode(PAL, InsertPos); } - + // Return the ParamAttrsList that we found or created. - return PAL; + return PAListPtr(PAL); } -const ParamAttrsList * -ParamAttrsList::getModified(const ParamAttrsList *PAL, - const ParamAttrsVector &modVec) { - if (modVec.empty()) - return PAL; -#ifndef NDEBUG - for (unsigned i = 0, e = modVec.size(); i < e; ++i) - assert((!i || modVec[i-1].index < modVec[i].index) - && "Misordered ParamAttrsList!"); -#endif +//===----------------------------------------------------------------------===// +// PAListPtr Method Implementations +//===----------------------------------------------------------------------===// - if (!PAL) { - // Strip any instances of ParamAttr::None from modVec before calling 'get'. - ParamAttrsVector newVec; - newVec.reserve(modVec.size()); - for (unsigned i = 0, e = modVec.size(); i < e; ++i) - if (modVec[i].attrs != ParamAttr::None) - newVec.push_back(modVec[i]); - return get(newVec); - } +PAListPtr::PAListPtr(ParamAttributeListImpl *LI) : PAList(LI) { + if (LI) LI->AddRef(); +} - const ParamAttrsVector &oldVec = PAL->attrs; - - ParamAttrsVector newVec; - unsigned oldI = 0; - unsigned modI = 0; - unsigned oldE = oldVec.size(); - unsigned modE = modVec.size(); - - while (oldI < oldE && modI < modE) { - uint16_t oldIndex = oldVec[oldI].index; - uint16_t modIndex = modVec[modI].index; - - if (oldIndex < modIndex) { - newVec.push_back(oldVec[oldI]); - ++oldI; - } else if (modIndex < oldIndex) { - if (modVec[modI].attrs != ParamAttr::None) - newVec.push_back(modVec[modI]); - ++modI; - } else { - // Same index - overwrite or delete existing attributes. - if (modVec[modI].attrs != ParamAttr::None) - newVec.push_back(modVec[modI]); - ++oldI; - ++modI; - } - } +PAListPtr::PAListPtr(const PAListPtr &P) : PAList(P.PAList) { + if (PAList) PAList->AddRef(); +} + +const PAListPtr &PAListPtr::operator=(const PAListPtr &RHS) { + if (PAList == RHS.PAList) return *this; + if (PAList) PAList->DropRef(); + PAList = RHS.PAList; + if (PAList) PAList->AddRef(); + return *this; +} + +PAListPtr::~PAListPtr() { + if (PAList) PAList->DropRef(); +} + +/// getNumSlots - Return the number of slots used in this attribute list. +/// This is the number of arguments that have an attribute set on them +/// (including the function itself). +unsigned PAListPtr::getNumSlots() const { + return PAList ? PAList->Attrs.size() : 0; +} - for (; oldI < oldE; ++oldI) - newVec.push_back(oldVec[oldI]); - for (; modI < modE; ++modI) - if (modVec[modI].attrs != ParamAttr::None) - newVec.push_back(modVec[modI]); +/// getSlot - Return the ParamAttrsWithIndex at the specified slot. This +/// holds a parameter number plus a set of attributes. +const ParamAttrsWithIndex &PAListPtr::getSlot(unsigned Slot) const { + assert(PAList && Slot < PAList->Attrs.size() && "Slot # out of range!"); + return PAList->Attrs[Slot]; +} + + +/// getParamAttrs - The parameter attributes for the specified parameter are +/// returned. Parameters for the result are denoted with Idx = 0. +ParameterAttributes PAListPtr::getParamAttrs(unsigned Idx) const { + if (PAList == 0) return ParamAttr::None; + + const SmallVector<ParamAttrsWithIndex, 4> &Attrs = PAList->Attrs; + for (unsigned i = 0, e = Attrs.size(); i != e && Attrs[i].Index <= Idx; ++i) + if (Attrs[i].Index == Idx) + return Attrs[i].Attrs; + return ParamAttr::None; +} - return get(newVec); +/// hasAttrSomewhere - Return true if the specified attribute is set for at +/// least one parameter or for the return value. +bool PAListPtr::hasAttrSomewhere(ParameterAttributes Attr) const { + if (PAList == 0) return false; + + const SmallVector<ParamAttrsWithIndex, 4> &Attrs = PAList->Attrs; + for (unsigned i = 0, e = Attrs.size(); i != e; ++i) + if (Attrs[i].Attrs & Attr) + return true; + return false; } -const ParamAttrsList * -ParamAttrsList::includeAttrs(const ParamAttrsList *PAL, - uint16_t idx, ParameterAttributes attrs) { - ParameterAttributes OldAttrs = PAL ? PAL->getParamAttrs(idx) : - ParamAttr::None; + +PAListPtr PAListPtr::addAttr(unsigned Idx, ParameterAttributes Attrs) const { + ParameterAttributes OldAttrs = getParamAttrs(Idx); #ifndef NDEBUG // FIXME it is not obvious how this should work for alignment. // For now, say we can't change a known alignment. ParameterAttributes OldAlign = OldAttrs & ParamAttr::Alignment; - ParameterAttributes NewAlign = attrs & ParamAttr::Alignment; + ParameterAttributes NewAlign = Attrs & ParamAttr::Alignment; assert((!OldAlign || !NewAlign || OldAlign == NewAlign) && "Attempt to change alignment!"); #endif - - ParameterAttributes NewAttrs = OldAttrs | attrs; + + ParameterAttributes NewAttrs = OldAttrs | Attrs; if (NewAttrs == OldAttrs) - return PAL; - - ParamAttrsVector modVec(1); - modVec[0] = ParamAttrsWithIndex::get(idx, NewAttrs); - return getModified(PAL, modVec); + return *this; + + SmallVector<ParamAttrsWithIndex, 8> NewAttrList; + if (PAList == 0) + NewAttrList.push_back(ParamAttrsWithIndex::get(Idx, Attrs)); + else { + const SmallVector<ParamAttrsWithIndex, 4> &OldAttrList = PAList->Attrs; + unsigned i = 0, e = OldAttrList.size(); + // Copy attributes for arguments before this one. + for (; i != e && OldAttrList[i].Index < Idx; ++i) + NewAttrList.push_back(OldAttrList[i]); + + // If there are attributes already at this index, merge them in. + if (i != e && OldAttrList[i].Index == Idx) { + Attrs |= OldAttrList[i].Attrs; + ++i; + } + + NewAttrList.push_back(ParamAttrsWithIndex::get(Idx, Attrs)); + + // Copy attributes for arguments after this one. + NewAttrList.insert(NewAttrList.end(), + OldAttrList.begin()+i, OldAttrList.end()); + } + + return get(&NewAttrList[0], NewAttrList.size()); } -const ParamAttrsList * -ParamAttrsList::excludeAttrs(const ParamAttrsList *PAL, - uint16_t idx, ParameterAttributes attrs) { +PAListPtr PAListPtr::removeAttr(unsigned Idx, ParameterAttributes Attrs) const { #ifndef NDEBUG // FIXME it is not obvious how this should work for alignment. // For now, say we can't pass in alignment, which no current use does. - assert(!(attrs & ParamAttr::Alignment) && "Attempt to exclude alignment!"); + assert(!(Attrs & ParamAttr::Alignment) && "Attempt to exclude alignment!"); #endif - ParameterAttributes OldAttrs = PAL ? PAL->getParamAttrs(idx) : - ParamAttr::None; - ParameterAttributes NewAttrs = OldAttrs & ~attrs; + if (PAList == 0) return PAListPtr(); + + ParameterAttributes OldAttrs = getParamAttrs(Idx); + ParameterAttributes NewAttrs = OldAttrs & ~Attrs; if (NewAttrs == OldAttrs) - return PAL; - - ParamAttrsVector modVec(1); - modVec[0] = ParamAttrsWithIndex::get(idx, NewAttrs); - return getModified(PAL, modVec); + return *this; + + SmallVector<ParamAttrsWithIndex, 8> NewAttrList; + const SmallVector<ParamAttrsWithIndex, 4> &OldAttrList = PAList->Attrs; + unsigned i = 0, e = OldAttrList.size(); + + // Copy attributes for arguments before this one. + for (; i != e && OldAttrList[i].Index < Idx; ++i) + NewAttrList.push_back(OldAttrList[i]); + + // If there are attributes already at this index, merge them in. + assert(OldAttrList[i].Index == Idx && "Attribute isn't set?"); + Attrs = OldAttrList[i].Attrs & ~Attrs; + ++i; + if (Attrs) // If any attributes left for this parameter, add them. + NewAttrList.push_back(ParamAttrsWithIndex::get(Idx, Attrs)); + + // Copy attributes for arguments after this one. + NewAttrList.insert(NewAttrList.end(), + OldAttrList.begin()+i, OldAttrList.end()); + + return get(&NewAttrList[0], NewAttrList.size()); } -ParameterAttributes ParamAttr::typeIncompatible (const Type *Ty) { - ParameterAttributes Incompatible = None; - - if (!Ty->isInteger()) - // Attributes that only apply to integers. - Incompatible |= SExt | ZExt; - - if (!isa<PointerType>(Ty)) - // Attributes that only apply to pointers. - Incompatible |= ByVal | Nest | NoAlias | StructRet; - - return Incompatible; +void PAListPtr::dump() const { + cerr << "PAL[ "; + for (unsigned i = 0; i < getNumSlots(); ++i) { + const ParamAttrsWithIndex &PAWI = getSlot(i); + cerr << "{" << PAWI.Index << "," << PAWI.Attrs << "} "; + } + + cerr << "]\n"; } diff --git a/lib/VMCore/Verifier.cpp b/lib/VMCore/Verifier.cpp index 01a4a94..6126253 100644 --- a/lib/VMCore/Verifier.cpp +++ b/lib/VMCore/Verifier.cpp @@ -40,18 +40,17 @@ //===----------------------------------------------------------------------===// #include "llvm/Analysis/Verifier.h" -#include "llvm/Assembly/Writer.h" #include "llvm/CallingConv.h" #include "llvm/Constants.h" -#include "llvm/Pass.h" -#include "llvm/Module.h" -#include "llvm/ModuleProvider.h" -#include "llvm/ParamAttrsList.h" #include "llvm/DerivedTypes.h" #include "llvm/InlineAsm.h" #include "llvm/IntrinsicInst.h" +#include "llvm/Module.h" +#include "llvm/ModuleProvider.h" +#include "llvm/Pass.h" #include "llvm/PassManager.h" #include "llvm/Analysis/Dominators.h" +#include "llvm/Assembly/Writer.h" #include "llvm/CodeGen/ValueTypes.h" #include "llvm/Support/CallSite.h" #include "llvm/Support/CFG.h" @@ -264,7 +263,7 @@ namespace { // Anonymous namespace for class unsigned Count, ...); void VerifyAttrs(ParameterAttributes Attrs, const Type *Ty, bool isReturnValue, const Value *V); - void VerifyFunctionAttrs(const FunctionType *FT, const ParamAttrsList *Attrs, + void VerifyFunctionAttrs(const FunctionType *FT, const PAListPtr &Attrs, const Value *V); void WriteValue(const Value *V) { @@ -394,11 +393,11 @@ void Verifier::VerifyAttrs(ParameterAttributes Attrs, const Type *Ty, if (isReturnValue) { ParameterAttributes RetI = Attrs & ParamAttr::ParameterOnly; - Assert1(!RetI, "Attribute " + ParamAttrsList::getParamAttrsText(RetI) + + Assert1(!RetI, "Attribute " + ParamAttr::getAsString(RetI) + "does not apply to return values!", V); } else { ParameterAttributes ParmI = Attrs & ParamAttr::ReturnOnly; - Assert1(!ParmI, "Attribute " + ParamAttrsList::getParamAttrsText(ParmI) + + Assert1(!ParmI, "Attribute " + ParamAttr::getAsString(ParmI) + "only applies to return values!", V); } @@ -406,37 +405,44 @@ void Verifier::VerifyAttrs(ParameterAttributes Attrs, const Type *Ty, i < array_lengthof(ParamAttr::MutuallyIncompatible); ++i) { ParameterAttributes MutI = Attrs & ParamAttr::MutuallyIncompatible[i]; Assert1(!(MutI & (MutI - 1)), "Attributes " + - ParamAttrsList::getParamAttrsText(MutI) + "are incompatible!", V); + ParamAttr::getAsString(MutI) + "are incompatible!", V); } ParameterAttributes TypeI = Attrs & ParamAttr::typeIncompatible(Ty); Assert1(!TypeI, "Wrong type for attribute " + - ParamAttrsList::getParamAttrsText(TypeI), V); + ParamAttr::getAsString(TypeI), V); } // VerifyFunctionAttrs - Check parameter attributes against a function type. // The value V is printed in error messages. void Verifier::VerifyFunctionAttrs(const FunctionType *FT, - const ParamAttrsList *Attrs, + const PAListPtr &Attrs, const Value *V) { - if (!Attrs) + if (Attrs.isEmpty()) return; bool SawNest = false; - for (unsigned Idx = 0; Idx <= FT->getNumParams(); ++Idx) { - ParameterAttributes Attr = Attrs->getParamAttrs(Idx); + for (unsigned i = 0, e = Attrs.getNumSlots(); i != e; ++i) { + const ParamAttrsWithIndex &Attr = Attrs.getSlot(i); - VerifyAttrs(Attr, FT->getParamType(Idx-1), !Idx, V); + const Type *Ty; + if (Attr.Index == 0) + Ty = FT->getReturnType(); + else if (Attr.Index-1 < FT->getNumParams()) + Ty = FT->getParamType(Attr.Index-1); + else + break; // VarArgs attributes, don't verify. + + VerifyAttrs(Attr.Attrs, Ty, Attr.Index == 0, V); - if (Attr & ParamAttr::Nest) { + if (Attr.Attrs & ParamAttr::Nest) { Assert1(!SawNest, "More than one parameter has attribute nest!", V); SawNest = true; } - if (Attr & ParamAttr::StructRet) { - Assert1(Idx == 1, "Attribute sret not on first parameter!", V); - } + if (Attr.Attrs & ParamAttr::StructRet) + Assert1(Attr.Index == 1, "Attribute sret not on first parameter!", V); } } @@ -458,11 +464,10 @@ void Verifier::visitFunction(Function &F) { Assert1(!F.hasStructRetAttr() || F.getReturnType() == Type::VoidTy, "Invalid struct return type!", &F); - const ParamAttrsList *Attrs = F.getParamAttrs(); + const PAListPtr &Attrs = F.getParamAttrs(); - Assert1(!Attrs || - (Attrs->size() && - Attrs->getParamIndex(Attrs->size()-1) <= FT->getNumParams()), + Assert1(Attrs.isEmpty() || + Attrs.getSlot(Attrs.getNumSlots()-1).Index <= FT->getNumParams(), "Attributes after last parameter!", &F); // Check function attributes. @@ -712,15 +717,19 @@ void Verifier::visitUIToFPInst(UIToFPInst &I) { const Type *SrcTy = I.getOperand(0)->getType(); const Type *DestTy = I.getType(); - bool SrcVec = SrcTy->getTypeID() == Type::VectorTyID; - bool DstVec = DestTy->getTypeID() == Type::VectorTyID; + bool SrcVec = isa<VectorType>(SrcTy); + bool DstVec = isa<VectorType>(DestTy); - Assert1(SrcVec == DstVec,"UIToFP source and dest must both be vector or scalar", &I); - Assert1(SrcTy->isIntOrIntVector(),"UIToFP source must be integer or integer vector", &I); - Assert1(DestTy->isFPOrFPVector(),"UIToFP result must be FP or FP vector", &I); + Assert1(SrcVec == DstVec, + "UIToFP source and dest must both be vector or scalar", &I); + Assert1(SrcTy->isIntOrIntVector(), + "UIToFP source must be integer or integer vector", &I); + Assert1(DestTy->isFPOrFPVector(), + "UIToFP result must be FP or FP vector", &I); if (SrcVec && DstVec) - Assert1(cast<VectorType>(SrcTy)->getNumElements() == cast<VectorType>(DestTy)->getNumElements(), + Assert1(cast<VectorType>(SrcTy)->getNumElements() == + cast<VectorType>(DestTy)->getNumElements(), "UIToFP source and dest vector length mismatch", &I); visitInstruction(I); @@ -734,12 +743,16 @@ void Verifier::visitSIToFPInst(SIToFPInst &I) { bool SrcVec = SrcTy->getTypeID() == Type::VectorTyID; bool DstVec = DestTy->getTypeID() == Type::VectorTyID; - Assert1(SrcVec == DstVec,"SIToFP source and dest must both be vector or scalar", &I); - Assert1(SrcTy->isIntOrIntVector(),"SIToFP source must be integer or integer vector", &I); - Assert1(DestTy->isFPOrFPVector(),"SIToFP result must be FP or FP vector", &I); + Assert1(SrcVec == DstVec, + "SIToFP source and dest must both be vector or scalar", &I); + Assert1(SrcTy->isIntOrIntVector(), + "SIToFP source must be integer or integer vector", &I); + Assert1(DestTy->isFPOrFPVector(), + "SIToFP result must be FP or FP vector", &I); if (SrcVec && DstVec) - Assert1(cast<VectorType>(SrcTy)->getNumElements() == cast<VectorType>(DestTy)->getNumElements(), + Assert1(cast<VectorType>(SrcTy)->getNumElements() == + cast<VectorType>(DestTy)->getNumElements(), "SIToFP source and dest vector length mismatch", &I); visitInstruction(I); @@ -750,15 +763,18 @@ void Verifier::visitFPToUIInst(FPToUIInst &I) { const Type *SrcTy = I.getOperand(0)->getType(); const Type *DestTy = I.getType(); - bool SrcVec = SrcTy->getTypeID() == Type::VectorTyID; - bool DstVec = DestTy->getTypeID() == Type::VectorTyID; + bool SrcVec = isa<VectorType>(SrcTy); + bool DstVec = isa<VectorType>(DestTy); - Assert1(SrcVec == DstVec,"FPToUI source and dest must both be vector or scalar", &I); - Assert1(SrcTy->isFPOrFPVector(),"FPToUI source must be FP or FP vector", &I); - Assert1(DestTy->isIntOrIntVector(),"FPToUI result must be integer or integer vector", &I); + Assert1(SrcVec == DstVec, + "FPToUI source and dest must both be vector or scalar", &I); + Assert1(SrcTy->isFPOrFPVector(), "FPToUI source must be FP or FP vector", &I); + Assert1(DestTy->isIntOrIntVector(), + "FPToUI result must be integer or integer vector", &I); if (SrcVec && DstVec) - Assert1(cast<VectorType>(SrcTy)->getNumElements() == cast<VectorType>(DestTy)->getNumElements(), + Assert1(cast<VectorType>(SrcTy)->getNumElements() == + cast<VectorType>(DestTy)->getNumElements(), "FPToUI source and dest vector length mismatch", &I); visitInstruction(I); @@ -769,15 +785,19 @@ void Verifier::visitFPToSIInst(FPToSIInst &I) { const Type *SrcTy = I.getOperand(0)->getType(); const Type *DestTy = I.getType(); - bool SrcVec = SrcTy->getTypeID() == Type::VectorTyID; - bool DstVec = DestTy->getTypeID() == Type::VectorTyID; + bool SrcVec = isa<VectorType>(SrcTy); + bool DstVec = isa<VectorType>(DestTy); - Assert1(SrcVec == DstVec,"FPToSI source and dest must both be vector or scalar", &I); - Assert1(SrcTy->isFPOrFPVector(),"FPToSI source must be FP or FP vector", &I); - Assert1(DestTy->isIntOrIntVector(),"FPToSI result must be integer or integer vector", &I); + Assert1(SrcVec == DstVec, + "FPToSI source and dest must both be vector or scalar", &I); + Assert1(SrcTy->isFPOrFPVector(), + "FPToSI source must be FP or FP vector", &I); + Assert1(DestTy->isIntOrIntVector(), + "FPToSI result must be integer or integer vector", &I); if (SrcVec && DstVec) - Assert1(cast<VectorType>(SrcTy)->getNumElements() == cast<VectorType>(DestTy)->getNumElements(), + Assert1(cast<VectorType>(SrcTy)->getNumElements() == + cast<VectorType>(DestTy)->getNumElements(), "FPToSI source and dest vector length mismatch", &I); visitInstruction(I); @@ -871,25 +891,24 @@ void Verifier::VerifyCallSite(CallSite CS) { "Call parameter type does not match function signature!", CS.getArgument(i), FTy->getParamType(i), I); - const ParamAttrsList *Attrs = CS.getParamAttrs(); + const PAListPtr &Attrs = CS.getParamAttrs(); - Assert1(!Attrs || - (Attrs->size() && - Attrs->getParamIndex(Attrs->size()-1) <= CS.arg_size()), - "Attributes after last argument!", I); + Assert1(Attrs.isEmpty() || + Attrs.getSlot(Attrs.getNumSlots()-1).Index <= CS.arg_size(), + "Attributes after last parameter!", I); // Verify call attributes. VerifyFunctionAttrs(FTy, Attrs, I); - if (Attrs && FTy->isVarArg()) + if (FTy->isVarArg()) // Check attributes on the varargs part. for (unsigned Idx = 1 + FTy->getNumParams(); Idx <= CS.arg_size(); ++Idx) { - ParameterAttributes Attr = Attrs->getParamAttrs(Idx); + ParameterAttributes Attr = Attrs.getParamAttrs(Idx); VerifyAttrs(Attr, CS.getArgument(Idx-1)->getType(), false, I); ParameterAttributes VArgI = Attr & ParamAttr::VarArgsIncompatible; - Assert1(!VArgI, "Attribute " + ParamAttrsList::getParamAttrsText(VArgI) + + Assert1(!VArgI, "Attribute " + ParamAttr::getAsString(VArgI) + "cannot be used for vararg call arguments!", I); } |