mirror of
https://github.com/RPCSX/llvm.git
synced 2024-11-24 20:29:53 +00:00
Extend Attributes to 64 bits
Problem: LLVM needs more function attributes than currently available (32 bits). One such proposed attribute is "address_safety", which shows that a function is being checked for address safety (by AddressSanitizer, SAFECode, etc). Solution: - extend the Attributes from 32 bits to 64-bits - wrap the object into a class so that unsigned is never erroneously used instead - change "unsigned" to "Attributes" throughout the code, including one place in clang. - the class has no "operator uint64 ()", but it has "uint64_t Raw() " to support packing/unpacking. - the class has "safe operator bool()" to support the common idiom: if (Attributes attr = getAttrs()) useAttrs(attr); - The CTOR from uint64_t is marked explicit, so I had to add a few explicit CTOR calls - Add the new attribute "address_safety". Doing it in the same commit to check that attributes beyond first 32 bits actually work. - Some of the functions from the Attribute namespace are worth moving inside the class, but I'd prefer to have it as a separate commit. Tested: "make check" on Linux (32-bit and 64-bit) and Mac (10.6) built/run spec CPU 2006 on Linux with clang -O2. This change will break clang build in lib/CodeGen/CGCall.cpp. The following patch will fix it. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@148553 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
3feccbaaee
commit
164b86b439
@ -1143,6 +1143,10 @@ define void @f() optsize { ... }
|
||||
</pre>
|
||||
|
||||
<dl>
|
||||
<dt><tt><b>address_safety</b></tt></dt>
|
||||
<dd>This attribute indicates that the address safety analysis
|
||||
is enabled for this function. </dd>
|
||||
|
||||
<dt><tt><b>alignstack(<<em>n</em>>)</b></tt></dt>
|
||||
<dd>This attribute indicates that, when emitting the prologue and epilogue,
|
||||
the backend should forcibly align the stack pointer. Specify the
|
||||
|
@ -118,7 +118,8 @@ typedef enum {
|
||||
LLVMStackAlignment = 7<<26,
|
||||
LLVMReturnsTwice = 1 << 29,
|
||||
LLVMUWTable = 1 << 30,
|
||||
LLVMNonLazyBind = 1 << 31
|
||||
LLVMNonLazyBind = 1U << 31,
|
||||
LLVMAddressSafety = 1ULL << 32,
|
||||
} LLVMAttribute;
|
||||
|
||||
typedef enum {
|
||||
|
@ -23,7 +23,47 @@ namespace llvm {
|
||||
class Type;
|
||||
|
||||
/// Attributes - A bitset of attributes.
|
||||
typedef unsigned Attributes;
|
||||
class Attributes {
|
||||
public:
|
||||
Attributes() : Bits(0) { }
|
||||
explicit Attributes(uint64_t Val) : Bits(Val) { }
|
||||
Attributes(const Attributes &Attrs) : Bits(Attrs.Bits) { }
|
||||
// This is a "safe bool() operator".
|
||||
operator const void *() const { return Bits ? this : 0; }
|
||||
bool isEmptyOrSingleton() const { return (Bits & (Bits - 1)) == 0; }
|
||||
Attributes &operator = (const Attributes &Attrs) {
|
||||
Bits = Attrs.Bits;
|
||||
return *this;
|
||||
}
|
||||
bool operator == (const Attributes &Attrs) const {
|
||||
return Bits == Attrs.Bits;
|
||||
}
|
||||
bool operator != (const Attributes &Attrs) const {
|
||||
return Bits != Attrs.Bits;
|
||||
}
|
||||
Attributes operator | (const Attributes &Attrs) const {
|
||||
return Attributes(Bits | Attrs.Bits);
|
||||
}
|
||||
Attributes operator & (const Attributes &Attrs) const {
|
||||
return Attributes(Bits & Attrs.Bits);
|
||||
}
|
||||
Attributes operator ^ (const Attributes &Attrs) const {
|
||||
return Attributes(Bits ^ Attrs.Bits);
|
||||
}
|
||||
Attributes &operator |= (const Attributes &Attrs) {
|
||||
Bits |= Attrs.Bits;
|
||||
return *this;
|
||||
}
|
||||
Attributes &operator &= (const Attributes &Attrs) {
|
||||
Bits &= Attrs.Bits;
|
||||
return *this;
|
||||
}
|
||||
Attributes operator ~ () const { return Attributes(~Bits); }
|
||||
uint64_t Raw() const { return Bits; }
|
||||
private:
|
||||
// Currently, we need less than 64 bits.
|
||||
uint64_t Bits;
|
||||
};
|
||||
|
||||
namespace Attribute {
|
||||
|
||||
@ -33,44 +73,45 @@ namespace Attribute {
|
||||
/// results or the function itself.
|
||||
/// @brief Function attributes.
|
||||
|
||||
const Attributes None = 0; ///< No attributes have been set
|
||||
const Attributes ZExt = 1<<0; ///< Zero extended before/after call
|
||||
const Attributes SExt = 1<<1; ///< Sign extended before/after call
|
||||
const Attributes NoReturn = 1<<2; ///< Mark the function as not returning
|
||||
const Attributes InReg = 1<<3; ///< Force argument to be passed in register
|
||||
const Attributes StructRet = 1<<4; ///< Hidden pointer to structure to return
|
||||
const Attributes NoUnwind = 1<<5; ///< Function doesn't unwind stack
|
||||
const Attributes NoAlias = 1<<6; ///< Considered to not alias after call
|
||||
const Attributes ByVal = 1<<7; ///< Pass structure by value
|
||||
const Attributes Nest = 1<<8; ///< Nested function static chain
|
||||
const Attributes ReadNone = 1<<9; ///< Function does not access memory
|
||||
const Attributes ReadOnly = 1<<10; ///< Function only reads from memory
|
||||
const Attributes NoInline = 1<<11; ///< inline=never
|
||||
const Attributes AlwaysInline = 1<<12; ///< inline=always
|
||||
const Attributes OptimizeForSize = 1<<13; ///< opt_size
|
||||
const Attributes StackProtect = 1<<14; ///< Stack protection.
|
||||
const Attributes StackProtectReq = 1<<15; ///< Stack protection required.
|
||||
const Attributes Alignment = 31<<16; ///< Alignment of parameter (5 bits)
|
||||
const Attributes None (0); ///< No attributes have been set
|
||||
const Attributes ZExt (1<<0); ///< Zero extended before/after call
|
||||
const Attributes SExt (1<<1); ///< Sign extended before/after call
|
||||
const Attributes NoReturn (1<<2); ///< Mark the function as not returning
|
||||
const Attributes InReg (1<<3); ///< Force argument to be passed in register
|
||||
const Attributes StructRet (1<<4); ///< Hidden pointer to structure to return
|
||||
const Attributes NoUnwind (1<<5); ///< Function doesn't unwind stack
|
||||
const Attributes NoAlias (1<<6); ///< Considered to not alias after call
|
||||
const Attributes ByVal (1<<7); ///< Pass structure by value
|
||||
const Attributes Nest (1<<8); ///< Nested function static chain
|
||||
const Attributes ReadNone (1<<9); ///< Function does not access memory
|
||||
const Attributes ReadOnly (1<<10); ///< Function only reads from memory
|
||||
const Attributes NoInline (1<<11); ///< inline=never
|
||||
const Attributes AlwaysInline (1<<12); ///< inline=always
|
||||
const Attributes OptimizeForSize (1<<13); ///< opt_size
|
||||
const Attributes StackProtect (1<<14); ///< Stack protection.
|
||||
const Attributes StackProtectReq (1<<15); ///< Stack protection required.
|
||||
const Attributes Alignment (31<<16); ///< Alignment of parameter (5 bits)
|
||||
// stored as log2 of alignment with +1 bias
|
||||
// 0 means unaligned different from align 1
|
||||
const Attributes NoCapture = 1<<21; ///< Function creates no aliases of pointer
|
||||
const Attributes NoRedZone = 1<<22; /// disable redzone
|
||||
const Attributes NoImplicitFloat = 1<<23; /// disable implicit floating point
|
||||
const Attributes NoCapture (1<<21); ///< Function creates no aliases of pointer
|
||||
const Attributes NoRedZone (1<<22); /// disable redzone
|
||||
const Attributes NoImplicitFloat (1<<23); /// disable implicit floating point
|
||||
/// instructions.
|
||||
const Attributes Naked = 1<<24; ///< Naked function
|
||||
const Attributes InlineHint = 1<<25; ///< source said inlining was
|
||||
const Attributes Naked (1<<24); ///< Naked function
|
||||
const Attributes InlineHint (1<<25); ///< source said inlining was
|
||||
///desirable
|
||||
const Attributes StackAlignment = 7<<26; ///< Alignment of stack for
|
||||
const Attributes StackAlignment (7<<26); ///< Alignment of stack for
|
||||
///function (3 bits) stored as log2
|
||||
///of alignment with +1 bias
|
||||
///0 means unaligned (different from
|
||||
///alignstack(1))
|
||||
const Attributes ReturnsTwice = 1<<29; ///< Function can return twice
|
||||
const Attributes UWTable = 1<<30; ///< Function must be in a unwind
|
||||
const Attributes ReturnsTwice (1<<29); ///< Function can return twice
|
||||
const Attributes UWTable (1<<30); ///< Function must be in a unwind
|
||||
///table
|
||||
const Attributes NonLazyBind = 1U<<31; ///< Function is called early and/or
|
||||
const Attributes NonLazyBind (1U<<31); ///< Function is called early and/or
|
||||
/// often, so lazy binding isn't
|
||||
/// worthwhile.
|
||||
const Attributes AddressSafety(1ULL<<32); ///< Address safety checking is on.
|
||||
|
||||
/// Note that uwtable is about the ABI or the user mandating an entry in the
|
||||
/// unwind table. The nounwind attribute is about an exception passing by the
|
||||
@ -92,7 +133,7 @@ const Attributes ParameterOnly = ByVal | Nest | StructRet | NoCapture;
|
||||
const Attributes FunctionOnly = NoReturn | NoUnwind | ReadNone | ReadOnly |
|
||||
NoInline | AlwaysInline | OptimizeForSize | StackProtect | StackProtectReq |
|
||||
NoRedZone | NoImplicitFloat | Naked | InlineHint | StackAlignment |
|
||||
UWTable | NonLazyBind | ReturnsTwice;
|
||||
UWTable | NonLazyBind | ReturnsTwice | AddressSafety;
|
||||
|
||||
/// @brief Parameter attributes that do not apply to vararg call arguments.
|
||||
const Attributes VarArgsIncompatible = StructRet;
|
||||
@ -113,20 +154,20 @@ Attributes typeIncompatible(Type *Ty);
|
||||
inline Attributes constructAlignmentFromInt(unsigned i) {
|
||||
// Default alignment, allow the target to define how to align it.
|
||||
if (i == 0)
|
||||
return 0;
|
||||
return None;
|
||||
|
||||
assert(isPowerOf2_32(i) && "Alignment must be a power of two.");
|
||||
assert(i <= 0x40000000 && "Alignment too large.");
|
||||
return (Log2_32(i)+1) << 16;
|
||||
return Attributes((Log2_32(i)+1) << 16);
|
||||
}
|
||||
|
||||
/// This returns the alignment field of an attribute as a byte alignment value.
|
||||
inline unsigned getAlignmentFromAttrs(Attributes A) {
|
||||
Attributes Align = A & Attribute::Alignment;
|
||||
if (Align == 0)
|
||||
if (!Align)
|
||||
return 0;
|
||||
|
||||
return 1U << ((Align >> 16) - 1);
|
||||
return 1U << ((Align.Raw() >> 16) - 1);
|
||||
}
|
||||
|
||||
/// This turns an int stack alignment (which must be a power of 2) into
|
||||
@ -134,21 +175,21 @@ inline unsigned getAlignmentFromAttrs(Attributes A) {
|
||||
inline Attributes constructStackAlignmentFromInt(unsigned i) {
|
||||
// Default alignment, allow the target to define how to align it.
|
||||
if (i == 0)
|
||||
return 0;
|
||||
return None;
|
||||
|
||||
assert(isPowerOf2_32(i) && "Alignment must be a power of two.");
|
||||
assert(i <= 0x100 && "Alignment too large.");
|
||||
return (Log2_32(i)+1) << 26;
|
||||
return Attributes((Log2_32(i)+1) << 26);
|
||||
}
|
||||
|
||||
/// This returns the stack alignment field of an attribute as a byte alignment
|
||||
/// value.
|
||||
inline unsigned getStackAlignmentFromAttrs(Attributes A) {
|
||||
Attributes StackAlign = A & Attribute::StackAlignment;
|
||||
if (StackAlign == 0)
|
||||
if (!StackAlign)
|
||||
return 0;
|
||||
|
||||
return 1U << ((StackAlign >> 26) - 1);
|
||||
return 1U << ((StackAlign.Raw() >> 26) - 1);
|
||||
}
|
||||
|
||||
|
||||
@ -242,7 +283,7 @@ public:
|
||||
/// paramHasAttr - Return true if the specified parameter index has the
|
||||
/// specified attribute set.
|
||||
bool paramHasAttr(unsigned Idx, Attributes Attr) const {
|
||||
return (getAttributes(Idx) & Attr) != 0;
|
||||
return getAttributes(Idx) & Attr;
|
||||
}
|
||||
|
||||
/// getParamAlignment - Return the alignment for the specified function
|
||||
|
@ -548,6 +548,7 @@ lltok::Kind LLLexer::LexIdentifier() {
|
||||
KEYWORD(noimplicitfloat);
|
||||
KEYWORD(naked);
|
||||
KEYWORD(nonlazybind);
|
||||
KEYWORD(address_safety);
|
||||
|
||||
KEYWORD(type);
|
||||
KEYWORD(opaque);
|
||||
|
@ -874,7 +874,7 @@ bool LLParser::ParseOptionalAddrSpace(unsigned &AddrSpace) {
|
||||
/// ParseOptionalAttrs - Parse a potentially empty attribute list. AttrKind
|
||||
/// indicates what kind of attribute list this is: 0: function arg, 1: result,
|
||||
/// 2: function attr.
|
||||
bool LLParser::ParseOptionalAttrs(unsigned &Attrs, unsigned AttrKind) {
|
||||
bool LLParser::ParseOptionalAttrs(Attributes &Attrs, unsigned AttrKind) {
|
||||
Attrs = Attribute::None;
|
||||
LocTy AttrLoc = Lex.getLoc();
|
||||
|
||||
@ -919,6 +919,7 @@ bool LLParser::ParseOptionalAttrs(unsigned &Attrs, unsigned AttrKind) {
|
||||
case lltok::kw_noimplicitfloat: Attrs |= Attribute::NoImplicitFloat; break;
|
||||
case lltok::kw_naked: Attrs |= Attribute::Naked; break;
|
||||
case lltok::kw_nonlazybind: Attrs |= Attribute::NonLazyBind; break;
|
||||
case lltok::kw_address_safety: Attrs |= Attribute::AddressSafety; break;
|
||||
|
||||
case lltok::kw_alignstack: {
|
||||
unsigned Alignment;
|
||||
@ -1353,8 +1354,8 @@ bool LLParser::ParseParameterList(SmallVectorImpl<ParamInfo> &ArgList,
|
||||
// Parse the argument.
|
||||
LocTy ArgLoc;
|
||||
Type *ArgTy = 0;
|
||||
unsigned ArgAttrs1 = Attribute::None;
|
||||
unsigned ArgAttrs2 = Attribute::None;
|
||||
Attributes ArgAttrs1;
|
||||
Attributes ArgAttrs2;
|
||||
Value *V;
|
||||
if (ParseType(ArgTy, ArgLoc))
|
||||
return true;
|
||||
@ -1394,7 +1395,7 @@ bool LLParser::ParseArgumentList(SmallVectorImpl<ArgInfo> &ArgList,
|
||||
} else {
|
||||
LocTy TypeLoc = Lex.getLoc();
|
||||
Type *ArgTy = 0;
|
||||
unsigned Attrs;
|
||||
Attributes Attrs;
|
||||
std::string Name;
|
||||
|
||||
if (ParseType(ArgTy) ||
|
||||
@ -1461,7 +1462,7 @@ bool LLParser::ParseFunctionType(Type *&Result) {
|
||||
for (unsigned i = 0, e = ArgList.size(); i != e; ++i) {
|
||||
if (!ArgList[i].Name.empty())
|
||||
return Error(ArgList[i].Loc, "argument name invalid in function type");
|
||||
if (ArgList[i].Attrs != 0)
|
||||
if (ArgList[i].Attrs)
|
||||
return Error(ArgList[i].Loc,
|
||||
"argument attributes invalid in function type");
|
||||
}
|
||||
@ -2586,7 +2587,8 @@ bool LLParser::ParseFunctionHeader(Function *&Fn, bool isDefine) {
|
||||
LocTy LinkageLoc = Lex.getLoc();
|
||||
unsigned Linkage;
|
||||
|
||||
unsigned Visibility, RetAttrs;
|
||||
unsigned Visibility;
|
||||
Attributes RetAttrs;
|
||||
CallingConv::ID CC;
|
||||
Type *RetType = 0;
|
||||
LocTy RetTypeLoc = Lex.getLoc();
|
||||
@ -2650,7 +2652,7 @@ bool LLParser::ParseFunctionHeader(Function *&Fn, bool isDefine) {
|
||||
|
||||
SmallVector<ArgInfo, 8> ArgList;
|
||||
bool isVarArg;
|
||||
unsigned FuncAttrs;
|
||||
Attributes FuncAttrs;
|
||||
std::string Section;
|
||||
unsigned Alignment;
|
||||
std::string GC;
|
||||
@ -3162,7 +3164,7 @@ bool LLParser::ParseIndirectBr(Instruction *&Inst, PerFunctionState &PFS) {
|
||||
/// OptionalAttrs 'to' TypeAndValue 'unwind' TypeAndValue
|
||||
bool LLParser::ParseInvoke(Instruction *&Inst, PerFunctionState &PFS) {
|
||||
LocTy CallLoc = Lex.getLoc();
|
||||
unsigned RetAttrs, FnAttrs;
|
||||
Attributes RetAttrs, FnAttrs;
|
||||
CallingConv::ID CC;
|
||||
Type *RetType = 0;
|
||||
LocTy RetTypeLoc;
|
||||
@ -3561,7 +3563,7 @@ bool LLParser::ParseLandingPad(Instruction *&Inst, PerFunctionState &PFS) {
|
||||
/// ParameterList OptionalAttrs
|
||||
bool LLParser::ParseCall(Instruction *&Inst, PerFunctionState &PFS,
|
||||
bool isTail) {
|
||||
unsigned RetAttrs, FnAttrs;
|
||||
Attributes RetAttrs, FnAttrs;
|
||||
CallingConv::ID CC;
|
||||
Type *RetType = 0;
|
||||
LocTy RetTypeLoc;
|
||||
|
@ -15,6 +15,7 @@
|
||||
#define LLVM_ASMPARSER_LLPARSER_H
|
||||
|
||||
#include "LLLexer.h"
|
||||
#include "llvm/Attributes.h"
|
||||
#include "llvm/Instructions.h"
|
||||
#include "llvm/Module.h"
|
||||
#include "llvm/Type.h"
|
||||
@ -171,7 +172,7 @@ namespace llvm {
|
||||
return ParseUInt32(Val);
|
||||
}
|
||||
bool ParseOptionalAddrSpace(unsigned &AddrSpace);
|
||||
bool ParseOptionalAttrs(unsigned &Attrs, unsigned AttrKind);
|
||||
bool ParseOptionalAttrs(Attributes &Attrs, unsigned AttrKind);
|
||||
bool ParseOptionalLinkage(unsigned &Linkage, bool &HasLinkage);
|
||||
bool ParseOptionalLinkage(unsigned &Linkage) {
|
||||
bool HasLinkage; return ParseOptionalLinkage(Linkage, HasLinkage);
|
||||
@ -304,8 +305,8 @@ namespace llvm {
|
||||
struct ParamInfo {
|
||||
LocTy Loc;
|
||||
Value *V;
|
||||
unsigned Attrs;
|
||||
ParamInfo(LocTy loc, Value *v, unsigned attrs)
|
||||
Attributes Attrs;
|
||||
ParamInfo(LocTy loc, Value *v, Attributes attrs)
|
||||
: Loc(loc), V(v), Attrs(attrs) {}
|
||||
};
|
||||
bool ParseParameterList(SmallVectorImpl<ParamInfo> &ArgList,
|
||||
@ -325,9 +326,9 @@ namespace llvm {
|
||||
struct ArgInfo {
|
||||
LocTy Loc;
|
||||
Type *Ty;
|
||||
unsigned Attrs;
|
||||
Attributes Attrs;
|
||||
std::string Name;
|
||||
ArgInfo(LocTy L, Type *ty, unsigned Attr, const std::string &N)
|
||||
ArgInfo(LocTy L, Type *ty, Attributes Attr, const std::string &N)
|
||||
: Loc(L), Ty(ty), Attrs(Attr), Name(N) {}
|
||||
};
|
||||
bool ParseArgumentList(SmallVectorImpl<ArgInfo> &ArgList, bool &isVarArg);
|
||||
|
@ -102,6 +102,7 @@ namespace lltok {
|
||||
kw_noimplicitfloat,
|
||||
kw_naked,
|
||||
kw_nonlazybind,
|
||||
kw_address_safety,
|
||||
|
||||
kw_type,
|
||||
kw_opaque,
|
||||
|
@ -461,8 +461,8 @@ bool BitcodeReader::ParseAttributeBlock() {
|
||||
// If Function attributes are using index 0 then transfer them
|
||||
// to index ~0. Index 0 is used for return value attributes but used to be
|
||||
// used for function attributes.
|
||||
Attributes RetAttribute = Attribute::None;
|
||||
Attributes FnAttribute = Attribute::None;
|
||||
Attributes RetAttribute;
|
||||
Attributes FnAttribute;
|
||||
for (unsigned i = 0, e = Record.size(); i != e; i += 2) {
|
||||
// FIXME: remove in LLVM 3.0
|
||||
// The alignment is stored as a 16-bit raw value from bits 31--16.
|
||||
@ -472,23 +472,24 @@ bool BitcodeReader::ParseAttributeBlock() {
|
||||
if (Alignment && !isPowerOf2_32(Alignment))
|
||||
return Error("Alignment is not a power of two.");
|
||||
|
||||
Attributes ReconstitutedAttr = Record[i+1] & 0xffff;
|
||||
Attributes ReconstitutedAttr(Record[i+1] & 0xffff);
|
||||
if (Alignment)
|
||||
ReconstitutedAttr |= Attribute::constructAlignmentFromInt(Alignment);
|
||||
ReconstitutedAttr |= (Record[i+1] & (0xffffull << 32)) >> 11;
|
||||
Record[i+1] = ReconstitutedAttr;
|
||||
ReconstitutedAttr |=
|
||||
Attributes((Record[i+1] & (0xffffull << 32)) >> 11);
|
||||
|
||||
Record[i+1] = ReconstitutedAttr.Raw();
|
||||
if (Record[i] == 0)
|
||||
RetAttribute = Record[i+1];
|
||||
RetAttribute = ReconstitutedAttr;
|
||||
else if (Record[i] == ~0U)
|
||||
FnAttribute = Record[i+1];
|
||||
FnAttribute = ReconstitutedAttr;
|
||||
}
|
||||
|
||||
unsigned OldRetAttrs = (Attribute::NoUnwind|Attribute::NoReturn|
|
||||
Attributes OldRetAttrs = (Attribute::NoUnwind|Attribute::NoReturn|
|
||||
Attribute::ReadOnly|Attribute::ReadNone);
|
||||
|
||||
if (FnAttribute == Attribute::None && RetAttribute != Attribute::None &&
|
||||
(RetAttribute & OldRetAttrs) != 0) {
|
||||
(RetAttribute & OldRetAttrs)) {
|
||||
if (FnAttribute == Attribute::None) { // add a slot so they get added.
|
||||
Record.push_back(~0U);
|
||||
Record.push_back(0);
|
||||
@ -505,8 +506,9 @@ bool BitcodeReader::ParseAttributeBlock() {
|
||||
} else if (Record[i] == ~0U) {
|
||||
if (FnAttribute != Attribute::None)
|
||||
Attrs.push_back(AttributeWithIndex::get(~0U, FnAttribute));
|
||||
} else if (Record[i+1] != Attribute::None)
|
||||
Attrs.push_back(AttributeWithIndex::get(Record[i], Record[i+1]));
|
||||
} else if (Attributes(Record[i+1]) != Attribute::None)
|
||||
Attrs.push_back(AttributeWithIndex::get(Record[i],
|
||||
Attributes(Record[i+1])));
|
||||
}
|
||||
|
||||
MAttributes.push_back(AttrListPtr::get(Attrs.begin(), Attrs.end()));
|
||||
|
@ -179,10 +179,11 @@ static void WriteAttributeTable(const ValueEnumerator &VE,
|
||||
// Store the alignment in the bitcode as a 16-bit raw value instead of a
|
||||
// 5-bit log2 encoded value. Shift the bits above the alignment up by
|
||||
// 11 bits.
|
||||
uint64_t FauxAttr = PAWI.Attrs & 0xffff;
|
||||
uint64_t FauxAttr = PAWI.Attrs.Raw() & 0xffff;
|
||||
if (PAWI.Attrs & Attribute::Alignment)
|
||||
FauxAttr |= (1ull<<16)<<(((PAWI.Attrs & Attribute::Alignment)-1) >> 16);
|
||||
FauxAttr |= (PAWI.Attrs & (0x3FFull << 21)) << 11;
|
||||
FauxAttr |= (1ull<<16)<<
|
||||
(((PAWI.Attrs & Attribute::Alignment).Raw()-1) >> 16);
|
||||
FauxAttr |= (PAWI.Attrs.Raw() & (0x3FFull << 21)) << 11;
|
||||
|
||||
Record.push_back(FauxAttr);
|
||||
}
|
||||
|
@ -259,7 +259,7 @@ bool llvm::isInTailCallPosition(ImmutableCallSite CS, Attributes CalleeRetAttr,
|
||||
// Conservatively require the attributes of the call to match those of
|
||||
// the return. Ignore noalias because it doesn't affect the call sequence.
|
||||
const Function *F = ExitBB->getParent();
|
||||
unsigned CallerRetAttr = F->getAttributes().getRetAttributes();
|
||||
Attributes CallerRetAttr = F->getAttributes().getRetAttributes();
|
||||
if ((CalleeRetAttr ^ CallerRetAttr) & ~Attribute::NoAlias)
|
||||
return false;
|
||||
|
||||
@ -299,7 +299,7 @@ bool llvm::isInTailCallPosition(SelectionDAG &DAG, SDNode *Node,
|
||||
|
||||
// Conservatively require the attributes of the call to match those of
|
||||
// the return. Ignore noalias because it doesn't affect the call sequence.
|
||||
unsigned CallerRetAttr = F->getAttributes().getRetAttributes();
|
||||
Attributes CallerRetAttr = F->getAttributes().getRetAttributes();
|
||||
if (CallerRetAttr & ~Attribute::NoAlias)
|
||||
return false;
|
||||
|
||||
|
@ -1063,7 +1063,7 @@ bool InstCombiner::transformConstExprCastCall(CallSite CS) {
|
||||
if (!CastInst::isCastable(ActTy, ParamTy))
|
||||
return false; // Cannot transform this parameter value.
|
||||
|
||||
unsigned Attrs = CallerPAL.getParamAttributes(i + 1);
|
||||
Attributes Attrs = CallerPAL.getParamAttributes(i + 1);
|
||||
if (Attrs & Attribute::typeIncompatible(ParamTy))
|
||||
return false; // Attribute not compatible with transformed value.
|
||||
|
||||
@ -1392,4 +1392,3 @@ InstCombiner::transformCallThroughTrampoline(CallSite CS,
|
||||
CS.setCalledFunction(NewCallee);
|
||||
return CS.getInstruction();
|
||||
}
|
||||
|
||||
|
@ -619,7 +619,7 @@ bool CodeGenPrepare::DupRetToEnableTailCallOpts(ReturnInst *RI) {
|
||||
// It's not safe to eliminate the sign / zero extension of the return value.
|
||||
// See llvm::isInTailCallPosition().
|
||||
const Function *F = BB->getParent();
|
||||
unsigned CallerRetAttr = F->getAttributes().getRetAttributes();
|
||||
Attributes CallerRetAttr = F->getAttributes().getRetAttributes();
|
||||
if ((CallerRetAttr & Attribute::ZExt) || (CallerRetAttr & Attribute::SExt))
|
||||
return false;
|
||||
|
||||
@ -674,7 +674,7 @@ bool CodeGenPrepare::DupRetToEnableTailCallOpts(ReturnInst *RI) {
|
||||
|
||||
// Conservatively require the attributes of the call to match those of the
|
||||
// return. Ignore noalias because it doesn't affect the call sequence.
|
||||
unsigned CalleeRetAttr = CS.getAttributes().getRetAttributes();
|
||||
Attributes CalleeRetAttr = CS.getAttributes().getRetAttributes();
|
||||
if ((CalleeRetAttr ^ CallerRetAttr) & ~Attribute::NoAlias)
|
||||
continue;
|
||||
|
||||
|
@ -76,6 +76,8 @@ std::string Attribute::getAsString(Attributes Attrs) {
|
||||
Result += "naked ";
|
||||
if (Attrs & Attribute::NonLazyBind)
|
||||
Result += "nonlazybind ";
|
||||
if (Attrs & Attribute::AddressSafety)
|
||||
Result += "address_safety ";
|
||||
if (Attrs & Attribute::StackAlignment) {
|
||||
Result += "alignstack(";
|
||||
Result += utostr(Attribute::getStackAlignmentFromAttrs(Attrs));
|
||||
@ -152,8 +154,10 @@ public:
|
||||
}
|
||||
static void Profile(FoldingSetNodeID &ID, const AttributeWithIndex *Attr,
|
||||
unsigned NumAttrs) {
|
||||
for (unsigned i = 0; i != NumAttrs; ++i)
|
||||
ID.AddInteger(uint64_t(Attr[i].Attrs) << 32 | unsigned(Attr[i].Index));
|
||||
for (unsigned i = 0; i != NumAttrs; ++i) {
|
||||
ID.AddInteger(Attr[i].Attrs.Raw());
|
||||
ID.AddInteger(Attr[i].Index);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
@ -13,6 +13,7 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "llvm-c/Core.h"
|
||||
#include "llvm/Attributes.h"
|
||||
#include "llvm/Bitcode/ReaderWriter.h"
|
||||
#include "llvm/Constants.h"
|
||||
#include "llvm/DerivedTypes.h"
|
||||
@ -1350,14 +1351,14 @@ void LLVMSetGC(LLVMValueRef Fn, const char *GC) {
|
||||
void LLVMAddFunctionAttr(LLVMValueRef Fn, LLVMAttribute PA) {
|
||||
Function *Func = unwrap<Function>(Fn);
|
||||
const AttrListPtr PAL = Func->getAttributes();
|
||||
const AttrListPtr PALnew = PAL.addAttr(~0U, PA);
|
||||
const AttrListPtr PALnew = PAL.addAttr(~0U, Attributes(PA));
|
||||
Func->setAttributes(PALnew);
|
||||
}
|
||||
|
||||
void LLVMRemoveFunctionAttr(LLVMValueRef Fn, LLVMAttribute PA) {
|
||||
Function *Func = unwrap<Function>(Fn);
|
||||
const AttrListPtr PAL = Func->getAttributes();
|
||||
const AttrListPtr PALnew = PAL.removeAttr(~0U, PA);
|
||||
const AttrListPtr PALnew = PAL.removeAttr(~0U, Attributes(PA));
|
||||
Func->setAttributes(PALnew);
|
||||
}
|
||||
|
||||
@ -1365,7 +1366,7 @@ LLVMAttribute LLVMGetFunctionAttr(LLVMValueRef Fn) {
|
||||
Function *Func = unwrap<Function>(Fn);
|
||||
const AttrListPtr PAL = Func->getAttributes();
|
||||
Attributes attr = PAL.getFnAttributes();
|
||||
return (LLVMAttribute)attr;
|
||||
return (LLVMAttribute)attr.Raw();
|
||||
}
|
||||
|
||||
/*--.. Operations on parameters ............................................--*/
|
||||
@ -1427,18 +1428,18 @@ LLVMValueRef LLVMGetPreviousParam(LLVMValueRef Arg) {
|
||||
}
|
||||
|
||||
void LLVMAddAttribute(LLVMValueRef Arg, LLVMAttribute PA) {
|
||||
unwrap<Argument>(Arg)->addAttr(PA);
|
||||
unwrap<Argument>(Arg)->addAttr(Attributes(PA));
|
||||
}
|
||||
|
||||
void LLVMRemoveAttribute(LLVMValueRef Arg, LLVMAttribute PA) {
|
||||
unwrap<Argument>(Arg)->removeAttr(PA);
|
||||
unwrap<Argument>(Arg)->removeAttr(Attributes(PA));
|
||||
}
|
||||
|
||||
LLVMAttribute LLVMGetAttribute(LLVMValueRef Arg) {
|
||||
Argument *A = unwrap<Argument>(Arg);
|
||||
Attributes attr = A->getParent()->getAttributes().getParamAttributes(
|
||||
A->getArgNo()+1);
|
||||
return (LLVMAttribute)attr;
|
||||
return (LLVMAttribute)attr.Raw();
|
||||
}
|
||||
|
||||
|
||||
@ -1635,14 +1636,14 @@ void LLVMAddInstrAttribute(LLVMValueRef Instr, unsigned index,
|
||||
LLVMAttribute PA) {
|
||||
CallSite Call = CallSite(unwrap<Instruction>(Instr));
|
||||
Call.setAttributes(
|
||||
Call.getAttributes().addAttr(index, PA));
|
||||
Call.getAttributes().addAttr(index, Attributes(PA)));
|
||||
}
|
||||
|
||||
void LLVMRemoveInstrAttribute(LLVMValueRef Instr, unsigned index,
|
||||
LLVMAttribute PA) {
|
||||
CallSite Call = CallSite(unwrap<Instruction>(Instr));
|
||||
Call.setAttributes(
|
||||
Call.getAttributes().removeAttr(index, PA));
|
||||
Call.getAttributes().removeAttr(index, Attributes(PA)));
|
||||
}
|
||||
|
||||
void LLVMSetInstrParamAlignment(LLVMValueRef Instr, unsigned index,
|
||||
|
@ -547,7 +547,7 @@ void Verifier::VerifyParameterAttrs(Attributes Attrs, Type *Ty,
|
||||
for (unsigned i = 0;
|
||||
i < array_lengthof(Attribute::MutuallyIncompatible); ++i) {
|
||||
Attributes MutI = Attrs & Attribute::MutuallyIncompatible[i];
|
||||
Assert1(!(MutI & (MutI - 1)), "Attributes " +
|
||||
Assert1(MutI.isEmptyOrSingleton(), "Attributes " +
|
||||
Attribute::getAsString(MutI) + " are incompatible!", V);
|
||||
}
|
||||
|
||||
@ -607,7 +607,7 @@ void Verifier::VerifyFunctionAttrs(FunctionType *FT,
|
||||
for (unsigned i = 0;
|
||||
i < array_lengthof(Attribute::MutuallyIncompatible); ++i) {
|
||||
Attributes MutI = FAttrs & Attribute::MutuallyIncompatible[i];
|
||||
Assert1(!(MutI & (MutI - 1)), "Attributes " +
|
||||
Assert1(MutI.isEmptyOrSingleton(), "Attributes " +
|
||||
Attribute::getAsString(MutI) + " are incompatible!", V);
|
||||
}
|
||||
}
|
||||
|
@ -174,6 +174,7 @@ FuncAttr ::= noreturn
|
||||
| sspreq
|
||||
| returns_twice
|
||||
| nonlazybind
|
||||
| address_safety
|
||||
;
|
||||
|
||||
OptFuncAttrs ::= + _ | OptFuncAttrs FuncAttr ;
|
||||
|
Loading…
Reference in New Issue
Block a user