/// Attributes - A bitset of attributes.
class Attributes {
+public:
+ enum AttrVal {
+ None = 0, ///< No attributes have been set
+ ZExt = 1, ///< Zero extended before/after call
+ SExt = 2, ///< Sign extended before/after call
+ 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
+ ///< 0 means unaligned different from align 1
+ NoCapture = 18, ///< Function creates no aliases of pointer
+ NoRedZone = 19, ///< Disable redzone
+ NoImplicitFloat = 20, ///< Disable implicit floating point insts
+ Naked = 21, ///< Naked function
+ InlineHint = 22, ///< Source said inlining was desirable
+ StackAlignment = 23, ///< Alignment of stack for function (3 bits)
+ ///< stored as log2 of alignment with +1 bias 0
+ ///< means unaligned (different from
+ ///< alignstack={1))
+ ReturnsTwice = 24, ///< Function can return twice
+ UWTable = 25, ///< Function must be in a unwind table
+ NonLazyBind = 26, ///< Function is called early and/or
+ ///< often, so lazy binding isn't worthwhile
+ AddressSafety = 27 ///< Address safety checking is on.
+ };
+private:
// Currently, we need less than 64 bits.
AttributesImpl Attrs;
+
explicit Attributes(AttributesImpl *A);
public:
Attributes() : Attrs(0) {}
/// @brief Parameter attributes that do not apply to vararg call arguments.
bool hasIncompatibleWithVarArgsAttrs() const {
- return hasStructRetAttr();
+ return hasAttribute(Attributes::StructRet);
}
// Attribute query methods.
return Attrs.hasAttributes();
}
bool hasAttributes(const Attributes &A) const;
- bool hasAddressSafetyAttr() const;
- bool hasAlignmentAttr() const;
- bool hasAlwaysInlineAttr() const;
- bool hasByValAttr() const;
- bool hasInRegAttr() const;
- bool hasInlineHintAttr() const;
- bool hasNakedAttr() const;
- bool hasNestAttr() const;
- bool hasNoAliasAttr() const;
- bool hasNoCaptureAttr() const;
- bool hasNoImplicitFloatAttr() const;
- bool hasNoInlineAttr() const;
- bool hasNonLazyBindAttr() const;
- bool hasNoRedZoneAttr() const;
- bool hasNoReturnAttr() const;
- bool hasNoUnwindAttr() const;
- bool hasOptimizeForSizeAttr() const;
- bool hasReadNoneAttr() const;
- bool hasReadOnlyAttr() const;
- bool hasReturnsTwiceAttr() const;
- bool hasSExtAttr() const;
- bool hasStackAlignmentAttr() const;
- bool hasStackProtectAttr() const;
- bool hasStackProtectReqAttr() const;
- bool hasStructRetAttr() const;
- bool hasUWTableAttr() const;
- bool hasZExtAttr() const;
+ bool hasAttribute(AttrVal Val) const;
/// This returns the alignment field of an attribute as a byte alignment
/// value.
// 5-bit log2 encoded value. Shift the bits above the alignment up by 11
// bits.
uint64_t EncodedAttrs = Attrs.Raw() & 0xffff;
- if (Attrs.hasAlignmentAttr())
+ if (Attrs.hasAttribute(Attributes::Alignment))
EncodedAttrs |= (1ULL << 16) <<
(((Attrs.Raw() & Attribute::Alignment_i) - 1) >> 16);
EncodedAttrs |= (Attrs.Raw() & (0xfffULL << 21)) << 11;
class AttributesImpl : public FoldingSetNode {
friend class Attributes;
-
uint64_t Bits; // FIXME: We will be expanding this.
+
+ uint64_t getAttrMask(uint64_t Val) const;
public:
AttributesImpl(uint64_t bits) : Bits(bits) {}
bool hasAttribute(uint64_t A) const;
+
bool hasAttributes() const;
bool hasAttributes(const Attributes &A) const;
/// @brief Determine if the function does not access memory.
bool doesNotAccessMemory() const {
- return getFnAttributes().hasReadNoneAttr();
+ return getFnAttributes().hasAttribute(Attributes::ReadNone);
}
void setDoesNotAccessMemory(bool DoesNotAccessMemory = true) {
if (DoesNotAccessMemory) addFnAttr(Attribute::ReadNone);
/// @brief Determine if the function does not access or only reads memory.
bool onlyReadsMemory() const {
- return doesNotAccessMemory() || getFnAttributes().hasReadOnlyAttr();
+ return doesNotAccessMemory() ||
+ getFnAttributes().hasAttribute(Attributes::ReadOnly);
}
void setOnlyReadsMemory(bool OnlyReadsMemory = true) {
if (OnlyReadsMemory) addFnAttr(Attribute::ReadOnly);
/// @brief Determine if the function cannot return.
bool doesNotReturn() const {
- return getFnAttributes().hasNoReturnAttr();
+ return getFnAttributes().hasAttribute(Attributes::NoReturn);
}
void setDoesNotReturn(bool DoesNotReturn = true) {
if (DoesNotReturn) addFnAttr(Attribute::NoReturn);
/// @brief Determine if the function cannot unwind.
bool doesNotThrow() const {
- return getFnAttributes().hasNoUnwindAttr();
+ return getFnAttributes().hasAttribute(Attributes::NoUnwind);
}
void setDoesNotThrow(bool DoesNotThrow = true) {
if (DoesNotThrow) addFnAttr(Attribute::NoUnwind);
/// @brief True if the ABI mandates (or the user requested) that this
/// function be in a unwind table.
bool hasUWTable() const {
- return getFnAttributes().hasUWTableAttr();
+ return getFnAttributes().hasAttribute(Attributes::UWTable);
}
void setHasUWTable(bool HasUWTable = true) {
if (HasUWTable)
/// @brief Determine if the function returns a structure through first
/// pointer argument.
bool hasStructRetAttr() const {
- return getParamAttributes(1).hasStructRetAttr();
+ return getParamAttributes(1).hasAttribute(Attributes::StructRet);
}
/// @brief Determine if the parameter does not alias other parameters.
/// @param n The parameter to check. 1 is the first parameter, 0 is the return
bool doesNotAlias(unsigned n) const {
- return n != 0 ? getParamAttributes(n).hasNoAliasAttr() :
- AttributeList.getRetAttributes().hasNoAliasAttr();
+ return getParamAttributes(n).hasAttribute(Attributes::NoAlias);
}
void setDoesNotAlias(unsigned n, bool DoesNotAlias = true) {
if (DoesNotAlias) addAttribute(n, Attribute::NoAlias);
/// @brief Determine if the parameter can be captured.
/// @param n The parameter to check. 1 is the first parameter, 0 is the return
bool doesNotCapture(unsigned n) const {
- return getParamAttributes(n).hasNoCaptureAttr();
+ return getParamAttributes(n).hasAttribute(Attributes::NoCapture);
}
void setDoesNotCapture(unsigned n, bool DoesNotCapture = true) {
if (DoesNotCapture) addAttribute(n, Attribute::NoCapture);
/// @brief Determine if any call argument is an aggregate passed by value.
bool hasByValArgument() const {
for (unsigned I = 0, E = AttributeList.getNumAttrs(); I != E; ++I)
- if (AttributeList.getAttributesAtIndex(I).hasByValAttr())
+ if (AttributeList.getAttributesAtIndex(I).hasAttribute(Attributes::ByVal))
return true;
return false;
}
/// @brief Determine if any call argument is an aggregate passed by value.
bool hasByValArgument() const {
for (unsigned I = 0, E = AttributeList.getNumAttrs(); I != E; ++I)
- if (AttributeList.getAttributesAtIndex(I).hasByValAttr())
+ if (AttributeList.getAttributesAtIndex(I).hasAttribute(Attributes::ByVal))
return true;
return false;
}
// as volatile if they are live across a setjmp call, and they probably
// won't do this in callers.
exposesReturnsTwice = F->callsFunctionThatReturnsTwice() &&
- !F->getFnAttributes().hasReturnsTwiceAttr();
+ !F->getFnAttributes().hasAttribute(Attributes::ReturnsTwice);
// Look at the size of the callee.
for (Function::const_iterator BB = F->begin(), E = F->end(); BB != E; ++BB)
public:
CallAnalyzer(const DataLayout *TD, Function &Callee, int Threshold)
: TD(TD), F(Callee), Threshold(Threshold), Cost(0),
- AlwaysInline(F.getFnAttributes().hasAlwaysInlineAttr()),
+ AlwaysInline(F.getFnAttributes().hasAttribute(Attributes::AlwaysInline)),
IsCallerRecursive(false), IsRecursiveCall(false),
ExposesReturnsTwice(false), HasDynamicAlloca(false), AllocatedSize(0),
NumInstructions(0), NumVectorInstructions(0),
bool CallAnalyzer::visitCallSite(CallSite CS) {
if (CS.isCall() && cast<CallInst>(CS.getInstruction())->canReturnTwice() &&
- !F.getFnAttributes().hasReturnsTwiceAttr()) {
+ !F.getFnAttributes().hasAttribute(Attributes::ReturnsTwice)) {
// This aborts the entire analysis.
ExposesReturnsTwice = true;
return false;
// something else. Don't inline functions marked noinline or call sites
// marked noinline.
if (!Callee || Callee->mayBeOverridden() ||
- Callee->getFnAttributes().hasNoInlineAttr() || CS.isNoInline())
+ Callee->getFnAttributes().hasAttribute(Attributes::NoInline) ||
+ CS.isNoInline())
return llvm::InlineCost::getNever();
DEBUG(llvm::dbgs() << " Analyzing call of " << Callee->getName()
return 0;
if (LIOffs+NewLoadByteSize > MemLocEnd &&
- LI->getParent()->getParent()->getFnAttributes().hasAddressSafetyAttr()){
+ LI->getParent()->getParent()->getFnAttributes().
+ hasAttribute(Attributes::AddressSafety))
// We will be reading past the location accessed by the original program.
// While this is safe in a regular build, Address Safety analysis tools
// may start reporting false warnings. So, don't do widening.
return 0;
- }
// If a load of this width would include all of MemLoc, then we succeed.
if (LIOffs+NewLoadByteSize >= MemLocEnd)
AttrListPtr PAL = AttrListPtr::get(Attrs);
- if (PAL.getParamAttributes(1).hasStructRetAttr() && !RetType->isVoidTy())
+ if (PAL.getParamAttributes(1).hasAttribute(Attributes::StructRet) &&
+ !RetType->isVoidTy())
return Error(RetTypeLoc, "functions with 'sret' argument must return void");
FunctionType *FT =
return false;
// It's not safe to eliminate the sign / zero extension of the return value.
- if (CallerRetAttr.hasZExtAttr() || CallerRetAttr.hasSExtAttr())
+ if (CallerRetAttr.hasAttribute(Attributes::ZExt) ||
+ CallerRetAttr.hasAttribute(Attributes::SExt))
return false;
// Otherwise, make sure the unmodified return value of I is the return value.
return false;
// It's not safe to eliminate the sign / zero extension of the return value.
- if (CallerRetAttr.hasZExtAttr() || CallerRetAttr.hasSExtAttr())
+ if (CallerRetAttr.hasAttribute(Attributes::ZExt) ||
+ CallerRetAttr.hasAttribute(Attributes::SExt))
return false;
// Check if the only use is a function return node.
// instructions that would be deleted in the merge.
MachineFunction *MF = MBB1->getParent();
if (EffectiveTailLen >= 2 &&
- MF->getFunction()->getFnAttributes().hasOptimizeForSizeAttr() &&
+ MF->getFunction()->getFnAttributes().
+ hasAttribute(Attributes::OptimizeForSize) &&
(I1 == MBB1->begin() || I2 == MBB2->begin()))
return true;
///
bool CodePlacementOpt::AlignLoops(MachineFunction &MF) {
const Function *F = MF.getFunction();
- if (F->getFnAttributes().hasOptimizeForSizeAttr())
+ if (F->getFnAttributes().hasAttribute(Attributes::OptimizeForSize))
return false;
unsigned Align = TLI->getPrefLoopAlignment();
// exclusively on the loop info here so that we can align backedges in
// unnatural CFGs and backedges that were introduced purely because of the
// loop rotations done during this layout pass.
- if (F.getFunction()->getFnAttributes().hasOptimizeForSizeAttr())
+ if (F.getFunction()->getFnAttributes().
+ hasAttribute(Attributes::OptimizeForSize))
return;
unsigned Align = TLI->getPrefLoopAlignment();
if (!Align)
RegInfo = 0;
MFInfo = 0;
FrameInfo = new (Allocator) MachineFrameInfo(*TM.getFrameLowering());
- if (Fn->getFnAttributes().hasStackAlignmentAttr())
+ if (Fn->getFnAttributes().hasAttribute(Attributes::StackAlignment))
FrameInfo->ensureMaxAlignment(Fn->getAttributes().
getFnAttributes().getStackAlignment());
ConstantPool = new (Allocator) MachineConstantPool(TM.getDataLayout());
Alignment = TM.getTargetLowering()->getMinFunctionAlignment();
// FIXME: Shouldn't use pref alignment if explicit alignment is set on Fn.
- if (!Fn->getFnAttributes().hasOptimizeForSizeAttr())
+ if (!Fn->getFnAttributes().hasAttribute(Attributes::OptimizeForSize))
Alignment = std::max(Alignment,
TM.getTargetLowering()->getPrefFunctionAlignment());
FunctionNumber = FunctionNum;
placeCSRSpillsAndRestores(Fn);
// Add the code to save and restore the callee saved registers
- if (!F->getFnAttributes().hasNakedAttr())
+ if (!F->getFnAttributes().hasAttribute(Attributes::Naked))
insertCSRSpillsAndRestores(Fn);
// Allow the target machine to make final modifications to the function
// called functions. Because of this, calculateCalleeSavedRegisters()
// must be called before this function in order to set the AdjustsStack
// and MaxCallFrameSize variables.
- if (!F->getFnAttributes().hasNakedAttr())
+ if (!F->getFnAttributes().hasAttribute(Attributes::Naked))
insertPrologEpilogCode(Fn);
// Replace all MO_FrameIndex operands with physical register references
return;
// In Naked functions we aren't going to save any registers.
- if (Fn.getFunction()->getFnAttributes().hasNakedAttr())
+ if (Fn.getFunction()->getFnAttributes().hasAttribute(Attributes::Naked))
return;
std::vector<CalleeSavedInfo> CSI;
bool DstAlignCanChange = false;
MachineFunction &MF = DAG.getMachineFunction();
MachineFrameInfo *MFI = MF.getFrameInfo();
- bool OptSize = MF.getFunction()->getFnAttributes().hasOptimizeForSizeAttr();
+ bool OptSize =
+ MF.getFunction()->getFnAttributes().
+ hasAttribute(Attributes::OptimizeForSize);
FrameIndexSDNode *FI = dyn_cast<FrameIndexSDNode>(Dst);
if (FI && !MFI->isFixedObjectIndex(FI->getIndex()))
DstAlignCanChange = true;
bool DstAlignCanChange = false;
MachineFunction &MF = DAG.getMachineFunction();
MachineFrameInfo *MFI = MF.getFrameInfo();
- bool OptSize = MF.getFunction()->getFnAttributes().hasOptimizeForSizeAttr();
+ bool OptSize = MF.getFunction()->getFnAttributes().
+ hasAttribute(Attributes::OptimizeForSize);
FrameIndexSDNode *FI = dyn_cast<FrameIndexSDNode>(Dst);
if (FI && !MFI->isFixedObjectIndex(FI->getIndex()))
DstAlignCanChange = true;
bool DstAlignCanChange = false;
MachineFunction &MF = DAG.getMachineFunction();
MachineFrameInfo *MFI = MF.getFrameInfo();
- bool OptSize = MF.getFunction()->getFnAttributes().hasOptimizeForSizeAttr();
+ bool OptSize = MF.getFunction()->getFnAttributes().
+ hasAttribute(Attributes::OptimizeForSize);
FrameIndexSDNode *FI = dyn_cast<FrameIndexSDNode>(Dst);
if (FI && !MFI->isFixedObjectIndex(FI->getIndex()))
DstAlignCanChange = true;
ISD::NodeType ExtendKind = ISD::ANY_EXTEND;
const Function *F = I.getParent()->getParent();
- if (F->getRetAttributes().hasSExtAttr())
+ if (F->getRetAttributes().hasAttribute(Attributes::SExt))
ExtendKind = ISD::SIGN_EXTEND;
- else if (F->getRetAttributes().hasZExtAttr())
+ else if (F->getRetAttributes().hasAttribute(Attributes::ZExt))
ExtendKind = ISD::ZERO_EXTEND;
if (ExtendKind != ISD::ANY_EXTEND && VT.isInteger())
// 'inreg' on function refers to return value
ISD::ArgFlagsTy Flags = ISD::ArgFlagsTy();
- if (F->getRetAttributes().hasInRegAttr())
+ if (F->getRetAttributes().hasAttribute(Attributes::InReg))
Flags.setInReg();
// Propagate extension type if any
return DAG.getConstantFP(1.0, LHS.getValueType());
const Function *F = DAG.getMachineFunction().getFunction();
- if (!F->getFnAttributes().hasOptimizeForSizeAttr() ||
+ if (!F->getFnAttributes().hasAttribute(Attributes::OptimizeForSize) ||
// If optimizing for size, don't insert too many multiplies. This
// inserts up to 5 multiplies.
CountPopulation_32(Val)+Log2_32(Val) < 7) {
unsigned OriginalAlignment =
TD->getABITypeAlignment(ArgTy);
- if (F.getParamAttributes(Idx).hasZExtAttr())
+ if (F.getParamAttributes(Idx).hasAttribute(Attributes::ZExt))
Flags.setZExt();
- if (F.getParamAttributes(Idx).hasSExtAttr())
+ if (F.getParamAttributes(Idx).hasAttribute(Attributes::SExt))
Flags.setSExt();
- if (F.getParamAttributes(Idx).hasInRegAttr())
+ if (F.getParamAttributes(Idx).hasAttribute(Attributes::InReg))
Flags.setInReg();
- if (F.getParamAttributes(Idx).hasStructRetAttr())
+ if (F.getParamAttributes(Idx).hasAttribute(Attributes::StructRet))
Flags.setSRet();
- if (F.getParamAttributes(Idx).hasByValAttr()) {
+ if (F.getParamAttributes(Idx).hasAttribute(Attributes::ByVal)) {
Flags.setByVal();
PointerType *Ty = cast<PointerType>(I->getType());
Type *ElementTy = Ty->getElementType();
FrameAlign = TLI.getByValTypeAlignment(ElementTy);
Flags.setByValAlign(FrameAlign);
}
- if (F.getParamAttributes(Idx).hasNestAttr())
+ if (F.getParamAttributes(Idx).hasAttribute(Attributes::Nest))
Flags.setNest();
Flags.setOrigAlign(OriginalAlignment);
if (!I->use_empty()) {
ISD::NodeType AssertOp = ISD::DELETED_NODE;
- if (F.getParamAttributes(Idx).hasSExtAttr())
+ if (F.getParamAttributes(Idx).hasAttribute(Attributes::SExt))
AssertOp = ISD::AssertSext;
- else if (F.getParamAttributes(Idx).hasZExtAttr())
+ else if (F.getParamAttributes(Idx).hasAttribute(Attributes::ZExt))
AssertOp = ISD::AssertZext;
ArgValues.push_back(getCopyFromParts(DAG, dl, &InVals[i],
EVT VT = ValueVTs[j];
ISD::NodeType ExtendKind = ISD::ANY_EXTEND;
- if (attr.hasSExtAttr())
+ if (attr.hasAttribute(Attributes::SExt))
ExtendKind = ISD::SIGN_EXTEND;
- else if (attr.hasZExtAttr())
+ else if (attr.hasAttribute(Attributes::ZExt))
ExtendKind = ISD::ZERO_EXTEND;
// FIXME: C calling convention requires the return type to be promoted to
// 'inreg' on function refers to return value
ISD::ArgFlagsTy Flags = ISD::ArgFlagsTy();
- if (attr.hasInRegAttr())
+ if (attr.hasAttribute(Attributes::InReg))
Flags.setInReg();
// Propagate extension type if any
- if (attr.hasSExtAttr())
+ if (attr.hasAttribute(Attributes::SExt))
Flags.setSExt();
- else if (attr.hasZExtAttr())
+ else if (attr.hasAttribute(Attributes::ZExt))
Flags.setZExt();
for (unsigned i = 0; i < NumParts; ++i)
/// add a guard variable to functions that call alloca, and functions with
/// buffers larger than SSPBufferSize bytes.
bool StackProtector::RequiresStackProtector() const {
- if (F->getFnAttributes().hasStackProtectReqAttr())
+ if (F->getFnAttributes().hasAttribute(Attributes::StackProtectReq))
return true;
- if (!F->getFnAttributes().hasStackProtectAttr())
+ if (!F->getFnAttributes().hasAttribute(Attributes::StackProtect))
return false;
for (Function::iterator I = F->begin(), E = F->end(); I != E; ++I) {
// compensate for the duplication.
unsigned MaxDuplicateCount;
if (TailDuplicateSize.getNumOccurrences() == 0 &&
- MF.getFunction()->getFnAttributes().hasOptimizeForSizeAttr())
+ MF.getFunction()->getFnAttributes().
+ hasAttribute(Attributes::OptimizeForSize))
MaxDuplicateCount = 1;
else
MaxDuplicateCount = TailDuplicateSize;
// instructions).
if (Latency > 0 && Subtarget.isThumb2()) {
const MachineFunction *MF = DefMI->getParent()->getParent();
- if (MF->getFunction()->getFnAttributes().hasOptimizeForSizeAttr())
+ if (MF->getFunction()->getFnAttributes().
+ hasAttribute(Attributes::OptimizeForSize))
--Latency;
}
return Latency;
const MachineFrameInfo *MFI = MF.getFrameInfo();
const Function *F = MF.getFunction();
unsigned StackAlign = MF.getTarget().getFrameLowering()->getStackAlignment();
- bool requiresRealignment = ((MFI->getMaxAlignment() > StackAlign) ||
- F->getFnAttributes().hasStackAlignmentAttr());
+ bool requiresRealignment =
+ ((MFI->getMaxAlignment() > StackAlign) ||
+ F->getFnAttributes().hasAttribute(Attributes::StackAlignment));
return requiresRealignment && canRealignStack(MF);
}
return;
// Naked functions don't spill callee-saved registers.
- if (MF.getFunction()->getFnAttributes().hasNakedAttr())
+ if (MF.getFunction()->getFnAttributes().hasAttribute(Attributes::Naked))
return;
// We are planning to use NEON instructions vst1 / vld1.
UnitSize = 2;
} else {
// Check whether we can use NEON instructions.
- if (!MF->getFunction()->getFnAttributes().hasNoImplicitFloatAttr() &&
+ if (!MF->getFunction()->getFnAttributes().
+ hasAttribute(Attributes::NoImplicitFloat) &&
Subtarget->hasNEON()) {
if ((Align % 16 == 0) && SizeVal >= 16) {
ldrOpc = ARM::VLD1q32wb_fixed;
// See if we can use NEON instructions for this...
if (IsZeroVal &&
- !F->getFnAttributes().hasNoImplicitFloatAttr() &&
+ !F->getFnAttributes().hasAttribute(Attributes::NoImplicitFloat) &&
Subtarget->hasNEON()) {
if (memOpAlign(SrcAlign, DstAlign, 16) && Size >= 16) {
return MVT::v4i32;
unsigned Idx = 1;
for (Function::arg_iterator AI = F.arg_begin(), AE = F.arg_end(); AI != AE;
++AI, ++Idx) {
- if (F.getParamAttributes(Idx).hasSExtAttr()) {
+ if (F.getParamAttributes(Idx).hasAttribute(Attributes::SExt)) {
Argument* Arg = AI;
if (!isa<PointerType>(Arg->getType())) {
for (Instruction::use_iterator UI = Arg->use_begin();
continue;
}
- if (PAL.getParamAttributes(paramIndex+1).hasByValAttr() == false) {
+ if (PAL.getParamAttributes(paramIndex+1).
+ hasAttribute(Attributes::ByVal) == false) {
// Just a scalar
const PointerType *PTy = dyn_cast<PointerType>(Ty);
if (isKernelFunc) {
// to newly created nodes. The SDNOdes for params have to
// appear in the same order as their order of appearance
// in the original function. "idx+1" holds that order.
- if (PAL.getParamAttributes(i+1).hasByValAttr() == false) {
+ if (PAL.getParamAttributes(i+1).hasAttribute(Attributes::ByVal) == false) {
// A plain scalar.
if (isABI || isKernel) {
// If ABI, load from the param symbol
// to adjust the stack pointer (we fit in the Red Zone). For 64-bit
// SVR4, we also require a stack frame if we need to spill the CR,
// since this spill area is addressed relative to the stack pointer.
- bool DisableRedZone = MF.getFunction()->getFnAttributes().hasNoRedZoneAttr();
+ bool DisableRedZone = MF.getFunction()->getFnAttributes().
+ hasAttribute(Attributes::NoRedZone);
// FIXME SVR4 The 32-bit SVR4 ABI has no red zone. However, it can
// still generate stackless code if all local vars are reg-allocated.
// Try: (FrameSize <= 224
// Naked functions have no stack frame pushed, so we don't have a frame
// pointer.
- if (MF.getFunction()->getFnAttributes().hasNakedAttr())
+ if (MF.getFunction()->getFnAttributes().hasAttribute(Attributes::Naked))
return false;
return MF.getTarget().Options.DisableFramePointerElim(MF) ||
bool is31 = (getTargetMachine().Options.DisableFramePointerElim(MF) ||
MFI->hasVarSizedObjects()) &&
MFI->getStackSize() &&
- !MF.getFunction()->getFnAttributes().hasNakedAttr();
+ !MF.getFunction()->getFnAttributes().
+ hasAttribute(Attributes::Naked);
unsigned FrameReg = isPPC64 ? (is31 ? PPC::X31 : PPC::X1) :
(is31 ? PPC::R31 : PPC::R1);
SDValue FrameAddr = DAG.getCopyFromReg(DAG.getEntryNode(), dl, FrameReg,
// to Offset to get the correct offset.
// Naked functions have stack size 0, although getStackSize may not reflect that
// because we didn't call all the pieces that compute it for naked functions.
- if (!MF.getFunction()->getFnAttributes().hasNakedAttr())
+ if (!MF.getFunction()->getFnAttributes().hasAttribute(Attributes::Naked))
Offset += MFI->getStackSize();
// If we can, encode the offset directly into the instruction. If this is a
// function, and use up to 128 bytes of stack space, don't have a frame
// pointer, calls, or dynamic alloca then we do not need to adjust the
// stack pointer (we fit in the Red Zone).
- if (Is64Bit && !Fn->getFnAttributes().hasNoRedZoneAttr() &&
+ if (Is64Bit && !Fn->getFnAttributes().hasAttribute(Attributes::NoRedZone) &&
!RegInfo->needsStackRealignment(MF) &&
!MFI->hasVarSizedObjects() && // No dynamic alloca.
!MFI->adjustsStack() && // No calls.
void X86DAGToDAGISel::PreprocessISelDAG() {
// OptForSize is used in pattern predicates that isel is matching.
- OptForSize = MF->getFunction()->getFnAttributes().hasOptimizeForSizeAttr();
+ OptForSize = MF->getFunction()->getFnAttributes().
+ hasAttribute(Attributes::OptimizeForSize);
for (SelectionDAG::allnodes_iterator I = CurDAG->allnodes_begin(),
E = CurDAG->allnodes_end(); I != E; ) {
// cases like PR2962. This should be removed when PR2962 is fixed.
const Function *F = MF.getFunction();
if (IsZeroVal &&
- !F->getFnAttributes().hasNoImplicitFloatAttr()) {
+ !F->getFnAttributes().hasAttribute(Attributes::NoImplicitFloat)) {
if (Size >= 16 &&
(Subtarget->isUnalignedMemAccessFast() ||
((DstAlign == 0 || DstAlign >= 16) &&
unsigned NumIntRegs = CCInfo.getFirstUnallocated(GPR64ArgRegs,
TotalNumIntRegs);
- bool NoImplicitFloatOps = Fn->getFnAttributes().hasNoImplicitFloatAttr();
+ bool NoImplicitFloatOps = Fn->getFnAttributes().
+ hasAttribute(Attributes::NoImplicitFloat);
assert(!(NumXMMRegs && !Subtarget->hasSSE1()) &&
"SSE register cannot be used when SSE is disabled!");
assert(!(NumXMMRegs && MF.getTarget().Options.UseSoftFloat &&
OpFlags = X86II::MO_DARWIN_STUB;
} else if (Subtarget->isPICStyleRIPRel() &&
isa<Function>(GV) &&
- cast<Function>(GV)->getFnAttributes().hasNonLazyBindAttr()) {
+ cast<Function>(GV)->getFnAttributes().
+ hasAttribute(Attributes::NonLazyBind)) {
// If the function is marked as non-lazy, generate an indirect call
// which loads from the GOT directly. This avoids runtime overhead
// at the cost of eager binding (and one extra byte of encoding).
bool HasAVX = Subtarget->hasAVX();
bool HasAVX2 = Subtarget->hasAVX2();
MachineFunction &MF = DAG.getMachineFunction();
- bool OptForSize = MF.getFunction()->getFnAttributes().hasOptimizeForSizeAttr();
+ bool OptForSize = MF.getFunction()->getFnAttributes().
+ hasAttribute(Attributes::OptimizeForSize);
assert(VT.getSizeInBits() != 64 && "Can't lower MMX shuffles");
// Sanity Check: Make sure using fp_offset makes sense.
assert(!getTargetMachine().Options.UseSoftFloat &&
!(DAG.getMachineFunction()
- .getFunction()->getFnAttributes().hasNoImplicitFloatAttr()) &&
+ .getFunction()->getFnAttributes()
+ .hasAttribute(Attributes::NoImplicitFloat)) &&
Subtarget->hasSSE1());
}
for (FunctionType::param_iterator I = FTy->param_begin(),
E = FTy->param_end(); I != E; ++I, ++Idx)
- if (Attrs.getParamAttributes(Idx).hasInRegAttr())
+ if (Attrs.getParamAttributes(Idx).hasAttribute(Attributes::InReg))
// FIXME: should only count parameters that are lowered to integers.
InRegCount += (TD->getTypeSizeInBits(*I) + 31) / 32;
return SDValue();
const Function *F = DAG.getMachineFunction().getFunction();
- bool NoImplicitFloatOps = F->getFnAttributes().hasNoImplicitFloatAttr();
+ bool NoImplicitFloatOps = F->getFnAttributes().
+ hasAttribute(Attributes::NoImplicitFloat);
bool F64IsLegal = !DAG.getTarget().Options.UseSoftFloat && !NoImplicitFloatOps
&& Subtarget->hasSSE2();
if ((VT.isVector() ||
// Unless optimizing for size, don't fold to avoid partial
// register update stalls
- if (!MF.getFunction()->getFnAttributes().hasOptimizeForSizeAttr() &&
+ if (!MF.getFunction()->getFnAttributes().
+ hasAttribute(Attributes::OptimizeForSize) &&
hasPartialRegUpdate(MI->getOpcode()))
return 0;
// Unless optimizing for size, don't fold to avoid partial
// register update stalls
- if (!MF.getFunction()->getFnAttributes().hasOptimizeForSizeAttr() &&
+ if (!MF.getFunction()->getFnAttributes().
+ hasAttribute(Attributes::OptimizeForSize) &&
hasPartialRegUpdate(MI->getOpcode()))
return 0;
const MachineFrameInfo *MFI = MF.getFrameInfo();
const Function *F = MF.getFunction();
unsigned StackAlign = TM.getFrameLowering()->getStackAlignment();
- bool requiresRealignment = ((MFI->getMaxAlignment() > StackAlign) ||
- F->getFnAttributes().hasStackAlignmentAttr());
+ bool requiresRealignment =
+ ((MFI->getMaxAlignment() > StackAlign) ||
+ F->getFnAttributes().hasAttribute(Attributes::StackAlignment));
// If we've requested that we force align the stack do so now.
if (ForceStackAlign)
const AttrListPtr &PAL = MF.getFunction()->getAttributes();
for (unsigned I = 0, E = PAL.getNumAttrs(); I != E; ++I)
- if (PAL.getAttributesAtIndex(I).hasNestAttr()) {
+ if (PAL.getAttributesAtIndex(I).hasAttribute(Attributes::Nest)) {
loadFromStack(MBB, MBBI, XCore::R11, 0, dl, TII);
break;
}
SmallPtrSet<Argument*, 8> ArgsToPromote;
SmallPtrSet<Argument*, 8> ByValArgsToTransform;
for (unsigned i = 0; i != PointerArgs.size(); ++i) {
- bool isByVal=F->getParamAttributes(PointerArgs[i].second+1).hasByValAttr();
+ bool isByVal=F->getParamAttributes(PointerArgs[i].second+1).
+ hasAttribute(Attributes::ByVal);
Argument *PtrArg = PointerArgs[i].first;
Type *AgTy = cast<PointerType>(PtrArg->getType())->getElementType();
static AttrListPtr StripNest(const AttrListPtr &Attrs) {
for (unsigned i = 0, e = Attrs.getNumSlots(); i != e; ++i) {
- if (!Attrs.getSlot(i).Attrs.hasNestAttr())
+ if (!Attrs.getSlot(i).Attrs.hasAttribute(Attributes::Nest))
continue;
// There can be only one.
/// \brief Minimal filter to detect invalid constructs for inlining.
static bool isInlineViable(Function &F) {
- bool ReturnsTwice = F.getFnAttributes().hasReturnsTwiceAttr();
+ bool ReturnsTwice =F.getFnAttributes().hasAttribute(Attributes::ReturnsTwice);
for (Function::iterator BI = F.begin(), BE = F.end(); BI != BE; ++BI) {
// Disallow inlining of functions which contain an indirect branch.
if (isa<IndirectBrInst>(BI->getTerminator()))
if (Callee->isDeclaration()) return InlineCost::getNever();
// Return never for anything not marked as always inline.
- if (!Callee->getFnAttributes().hasAlwaysInlineAttr())
+ if (!Callee->getFnAttributes().hasAttribute(Attributes::AlwaysInline))
return InlineCost::getNever();
// Do some minimal analysis to preclude non-viable functions.
// If the inlined function had a higher stack protection level than the
// calling function, then bump up the caller's stack protection level.
- if (Callee->getFnAttributes().hasStackProtectReqAttr())
+ if (Callee->getFnAttributes().hasAttribute(Attributes::StackProtectReq))
Caller->addFnAttr(Attribute::StackProtectReq);
- else if (Callee->getFnAttributes().hasStackProtectAttr() &&
- !Caller->getFnAttributes().hasStackProtectReqAttr())
+ else if (Callee->getFnAttributes().hasAttribute(Attributes::StackProtect) &&
+ !Caller->getFnAttributes().hasAttribute(Attributes::StackProtectReq))
Caller->addFnAttr(Attribute::StackProtect);
// Look at all of the allocas that we inlined through this call site. If we
// would decrease the threshold.
Function *Caller = CS.getCaller();
bool OptSize = Caller && !Caller->isDeclaration() &&
- Caller->getFnAttributes().hasOptimizeForSizeAttr();
+ Caller->getFnAttributes().hasAttribute(Attributes::OptimizeForSize);
if (!(InlineLimit.getNumOccurrences() > 0) && OptSize &&
OptSizeThreshold < thres)
thres = OptSizeThreshold;
// Listen to the inlinehint attribute when it would increase the threshold.
Function *Callee = CS.getCalledFunction();
bool InlineHint = Callee && !Callee->isDeclaration() &&
- Callee->getFnAttributes().hasInlineHintAttr();
+ Callee->getFnAttributes().hasAttribute(Attributes::InlineHint);
if (InlineHint && HintThreshold > thres)
thres = HintThreshold;
// Handle the case when this function is called and we only want to care
// about always-inline functions. This is a bit of a hack to share code
// between here and the InlineAlways pass.
- if (AlwaysInlineOnly && !F->getFnAttributes().hasAlwaysInlineAttr())
+ if (AlwaysInlineOnly &&
+ !F->getFnAttributes().hasAttribute(Attributes::AlwaysInline))
continue;
// If the only remaining users of the function are dead constants, remove
// If the parameter is passed as a byval argument, then we have to have a
// sized type and the sized type has to have the same size as the old type.
- if (ParamTy != ActTy && Attrs.hasByValAttr()) {
+ if (ParamTy != ActTy && Attrs.hasAttribute(Attributes::ByVal)) {
PointerType *ParamPTy = dyn_cast<PointerType>(ParamTy);
if (ParamPTy == 0 || !ParamPTy->getElementType()->isSized() || TD == 0)
return false;
// If the call already has the 'nest' attribute somewhere then give up -
// otherwise 'nest' would occur twice after splicing in the chain.
for (unsigned I = 0, E = Attrs.getNumAttrs(); I != E; ++I)
- if (Attrs.getAttributesAtIndex(I).hasNestAttr())
+ if (Attrs.getAttributesAtIndex(I).hasAttribute(Attributes::Nest))
return 0;
assert(Tramp &&
// Look for a parameter marked with the 'nest' attribute.
for (FunctionType::param_iterator I = NestFTy->param_begin(),
E = NestFTy->param_end(); I != E; ++NestIdx, ++I)
- if (NestAttrs.getParamAttributes(NestIdx).hasNestAttr()) {
+ if (NestAttrs.getParamAttributes(NestIdx).hasAttribute(Attributes::Nest)){
// Record the parameter type and any other attributes.
NestTy = *I;
NestAttr = NestAttrs.getParamAttributes(NestIdx);
// If needed, insert __asan_init before checking for AddressSafety attr.
maybeInsertAsanInitAtFunctionEntry(F);
- if (!F.getFnAttributes().hasAddressSafetyAttr()) return false;
+ if (!F.getFnAttributes().hasAttribute(Attributes::AddressSafety))
+ return false;
if (!ClDebugFunc.empty() && ClDebugFunc != F.getName())
return false;
- // We want to instrument every address only once per basic block
- // (unless there are calls between uses).
+
+ // We want to instrument every address only once per basic block (unless there
+ // are calls between uses).
SmallSet<Value*, 16> TempsToInstrument;
SmallVector<Instruction*, 16> ToInstrument;
SmallVector<Instruction*, 8> NoReturnCalls;
TLInfo = &getAnalysis<TargetLibraryInfo>();
DT = getAnalysisIfAvailable<DominatorTree>();
PFI = getAnalysisIfAvailable<ProfileInfo>();
- OptSize = F.getFnAttributes().hasOptimizeForSizeAttr();
+ OptSize = F.getFnAttributes().hasAttribute(Attributes::OptimizeForSize);
/// This optimization identifies DIV instructions that can be
/// profitably bypassed and carried out with a shorter, faster divide.
// See llvm::isInTailCallPosition().
const Function *F = BB->getParent();
Attributes CallerRetAttr = F->getAttributes().getRetAttributes();
- if (CallerRetAttr.hasZExtAttr() || CallerRetAttr.hasSExtAttr())
+ if (CallerRetAttr.hasAttribute(Attributes::ZExt) ||
+ CallerRetAttr.hasAttribute(Attributes::SExt))
return false;
// Make sure there are no instructions between the PHI and return, or that the
// not user specified.
unsigned Threshold = CurrentThreshold;
if (!UserThreshold &&
- Header->getParent()->getFnAttributes().hasOptimizeForSizeAttr())
+ Header->getParent()->getFnAttributes().
+ hasAttribute(Attributes::OptimizeForSize))
Threshold = OptSizeUnrollThreshold;
// Find trip count and trip multiple if count is not available
// Check to see if it would be profitable to unswitch current loop.
// Do not do non-trivial unswitch while optimizing for size.
- if (OptimizeForSize || F->getFnAttributes().hasOptimizeForSizeAttr())
+ if (OptimizeForSize ||
+ F->getFnAttributes().hasAttribute(Attributes::OptimizeForSize))
return false;
UnswitchNontrivialCondition(LoopCond, Val, currentLoop);
bool Attributes::hasAttributes(const Attributes &A) const {
return Attrs.hasAttributes(A);
}
-bool Attributes::hasAddressSafetyAttr() const {
- return Attrs.hasAttribute(Attribute::AddressSafety_i);
-}
-bool Attributes::hasAlignmentAttr() const {
- return Attrs.hasAttribute(Attribute::Alignment_i);
-}
-bool Attributes::hasAlwaysInlineAttr() const {
- return Attrs.hasAttribute(Attribute::AlwaysInline_i);
-}
-bool Attributes::hasByValAttr() const {
- return Attrs.hasAttribute(Attribute::ByVal_i);
-}
-bool Attributes::hasInlineHintAttr() const {
- return Attrs.hasAttribute(Attribute::InlineHint_i);
-}
-bool Attributes::hasInRegAttr() const {
- return Attrs.hasAttribute(Attribute::InReg_i);
-}
-bool Attributes::hasNakedAttr() const {
- return Attrs.hasAttribute(Attribute::Naked_i);
-}
-bool Attributes::hasNestAttr() const {
- return Attrs.hasAttribute(Attribute::Nest_i);
-}
-bool Attributes::hasNoAliasAttr() const {
- return Attrs.hasAttribute(Attribute::NoAlias_i);
-}
-bool Attributes::hasNoCaptureAttr() const {
- return Attrs.hasAttribute(Attribute::NoCapture_i);
-}
-bool Attributes::hasNoImplicitFloatAttr() const {
- return Attrs.hasAttribute(Attribute::NoImplicitFloat_i);
-}
-bool Attributes::hasNoInlineAttr() const {
- return Attrs.hasAttribute(Attribute::NoInline_i);
-}
-bool Attributes::hasNonLazyBindAttr() const {
- return Attrs.hasAttribute(Attribute::NonLazyBind_i);
-}
-bool Attributes::hasNoRedZoneAttr() const {
- return Attrs.hasAttribute(Attribute::NoRedZone_i);
-}
-bool Attributes::hasNoReturnAttr() const {
- return Attrs.hasAttribute(Attribute::NoReturn_i);
-}
-bool Attributes::hasNoUnwindAttr() const {
- return Attrs.hasAttribute(Attribute::NoUnwind_i);
-}
-bool Attributes::hasOptimizeForSizeAttr() const {
- return Attrs.hasAttribute(Attribute::OptimizeForSize_i);
-}
-bool Attributes::hasReadNoneAttr() const {
- return Attrs.hasAttribute(Attribute::ReadNone_i);
-}
-bool Attributes::hasReadOnlyAttr() const {
- return Attrs.hasAttribute(Attribute::ReadOnly_i);
-}
-bool Attributes::hasReturnsTwiceAttr() const {
- return Attrs.hasAttribute(Attribute::ReturnsTwice_i);
-}
-bool Attributes::hasSExtAttr() const {
- return Attrs.hasAttribute(Attribute::SExt_i);
-}
-bool Attributes::hasStackAlignmentAttr() const {
- return Attrs.hasAttribute(Attribute::StackAlignment_i);
-}
-bool Attributes::hasStackProtectAttr() const {
- return Attrs.hasAttribute(Attribute::StackProtect_i);
-}
-bool Attributes::hasStackProtectReqAttr() const {
- return Attrs.hasAttribute(Attribute::StackProtectReq_i);
-}
-bool Attributes::hasStructRetAttr() const {
- return Attrs.hasAttribute(Attribute::StructRet_i);
-}
-bool Attributes::hasUWTableAttr() const {
- return Attrs.hasAttribute(Attribute::UWTable_i);
-}
-bool Attributes::hasZExtAttr() const {
- return Attrs.hasAttribute(Attribute::ZExt_i);
+
+bool Attributes::hasAttribute(AttrVal Val) const {
+ return Attrs.hasAttribute(Val);
}
/// This returns the alignment field of an attribute as a byte alignment value.
unsigned Attributes::getAlignment() const {
- if (!hasAlignmentAttr())
+ if (!hasAttribute(Attributes::Alignment))
return 0;
return 1U << ((Attrs.getAlignment() >> 16) - 1);
}
/// This returns the stack alignment field of an attribute as a byte alignment
/// value.
unsigned Attributes::getStackAlignment() const {
- if (!hasStackAlignmentAttr())
+ if (!hasAttribute(Attributes::StackAlignment))
return 0;
return 1U << ((Attrs.getStackAlignment() >> 26) - 1);
}
std::string Attributes::getAsString() const {
std::string Result;
- if (hasZExtAttr())
+ if (hasAttribute(Attributes::ZExt))
Result += "zeroext ";
- if (hasSExtAttr())
+ if (hasAttribute(Attributes::SExt))
Result += "signext ";
- if (hasNoReturnAttr())
+ if (hasAttribute(Attributes::NoReturn))
Result += "noreturn ";
- if (hasNoUnwindAttr())
+ if (hasAttribute(Attributes::NoUnwind))
Result += "nounwind ";
- if (hasUWTableAttr())
+ if (hasAttribute(Attributes::UWTable))
Result += "uwtable ";
- if (hasReturnsTwiceAttr())
+ if (hasAttribute(Attributes::ReturnsTwice))
Result += "returns_twice ";
- if (hasInRegAttr())
+ if (hasAttribute(Attributes::InReg))
Result += "inreg ";
- if (hasNoAliasAttr())
+ if (hasAttribute(Attributes::NoAlias))
Result += "noalias ";
- if (hasNoCaptureAttr())
+ if (hasAttribute(Attributes::NoCapture))
Result += "nocapture ";
- if (hasStructRetAttr())
+ if (hasAttribute(Attributes::StructRet))
Result += "sret ";
- if (hasByValAttr())
+ if (hasAttribute(Attributes::ByVal))
Result += "byval ";
- if (hasNestAttr())
+ if (hasAttribute(Attributes::Nest))
Result += "nest ";
- if (hasReadNoneAttr())
+ if (hasAttribute(Attributes::ReadNone))
Result += "readnone ";
- if (hasReadOnlyAttr())
+ if (hasAttribute(Attributes::ReadOnly))
Result += "readonly ";
- if (hasOptimizeForSizeAttr())
+ if (hasAttribute(Attributes::OptimizeForSize))
Result += "optsize ";
- if (hasNoInlineAttr())
+ if (hasAttribute(Attributes::NoInline))
Result += "noinline ";
- if (hasInlineHintAttr())
+ if (hasAttribute(Attributes::InlineHint))
Result += "inlinehint ";
- if (hasAlwaysInlineAttr())
+ if (hasAttribute(Attributes::AlwaysInline))
Result += "alwaysinline ";
- if (hasStackProtectAttr())
+ if (hasAttribute(Attributes::StackProtect))
Result += "ssp ";
- if (hasStackProtectReqAttr())
+ if (hasAttribute(Attributes::StackProtectReq))
Result += "sspreq ";
- if (hasNoRedZoneAttr())
+ if (hasAttribute(Attributes::NoRedZone))
Result += "noredzone ";
- if (hasNoImplicitFloatAttr())
+ if (hasAttribute(Attributes::NoImplicitFloat))
Result += "noimplicitfloat ";
- if (hasNakedAttr())
+ if (hasAttribute(Attributes::Naked))
Result += "naked ";
- if (hasNonLazyBindAttr())
+ if (hasAttribute(Attributes::NonLazyBind))
Result += "nonlazybind ";
- if (hasAddressSafetyAttr())
+ if (hasAttribute(Attributes::AddressSafety))
Result += "address_safety ";
- if (hasStackAlignmentAttr()) {
+ if (hasAttribute(Attributes::StackAlignment)) {
Result += "alignstack(";
Result += utostr(getStackAlignment());
Result += ") ";
}
- if (hasAlignmentAttr()) {
+ if (hasAttribute(Attributes::Alignment)) {
Result += "align ";
Result += utostr(getAlignment());
Result += " ";
// AttributeImpl Definition
//===----------------------------------------------------------------------===//
+uint64_t AttributesImpl::getAttrMask(uint64_t Val) const {
+ switch (Val) {
+ case Attributes::None: return 0;
+ case Attributes::ZExt: return 1 << 0;
+ case Attributes::SExt: return 1 << 1;
+ case Attributes::NoReturn: return 1 << 2;
+ case Attributes::InReg: return 1 << 3;
+ case Attributes::StructRet: return 1 << 4;
+ case Attributes::NoUnwind: return 1 << 5;
+ case Attributes::NoAlias: return 1 << 6;
+ case Attributes::ByVal: return 1 << 7;
+ case Attributes::Nest: return 1 << 8;
+ case Attributes::ReadNone: return 1 << 9;
+ case Attributes::ReadOnly: return 1 << 10;
+ case Attributes::NoInline: return 1 << 11;
+ case Attributes::AlwaysInline: return 1 << 12;
+ case Attributes::OptimizeForSize: return 1 << 13;
+ case Attributes::StackProtect: return 1 << 14;
+ case Attributes::StackProtectReq: return 1 << 15;
+ case Attributes::Alignment: return 31 << 16;
+ case Attributes::NoCapture: return 1 << 21;
+ case Attributes::NoRedZone: return 1 << 22;
+ case Attributes::NoImplicitFloat: return 1 << 23;
+ case Attributes::Naked: return 1 << 24;
+ case Attributes::InlineHint: return 1 << 25;
+ case Attributes::StackAlignment: return 7 << 26;
+ case Attributes::ReturnsTwice: return 1 << 29;
+ case Attributes::UWTable: return 1 << 30;
+ case Attributes::NonLazyBind: return 1U << 31;
+ case Attributes::AddressSafety: return 1ULL << 32;
+ }
+ llvm_unreachable("Unsupported attribute type");
+}
+
bool AttributesImpl::hasAttribute(uint64_t A) const {
- return (Bits & A) != 0;
+ return (Bits & getAttrMask(A)) != 0;
}
bool AttributesImpl::hasAttributes() 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.hasAlignmentAttr() && "Attempt to exclude alignment!");
+ assert(!Attrs.hasAttribute(Attributes::Alignment) &&
+ "Attempt to exclude alignment!");
#endif
if (AttrList == 0) return AttrListPtr();
/// in its containing function.
bool Argument::hasByValAttr() const {
if (!getType()->isPointerTy()) return false;
- return getParent()->getParamAttributes(getArgNo()+1).hasByValAttr();
+ return getParent()->getParamAttributes(getArgNo()+1).
+ hasAttribute(Attributes::ByVal);
}
unsigned Argument::getParamAlignment() const {
/// it in its containing function.
bool Argument::hasNestAttr() const {
if (!getType()->isPointerTy()) return false;
- return getParent()->getParamAttributes(getArgNo()+1).hasNestAttr();
+ return getParent()->getParamAttributes(getArgNo()+1).
+ hasAttribute(Attributes::Nest);
}
/// hasNoAliasAttr - Return true if this argument has the noalias attribute on
/// it in its containing function.
bool Argument::hasNoAliasAttr() const {
if (!getType()->isPointerTy()) return false;
- return getParent()->getParamAttributes(getArgNo()+1).hasNoAliasAttr();
+ return getParent()->getParamAttributes(getArgNo()+1).
+ hasAttribute(Attributes::NoAlias);
}
/// hasNoCaptureAttr - Return true if this argument has the nocapture attribute
/// on it in its containing function.
bool Argument::hasNoCaptureAttr() const {
if (!getType()->isPointerTy()) return false;
- return getParent()->getParamAttributes(getArgNo()+1).hasNoCaptureAttr();
+ return getParent()->getParamAttributes(getArgNo()+1).
+ hasAttribute(Attributes::NoCapture);
}
/// hasSRetAttr - Return true if this argument has the sret attribute on
if (!getType()->isPointerTy()) return false;
if (this != getParent()->arg_begin())
return false; // StructRet param must be first param
- return getParent()->getParamAttributes(1).hasStructRetAttr();
+ return getParent()->getParamAttributes(1).
+ hasAttribute(Attributes::StructRet);
}
/// addAttr - Add a Attribute to an argument
}
bool CallInst::fnHasNoAliasAttr() const {
- if (AttributeList.getParamAttributes(~0U).hasNoAliasAttr())
+ if (AttributeList.getParamAttributes(~0U).hasAttribute(Attributes::NoAlias))
return true;
if (const Function *F = getCalledFunction())
- return F->getParamAttributes(~0U).hasNoAliasAttr();
+ return F->getParamAttributes(~0U).hasAttribute(Attributes::NoAlias);
return false;
}
bool CallInst::fnHasNoInlineAttr() const {
- if (AttributeList.getParamAttributes(~0U).hasNoInlineAttr())
+ if (AttributeList.getParamAttributes(~0U).hasAttribute(Attributes::NoInline))
return true;
if (const Function *F = getCalledFunction())
- return F->getParamAttributes(~0U).hasNoInlineAttr();
+ return F->getParamAttributes(~0U).hasAttribute(Attributes::NoInline);
return false;
}
bool CallInst::fnHasNoReturnAttr() const {
- if (AttributeList.getParamAttributes(~0U).hasNoReturnAttr())
+ if (AttributeList.getParamAttributes(~0U).hasAttribute(Attributes::NoReturn))
return true;
if (const Function *F = getCalledFunction())
- return F->getParamAttributes(~0U).hasNoReturnAttr();
+ return F->getParamAttributes(~0U).hasAttribute(Attributes::NoReturn);
return false;
}
bool CallInst::fnHasNoUnwindAttr() const {
- if (AttributeList.getParamAttributes(~0U).hasNoUnwindAttr())
+ if (AttributeList.getParamAttributes(~0U).hasAttribute(Attributes::NoUnwind))
return true;
if (const Function *F = getCalledFunction())
- return F->getParamAttributes(~0U).hasNoUnwindAttr();
+ return F->getParamAttributes(~0U).hasAttribute(Attributes::NoUnwind);
return false;
}
bool CallInst::fnHasReadNoneAttr() const {
- if (AttributeList.getParamAttributes(~0U).hasReadNoneAttr())
+ if (AttributeList.getParamAttributes(~0U).hasAttribute(Attributes::ReadNone))
return true;
if (const Function *F = getCalledFunction())
- return F->getParamAttributes(~0U).hasReadNoneAttr();
+ return F->getParamAttributes(~0U).hasAttribute(Attributes::ReadNone);
return false;
}
bool CallInst::fnHasReadOnlyAttr() const {
- if (AttributeList.getParamAttributes(~0U).hasReadOnlyAttr())
+ if (AttributeList.getParamAttributes(~0U).hasAttribute(Attributes::ReadOnly))
return true;
if (const Function *F = getCalledFunction())
- return F->getParamAttributes(~0U).hasReadOnlyAttr();
+ return F->getParamAttributes(~0U).hasAttribute(Attributes::ReadOnly);
return false;
}
bool CallInst::fnHasReturnsTwiceAttr() const {
- if (AttributeList.getParamAttributes(~0U).hasReturnsTwiceAttr())
+ if (AttributeList.getParamAttributes(~0U).
+ hasAttribute(Attributes::ReturnsTwice))
return true;
if (const Function *F = getCalledFunction())
- return F->getParamAttributes(~0U).hasReturnsTwiceAttr();
+ return F->getParamAttributes(~0U).hasAttribute(Attributes::ReturnsTwice);
return false;
}
bool CallInst::paramHasSExtAttr(unsigned i) const {
- if (AttributeList.getParamAttributes(i).hasSExtAttr())
+ if (AttributeList.getParamAttributes(i).hasAttribute(Attributes::SExt))
return true;
if (const Function *F = getCalledFunction())
- return F->getParamAttributes(i).hasSExtAttr();
+ return F->getParamAttributes(i).hasAttribute(Attributes::SExt);
return false;
}
bool CallInst::paramHasZExtAttr(unsigned i) const {
- if (AttributeList.getParamAttributes(i).hasZExtAttr())
+ if (AttributeList.getParamAttributes(i).hasAttribute(Attributes::ZExt))
return true;
if (const Function *F = getCalledFunction())
- return F->getParamAttributes(i).hasZExtAttr();
+ return F->getParamAttributes(i).hasAttribute(Attributes::ZExt);
return false;
}
bool CallInst::paramHasInRegAttr(unsigned i) const {
- if (AttributeList.getParamAttributes(i).hasInRegAttr())
+ if (AttributeList.getParamAttributes(i).hasAttribute(Attributes::InReg))
return true;
if (const Function *F = getCalledFunction())
- return F->getParamAttributes(i).hasInRegAttr();
+ return F->getParamAttributes(i).hasAttribute(Attributes::InReg);
return false;
}
bool CallInst::paramHasStructRetAttr(unsigned i) const {
- if (AttributeList.getParamAttributes(i).hasStructRetAttr())
+ if (AttributeList.getParamAttributes(i).hasAttribute(Attributes::StructRet))
return true;
if (const Function *F = getCalledFunction())
- return F->getParamAttributes(i).hasStructRetAttr();
+ return F->getParamAttributes(i).hasAttribute(Attributes::StructRet);
return false;
}
bool CallInst::paramHasNestAttr(unsigned i) const {
- if (AttributeList.getParamAttributes(i).hasNestAttr())
+ if (AttributeList.getParamAttributes(i).hasAttribute(Attributes::Nest))
return true;
if (const Function *F = getCalledFunction())
- return F->getParamAttributes(i).hasNestAttr();
+ return F->getParamAttributes(i).hasAttribute(Attributes::Nest);
return false;
}
bool CallInst::paramHasByValAttr(unsigned i) const {
- if (AttributeList.getParamAttributes(i).hasByValAttr())
+ if (AttributeList.getParamAttributes(i).hasAttribute(Attributes::ByVal))
return true;
if (const Function *F = getCalledFunction())
- return F->getParamAttributes(i).hasByValAttr();
+ return F->getParamAttributes(i).hasAttribute(Attributes::ByVal);
return false;
}
bool CallInst::paramHasNoAliasAttr(unsigned i) const {
- if (AttributeList.getParamAttributes(i).hasNoAliasAttr())
+ if (AttributeList.getParamAttributes(i).hasAttribute(Attributes::NoAlias))
return true;
if (const Function *F = getCalledFunction())
- return F->getParamAttributes(i).hasNoAliasAttr();
+ return F->getParamAttributes(i).hasAttribute(Attributes::NoAlias);
return false;
}
bool CallInst::paramHasNoCaptureAttr(unsigned i) const {
- if (AttributeList.getParamAttributes(i).hasNoCaptureAttr())
+ if (AttributeList.getParamAttributes(i).hasAttribute(Attributes::NoCapture))
return true;
if (const Function *F = getCalledFunction())
- return F->getParamAttributes(i).hasNoCaptureAttr();
+ return F->getParamAttributes(i).hasAttribute(Attributes::NoCapture);
return false;
}
}
bool InvokeInst::fnHasNoAliasAttr() const {
- if (AttributeList.getParamAttributes(~0U).hasNoAliasAttr())
+ if (AttributeList.getParamAttributes(~0U).hasAttribute(Attributes::NoAlias))
return true;
if (const Function *F = getCalledFunction())
- return F->getParamAttributes(~0U).hasNoAliasAttr();
+ return F->getParamAttributes(~0U).hasAttribute(Attributes::NoAlias);
return false;
}
bool InvokeInst::fnHasNoInlineAttr() const {
- if (AttributeList.getParamAttributes(~0U).hasNoInlineAttr())
+ if (AttributeList.getParamAttributes(~0U).hasAttribute(Attributes::NoInline))
return true;
if (const Function *F = getCalledFunction())
- return F->getParamAttributes(~0U).hasNoInlineAttr();
+ return F->getParamAttributes(~0U).hasAttribute(Attributes::NoInline);
return false;
}
bool InvokeInst::fnHasNoReturnAttr() const {
- if (AttributeList.getParamAttributes(~0U).hasNoReturnAttr())
+ if (AttributeList.getParamAttributes(~0U).hasAttribute(Attributes::NoReturn))
return true;
if (const Function *F = getCalledFunction())
- return F->getParamAttributes(~0U).hasNoReturnAttr();
+ return F->getParamAttributes(~0U).hasAttribute(Attributes::NoReturn);
return false;
}
bool InvokeInst::fnHasNoUnwindAttr() const {
- if (AttributeList.getParamAttributes(~0U).hasNoUnwindAttr())
+ if (AttributeList.getParamAttributes(~0U).hasAttribute(Attributes::NoUnwind))
return true;
if (const Function *F = getCalledFunction())
- return F->getParamAttributes(~0U).hasNoUnwindAttr();
+ return F->getParamAttributes(~0U).hasAttribute(Attributes::NoUnwind);
return false;
}
bool InvokeInst::fnHasReadNoneAttr() const {
- if (AttributeList.getParamAttributes(~0U).hasReadNoneAttr())
+ if (AttributeList.getParamAttributes(~0U).hasAttribute(Attributes::ReadNone))
return true;
if (const Function *F = getCalledFunction())
- return F->getParamAttributes(~0U).hasReadNoneAttr();
+ return F->getParamAttributes(~0U).hasAttribute(Attributes::ReadNone);
return false;
}
bool InvokeInst::fnHasReadOnlyAttr() const {
- if (AttributeList.getParamAttributes(~0U).hasReadOnlyAttr())
+ if (AttributeList.getParamAttributes(~0U).hasAttribute(Attributes::ReadOnly))
return true;
if (const Function *F = getCalledFunction())
- return F->getParamAttributes(~0U).hasReadOnlyAttr();
+ return F->getParamAttributes(~0U).hasAttribute(Attributes::ReadOnly);
return false;
}
bool InvokeInst::fnHasReturnsTwiceAttr() const {
- if (AttributeList.getParamAttributes(~0U).hasReturnsTwiceAttr())
+ if (AttributeList.getParamAttributes(~0U).
+ hasAttribute(Attributes::ReturnsTwice))
return true;
if (const Function *F = getCalledFunction())
- return F->getParamAttributes(~0U).hasReturnsTwiceAttr();
+ return F->getParamAttributes(~0U).hasAttribute(Attributes::ReturnsTwice);
return false;
}
bool InvokeInst::paramHasSExtAttr(unsigned i) const {
- if (AttributeList.getParamAttributes(i).hasSExtAttr())
+ if (AttributeList.getParamAttributes(i).hasAttribute(Attributes::SExt))
return true;
if (const Function *F = getCalledFunction())
- return F->getParamAttributes(i).hasSExtAttr();
+ return F->getParamAttributes(i).hasAttribute(Attributes::SExt);
return false;
}
bool InvokeInst::paramHasZExtAttr(unsigned i) const {
- if (AttributeList.getParamAttributes(i).hasZExtAttr())
+ if (AttributeList.getParamAttributes(i).hasAttribute(Attributes::ZExt))
return true;
if (const Function *F = getCalledFunction())
- return F->getParamAttributes(i).hasZExtAttr();
+ return F->getParamAttributes(i).hasAttribute(Attributes::ZExt);
return false;
}
bool InvokeInst::paramHasInRegAttr(unsigned i) const {
- if (AttributeList.getParamAttributes(i).hasInRegAttr())
+ if (AttributeList.getParamAttributes(i).hasAttribute(Attributes::InReg))
return true;
if (const Function *F = getCalledFunction())
- return F->getParamAttributes(i).hasInRegAttr();
+ return F->getParamAttributes(i).hasAttribute(Attributes::InReg);
return false;
}
bool InvokeInst::paramHasStructRetAttr(unsigned i) const {
- if (AttributeList.getParamAttributes(i).hasStructRetAttr())
+ if (AttributeList.getParamAttributes(i).hasAttribute(Attributes::StructRet))
return true;
if (const Function *F = getCalledFunction())
- return F->getParamAttributes(i).hasStructRetAttr();
+ return F->getParamAttributes(i).hasAttribute(Attributes::StructRet);
return false;
}
bool InvokeInst::paramHasNestAttr(unsigned i) const {
- if (AttributeList.getParamAttributes(i).hasNestAttr())
+ if (AttributeList.getParamAttributes(i).hasAttribute(Attributes::Nest))
return true;
if (const Function *F = getCalledFunction())
- return F->getParamAttributes(i).hasNestAttr();
+ return F->getParamAttributes(i).hasAttribute(Attributes::Nest);
return false;
}
bool InvokeInst::paramHasByValAttr(unsigned i) const {
- if (AttributeList.getParamAttributes(i).hasByValAttr())
+ if (AttributeList.getParamAttributes(i).hasAttribute(Attributes::ByVal))
return true;
if (const Function *F = getCalledFunction())
- return F->getParamAttributes(i).hasByValAttr();
+ return F->getParamAttributes(i).hasAttribute(Attributes::ByVal);
return false;
}
bool InvokeInst::paramHasNoAliasAttr(unsigned i) const {
- if (AttributeList.getParamAttributes(i).hasNoAliasAttr())
+ if (AttributeList.getParamAttributes(i).hasAttribute(Attributes::NoAlias))
return true;
if (const Function *F = getCalledFunction())
- return F->getParamAttributes(i).hasNoAliasAttr();
+ return F->getParamAttributes(i).hasAttribute(Attributes::NoAlias);
return false;
}
bool InvokeInst::paramHasNoCaptureAttr(unsigned i) const {
- if (AttributeList.getParamAttributes(i).hasNoCaptureAttr())
+ if (AttributeList.getParamAttributes(i).hasAttribute(Attributes::NoCapture))
return true;
if (const Function *F = getCalledFunction())
- return F->getParamAttributes(i).hasNoCaptureAttr();
+ return F->getParamAttributes(i).hasAttribute(Attributes::NoCapture);
return false;
}
VerifyParameterAttrs(Attr.Attrs, Ty, Attr.Index == 0, V);
- if (Attr.Attrs.hasNestAttr()) {
+ if (Attr.Attrs.hasAttribute(Attributes::Nest)) {
Assert1(!SawNest, "More than one parameter has attribute nest!", V);
SawNest = true;
}
- if (Attr.Attrs.hasStructRetAttr())
+ if (Attr.Attrs.hasAttribute(Attributes::StructRet))
Assert1(Attr.Index == 1, "Attribute sret not on first parameter!", V);
}