mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-23 11:13:28 +01:00
Now Attributes are divided in three groups
- return attributes - inreg, zext and sext - parameter attributes - function attributes - nounwind, readonly, readnone, noreturn Return attributes use 0 as the index. Function attributes use ~0U as the index. This patch requires corresponding changes in llvm-gcc and clang. llvm-svn: 56704
This commit is contained in:
parent
7273078850
commit
e4e6ea0728
@ -146,10 +146,23 @@ public:
|
||||
//===--------------------------------------------------------------------===//
|
||||
// Attribute List Accessors
|
||||
//===--------------------------------------------------------------------===//
|
||||
|
||||
/// getAttributes - The attributes for the specified index are
|
||||
/// returned. Attributes for the result are denoted with Idx = 0.
|
||||
Attributes getAttributes(unsigned Idx) const;
|
||||
/// getParamAttributes - The attributes for the specified index are
|
||||
/// returned.
|
||||
Attributes getParamAttributes(unsigned Idx) const {
|
||||
assert (Idx && Idx != ~0U && "Invalid parameter index!");
|
||||
return getAttributes(Idx);
|
||||
}
|
||||
|
||||
/// getRetAttributes - The attributes for the ret value are
|
||||
/// returned.
|
||||
Attributes getRetAttributes() const {
|
||||
return getAttributes(0);
|
||||
}
|
||||
|
||||
/// getFnAttributes - The function attributes are returned.
|
||||
Attributes getFnAttributes() const {
|
||||
return getAttributes(~0);
|
||||
}
|
||||
|
||||
/// paramHasAttr - Return true if the specified parameter index has the
|
||||
/// specified attribute set.
|
||||
@ -204,6 +217,11 @@ public:
|
||||
|
||||
private:
|
||||
explicit AttrListPtr(AttributeListImpl *L);
|
||||
|
||||
/// getAttributes - The attributes for the specified index are
|
||||
/// returned. Attributes for the result are denoted with Idx = 0.
|
||||
Attributes getAttributes(unsigned Idx) const;
|
||||
|
||||
};
|
||||
|
||||
} // End llvm namespace
|
||||
|
@ -187,38 +187,38 @@ public:
|
||||
|
||||
/// @brief Determine if the function does not access memory.
|
||||
bool doesNotAccessMemory() const {
|
||||
return paramHasAttr(0, Attribute::ReadNone);
|
||||
return paramHasAttr(~0, Attribute::ReadNone);
|
||||
}
|
||||
void setDoesNotAccessMemory(bool DoesNotAccessMemory = true) {
|
||||
if (DoesNotAccessMemory) addAttribute(0, Attribute::ReadNone);
|
||||
else removeAttribute(0, Attribute::ReadNone);
|
||||
if (DoesNotAccessMemory) addAttribute(~0, Attribute::ReadNone);
|
||||
else removeAttribute(~0, Attribute::ReadNone);
|
||||
}
|
||||
|
||||
/// @brief Determine if the function does not access or only reads memory.
|
||||
bool onlyReadsMemory() const {
|
||||
return doesNotAccessMemory() || paramHasAttr(0, Attribute::ReadOnly);
|
||||
return doesNotAccessMemory() || paramHasAttr(~0, Attribute::ReadOnly);
|
||||
}
|
||||
void setOnlyReadsMemory(bool OnlyReadsMemory = true) {
|
||||
if (OnlyReadsMemory) addAttribute(0, Attribute::ReadOnly);
|
||||
else removeAttribute(0, Attribute::ReadOnly | Attribute::ReadNone);
|
||||
if (OnlyReadsMemory) addAttribute(~0, Attribute::ReadOnly);
|
||||
else removeAttribute(~0, Attribute::ReadOnly | Attribute::ReadNone);
|
||||
}
|
||||
|
||||
/// @brief Determine if the function cannot return.
|
||||
bool doesNotReturn() const {
|
||||
return paramHasAttr(0, Attribute::NoReturn);
|
||||
return paramHasAttr(~0, Attribute::NoReturn);
|
||||
}
|
||||
void setDoesNotReturn(bool DoesNotReturn = true) {
|
||||
if (DoesNotReturn) addAttribute(0, Attribute::NoReturn);
|
||||
else removeAttribute(0, Attribute::NoReturn);
|
||||
if (DoesNotReturn) addAttribute(~0, Attribute::NoReturn);
|
||||
else removeAttribute(~0, Attribute::NoReturn);
|
||||
}
|
||||
|
||||
/// @brief Determine if the function cannot unwind.
|
||||
bool doesNotThrow() const {
|
||||
return paramHasAttr(0, Attribute::NoUnwind);
|
||||
return paramHasAttr(~0, Attribute::NoUnwind);
|
||||
}
|
||||
void setDoesNotThrow(bool DoesNotThrow = true) {
|
||||
if (DoesNotThrow) addAttribute(0, Attribute::NoUnwind);
|
||||
else removeAttribute(0, Attribute::NoUnwind);
|
||||
if (DoesNotThrow) addAttribute(~0, Attribute::NoUnwind);
|
||||
else removeAttribute(~0, Attribute::NoUnwind);
|
||||
}
|
||||
|
||||
/// @brief Determine if the function returns a structure through first
|
||||
|
@ -1097,38 +1097,38 @@ public:
|
||||
|
||||
/// @brief Determine if the call does not access memory.
|
||||
bool doesNotAccessMemory() const {
|
||||
return paramHasAttr(0, Attribute::ReadNone);
|
||||
return paramHasAttr(~0, Attribute::ReadNone);
|
||||
}
|
||||
void setDoesNotAccessMemory(bool NotAccessMemory = true) {
|
||||
if (NotAccessMemory) addAttribute(0, Attribute::ReadNone);
|
||||
else removeAttribute(0, Attribute::ReadNone);
|
||||
if (NotAccessMemory) addAttribute(~0, Attribute::ReadNone);
|
||||
else removeAttribute(~0, Attribute::ReadNone);
|
||||
}
|
||||
|
||||
/// @brief Determine if the call does not access or only reads memory.
|
||||
bool onlyReadsMemory() const {
|
||||
return doesNotAccessMemory() || paramHasAttr(0, Attribute::ReadOnly);
|
||||
return doesNotAccessMemory() || paramHasAttr(~0, Attribute::ReadOnly);
|
||||
}
|
||||
void setOnlyReadsMemory(bool OnlyReadsMemory = true) {
|
||||
if (OnlyReadsMemory) addAttribute(0, Attribute::ReadOnly);
|
||||
else removeAttribute(0, Attribute::ReadOnly | Attribute::ReadNone);
|
||||
if (OnlyReadsMemory) addAttribute(~0, Attribute::ReadOnly);
|
||||
else removeAttribute(~0, Attribute::ReadOnly | Attribute::ReadNone);
|
||||
}
|
||||
|
||||
/// @brief Determine if the call cannot return.
|
||||
bool doesNotReturn() const {
|
||||
return paramHasAttr(0, Attribute::NoReturn);
|
||||
return paramHasAttr(~0, Attribute::NoReturn);
|
||||
}
|
||||
void setDoesNotReturn(bool DoesNotReturn = true) {
|
||||
if (DoesNotReturn) addAttribute(0, Attribute::NoReturn);
|
||||
else removeAttribute(0, Attribute::NoReturn);
|
||||
if (DoesNotReturn) addAttribute(~0, Attribute::NoReturn);
|
||||
else removeAttribute(~0, Attribute::NoReturn);
|
||||
}
|
||||
|
||||
/// @brief Determine if the call cannot unwind.
|
||||
bool doesNotThrow() const {
|
||||
return paramHasAttr(0, Attribute::NoUnwind);
|
||||
return paramHasAttr(~0, Attribute::NoUnwind);
|
||||
}
|
||||
void setDoesNotThrow(bool DoesNotThrow = true) {
|
||||
if (DoesNotThrow) addAttribute(0, Attribute::NoUnwind);
|
||||
else removeAttribute(0, Attribute::NoUnwind);
|
||||
if (DoesNotThrow) addAttribute(~0, Attribute::NoUnwind);
|
||||
else removeAttribute(~0, Attribute::NoUnwind);
|
||||
}
|
||||
|
||||
/// @brief Determine if the call returns a structure through first
|
||||
@ -2459,35 +2459,35 @@ public:
|
||||
return paramHasAttr(0, Attribute::ReadNone);
|
||||
}
|
||||
void setDoesNotAccessMemory(bool NotAccessMemory = true) {
|
||||
if (NotAccessMemory) addAttribute(0, Attribute::ReadNone);
|
||||
else removeAttribute(0, Attribute::ReadNone);
|
||||
if (NotAccessMemory) addAttribute(~0, Attribute::ReadNone);
|
||||
else removeAttribute(~0, Attribute::ReadNone);
|
||||
}
|
||||
|
||||
/// @brief Determine if the call does not access or only reads memory.
|
||||
bool onlyReadsMemory() const {
|
||||
return doesNotAccessMemory() || paramHasAttr(0, Attribute::ReadOnly);
|
||||
return doesNotAccessMemory() || paramHasAttr(~0, Attribute::ReadOnly);
|
||||
}
|
||||
void setOnlyReadsMemory(bool OnlyReadsMemory = true) {
|
||||
if (OnlyReadsMemory) addAttribute(0, Attribute::ReadOnly);
|
||||
else removeAttribute(0, Attribute::ReadOnly | Attribute::ReadNone);
|
||||
if (OnlyReadsMemory) addAttribute(~0, Attribute::ReadOnly);
|
||||
else removeAttribute(~0, Attribute::ReadOnly | Attribute::ReadNone);
|
||||
}
|
||||
|
||||
/// @brief Determine if the call cannot return.
|
||||
bool doesNotReturn() const {
|
||||
return paramHasAttr(0, Attribute::NoReturn);
|
||||
return paramHasAttr(~0, Attribute::NoReturn);
|
||||
}
|
||||
void setDoesNotReturn(bool DoesNotReturn = true) {
|
||||
if (DoesNotReturn) addAttribute(0, Attribute::NoReturn);
|
||||
else removeAttribute(0, Attribute::NoReturn);
|
||||
if (DoesNotReturn) addAttribute(~0, Attribute::NoReturn);
|
||||
else removeAttribute(~0, Attribute::NoReturn);
|
||||
}
|
||||
|
||||
/// @brief Determine if the call cannot unwind.
|
||||
bool doesNotThrow() const {
|
||||
return paramHasAttr(0, Attribute::NoUnwind);
|
||||
return paramHasAttr(~0, Attribute::NoUnwind);
|
||||
}
|
||||
void setDoesNotThrow(bool DoesNotThrow = true) {
|
||||
if (DoesNotThrow) addAttribute(0, Attribute::NoUnwind);
|
||||
else removeAttribute(0, Attribute::NoUnwind);
|
||||
if (DoesNotThrow) addAttribute(~0, Attribute::NoUnwind);
|
||||
else removeAttribute(~0, Attribute::NoUnwind);
|
||||
}
|
||||
|
||||
/// @brief Determine if the call returns a structure through first
|
||||
|
@ -2346,8 +2346,25 @@ FunctionHeaderH : OptCallingConv ResultTypes GlobalName '(' ArgList ')'
|
||||
|
||||
std::vector<const Type*> ParamTypeList;
|
||||
SmallVector<AttributeWithIndex, 8> Attrs;
|
||||
if ($7 != Attribute::None)
|
||||
Attrs.push_back(AttributeWithIndex::get(0, $7));
|
||||
//FIXME : In 3.0, stop accepting zext, sext and inreg as optional function
|
||||
//attributes.
|
||||
Attributes RetAttrs = 0;
|
||||
if ($7 != Attribute::None) {
|
||||
if ($7 & Attribute::ZExt) {
|
||||
RetAttrs = RetAttrs | Attribute::ZExt;
|
||||
$7 = $7 ^ Attribute::ZExt;
|
||||
}
|
||||
if ($7 & Attribute::SExt) {
|
||||
RetAttrs = RetAttrs | Attribute::SExt;
|
||||
$7 = $7 ^ Attribute::SExt;
|
||||
}
|
||||
if ($7 & Attribute::InReg) {
|
||||
RetAttrs = RetAttrs | Attribute::InReg;
|
||||
$7 = $7 ^ Attribute::InReg;
|
||||
}
|
||||
if (RetAttrs != Attribute::None)
|
||||
Attrs.push_back(AttributeWithIndex::get(0, RetAttrs));
|
||||
}
|
||||
if ($5) { // If there are arguments...
|
||||
unsigned index = 1;
|
||||
for (ArgListType::iterator I = $5->begin(); I != $5->end(); ++I, ++index) {
|
||||
@ -2359,6 +2376,8 @@ FunctionHeaderH : OptCallingConv ResultTypes GlobalName '(' ArgList ')'
|
||||
Attrs.push_back(AttributeWithIndex::get(index, I->Attrs));
|
||||
}
|
||||
}
|
||||
if ($7 != Attribute::None)
|
||||
Attrs.push_back(AttributeWithIndex::get(~0, $7));
|
||||
|
||||
bool isVarArg = ParamTypeList.size() && ParamTypeList.back() == Type::VoidTy;
|
||||
if (isVarArg) ParamTypeList.pop_back();
|
||||
@ -2860,9 +2879,26 @@ BBTerminatorInst :
|
||||
CHECK_FOR_ERROR
|
||||
|
||||
SmallVector<AttributeWithIndex, 8> Attrs;
|
||||
if ($8 != Attribute::None)
|
||||
Attrs.push_back(AttributeWithIndex::get(0, $8));
|
||||
|
||||
//FIXME : In 3.0, stop accepting zext, sext and inreg as optional function
|
||||
//attributes.
|
||||
Attributes RetAttrs = 0;
|
||||
if ($8 != Attribute::None) {
|
||||
if ($8 & Attribute::ZExt) {
|
||||
RetAttrs = RetAttrs | Attribute::ZExt;
|
||||
$8 = $8 ^ Attribute::ZExt;
|
||||
}
|
||||
if ($8 & Attribute::SExt) {
|
||||
RetAttrs = RetAttrs | Attribute::SExt;
|
||||
$8 = $8 ^ Attribute::SExt;
|
||||
}
|
||||
if ($8 & Attribute::InReg) {
|
||||
RetAttrs = RetAttrs | Attribute::InReg;
|
||||
$8 = $8 ^ Attribute::InReg;
|
||||
}
|
||||
if (RetAttrs != Attribute::None)
|
||||
Attrs.push_back(AttributeWithIndex::get(0, RetAttrs));
|
||||
}
|
||||
|
||||
// Check the arguments
|
||||
ValueList Args;
|
||||
if ($6->empty()) { // Has no arguments?
|
||||
@ -2897,7 +2933,8 @@ BBTerminatorInst :
|
||||
} else if (I != E || ArgI != ArgE)
|
||||
GEN_ERROR("Invalid number of parameters detected");
|
||||
}
|
||||
|
||||
if ($8 != Attribute::None)
|
||||
Attrs.push_back(AttributeWithIndex::get(~0, $8));
|
||||
AttrListPtr PAL;
|
||||
if (!Attrs.empty())
|
||||
PAL = AttrListPtr::get(Attrs.begin(), Attrs.end());
|
||||
@ -3258,8 +3295,27 @@ InstVal : ArithmeticOps Types ValueRef ',' ValueRef {
|
||||
|
||||
// Set up the Attributes for the function
|
||||
SmallVector<AttributeWithIndex, 8> Attrs;
|
||||
if ($8 != Attribute::None)
|
||||
Attrs.push_back(AttributeWithIndex::get(0, $8));
|
||||
//FIXME : In 3.0, stop accepting zext, sext and inreg as optional function
|
||||
//attributes.
|
||||
Attributes RetAttrs = 0;
|
||||
Attributes TmpAttr = $8;
|
||||
if ($8 != Attribute::None) {
|
||||
if ($8 & Attribute::ZExt) {
|
||||
RetAttrs = RetAttrs | Attribute::ZExt;
|
||||
$8 = $8 ^ Attribute::ZExt;
|
||||
}
|
||||
if ($8 & Attribute::SExt) {
|
||||
RetAttrs = RetAttrs | Attribute::SExt;
|
||||
$8 = $8 ^ Attribute::SExt;
|
||||
}
|
||||
if ($8 & Attribute::InReg) {
|
||||
RetAttrs = RetAttrs | Attribute::InReg;
|
||||
$8 = $8 ^ Attribute::InReg;
|
||||
}
|
||||
if (RetAttrs != Attribute::None)
|
||||
Attrs.push_back(AttributeWithIndex::get(0, RetAttrs));
|
||||
}
|
||||
|
||||
// Check the arguments
|
||||
ValueList Args;
|
||||
if ($6->empty()) { // Has no arguments?
|
||||
@ -3293,6 +3349,8 @@ InstVal : ArithmeticOps Types ValueRef ',' ValueRef {
|
||||
} else if (I != E || ArgI != ArgE)
|
||||
GEN_ERROR("Invalid number of parameters detected");
|
||||
}
|
||||
if ($8 != Attribute::None)
|
||||
Attrs.push_back(AttributeWithIndex::get(~0, $8));
|
||||
|
||||
// Finish off the Attributes and check them
|
||||
AttrListPtr PAL;
|
||||
|
@ -2346,8 +2346,25 @@ FunctionHeaderH : OptCallingConv ResultTypes GlobalName '(' ArgList ')'
|
||||
|
||||
std::vector<const Type*> ParamTypeList;
|
||||
SmallVector<AttributeWithIndex, 8> Attrs;
|
||||
if ($7 != Attribute::None)
|
||||
Attrs.push_back(AttributeWithIndex::get(0, $7));
|
||||
//FIXME : In 3.0, stop accepting zext, sext and inreg as optional function
|
||||
//attributes.
|
||||
Attributes RetAttrs = 0;
|
||||
if ($7 != Attribute::None) {
|
||||
if ($7 & Attribute::ZExt) {
|
||||
RetAttrs = RetAttrs | Attribute::ZExt;
|
||||
$7 = $7 ^ Attribute::ZExt;
|
||||
}
|
||||
if ($7 & Attribute::SExt) {
|
||||
RetAttrs = RetAttrs | Attribute::SExt;
|
||||
$7 = $7 ^ Attribute::SExt;
|
||||
}
|
||||
if ($7 & Attribute::InReg) {
|
||||
RetAttrs = RetAttrs | Attribute::InReg;
|
||||
$7 = $7 ^ Attribute::InReg;
|
||||
}
|
||||
if (RetAttrs != Attribute::None)
|
||||
Attrs.push_back(AttributeWithIndex::get(0, RetAttrs));
|
||||
}
|
||||
if ($5) { // If there are arguments...
|
||||
unsigned index = 1;
|
||||
for (ArgListType::iterator I = $5->begin(); I != $5->end(); ++I, ++index) {
|
||||
@ -2359,6 +2376,8 @@ FunctionHeaderH : OptCallingConv ResultTypes GlobalName '(' ArgList ')'
|
||||
Attrs.push_back(AttributeWithIndex::get(index, I->Attrs));
|
||||
}
|
||||
}
|
||||
if ($7 != Attribute::None)
|
||||
Attrs.push_back(AttributeWithIndex::get(~0, $7));
|
||||
|
||||
bool isVarArg = ParamTypeList.size() && ParamTypeList.back() == Type::VoidTy;
|
||||
if (isVarArg) ParamTypeList.pop_back();
|
||||
@ -2860,9 +2879,26 @@ BBTerminatorInst :
|
||||
CHECK_FOR_ERROR
|
||||
|
||||
SmallVector<AttributeWithIndex, 8> Attrs;
|
||||
if ($8 != Attribute::None)
|
||||
Attrs.push_back(AttributeWithIndex::get(0, $8));
|
||||
|
||||
//FIXME : In 3.0, stop accepting zext, sext and inreg as optional function
|
||||
//attributes.
|
||||
Attributes RetAttrs = 0;
|
||||
if ($8 != Attribute::None) {
|
||||
if ($8 & Attribute::ZExt) {
|
||||
RetAttrs = RetAttrs | Attribute::ZExt;
|
||||
$8 = $8 ^ Attribute::ZExt;
|
||||
}
|
||||
if ($8 & Attribute::SExt) {
|
||||
RetAttrs = RetAttrs | Attribute::SExt;
|
||||
$8 = $8 ^ Attribute::SExt;
|
||||
}
|
||||
if ($8 & Attribute::InReg) {
|
||||
RetAttrs = RetAttrs | Attribute::InReg;
|
||||
$8 = $8 ^ Attribute::InReg;
|
||||
}
|
||||
if (RetAttrs != Attribute::None)
|
||||
Attrs.push_back(AttributeWithIndex::get(0, RetAttrs));
|
||||
}
|
||||
|
||||
// Check the arguments
|
||||
ValueList Args;
|
||||
if ($6->empty()) { // Has no arguments?
|
||||
@ -2897,7 +2933,8 @@ BBTerminatorInst :
|
||||
} else if (I != E || ArgI != ArgE)
|
||||
GEN_ERROR("Invalid number of parameters detected");
|
||||
}
|
||||
|
||||
if ($8 != Attribute::None)
|
||||
Attrs.push_back(AttributeWithIndex::get(~0, $8));
|
||||
AttrListPtr PAL;
|
||||
if (!Attrs.empty())
|
||||
PAL = AttrListPtr::get(Attrs.begin(), Attrs.end());
|
||||
@ -3258,8 +3295,27 @@ InstVal : ArithmeticOps Types ValueRef ',' ValueRef {
|
||||
|
||||
// Set up the Attributes for the function
|
||||
SmallVector<AttributeWithIndex, 8> Attrs;
|
||||
if ($8 != Attribute::None)
|
||||
Attrs.push_back(AttributeWithIndex::get(0, $8));
|
||||
//FIXME : In 3.0, stop accepting zext, sext and inreg as optional function
|
||||
//attributes.
|
||||
Attributes RetAttrs = 0;
|
||||
Attributes TmpAttr = $8;
|
||||
if ($8 != Attribute::None) {
|
||||
if ($8 & Attribute::ZExt) {
|
||||
RetAttrs = RetAttrs | Attribute::ZExt;
|
||||
$8 = $8 ^ Attribute::ZExt;
|
||||
}
|
||||
if ($8 & Attribute::SExt) {
|
||||
RetAttrs = RetAttrs | Attribute::SExt;
|
||||
$8 = $8 ^ Attribute::SExt;
|
||||
}
|
||||
if ($8 & Attribute::InReg) {
|
||||
RetAttrs = RetAttrs | Attribute::InReg;
|
||||
$8 = $8 ^ Attribute::InReg;
|
||||
}
|
||||
if (RetAttrs != Attribute::None)
|
||||
Attrs.push_back(AttributeWithIndex::get(0, RetAttrs));
|
||||
}
|
||||
|
||||
// Check the arguments
|
||||
ValueList Args;
|
||||
if ($6->empty()) { // Has no arguments?
|
||||
@ -3293,6 +3349,8 @@ InstVal : ArithmeticOps Types ValueRef ',' ValueRef {
|
||||
} else if (I != E || ArgI != ArgE)
|
||||
GEN_ERROR("Invalid number of parameters detected");
|
||||
}
|
||||
if ($8 != Attribute::None)
|
||||
Attrs.push_back(AttributeWithIndex::get(~0, $8));
|
||||
|
||||
// Finish off the Attributes and check them
|
||||
AttrListPtr PAL;
|
||||
|
@ -32,7 +32,7 @@ void BitcodeReader::FreeState() {
|
||||
std::vector<PATypeHolder>().swap(TypeList);
|
||||
ValueList.clear();
|
||||
|
||||
std::vector<AttrListPtr>().swap(Attributes);
|
||||
std::vector<AttrListPtr>().swap(MAttributes);
|
||||
std::vector<BasicBlock*>().swap(FunctionBBs);
|
||||
std::vector<Function*>().swap(FunctionsWithBodies);
|
||||
DeferredFunctionInfo.clear();
|
||||
@ -317,7 +317,7 @@ bool BitcodeReader::ParseAttributeBlock() {
|
||||
if (Stream.EnterSubBlock(bitc::PARAMATTR_BLOCK_ID))
|
||||
return Error("Malformed block record");
|
||||
|
||||
if (!Attributes.empty())
|
||||
if (!MAttributes.empty())
|
||||
return Error("Multiple PARAMATTR blocks found!");
|
||||
|
||||
SmallVector<uint64_t, 64> Record;
|
||||
@ -355,12 +355,53 @@ bool BitcodeReader::ParseAttributeBlock() {
|
||||
if (Record.size() & 1)
|
||||
return Error("Invalid ENTRY record");
|
||||
|
||||
// FIXME : Remove this backword compatibility one day.
|
||||
// If Function attributes are using index 0 then transfer them
|
||||
// to index ~0. Index 0 is strictly used for return value
|
||||
// attributes.
|
||||
Attributes RetAttribute = Attribute::None;
|
||||
Attributes FnAttribute = Attribute::None;
|
||||
for (unsigned i = 0, e = Record.size(); i != e; i += 2) {
|
||||
if (Record[i+1] != Attribute::None)
|
||||
Attrs.push_back(AttributeWithIndex::get(Record[i], Record[i+1]));
|
||||
if (Record[i] == 0)
|
||||
RetAttribute = Record[i+1];
|
||||
else if (Record[i] == ~0U)
|
||||
FnAttribute = Record[i+1];
|
||||
}
|
||||
bool useUpdatedAttrs = false;
|
||||
if (FnAttribute == Attribute::None && RetAttribute != Attribute::None) {
|
||||
if (RetAttribute & Attribute::NoUnwind) {
|
||||
FnAttribute = FnAttribute | Attribute::NoUnwind;
|
||||
RetAttribute = RetAttribute ^ Attribute::NoUnwind;
|
||||
useUpdatedAttrs = true;
|
||||
}
|
||||
if (RetAttribute & Attribute::NoReturn) {
|
||||
FnAttribute = FnAttribute | Attribute::NoReturn;
|
||||
RetAttribute = RetAttribute ^ Attribute::NoReturn;
|
||||
useUpdatedAttrs = true;
|
||||
}
|
||||
if (RetAttribute & Attribute::ReadOnly) {
|
||||
FnAttribute = FnAttribute | Attribute::ReadOnly;
|
||||
RetAttribute = RetAttribute ^ Attribute::ReadOnly;
|
||||
useUpdatedAttrs = true;
|
||||
}
|
||||
if (RetAttribute & Attribute::ReadNone) {
|
||||
FnAttribute = FnAttribute | Attribute::ReadNone;
|
||||
RetAttribute = RetAttribute ^ Attribute::ReadNone;
|
||||
useUpdatedAttrs = true;
|
||||
}
|
||||
}
|
||||
|
||||
Attributes.push_back(AttrListPtr::get(Attrs.begin(), Attrs.end()));
|
||||
for (unsigned i = 0, e = Record.size(); i != e; i += 2) {
|
||||
if (useUpdatedAttrs && Record[i] == 0
|
||||
&& RetAttribute != Attribute::None)
|
||||
Attrs.push_back(AttributeWithIndex::get(0, RetAttribute));
|
||||
else if (Record[i+1] != Attribute::None)
|
||||
Attrs.push_back(AttributeWithIndex::get(Record[i], Record[i+1]));
|
||||
}
|
||||
if (useUpdatedAttrs && FnAttribute != Attribute::None)
|
||||
Attrs.push_back(AttributeWithIndex::get(~0, FnAttribute));
|
||||
|
||||
MAttributes.push_back(AttrListPtr::get(Attrs.begin(), Attrs.end()));
|
||||
Attrs.clear();
|
||||
break;
|
||||
}
|
||||
|
@ -136,10 +136,10 @@ class BitcodeReader : public ModuleProvider {
|
||||
std::vector<std::pair<GlobalVariable*, unsigned> > GlobalInits;
|
||||
std::vector<std::pair<GlobalAlias*, unsigned> > AliasInits;
|
||||
|
||||
/// Attributes - The set of parameter attributes by index. Index zero in the
|
||||
/// MAttributes - The set of attributes by index. Index zero in the
|
||||
/// file is for null, and is thus not represented here. As such all indices
|
||||
/// are off by one.
|
||||
std::vector<AttrListPtr> Attributes;
|
||||
std::vector<AttrListPtr> MAttributes;
|
||||
|
||||
/// FunctionBBs - While parsing a function body, this is a list of the basic
|
||||
/// blocks for the function.
|
||||
@ -204,8 +204,8 @@ private:
|
||||
return FunctionBBs[ID];
|
||||
}
|
||||
AttrListPtr getAttributes(unsigned i) const {
|
||||
if (i-1 < Attributes.size())
|
||||
return Attributes[i-1];
|
||||
if (i-1 < MAttributes.size())
|
||||
return MAttributes[i-1];
|
||||
return AttrListPtr();
|
||||
}
|
||||
|
||||
|
@ -105,10 +105,10 @@ bool AddReadAttrs::runOnSCC(const std::vector<CallGraphNode *> &SCC) {
|
||||
MadeChange = true;
|
||||
|
||||
// Clear out any existing attributes.
|
||||
F->removeAttribute(0, Attribute::ReadOnly | Attribute::ReadNone);
|
||||
F->removeAttribute(~0, Attribute::ReadOnly | Attribute::ReadNone);
|
||||
|
||||
// Add in the new attribute.
|
||||
F->addAttribute(0, ReadsMemory ? Attribute::ReadOnly : Attribute::ReadNone);
|
||||
F->addAttribute(~0, ReadsMemory ? Attribute::ReadOnly : Attribute::ReadNone);
|
||||
|
||||
if (ReadsMemory)
|
||||
NumReadOnly++;
|
||||
|
@ -508,7 +508,7 @@ Function *ArgPromotion::DoPromotion(Function *F,
|
||||
const AttrListPtr &PAL = F->getAttributes();
|
||||
|
||||
// Add any return attributes.
|
||||
if (Attributes attrs = PAL.getAttributes(0))
|
||||
if (Attributes attrs = PAL.getRetAttributes())
|
||||
AttributesVec.push_back(AttributeWithIndex::get(0, attrs));
|
||||
|
||||
// First, determine the new argument list
|
||||
@ -525,7 +525,7 @@ Function *ArgPromotion::DoPromotion(Function *F,
|
||||
} else if (!ArgsToPromote.count(I)) {
|
||||
// Unchanged argument
|
||||
Params.push_back(I->getType());
|
||||
if (Attributes attrs = PAL.getAttributes(ArgIndex))
|
||||
if (Attributes attrs = PAL.getParamAttributes(ArgIndex))
|
||||
AttributesVec.push_back(AttributeWithIndex::get(Params.size(), attrs));
|
||||
} else if (I->use_empty()) {
|
||||
// Dead argument (which are always marked as promotable)
|
||||
@ -578,6 +578,10 @@ Function *ArgPromotion::DoPromotion(Function *F,
|
||||
}
|
||||
}
|
||||
|
||||
// Add any function attributes.
|
||||
if (Attributes attrs = PAL.getFnAttributes())
|
||||
AttributesVec.push_back(AttributeWithIndex::get(~0, attrs));
|
||||
|
||||
const Type *RetTy = FTy->getReturnType();
|
||||
|
||||
// Work around LLVM bug PR56: the CWriter cannot emit varargs functions which
|
||||
@ -621,7 +625,7 @@ Function *ArgPromotion::DoPromotion(Function *F,
|
||||
const AttrListPtr &CallPAL = CS.getAttributes();
|
||||
|
||||
// Add any return attributes.
|
||||
if (Attributes attrs = CallPAL.getAttributes(0))
|
||||
if (Attributes attrs = CallPAL.getRetAttributes())
|
||||
AttributesVec.push_back(AttributeWithIndex::get(0, attrs));
|
||||
|
||||
// Loop over the operands, inserting GEP and loads in the caller as
|
||||
@ -633,7 +637,7 @@ Function *ArgPromotion::DoPromotion(Function *F,
|
||||
if (!ArgsToPromote.count(I) && !ByValArgsToTransform.count(I)) {
|
||||
Args.push_back(*AI); // Unmodified argument
|
||||
|
||||
if (Attributes Attrs = CallPAL.getAttributes(ArgIndex))
|
||||
if (Attributes Attrs = CallPAL.getParamAttributes(ArgIndex))
|
||||
AttributesVec.push_back(AttributeWithIndex::get(Args.size(), Attrs));
|
||||
|
||||
} else if (ByValArgsToTransform.count(I)) {
|
||||
@ -688,10 +692,14 @@ Function *ArgPromotion::DoPromotion(Function *F,
|
||||
// Push any varargs arguments on the list
|
||||
for (; AI != CS.arg_end(); ++AI, ++ArgIndex) {
|
||||
Args.push_back(*AI);
|
||||
if (Attributes Attrs = CallPAL.getAttributes(ArgIndex))
|
||||
if (Attributes Attrs = CallPAL.getParamAttributes(ArgIndex))
|
||||
AttributesVec.push_back(AttributeWithIndex::get(Args.size(), Attrs));
|
||||
}
|
||||
|
||||
// Add any function attributes.
|
||||
if (Attributes attrs = CallPAL.getFnAttributes())
|
||||
AttributesVec.push_back(AttributeWithIndex::get(~0, attrs));
|
||||
|
||||
Instruction *New;
|
||||
if (InvokeInst *II = dyn_cast<InvokeInst>(Call)) {
|
||||
New = InvokeInst::Create(NF, II->getNormalDest(), II->getUnwindDest(),
|
||||
|
@ -229,6 +229,8 @@ bool DAE::DeleteDeadVarargs(Function &Fn) {
|
||||
SmallVector<AttributeWithIndex, 8> AttributesVec;
|
||||
for (unsigned i = 0; PAL.getSlot(i).Index <= NumArgs; ++i)
|
||||
AttributesVec.push_back(PAL.getSlot(i));
|
||||
if (Attributes FnAttrs = PAL.getFnAttributes())
|
||||
AttributesVec.push_back(AttributeWithIndex::get(~0, FnAttrs));
|
||||
PAL = AttrListPtr::get(AttributesVec.begin(), AttributesVec.end());
|
||||
}
|
||||
|
||||
@ -593,8 +595,8 @@ bool DAE::RemoveDeadStuffFromFunction(Function *F) {
|
||||
const AttrListPtr &PAL = F->getAttributes();
|
||||
|
||||
// The existing function return attributes.
|
||||
Attributes RAttrs = PAL.getAttributes(0);
|
||||
|
||||
Attributes RAttrs = PAL.getRetAttributes();
|
||||
Attributes FnAttrs = PAL.getFnAttributes();
|
||||
|
||||
// Find out the new return value.
|
||||
|
||||
@ -678,7 +680,7 @@ bool DAE::RemoveDeadStuffFromFunction(Function *F) {
|
||||
|
||||
// Get the original parameter attributes (skipping the first one, that is
|
||||
// for the return value.
|
||||
if (Attributes Attrs = PAL.getAttributes(i + 1))
|
||||
if (Attributes Attrs = PAL.getParamAttributes(i + 1))
|
||||
AttributesVec.push_back(AttributeWithIndex::get(Params.size(), Attrs));
|
||||
} else {
|
||||
++NumArgumentsEliminated;
|
||||
@ -687,6 +689,9 @@ bool DAE::RemoveDeadStuffFromFunction(Function *F) {
|
||||
}
|
||||
}
|
||||
|
||||
if (FnAttrs != Attribute::None)
|
||||
AttributesVec.push_back(AttributeWithIndex::get(~0, FnAttrs));
|
||||
|
||||
// Reconstruct the AttributesList based on the vector we constructed.
|
||||
AttrListPtr NewPAL = AttrListPtr::get(AttributesVec.begin(), AttributesVec.end());
|
||||
|
||||
@ -730,7 +735,8 @@ bool DAE::RemoveDeadStuffFromFunction(Function *F) {
|
||||
const AttrListPtr &CallPAL = CS.getAttributes();
|
||||
|
||||
// The call return attributes.
|
||||
Attributes RAttrs = CallPAL.getAttributes(0);
|
||||
Attributes RAttrs = CallPAL.getRetAttributes();
|
||||
Attributes FnAttrs = CallPAL.getFnAttributes();
|
||||
// Adjust in case the function was changed to return void.
|
||||
RAttrs &= ~Attribute::typeIncompatible(NF->getReturnType());
|
||||
if (RAttrs)
|
||||
@ -746,7 +752,7 @@ bool DAE::RemoveDeadStuffFromFunction(Function *F) {
|
||||
if (ArgAlive[i]) {
|
||||
Args.push_back(*I);
|
||||
// Get original parameter attributes, but skip return attributes.
|
||||
if (Attributes Attrs = CallPAL.getAttributes(i + 1))
|
||||
if (Attributes Attrs = CallPAL.getParamAttributes(i + 1))
|
||||
AttributesVec.push_back(AttributeWithIndex::get(Args.size(), Attrs));
|
||||
}
|
||||
|
||||
@ -756,13 +762,16 @@ bool DAE::RemoveDeadStuffFromFunction(Function *F) {
|
||||
// Push any varargs arguments on the list. Don't forget their attributes.
|
||||
for (CallSite::arg_iterator E = CS.arg_end(); I != E; ++I, ++i) {
|
||||
Args.push_back(*I);
|
||||
if (Attributes Attrs = CallPAL.getAttributes(i + 1))
|
||||
if (Attributes Attrs = CallPAL.getParamAttributes(i + 1))
|
||||
AttributesVec.push_back(AttributeWithIndex::get(Args.size(), Attrs));
|
||||
}
|
||||
|
||||
if (FnAttrs != Attribute::None)
|
||||
AttributesVec.push_back(AttributeWithIndex::get(~0, FnAttrs));
|
||||
|
||||
// Reconstruct the AttributesList based on the vector we constructed.
|
||||
AttrListPtr NewCallPAL = AttrListPtr::get(AttributesVec.begin(),
|
||||
AttributesVec.end());
|
||||
AttributesVec.end());
|
||||
|
||||
Instruction *New;
|
||||
if (InvokeInst *II = dyn_cast<InvokeInst>(Call)) {
|
||||
|
@ -133,7 +133,7 @@ bool PruneEH::runOnSCC(const std::vector<CallGraphNode *> &SCC) {
|
||||
NewAttributes |= Attribute::NoReturn;
|
||||
|
||||
const AttrListPtr &PAL = SCC[i]->getFunction()->getAttributes();
|
||||
const AttrListPtr &NPAL = PAL.addAttr(0, NewAttributes);
|
||||
const AttrListPtr &NPAL = PAL.addAttr(~0, NewAttributes);
|
||||
if (PAL != NPAL) {
|
||||
MadeChange = true;
|
||||
SCC[i]->getFunction()->setAttributes(NPAL);
|
||||
|
@ -210,7 +210,7 @@ Function *SRETPromotion::cloneFunctionBody(Function *F,
|
||||
const AttrListPtr &PAL = F->getAttributes();
|
||||
|
||||
// Add any return attributes.
|
||||
if (Attributes attrs = PAL.getAttributes(0))
|
||||
if (Attributes attrs = PAL.getRetAttributes())
|
||||
AttributesVec.push_back(AttributeWithIndex::get(0, attrs));
|
||||
|
||||
// Skip first argument.
|
||||
@ -221,12 +221,17 @@ Function *SRETPromotion::cloneFunctionBody(Function *F,
|
||||
unsigned ParamIndex = 2;
|
||||
while (I != E) {
|
||||
Params.push_back(I->getType());
|
||||
if (Attributes Attrs = PAL.getAttributes(ParamIndex))
|
||||
if (Attributes Attrs = PAL.getParamAttributes(ParamIndex))
|
||||
AttributesVec.push_back(AttributeWithIndex::get(ParamIndex - 1, Attrs));
|
||||
++I;
|
||||
++ParamIndex;
|
||||
}
|
||||
|
||||
// Add any fn attributes.
|
||||
if (Attributes attrs = PAL.getFnAttributes())
|
||||
AttributesVec.push_back(AttributeWithIndex::get(~0, attrs));
|
||||
|
||||
|
||||
FunctionType *NFTy = FunctionType::get(STy, Params, FTy->isVarArg());
|
||||
Function *NF = Function::Create(NFTy, F->getLinkage());
|
||||
NF->takeName(F);
|
||||
@ -264,7 +269,7 @@ void SRETPromotion::updateCallSites(Function *F, Function *NF) {
|
||||
|
||||
const AttrListPtr &PAL = F->getAttributes();
|
||||
// Add any return attributes.
|
||||
if (Attributes attrs = PAL.getAttributes(0))
|
||||
if (Attributes attrs = PAL.getRetAttributes())
|
||||
ArgAttrsVec.push_back(AttributeWithIndex::get(0, attrs));
|
||||
|
||||
// Copy arguments, however skip first one.
|
||||
@ -276,12 +281,15 @@ void SRETPromotion::updateCallSites(Function *F, Function *NF) {
|
||||
unsigned ParamIndex = 2;
|
||||
while (AI != AE) {
|
||||
Args.push_back(*AI);
|
||||
if (Attributes Attrs = PAL.getAttributes(ParamIndex))
|
||||
if (Attributes Attrs = PAL.getParamAttributes(ParamIndex))
|
||||
ArgAttrsVec.push_back(AttributeWithIndex::get(ParamIndex - 1, Attrs));
|
||||
++ParamIndex;
|
||||
++AI;
|
||||
}
|
||||
|
||||
// Add any function attributes.
|
||||
if (Attributes attrs = PAL.getFnAttributes())
|
||||
ArgAttrsVec.push_back(AttributeWithIndex::get(~0, attrs));
|
||||
|
||||
AttrListPtr NewPAL = AttrListPtr::get(ArgAttrsVec.begin(), ArgAttrsVec.end());
|
||||
|
||||
|
@ -9127,7 +9127,7 @@ bool InstCombiner::transformConstExprCastCall(CallSite CS) {
|
||||
return false; // Cannot transform this return value.
|
||||
|
||||
if (!CallerPAL.isEmpty() && !Caller->use_empty()) {
|
||||
Attributes RAttrs = CallerPAL.getAttributes(0);
|
||||
Attributes RAttrs = CallerPAL.getRetAttributes();
|
||||
if (RAttrs & Attribute::typeIncompatible(NewRetTy))
|
||||
return false; // Attribute not compatible with transformed value.
|
||||
}
|
||||
@ -9157,7 +9157,8 @@ bool InstCombiner::transformConstExprCastCall(CallSite CS) {
|
||||
if (!CastInst::isCastable(ActTy, ParamTy))
|
||||
return false; // Cannot transform this parameter value.
|
||||
|
||||
if (CallerPAL.getAttributes(i + 1) & Attribute::typeIncompatible(ParamTy))
|
||||
if (CallerPAL.getParamAttributes(i + 1)
|
||||
& Attribute::typeIncompatible(ParamTy))
|
||||
return false; // Attribute not compatible with transformed value.
|
||||
|
||||
// Converting from one pointer type to another or between a pointer and an
|
||||
@ -9193,7 +9194,7 @@ bool InstCombiner::transformConstExprCastCall(CallSite CS) {
|
||||
attrVec.reserve(NumCommonArgs);
|
||||
|
||||
// Get any return attributes.
|
||||
Attributes RAttrs = CallerPAL.getAttributes(0);
|
||||
Attributes RAttrs = CallerPAL.getRetAttributes();
|
||||
|
||||
// If the return value is not being used, the type may not be compatible
|
||||
// with the existing attributes. Wipe out any problematic attributes.
|
||||
@ -9216,7 +9217,7 @@ bool InstCombiner::transformConstExprCastCall(CallSite CS) {
|
||||
}
|
||||
|
||||
// Add any parameter attributes.
|
||||
if (Attributes PAttrs = CallerPAL.getAttributes(i + 1))
|
||||
if (Attributes PAttrs = CallerPAL.getParamAttributes(i + 1))
|
||||
attrVec.push_back(AttributeWithIndex::get(i + 1, PAttrs));
|
||||
}
|
||||
|
||||
@ -9246,12 +9247,15 @@ bool InstCombiner::transformConstExprCastCall(CallSite CS) {
|
||||
}
|
||||
|
||||
// Add any parameter attributes.
|
||||
if (Attributes PAttrs = CallerPAL.getAttributes(i + 1))
|
||||
if (Attributes PAttrs = CallerPAL.getParamAttributes(i + 1))
|
||||
attrVec.push_back(AttributeWithIndex::get(i + 1, PAttrs));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (Attributes FnAttrs = CallerPAL.getFnAttributes())
|
||||
attrVec.push_back(AttributeWithIndex::get(~0, FnAttrs));
|
||||
|
||||
if (NewRetTy == Type::VoidTy)
|
||||
Caller->setName(""); // Void type should not have a name.
|
||||
|
||||
@ -9337,7 +9341,7 @@ Instruction *InstCombiner::transformCallThroughTrampoline(CallSite CS) {
|
||||
if (NestAttrs.paramHasAttr(NestIdx, Attribute::Nest)) {
|
||||
// Record the parameter type and any other attributes.
|
||||
NestTy = *I;
|
||||
NestAttr = NestAttrs.getAttributes(NestIdx);
|
||||
NestAttr = NestAttrs.getParamAttributes(NestIdx);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -9352,8 +9356,8 @@ Instruction *InstCombiner::transformCallThroughTrampoline(CallSite CS) {
|
||||
// Insert the nest argument into the call argument list, which may
|
||||
// mean appending it. Likewise for attributes.
|
||||
|
||||
// Add any function result attributes.
|
||||
if (Attributes Attr = Attrs.getAttributes(0))
|
||||
// Add any result attributes.
|
||||
if (Attributes Attr = Attrs.getRetAttributes())
|
||||
NewAttrs.push_back(AttributeWithIndex::get(0, Attr));
|
||||
|
||||
{
|
||||
@ -9374,7 +9378,7 @@ Instruction *InstCombiner::transformCallThroughTrampoline(CallSite CS) {
|
||||
|
||||
// Add the original argument and attributes.
|
||||
NewArgs.push_back(*I);
|
||||
if (Attributes Attr = Attrs.getAttributes(Idx))
|
||||
if (Attributes Attr = Attrs.getParamAttributes(Idx))
|
||||
NewAttrs.push_back
|
||||
(AttributeWithIndex::get(Idx + (Idx >= NestIdx), Attr));
|
||||
|
||||
@ -9382,6 +9386,10 @@ Instruction *InstCombiner::transformCallThroughTrampoline(CallSite CS) {
|
||||
} while (1);
|
||||
}
|
||||
|
||||
// Add any function attributes.
|
||||
if (Attributes Attr = Attrs.getFnAttributes())
|
||||
NewAttrs.push_back(AttributeWithIndex::get(~0, Attr));
|
||||
|
||||
// The trampoline may have been bitcast to a bogus type (FTy).
|
||||
// Handle this by synthesizing a new function type, equal to FTy
|
||||
// with the chain parameter inserted.
|
||||
|
@ -1374,7 +1374,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.getAttributes(Idx));
|
||||
printArgument(I, Attrs.getParamAttributes(Idx));
|
||||
Idx++;
|
||||
}
|
||||
} else {
|
||||
@ -1386,7 +1386,7 @@ void AssemblyWriter::printFunction(const Function *F) {
|
||||
// Output type...
|
||||
printType(FT->getParamType(i));
|
||||
|
||||
Attributes ArgAttrs = Attrs.getAttributes(i+1);
|
||||
Attributes ArgAttrs = Attrs.getParamAttributes(i+1);
|
||||
if (ArgAttrs != Attribute::None)
|
||||
Out << ' ' << Attribute::getAsString(ArgAttrs);
|
||||
}
|
||||
@ -1398,9 +1398,12 @@ void AssemblyWriter::printFunction(const Function *F) {
|
||||
Out << "..."; // Output varargs portion of signature!
|
||||
}
|
||||
Out << ')';
|
||||
Attributes RetAttrs = Attrs.getAttributes(0);
|
||||
Attributes RetAttrs = Attrs.getRetAttributes();
|
||||
if (RetAttrs != Attribute::None)
|
||||
Out << ' ' << Attribute::getAsString(Attrs.getAttributes(0));
|
||||
Out << ' ' << Attribute::getAsString(Attrs.getRetAttributes());
|
||||
Attributes FnAttrs = Attrs.getFnAttributes();
|
||||
if (FnAttrs != Attribute::None)
|
||||
Out << ' ' << Attribute::getAsString(Attrs.getFnAttributes());
|
||||
if (F->hasSection())
|
||||
Out << " section \"" << F->getSection() << '"';
|
||||
if (F->getAlignment())
|
||||
@ -1660,11 +1663,13 @@ 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.getAttributes(op));
|
||||
writeParamOperand(I.getOperand(op), PAL.getParamAttributes(op));
|
||||
}
|
||||
Out << ')';
|
||||
if (PAL.getAttributes(0) != Attribute::None)
|
||||
Out << ' ' << Attribute::getAsString(PAL.getAttributes(0));
|
||||
if (PAL.getRetAttributes() != Attribute::None)
|
||||
Out << ' ' << Attribute::getAsString(PAL.getRetAttributes());
|
||||
if (PAL.getFnAttributes() != Attribute::None)
|
||||
Out << ' ' << Attribute::getAsString(PAL.getFnAttributes());
|
||||
} else if (const InvokeInst *II = dyn_cast<InvokeInst>(&I)) {
|
||||
const PointerType *PTy = cast<PointerType>(Operand->getType());
|
||||
const FunctionType *FTy = cast<FunctionType>(PTy->getElementType());
|
||||
@ -1699,12 +1704,15 @@ 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.getAttributes(op-2));
|
||||
writeParamOperand(I.getOperand(op), PAL.getParamAttributes(op-2));
|
||||
}
|
||||
|
||||
Out << ')';
|
||||
if (PAL.getAttributes(0) != Attribute::None)
|
||||
Out << ' ' << Attribute::getAsString(PAL.getAttributes(0));
|
||||
if (PAL.getRetAttributes() != Attribute::None)
|
||||
Out << ' ' << Attribute::getAsString(PAL.getRetAttributes());
|
||||
if (PAL.getFnAttributes() != Attribute::None)
|
||||
Out << ' ' << Attribute::getAsString(PAL.getFnAttributes());
|
||||
|
||||
Out << "\n\t\t\tto ";
|
||||
writeOperand(II->getNormalDest(), true);
|
||||
Out << " unwind ";
|
||||
|
@ -47,6 +47,12 @@ std::string Attribute::getAsString(Attributes Attrs) {
|
||||
Result += "readnone ";
|
||||
if (Attrs & Attribute::ReadOnly)
|
||||
Result += "readonly ";
|
||||
if (Attrs & Attribute::OptimizeForSize)
|
||||
Result += "optsize ";
|
||||
if (Attrs & Attribute::NoInline)
|
||||
Result += "noinline ";
|
||||
if (Attrs & Attribute::AlwaysInline)
|
||||
Result += "alwaysinline ";
|
||||
if (Attrs & Attribute::Alignment) {
|
||||
Result += "align ";
|
||||
Result += utostr((Attrs & Attribute::Alignment) >> 16);
|
||||
|
@ -365,7 +365,7 @@ AttrListPtr Intrinsic::getAttributes(ID id) {
|
||||
// Intrinsics cannot throw exceptions.
|
||||
Attr |= Attribute::NoUnwind;
|
||||
|
||||
AttributeWithIndex PAWI = AttributeWithIndex::get(0, Attr);
|
||||
AttributeWithIndex PAWI = AttributeWithIndex::get(~0, Attr);
|
||||
return AttrListPtr::get(&PAWI, 1);
|
||||
}
|
||||
|
||||
|
@ -975,7 +975,7 @@ void Verifier::VerifyCallSite(CallSite CS) {
|
||||
if (FTy->isVarArg())
|
||||
// Check attributes on the varargs part.
|
||||
for (unsigned Idx = 1 + FTy->getNumParams(); Idx <= CS.arg_size(); ++Idx) {
|
||||
Attributes Attr = Attrs.getAttributes(Idx);
|
||||
Attributes Attr = Attrs.getParamAttributes(Idx);
|
||||
|
||||
VerifyAttrs(Attr, CS.getArgument(Idx-1)->getType(), false, I);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user