Index: include/llvm/IR/DiagnosticInfo.h =================================================================== --- include/llvm/IR/DiagnosticInfo.h +++ include/llvm/IR/DiagnosticInfo.h @@ -48,6 +48,7 @@ enum DiagnosticKind { DK_Bitcode, DK_InlineAsm, + DK_ResourceLimit, DK_StackSize, DK_Linker, DK_DebugMetadataVersion, @@ -160,29 +161,64 @@ } }; -/// Diagnostic information for stack size reporting. +/// Diagnostic information for stack size etc. reporting. /// This is basically a function and a size. -class DiagnosticInfoStackSize : public DiagnosticInfo { +class DiagnosticInfoResourceLimit : public DiagnosticInfo { private: - /// The function that is concerned by this stack size diagnostic. + /// The function that is concerned by this resource limit diagnostic. const Function &Fn; - /// The computed stack size. - unsigned StackSize; + + /// Description of the resource type (e.g. stack size) + const char *ResourceName; + + /// The computed size usage + uint64_t ResourceSize; + + // Threshould passed + uint64_t ResourceLimit; public: /// \p The function that is concerned by this stack size diagnostic. /// \p The computed stack size. - DiagnosticInfoStackSize(const Function &Fn, unsigned StackSize, - DiagnosticSeverity Severity = DS_Warning) - : DiagnosticInfo(DK_StackSize, Severity), Fn(Fn), StackSize(StackSize) {} + DiagnosticInfoResourceLimit(const Function &Fn, + const char *ResourceName, + uint64_t ResourceSize, + DiagnosticSeverity Severity = DS_Warning, + DiagnosticKind Kind = DK_ResourceLimit, + uint64_t ResourceLimit = 0) + : DiagnosticInfo(Kind, Severity), + Fn(Fn), + ResourceName(ResourceName), + ResourceSize(ResourceSize), + ResourceLimit(ResourceLimit) {} const Function &getFunction() const { return Fn; } - unsigned getStackSize() const { return StackSize; } + const char *getResourceName() const { return ResourceName; } + uint64_t getResourceSize() const { return ResourceSize; } + uint64_t getResourceLimit() const { return ResourceLimit; } /// \see DiagnosticInfo::print. void print(DiagnosticPrinter &DP) const override; static bool classof(const DiagnosticInfo *DI) { + return DI->getKind() == DK_ResourceLimit || + DI->getKind() == DK_StackSize; + } +}; + +class DiagnosticInfoStackSize : public DiagnosticInfoResourceLimit { +public: + DiagnosticInfoStackSize(const Function &Fn, + uint64_t StackSize, + DiagnosticSeverity Severity = DS_Warning, + uint64_t StackLimit = 0) + : DiagnosticInfoResourceLimit(Fn, "stack size", StackSize, + Severity, DK_StackSize, StackLimit) {} + + uint64_t getStackSize() const { return getResourceSize(); } + uint64_t getStackLimit() const { return getResourceLimit(); } + + static bool classof(const DiagnosticInfo *DI) { return DI->getKind() == DK_StackSize; } }; Index: lib/IR/DiagnosticInfo.cpp =================================================================== --- lib/IR/DiagnosticInfo.cpp +++ lib/IR/DiagnosticInfo.cpp @@ -112,9 +112,13 @@ DP << " at line " << getLocCookie(); } -void DiagnosticInfoStackSize::print(DiagnosticPrinter &DP) const { - DP << "stack size limit exceeded (" << getStackSize() << ") in " - << getFunction(); +void DiagnosticInfoResourceLimit::print(DiagnosticPrinter &DP) const { + DP << getResourceName() << " limit"; + + if (getResourceLimit() != 0) + DP << " of " << getResourceLimit(); + + DP << " exceeded (" << getResourceSize() << ") in " << getFunction(); } void DiagnosticInfoDebugMetadataVersion::print(DiagnosticPrinter &DP) const { Index: lib/Target/AMDGPU/AMDGPUAsmPrinter.cpp =================================================================== --- lib/Target/AMDGPU/AMDGPUAsmPrinter.cpp +++ lib/Target/AMDGPU/AMDGPUAsmPrinter.cpp @@ -31,6 +31,7 @@ #include "SIRegisterInfo.h" #include "SIInstrInfo.h" #include "llvm/CodeGen/MachineFrameInfo.h" +#include "llvm/IR/DiagnosticInfo.h" #include "llvm/MC/MCContext.h" #include "llvm/MC/MCSectionELF.h" #include "llvm/MC/MCStreamer.h" @@ -455,7 +456,10 @@ if (STM.hasSGPRInitBug()) { if (ProgInfo.NumSGPR > AMDGPUSubtarget::FIXED_SGPR_COUNT_FOR_INIT_BUG) { LLVMContext &Ctx = MF.getFunction()->getContext(); - Ctx.emitError("too many SGPRs used with the SGPR init bug"); + DiagnosticInfoResourceLimit Diag(*MF.getFunction(), + "SGPRs with SGPR init bug", + ProgInfo.NumSGPR, DS_Error); + Ctx.diagnose(Diag); } ProgInfo.NumSGPR = AMDGPUSubtarget::FIXED_SGPR_COUNT_FOR_INIT_BUG; @@ -463,12 +467,16 @@ if (MFI->NumUserSGPRs > STM.getMaxNumUserSGPRs()) { LLVMContext &Ctx = MF.getFunction()->getContext(); - Ctx.emitError("too many user SGPRs used"); + DiagnosticInfoResourceLimit Diag(*MF.getFunction(), "user SGPRs", + MFI->NumUserSGPRs, DS_Error); + Ctx.diagnose(Diag); } if (MFI->LDSSize > static_cast(STM.getLocalMemorySize())) { LLVMContext &Ctx = MF.getFunction()->getContext(); - Ctx.emitError("LDS size exceeds device maximum"); + DiagnosticInfoResourceLimit Diag(*MF.getFunction(), "local memory", + MFI->LDSSize, DS_Error); + Ctx.diagnose(Diag); } ProgInfo.VGPRBlocks = (ProgInfo.NumVGPR - 1) / 4; Index: test/CodeGen/AMDGPU/over-max-lds-size.ll =================================================================== --- test/CodeGen/AMDGPU/over-max-lds-size.ll +++ test/CodeGen/AMDGPU/over-max-lds-size.ll @@ -2,11 +2,11 @@ ; RUN: not llc -march=amdgcn -mcpu=hawaii < %s 2>&1 | FileCheck -check-prefix=ERROR %s ; RUN: not llc -march=amdgcn -mcpu=fiji < %s 2>&1 | FileCheck -check-prefix=ERROR %s -; ERROR: error: LDS size exceeds device maximum +; ERROR: error: local memory limit exceeded (400000) in use_huge_lds @huge = internal unnamed_addr addrspace(3) global [100000 x i32] undef, align 4 -define void @promote_alloca_size_256() { +define void @use_huge_lds() { entry: %v0 = getelementptr inbounds [100000 x i32], [100000 x i32] addrspace(3)* @huge, i32 0, i32 0 store i32 0, i32 addrspace(3)* %v0