Index: llvm/include/llvm/CodeGen/StackProtector.h =================================================================== --- llvm/include/llvm/CodeGen/StackProtector.h +++ llvm/include/llvm/CodeGen/StackProtector.h @@ -35,6 +35,8 @@ class StackProtector : public FunctionPass { private: + static constexpr unsigned DefaultSSPBufferSize = 8; + /// A mapping of AllocaInsts to their required SSP layout. using SSPLayoutMap = DenseMap; @@ -58,7 +60,7 @@ /// The minimum size of buffers that will receive stack smashing /// protection when -fstack-protection is used. - unsigned SSPBufferSize = 0; + unsigned SSPBufferSize = DefaultSSPBufferSize; /// VisitedPHIs - The set of PHI nodes visited when determining /// if a variable's reference has been taken. This set Index: llvm/include/llvm/IR/Function.h =================================================================== --- llvm/include/llvm/IR/Function.h +++ llvm/include/llvm/IR/Function.h @@ -406,6 +406,15 @@ /// Return the attribute for the given attribute kind. Attribute getFnAttribute(StringRef Kind) const; + /// For a string attribute \p Kind, parse attribute as an integer. + /// + /// \returns \p Default if attribute is not present. + /// + /// \returns \p Default if there is an error parsing the attribute integer, + /// and error is emitted to the LLVMContext + uint64_t getFnAttributeAsParsedInteger(StringRef Kind, + uint64_t Default = 0) const; + /// gets the specified attribute from the list of attributes. Attribute getParamAttribute(unsigned ArgNo, Attribute::AttrKind Kind) const; Index: llvm/lib/CodeGen/StackProtector.cpp =================================================================== --- llvm/lib/CodeGen/StackProtector.cpp +++ llvm/lib/CodeGen/StackProtector.cpp @@ -62,7 +62,7 @@ char StackProtector::ID = 0; -StackProtector::StackProtector() : FunctionPass(ID), SSPBufferSize(8) { +StackProtector::StackProtector() : FunctionPass(ID) { initializeStackProtectorPass(*PassRegistry::getPassRegistry()); } @@ -92,11 +92,8 @@ HasPrologue = false; HasIRCheck = false; - Attribute Attr = Fn.getFnAttribute("stack-protector-buffer-size"); - if (Attr.isStringAttribute() && - Attr.getValueAsString().getAsInteger(10, SSPBufferSize)) - return false; // Invalid integer string - + SSPBufferSize = Fn.getFnAttributeAsParsedInteger( + "stack-protector-buffer-size", DefaultSSPBufferSize); if (!RequiresStackProtector()) return false; Index: llvm/lib/CodeGen/XRayInstrumentation.cpp =================================================================== --- llvm/lib/CodeGen/XRayInstrumentation.cpp +++ llvm/lib/CodeGen/XRayInstrumentation.cpp @@ -151,19 +151,18 @@ InstrAttr.getValueAsString() == "xray-never"; if (NeverInstrument && !AlwaysInstrument) return false; - auto ThresholdAttr = F.getFnAttribute("xray-instruction-threshold"); auto IgnoreLoopsAttr = F.getFnAttribute("xray-ignore-loops"); - unsigned int XRayThreshold = 0; - if (!AlwaysInstrument) { - if (!ThresholdAttr.isStringAttribute()) - return false; // XRay threshold attribute not found. - if (ThresholdAttr.getValueAsString().getAsInteger(10, XRayThreshold)) - return false; // Invalid value for threshold. + uint64_t XRayThreshold = 0; + if (!AlwaysInstrument) { bool IgnoreLoops = IgnoreLoopsAttr.isValid(); + XRayThreshold = F.getFnAttributeAsParsedInteger( + "xray-instruction-threshold", std::numeric_limits::max()); + if (XRayThreshold == std::numeric_limits::max()) + return false; // Count the number of MachineInstr`s in MachineFunction - int64_t MICount = 0; + uint64_t MICount = 0; for (const auto &MBB : MF) MICount += MBB.size(); Index: llvm/lib/IR/Function.cpp =================================================================== --- llvm/lib/IR/Function.cpp +++ llvm/lib/IR/Function.cpp @@ -660,6 +660,19 @@ return AttributeSets.getFnAttr(Kind); } +uint64_t Function::getFnAttributeAsParsedInteger(StringRef Name, + uint64_t Default) const { + Attribute A = getFnAttribute(Name); + uint64_t Result = Default; + if (A.isStringAttribute()) { + StringRef Str = A.getValueAsString(); + if (Str.getAsInteger(0, Result)) + getContext().emitError("cannot parse integer attribute " + Name); + } + + return Result; +} + /// gets the specified attribute from the list of attributes. Attribute Function::getParamAttribute(unsigned ArgNo, Attribute::AttrKind Kind) const { Index: llvm/lib/Target/AArch64/AArch64FrameLowering.cpp =================================================================== --- llvm/lib/Target/AArch64/AArch64FrameLowering.cpp +++ llvm/lib/Target/AArch64/AArch64FrameLowering.cpp @@ -871,11 +871,8 @@ const Function &F = MF.getFunction(); // TODO: When implementing stack protectors, take that into account // for the probe threshold. - unsigned StackProbeSize = 4096; - if (F.hasFnAttribute("stack-probe-size")) - F.getFnAttribute("stack-probe-size") - .getValueAsString() - .getAsInteger(0, StackProbeSize); + unsigned StackProbeSize = + F.getFnAttributeAsParsedInteger("stack-probe-size", 4096); return (StackSizeInBytes >= StackProbeSize) && !F.hasFnAttribute("no-stack-arg-probe"); } Index: llvm/lib/Target/AMDGPU/AMDGPUSubtarget.cpp =================================================================== --- llvm/lib/Target/AMDGPU/AMDGPUSubtarget.cpp +++ llvm/lib/Target/AMDGPU/AMDGPUSubtarget.cpp @@ -524,7 +524,8 @@ // Assume all implicit inputs are used by default unsigned NBytes = (AMDGPU::getAmdhsaCodeObjectVersion() >= 5) ? 256 : 56; - return AMDGPU::getIntegerAttribute(F, "amdgpu-implicitarg-num-bytes", NBytes); + return F.getFnAttributeAsParsedInteger("amdgpu-implicitarg-num-bytes", + NBytes); } uint64_t AMDGPUSubtarget::getExplicitKernArgSize(const Function &F, @@ -683,8 +684,8 @@ // Check if maximum number of SGPRs was explicitly requested using // "amdgpu-num-sgpr" attribute. if (F.hasFnAttribute("amdgpu-num-sgpr")) { - unsigned Requested = AMDGPU::getIntegerAttribute( - F, "amdgpu-num-sgpr", MaxNumSGPRs); + unsigned Requested = + F.getFnAttributeAsParsedInteger("amdgpu-num-sgpr", MaxNumSGPRs); // Make sure requested value does not violate subtarget's specifications. if (Requested && (Requested <= ReservedNumSGPRs)) @@ -763,8 +764,8 @@ // Check if maximum number of VGPRs was explicitly requested using // "amdgpu-num-vgpr" attribute. if (F.hasFnAttribute("amdgpu-num-vgpr")) { - unsigned Requested = AMDGPU::getIntegerAttribute( - F, "amdgpu-num-vgpr", MaxNumVGPRs); + unsigned Requested = + F.getFnAttributeAsParsedInteger("amdgpu-num-vgpr", MaxNumVGPRs); if (hasGFX90AInsts()) Requested *= 2; @@ -953,7 +954,8 @@ if (NSAThreshold.getNumOccurrences() > 0) return std::max(NSAThreshold.getValue(), 2u); - int Value = AMDGPU::getIntegerAttribute(MF.getFunction(), "amdgpu-nsa-threshold", -1); + int Value = MF.getFunction().getFnAttributeAsParsedInteger( + "amdgpu-nsa-threshold", -1); if (Value > 0) return std::max(Value, 2); Index: llvm/lib/Target/AMDGPU/AMDGPUTargetTransformInfo.cpp =================================================================== --- llvm/lib/Target/AMDGPU/AMDGPUTargetTransformInfo.cpp +++ llvm/lib/Target/AMDGPU/AMDGPUTargetTransformInfo.cpp @@ -106,7 +106,8 @@ TTI::UnrollingPreferences &UP, OptimizationRemarkEmitter *ORE) { const Function &F = *L->getHeader()->getParent(); - UP.Threshold = AMDGPU::getIntegerAttribute(F, "amdgpu-unroll-threshold", 300); + UP.Threshold = + F.getFnAttributeAsParsedInteger("amdgpu-unroll-threshold", 300); UP.MaxCount = std::numeric_limits::max(); UP.Partial = true; Index: llvm/lib/Target/AMDGPU/SIFormMemoryClauses.cpp =================================================================== --- llvm/lib/Target/AMDGPU/SIFormMemoryClauses.cpp +++ llvm/lib/Target/AMDGPU/SIFormMemoryClauses.cpp @@ -274,8 +274,8 @@ MaxVGPRs = TRI->getAllocatableSet(MF, &AMDGPU::VGPR_32RegClass).count(); MaxSGPRs = TRI->getAllocatableSet(MF, &AMDGPU::SGPR_32RegClass).count(); - unsigned FuncMaxClause = AMDGPU::getIntegerAttribute( - MF.getFunction(), "amdgpu-max-memory-clause", MaxClause); + unsigned FuncMaxClause = MF.getFunction().getFnAttributeAsParsedInteger( + "amdgpu-max-memory-clause", MaxClause); for (MachineBasicBlock &MBB : MF) { GCNDownwardRPTracker RPT(*LIS); Index: llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.cpp =================================================================== --- llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.cpp +++ llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.cpp @@ -1159,21 +1159,6 @@ return TT.getArch() == Triple::r600; } -int getIntegerAttribute(const Function &F, StringRef Name, int Default) { - Attribute A = F.getFnAttribute(Name); - int Result = Default; - - if (A.isStringAttribute()) { - StringRef Str = A.getValueAsString(); - if (Str.getAsInteger(0, Result)) { - LLVMContext &Ctx = F.getContext(); - Ctx.emitError("can't parse integer attribute " + Name); - } - } - - return Result; -} - std::pair getIntegerPairAttribute(const Function &F, StringRef Name, std::pair Default, @@ -1814,18 +1799,18 @@ //===----------------------------------------------------------------------===// unsigned getInitialPSInputAddr(const Function &F) { - return getIntegerAttribute(F, "InitialPSInputAddr", 0); + return F.getFnAttributeAsParsedInteger("InitialPSInputAddr", 0); } bool getHasColorExport(const Function &F) { // As a safe default always respond as if PS has color exports. - return getIntegerAttribute( - F, "amdgpu-color-export", + return F.getFnAttributeAsParsedInteger( + "amdgpu-color-export", F.getCallingConv() == CallingConv::AMDGPU_PS ? 1 : 0) != 0; } bool getHasDepthExport(const Function &F) { - return getIntegerAttribute(F, "amdgpu-depth-export", 0) != 0; + return F.getFnAttributeAsParsedInteger("amdgpu-depth-export", 0) != 0; } bool isShader(CallingConv::ID cc) { Index: llvm/lib/Target/ARM/ARMFrameLowering.cpp =================================================================== --- llvm/lib/Target/ARM/ARMFrameLowering.cpp +++ llvm/lib/Target/ARM/ARMFrameLowering.cpp @@ -557,10 +557,9 @@ const MachineFrameInfo &MFI = MF.getFrameInfo(); const Function &F = MF.getFunction(); unsigned StackProbeSize = (MFI.getStackProtectorIndex() > 0) ? 4080 : 4096; - if (F.hasFnAttribute("stack-probe-size")) - F.getFnAttribute("stack-probe-size") - .getValueAsString() - .getAsInteger(0, StackProbeSize); + + StackProbeSize = + F.getFnAttributeAsParsedInteger("stack-probe-size", StackProbeSize); return (StackSizeInBytes >= StackProbeSize) && !F.hasFnAttribute("no-stack-arg-probe"); } Index: llvm/lib/Target/PowerPC/PPCISelLowering.cpp =================================================================== --- llvm/lib/Target/PowerPC/PPCISelLowering.cpp +++ llvm/lib/Target/PowerPC/PPCISelLowering.cpp @@ -12177,12 +12177,9 @@ "Unexpected stack alignment"); // The default stack probe size is 4096 if the function has no // stack-probe-size attribute. - unsigned StackProbeSize = 4096; const Function &Fn = MF.getFunction(); - if (Fn.hasFnAttribute("stack-probe-size")) - Fn.getFnAttribute("stack-probe-size") - .getValueAsString() - .getAsInteger(0, StackProbeSize); + unsigned StackProbeSize = + Fn.getFnAttributeAsParsedInteger("stack-probe-size", 4096); // Round down to the stack alignment. StackProbeSize &= ~(StackAlign - 1); return StackProbeSize ? StackProbeSize : StackAlign; Index: llvm/lib/Target/SystemZ/SystemZISelLowering.cpp =================================================================== --- llvm/lib/Target/SystemZ/SystemZISelLowering.cpp +++ llvm/lib/Target/SystemZ/SystemZISelLowering.cpp @@ -7449,12 +7449,8 @@ "Unexpected stack alignment"); // The default stack probe size is 4096 if the function has no // stack-probe-size attribute. - unsigned StackProbeSize = 4096; - const Function &Fn = MF.getFunction(); - if (Fn.hasFnAttribute("stack-probe-size")) - Fn.getFnAttribute("stack-probe-size") - .getValueAsString() - .getAsInteger(0, StackProbeSize); + unsigned StackProbeSize = + MF.getFunction().getFnAttributeAsParsedInteger("stack-probe-size", 4096); // Round down to the stack alignment. StackProbeSize &= ~(StackAlign - 1); return StackProbeSize ? StackProbeSize : StackAlign; Index: llvm/lib/Target/X86/X86DynAllocaExpander.cpp =================================================================== --- llvm/lib/Target/X86/X86DynAllocaExpander.cpp +++ llvm/lib/Target/X86/X86DynAllocaExpander.cpp @@ -287,14 +287,7 @@ TRI = STI->getRegisterInfo(); StackPtr = TRI->getStackRegister(); SlotSize = TRI->getSlotSize(); - - StackProbeSize = 4096; - if (MF.getFunction().hasFnAttribute("stack-probe-size")) { - MF.getFunction() - .getFnAttribute("stack-probe-size") - .getValueAsString() - .getAsInteger(0, StackProbeSize); - } + StackProbeSize = STI->getTargetLowering()->getStackProbeSize(MF); NoStackArgProbe = MF.getFunction().hasFnAttribute("no-stack-arg-probe"); if (NoStackArgProbe) StackProbeSize = INT64_MAX; Index: llvm/lib/Target/X86/X86ISelLowering.cpp =================================================================== --- llvm/lib/Target/X86/X86ISelLowering.cpp +++ llvm/lib/Target/X86/X86ISelLowering.cpp @@ -57374,13 +57374,8 @@ X86TargetLowering::getStackProbeSize(const MachineFunction &MF) const { // The default stack probe size is 4096 if the function has no stackprobesize // attribute. - unsigned StackProbeSize = 4096; - const Function &Fn = MF.getFunction(); - if (Fn.hasFnAttribute("stack-probe-size")) - Fn.getFnAttribute("stack-probe-size") - .getValueAsString() - .getAsInteger(0, StackProbeSize); - return StackProbeSize; + return MF.getFunction().getFnAttributeAsParsedInteger("stack-probe-size", + 4096); } Align X86TargetLowering::getPrefLoopAlignment(MachineLoop *ML) const {