Generalize DiagnosticInfoStackSize to support other limits

Backends may want to report errors on resources other than
stack size.

llvm-svn: 273177
This commit is contained in:
Matt Arsenault 2016-06-20 18:13:04 +00:00
parent 3ac879f9a6
commit ff98241f37
4 changed files with 65 additions and 17 deletions

View File

@ -48,6 +48,7 @@ enum DiagnosticSeverity : char {
enum DiagnosticKind {
DK_Bitcode,
DK_InlineAsm,
DK_ResourceLimit,
DK_StackSize,
DK_Linker,
DK_DebugMetadataVersion,
@ -160,28 +161,63 @@ public:
}
};
/// 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;
}

View File

@ -112,9 +112,13 @@ void DiagnosticInfoInlineAsm::print(DiagnosticPrinter &DP) const {
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 {

View File

@ -31,6 +31,7 @@
#include "SIInstrInfo.h"
#include "SIRegisterInfo.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"
@ -454,7 +455,10 @@ void AMDGPUAsmPrinter::getSIProgramInfo(SIProgramInfo &ProgInfo,
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;
@ -462,12 +466,16 @@ void AMDGPUAsmPrinter::getSIProgramInfo(SIProgramInfo &ProgInfo,
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<unsigned>(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;

View File

@ -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