mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-07-23 14:25:07 +00:00
Move the 'FunctionOnly' attributes thingy inside of the Attributes class.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@165530 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@@ -110,14 +110,6 @@ DECLARE_LLVM_ATTRIBUTE(AddressSafety,1ULL<<32) ///< Address safety checking is o
|
|||||||
/// an exception might pass by.
|
/// an exception might pass by.
|
||||||
/// uwtable + nounwind = Needs an entry because the ABI says so.
|
/// uwtable + nounwind = Needs an entry because the ABI says so.
|
||||||
|
|
||||||
/// @brief Attributes that may be applied to the function itself. These cannot
|
|
||||||
/// be used on return values or function parameters.
|
|
||||||
const AttrConst FunctionOnly = {NoReturn_i | NoUnwind_i | ReadNone_i |
|
|
||||||
ReadOnly_i | NoInline_i | AlwaysInline_i | OptimizeForSize_i |
|
|
||||||
StackProtect_i | StackProtectReq_i | NoRedZone_i | NoImplicitFloat_i |
|
|
||||||
Naked_i | InlineHint_i | StackAlignment_i |
|
|
||||||
UWTable_i | NonLazyBind_i | ReturnsTwice_i | AddressSafety_i};
|
|
||||||
|
|
||||||
/// @brief Attributes that are mutually incompatible.
|
/// @brief Attributes that are mutually incompatible.
|
||||||
const AttrConst MutuallyIncompatible[5] = {
|
const AttrConst MutuallyIncompatible[5] = {
|
||||||
{ByVal_i | Nest_i | StructRet_i},
|
{ByVal_i | Nest_i | StructRet_i},
|
||||||
@@ -138,39 +130,39 @@ class Attributes {
|
|||||||
public:
|
public:
|
||||||
enum AttrVal {
|
enum AttrVal {
|
||||||
None = 0, ///< No attributes have been set
|
None = 0, ///< No attributes have been set
|
||||||
ZExt = 1, ///< Zero extended before/after call
|
AddressSafety = 1, ///< Address safety checking is on.
|
||||||
SExt = 2, ///< Sign extended before/after call
|
Alignment = 2, ///< Alignment of parameter (5 bits)
|
||||||
NoReturn = 3, ///< Mark the function as not returning
|
|
||||||
InReg = 4, ///< Force argument to be passed in register
|
|
||||||
StructRet = 5, ///< Hidden pointer to structure to return
|
|
||||||
NoUnwind = 6, ///< Function doesn't unwind stack
|
|
||||||
NoAlias = 7, ///< Considered to not alias after call
|
|
||||||
ByVal = 8, ///< Pass structure by value
|
|
||||||
Nest = 9, ///< Nested function static chain
|
|
||||||
ReadNone = 10, ///< Function does not access memory
|
|
||||||
ReadOnly = 11, ///< Function only reads from memory
|
|
||||||
NoInline = 12, ///< inline=never
|
|
||||||
AlwaysInline = 13, ///< inline=always
|
|
||||||
OptimizeForSize = 14, ///< opt_size
|
|
||||||
StackProtect = 15, ///< Stack protection.
|
|
||||||
StackProtectReq = 16, ///< Stack protection required.
|
|
||||||
Alignment = 17, ///< Alignment of parameter (5 bits)
|
|
||||||
///< stored as log2 of alignment with +1 bias
|
///< stored as log2 of alignment with +1 bias
|
||||||
///< 0 means unaligned different from align 1
|
///< 0 means unaligned different from align 1
|
||||||
NoCapture = 18, ///< Function creates no aliases of pointer
|
AlwaysInline = 3, ///< inline=always
|
||||||
NoRedZone = 19, ///< Disable redzone
|
ByVal = 4, ///< Pass structure by value
|
||||||
NoImplicitFloat = 20, ///< Disable implicit floating point insts
|
InlineHint = 5, ///< Source said inlining was desirable
|
||||||
Naked = 21, ///< Naked function
|
InReg = 6, ///< Force argument to be passed in register
|
||||||
InlineHint = 22, ///< Source said inlining was desirable
|
Naked = 7, ///< Naked function
|
||||||
StackAlignment = 23, ///< Alignment of stack for function (3 bits)
|
Nest = 8, ///< Nested function static chain
|
||||||
|
NoAlias = 9, ///< Considered to not alias after call
|
||||||
|
NoCapture = 10, ///< Function creates no aliases of pointer
|
||||||
|
NoImplicitFloat = 11, ///< Disable implicit floating point insts
|
||||||
|
NoInline = 12, ///< inline=never
|
||||||
|
NonLazyBind = 13, ///< Function is called early and/or
|
||||||
|
///< often, so lazy binding isn't worthwhile
|
||||||
|
NoRedZone = 14, ///< Disable redzone
|
||||||
|
NoReturn = 15, ///< Mark the function as not returning
|
||||||
|
NoUnwind = 16, ///< Function doesn't unwind stack
|
||||||
|
OptimizeForSize = 17, ///< opt_size
|
||||||
|
ReadNone = 18, ///< Function does not access memory
|
||||||
|
ReadOnly = 19, ///< Function only reads from memory
|
||||||
|
ReturnsTwice = 20, ///< Function can return twice
|
||||||
|
SExt = 21, ///< Sign extended before/after call
|
||||||
|
StackAlignment = 22, ///< Alignment of stack for function (3 bits)
|
||||||
///< stored as log2 of alignment with +1 bias 0
|
///< stored as log2 of alignment with +1 bias 0
|
||||||
///< means unaligned (different from
|
///< means unaligned (different from
|
||||||
///< alignstack={1))
|
///< alignstack={1))
|
||||||
ReturnsTwice = 24, ///< Function can return twice
|
StackProtect = 23, ///< Stack protection.
|
||||||
UWTable = 25, ///< Function must be in a unwind table
|
StackProtectReq = 24, ///< Stack protection required.
|
||||||
NonLazyBind = 26, ///< Function is called early and/or
|
StructRet = 25, ///< Hidden pointer to structure to return
|
||||||
///< often, so lazy binding isn't worthwhile
|
UWTable = 26, ///< Function must be in a unwind table
|
||||||
AddressSafety = 27 ///< Address safety checking is on.
|
ZExt = 27 ///< Zero extended before/after call
|
||||||
};
|
};
|
||||||
private:
|
private:
|
||||||
AttributesImpl Attrs;
|
AttributesImpl Attrs;
|
||||||
@@ -197,13 +189,35 @@ public:
|
|||||||
|
|
||||||
uint64_t getAlignment() const;
|
uint64_t getAlignment() const;
|
||||||
|
|
||||||
void addAttribute(Attributes::AttrVal Val);
|
Builder &addAttribute(Attributes::AttrVal Val);
|
||||||
void removeAttribute(Attributes::AttrVal Val);
|
Builder &removeAttribute(Attributes::AttrVal Val);
|
||||||
|
|
||||||
void addAlignmentAttr(unsigned Align);
|
void addAlignmentAttr(unsigned Align);
|
||||||
void addStackAlignmentAttr(unsigned Align);
|
void addStackAlignmentAttr(unsigned Align);
|
||||||
|
|
||||||
void removeAttributes(const Attributes &A);
|
void removeAttributes(const Attributes &A);
|
||||||
|
|
||||||
|
/// @brief Remove attributes that are used on functions only.
|
||||||
|
void removeFunctionOnlyAttrs() {
|
||||||
|
removeAttribute(Attributes::NoReturn)
|
||||||
|
.removeAttribute(Attributes::NoUnwind)
|
||||||
|
.removeAttribute(Attributes::ReadNone)
|
||||||
|
.removeAttribute(Attributes::ReadOnly)
|
||||||
|
.removeAttribute(Attributes::NoInline)
|
||||||
|
.removeAttribute(Attributes::AlwaysInline)
|
||||||
|
.removeAttribute(Attributes::OptimizeForSize)
|
||||||
|
.removeAttribute(Attributes::StackProtect)
|
||||||
|
.removeAttribute(Attributes::StackProtectReq)
|
||||||
|
.removeAttribute(Attributes::NoRedZone)
|
||||||
|
.removeAttribute(Attributes::NoImplicitFloat)
|
||||||
|
.removeAttribute(Attributes::Naked)
|
||||||
|
.removeAttribute(Attributes::InlineHint)
|
||||||
|
.removeAttribute(Attributes::StackAlignment)
|
||||||
|
.removeAttribute(Attributes::UWTable)
|
||||||
|
.removeAttribute(Attributes::NonLazyBind)
|
||||||
|
.removeAttribute(Attributes::ReturnsTwice)
|
||||||
|
.removeAttribute(Attributes::AddressSafety);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/// get - Return a uniquified Attributes object. This takes the uniquified
|
/// get - Return a uniquified Attributes object. This takes the uniquified
|
||||||
@@ -243,6 +257,29 @@ public:
|
|||||||
hasAttribute(Attributes::NoCapture);
|
hasAttribute(Attributes::NoCapture);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// @brief Attributes that may be applied to the function itself. These cannot
|
||||||
|
/// be used on return values or function parameters.
|
||||||
|
bool hasFunctionOnlyAttrs() const {
|
||||||
|
return hasAttribute(Attributes::NoReturn) ||
|
||||||
|
hasAttribute(Attributes::NoUnwind) ||
|
||||||
|
hasAttribute(Attributes::ReadNone) ||
|
||||||
|
hasAttribute(Attributes::ReadOnly) ||
|
||||||
|
hasAttribute(Attributes::NoInline) ||
|
||||||
|
hasAttribute(Attributes::AlwaysInline) ||
|
||||||
|
hasAttribute(Attributes::OptimizeForSize) ||
|
||||||
|
hasAttribute(Attributes::StackProtect) ||
|
||||||
|
hasAttribute(Attributes::StackProtectReq) ||
|
||||||
|
hasAttribute(Attributes::NoRedZone) ||
|
||||||
|
hasAttribute(Attributes::NoImplicitFloat) ||
|
||||||
|
hasAttribute(Attributes::Naked) ||
|
||||||
|
hasAttribute(Attributes::InlineHint) ||
|
||||||
|
hasAttribute(Attributes::StackAlignment) ||
|
||||||
|
hasAttribute(Attributes::UWTable) ||
|
||||||
|
hasAttribute(Attributes::NonLazyBind) ||
|
||||||
|
hasAttribute(Attributes::ReturnsTwice) ||
|
||||||
|
hasAttribute(Attributes::AddressSafety);
|
||||||
|
}
|
||||||
|
|
||||||
bool isEmptyOrSingleton() const;
|
bool isEmptyOrSingleton() const;
|
||||||
|
|
||||||
// This is a "safe bool() operator".
|
// This is a "safe bool() operator".
|
||||||
|
@@ -120,20 +120,18 @@ uint64_t Attributes::Raw() const {
|
|||||||
Attributes Attributes::typeIncompatible(Type *Ty) {
|
Attributes Attributes::typeIncompatible(Type *Ty) {
|
||||||
Attributes::Builder Incompatible;
|
Attributes::Builder Incompatible;
|
||||||
|
|
||||||
if (!Ty->isIntegerTy()) {
|
if (!Ty->isIntegerTy())
|
||||||
// Attributes that only apply to integers.
|
// Attributes that only apply to integers.
|
||||||
Incompatible.addAttribute(Attributes::SExt);
|
Incompatible.addAttribute(Attributes::SExt)
|
||||||
Incompatible.addAttribute(Attributes::ZExt);
|
.addAttribute(Attributes::ZExt);
|
||||||
}
|
|
||||||
|
|
||||||
if (!Ty->isPointerTy()) {
|
if (!Ty->isPointerTy())
|
||||||
// Attributes that only apply to pointers.
|
// Attributes that only apply to pointers.
|
||||||
Incompatible.addAttribute(Attributes::ByVal);
|
Incompatible.addAttribute(Attributes::ByVal)
|
||||||
Incompatible.addAttribute(Attributes::Nest);
|
.addAttribute(Attributes::Nest)
|
||||||
Incompatible.addAttribute(Attributes::NoAlias);
|
.addAttribute(Attributes::NoAlias)
|
||||||
Incompatible.addAttribute(Attributes::NoCapture);
|
.addAttribute(Attributes::NoCapture)
|
||||||
Incompatible.addAttribute(Attributes::StructRet);
|
.addAttribute(Attributes::StructRet);
|
||||||
}
|
|
||||||
|
|
||||||
return Attributes(Incompatible.Bits); // FIXME: Use Attributes::get().
|
return Attributes(Incompatible.Bits); // FIXME: Use Attributes::get().
|
||||||
}
|
}
|
||||||
@@ -210,8 +208,10 @@ std::string Attributes::getAsString() const {
|
|||||||
// Attributes::Builder Implementation
|
// Attributes::Builder Implementation
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
void Attributes::Builder::addAttribute(Attributes::AttrVal Val) {
|
Attributes::Builder &Attributes::Builder::
|
||||||
|
addAttribute(Attributes::AttrVal Val) {
|
||||||
Bits |= AttributesImpl::getAttrMask(Val);
|
Bits |= AttributesImpl::getAttrMask(Val);
|
||||||
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Attributes::Builder::addAlignmentAttr(unsigned Align) {
|
void Attributes::Builder::addAlignmentAttr(unsigned Align) {
|
||||||
@@ -228,8 +228,10 @@ void Attributes::Builder::addStackAlignmentAttr(unsigned Align) {
|
|||||||
Bits |= (Log2_32(Align) + 1) << 26;
|
Bits |= (Log2_32(Align) + 1) << 26;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Attributes::Builder::removeAttribute(Attributes::AttrVal Val) {
|
Attributes::Builder &Attributes::Builder::
|
||||||
|
removeAttribute(Attributes::AttrVal Val) {
|
||||||
Bits &= ~AttributesImpl::getAttrMask(Val);
|
Bits &= ~AttributesImpl::getAttrMask(Val);
|
||||||
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Attributes::Builder::removeAttributes(const Attributes &A) {
|
void Attributes::Builder::removeAttributes(const Attributes &A) {
|
||||||
|
@@ -529,9 +529,9 @@ void Verifier::VerifyParameterAttrs(Attributes Attrs, Type *Ty,
|
|||||||
if (!Attrs.hasAttributes())
|
if (!Attrs.hasAttributes())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
Attributes FnCheckAttr = Attrs & Attribute::FunctionOnly;
|
Assert1(!Attrs.hasFunctionOnlyAttrs(),
|
||||||
Assert1(!FnCheckAttr, "Attribute " + FnCheckAttr.getAsString() +
|
"Some attributes in '" + Attrs.getAsString() +
|
||||||
" only applies to the function!", V);
|
"' only apply to functions!", V);
|
||||||
|
|
||||||
if (isReturnValue)
|
if (isReturnValue)
|
||||||
Assert1(!Attrs.hasParameterOnlyAttrs(),
|
Assert1(!Attrs.hasParameterOnlyAttrs(),
|
||||||
@@ -541,8 +541,8 @@ void Verifier::VerifyParameterAttrs(Attributes Attrs, Type *Ty,
|
|||||||
for (unsigned i = 0;
|
for (unsigned i = 0;
|
||||||
i < array_lengthof(Attribute::MutuallyIncompatible); ++i) {
|
i < array_lengthof(Attribute::MutuallyIncompatible); ++i) {
|
||||||
Attributes MutI = Attrs & Attribute::MutuallyIncompatible[i];
|
Attributes MutI = Attrs & Attribute::MutuallyIncompatible[i];
|
||||||
Assert1(MutI.isEmptyOrSingleton(), "Attributes " +
|
Assert1(MutI.isEmptyOrSingleton(), "Attributes '" +
|
||||||
MutI.getAsString() + " are incompatible!", V);
|
MutI.getAsString() + "' are incompatible!", V);
|
||||||
}
|
}
|
||||||
|
|
||||||
Attributes TypeI = Attrs & Attributes::typeIncompatible(Ty);
|
Attributes TypeI = Attrs & Attributes::typeIncompatible(Ty);
|
||||||
@@ -592,9 +592,11 @@ void Verifier::VerifyFunctionAttrs(FunctionType *FT,
|
|||||||
}
|
}
|
||||||
|
|
||||||
Attributes FAttrs = Attrs.getFnAttributes();
|
Attributes FAttrs = Attrs.getFnAttributes();
|
||||||
Attributes NotFn = FAttrs & (~Attribute::FunctionOnly);
|
Attributes::Builder NotFn(FAttrs);
|
||||||
Assert1(!NotFn, "Attribute " + NotFn.getAsString() +
|
NotFn.removeFunctionOnlyAttrs();
|
||||||
" does not apply to the function!", V);
|
Assert1(!NotFn.hasAttributes(), "Attributes '" +
|
||||||
|
Attributes::get(NotFn).getAsString() +
|
||||||
|
"' do not apply to the function!", V);
|
||||||
|
|
||||||
for (unsigned i = 0;
|
for (unsigned i = 0;
|
||||||
i < array_lengthof(Attribute::MutuallyIncompatible); ++i) {
|
i < array_lengthof(Attribute::MutuallyIncompatible); ++i) {
|
||||||
|
Reference in New Issue
Block a user