Skip to content

Commit 79aa84f

Browse files
mbelickiigcbot
authored andcommitted
Updated error messages with source file locations and names of the kernel causing compilation failure.
1 parent 64e2d9f commit 79aa84f

File tree

13 files changed

+157
-37
lines changed

13 files changed

+157
-37
lines changed

IGC/AdaptorCommon/AddImplicitArgs.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -393,7 +393,7 @@ void AddImplicitArgs::replaceAllUsesWithNewOCLBuiltinFunction(CodeGenContext* ct
393393
if (!cInst)
394394
{
395395
IGC_ASSERT_MESSAGE(0, "Unknown function usage");
396-
getAnalysis<CodeGenContextWrapper>().getCodeGenContext()->EmitError(" undefined reference to `jmp()' ");
396+
getAnalysis<CodeGenContextWrapper>().getCodeGenContext()->EmitError(" undefined reference to `jmp()' ", U);
397397
return;
398398
}
399399
//Return if any error
@@ -596,7 +596,7 @@ void BuiltinCallGraphAnalysis::traveseCallGraphSCC(const std::vector<CallGraphNo
596596
std::string Msg = "Invalid user defined function being processed: ";
597597
Msg += f->getName();
598598
Msg += "()\n";
599-
getAnalysis<CodeGenContextWrapper>().getCodeGenContext()->EmitError(Msg.c_str());
599+
getAnalysis<CodeGenContextWrapper>().getCodeGenContext()->EmitError(Msg.c_str(), f);
600600
return;
601601
}
602602
if (argData == nullptr)
@@ -721,7 +721,7 @@ void BuiltinCallGraphAnalysis::combineTwoArgDetail(
721721
if (!cInst)
722722
{
723723
IGC_ASSERT_MESSAGE(0, " Not supported");
724-
getAnalysis<CodeGenContextWrapper>().getCodeGenContext()->EmitError(" undefined reference to `jmp()' ");
724+
getAnalysis<CodeGenContextWrapper>().getCodeGenContext()->EmitError(" undefined reference to `jmp()' ", v);
725725
return;
726726
}
727727

IGC/Compiler/CISACodeGen/CISABuilder.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5123,7 +5123,7 @@ namespace IGC
51235123
raw_string_ostream S(output);
51245124
S << "parsing vISA inline assembly failed:\n" << vAsmTextBuilder->GetCriticalMsg();
51255125
S.flush();
5126-
context->EmitError(output.c_str());
5126+
context->EmitError(output.c_str(), nullptr);
51275127
vISAAsmParseError = true;
51285128
}
51295129
}

IGC/Compiler/CISACodeGen/OpenCLKernelCodeGen.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1758,7 +1758,7 @@ namespace IGC
17581758
uint totalOffset = offset + (allocSize * i);
17591759
if ((totalOffset / getGRFSize()) >= m_Context->getNumGRFPerThread())
17601760
{
1761-
m_Context->EmitError("Kernel inputs exceed total register size!");
1761+
m_Context->EmitError("Kernel inputs exceed total register size!", A);
17621762
return;
17631763
}
17641764
AllocateInput(var, totalOffset, i);

IGC/Compiler/CodeGenContext.cpp

Lines changed: 128 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,11 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
2424
2525
======================= end_copyright_notice ==================================*/
2626

27+
#include <sstream>
2728
#include "common/LLVMWarningsPush.hpp"
2829
#include <llvm/Support/ScaledNumber.h>
30+
#include <llvm/Demangle/Demangle.h>
31+
#include <llvm/IR/DebugInfo.h>
2932
#include "common/LLVMWarningsPop.hpp"
3033
#include "Compiler/CISACodeGen/ComputeShaderCodeGen.hpp"
3134
#include "Compiler/CISACodeGen/ShaderCodeGen.hpp"
@@ -706,15 +709,132 @@ namespace IGC
706709
llvmCtxWrapper = nullptr;
707710
}
708711

709-
void CodeGenContext::EmitError(const char* errorstr)
712+
static const llvm::Function *getRelatedFunction(const llvm::Value *value)
710713
{
711-
std::string str(errorstr);
712-
std::string msg;
713-
msg += "\nerror: ";
714-
msg += str;
715-
msg += "\nerror: backend compiler failed build.\n";
716-
str = msg;
717-
this->oclErrorMessage = str;// where to get this from
714+
if (value == nullptr)
715+
return nullptr;
716+
717+
if (const llvm::Function *F = llvm::dyn_cast<llvm::Function>(value)) {
718+
return F;
719+
}
720+
if (const llvm::Argument *A = llvm::dyn_cast<llvm::Argument>(value)) {
721+
return A->getParent();
722+
}
723+
if (const llvm::BasicBlock *BB = llvm::dyn_cast<llvm::BasicBlock>(value)) {
724+
return BB->getParent();
725+
}
726+
if (const llvm::Instruction *I = llvm::dyn_cast<llvm::Instruction>(value)) {
727+
return I->getParent()->getParent();
728+
}
729+
730+
return nullptr;
731+
}
732+
733+
static bool isEntryPoint(CodeGenContext *ctx, const llvm::Function *F)
734+
{
735+
if (F == nullptr) {
736+
return false;
737+
}
738+
739+
auto& FuncMD = ctx->getModuleMetaData()->FuncMD;
740+
auto FuncInfo = FuncMD.find(const_cast<llvm::Function *>(F));
741+
if (FuncInfo == FuncMD.end()) {
742+
return false;
743+
}
744+
745+
const FunctionMetaData* MD = &FuncInfo->second;
746+
return MD->functionType == KernelFunction;
747+
}
748+
749+
static void findCallingKernles
750+
(CodeGenContext *ctx, const llvm::Function *F, llvm::SmallPtrSetImpl<const llvm::Function *> *kernels)
751+
{
752+
if (F == nullptr || kernels->count(F))
753+
return;
754+
755+
for (const llvm::User *U : F->users()) {
756+
auto *CI = llvm::dyn_cast<llvm::CallInst>(U);
757+
if (CI == nullptr)
758+
continue;
759+
760+
if (CI->getCalledFunction() != F)
761+
continue;
762+
763+
const llvm::Function *caller = getRelatedFunction(CI);
764+
if (isEntryPoint(ctx, caller)) {
765+
kernels->insert(caller);
766+
continue;
767+
}
768+
// Caller is not a kernel, try to check which kerneles might
769+
// be calling it:
770+
findCallingKernles(ctx, caller, kernels);
771+
}
772+
}
773+
774+
// TODO: remove this wrapper once we move to LLVM 11
775+
static std::string demangle_wrapper(const std::string &name) {
776+
#if LLVM_VERSION_MAJOR >= 11
777+
return llvm::demangle(name);
778+
#else
779+
char *demangled = nullptr;
780+
781+
demangled = llvm::itaniumDemangle(name.c_str(), nullptr, nullptr, nullptr);
782+
if (demangled == nullptr) {
783+
demangled = llvm::microsoftDemangle(name.c_str(), nullptr, nullptr, nullptr);
784+
}
785+
786+
if (demangled == nullptr) {
787+
return name;
788+
}
789+
790+
std::string result = demangled;
791+
std::free(demangled);
792+
return result;
793+
#endif
794+
}
795+
796+
void CodeGenContext::EmitError(const char* errorstr, const llvm::Value *context)
797+
{
798+
std::stringstream ss;
799+
800+
ss << "\nerror :";
801+
ss << errorstr;
802+
// Try to get debug location to print out the relevant info.
803+
if (const llvm::Instruction *I = llvm::dyn_cast<llvm::Instruction>(context)) {
804+
if (const llvm::DILocation *DL = I->getDebugLoc()) {
805+
ss << "\nin file: " << DL->getFilename().str() << ":" << DL->getLine() << "\n";
806+
}
807+
}
808+
// Try to find function related to given context
809+
// to print more informative error message.
810+
if (const llvm::Function *F = getRelatedFunction(context)) {
811+
// If the function is a kernel just print the kernel name.
812+
if (isEntryPoint(this, F)) {
813+
ss << "\nin kernel: '" << demangle_wrapper(F->getName()) << "'";
814+
// If the function is not a kernel try to print all kernels that
815+
// might be using this function.
816+
} else {
817+
llvm::SmallPtrSet<const llvm::Function *, 16> kernels;
818+
findCallingKernles(this, F, &kernels);
819+
820+
const size_t kernelsCount = kernels.size();
821+
ss << "\nin function: '" << demangle_wrapper(F->getName()) << "' ";
822+
if (kernelsCount == 0) {
823+
ss << "called indirectly by at least one of the kernels.\n";
824+
} else if (kernelsCount == 1) {
825+
const llvm::Function *kernel = *kernels.begin();
826+
ss << "called by kernel: '" << demangle_wrapper(kernel->getName()) << "'\n";
827+
} else {
828+
ss << "called by kernels:\n";
829+
for (const llvm::Function *kernel : kernels) {
830+
ss << " - '" << demangle_wrapper(kernel->getName()) << "'\n";
831+
}
832+
}
833+
}
834+
}
835+
ss << "\nerror: backend compiler failed build.\n";
836+
837+
this->oclErrorMessage = ss.str();// where to get this from
718838
return;
719839
}
720840

IGC/Compiler/CodeGenPublic.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -958,7 +958,7 @@ namespace IGC
958958
virtual void InitVarMetaData();
959959
virtual ~CodeGenContext();
960960
void clear();
961-
void EmitError(const char* errorstr);
961+
void EmitError(const char* errorstr, const llvm::Value *context);
962962
bool HasError() const;
963963
CompOptions& getCompilerOption();
964964
virtual void resetOnRetry();

IGC/Compiler/Optimizer/OCLBIUtils.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -198,7 +198,7 @@ void CImagesBI::verifyCommand()
198198
{
199199
if (m_IncorrectBti)
200200
{
201-
m_pCodeGenContext->EmitError("Inconsistent use of image!");
201+
m_pCodeGenContext->EmitError("Inconsistent use of image!", NULL);
202202
}
203203
}
204204

@@ -371,7 +371,7 @@ class COCL_sample : public CImagesBI
371371
ConstantInt* samplerIndex = nullptr;
372372
Value* samplerParam = ValueTracker::track(m_pCallInst, 1, m_pMdUtils, m_modMD);
373373
if (!samplerParam) {
374-
m_pCodeGenContext->EmitError("There are instructions that use a sampler, but no sampler found in the kernel!");
374+
m_pCodeGenContext->EmitError("There are instructions that use a sampler, but no sampler found in the kernel!", m_pCallInst);
375375
return nullptr;
376376
}
377377

IGC/Compiler/Optimizer/OpenCLPasses/ErrorCheckPass.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ void ErrorCheck::checkArgsSize(Function& F)
101101
std::string ErrorMsg = "Total size of kernel arguments exceeds limit! Total arguments size: "
102102
+ std::to_string(TotalSize) + ", limit: " + std::to_string(MaxParamSize);
103103

104-
Ctx->EmitError(ErrorMsg.c_str());
104+
Ctx->EmitError(ErrorMsg.c_str(), &F);
105105
m_hasError = true;
106106
}
107107
}
@@ -117,15 +117,15 @@ void ErrorCheck::visitInstruction(llvm::Instruction& I)
117117
// For testing purpose, this check is skipped if ForceDPEmulation is on.
118118
if (I.getType()->isDoubleTy())
119119
{
120-
ctx->EmitError("double type is not supported on this platform");
120+
ctx->EmitError("double type is not supported on this platform", &I);
121121
m_hasError = true;
122122
return;
123123
}
124124
for (int i = 0, numOpnd = (int)I.getNumOperands(); i < numOpnd; ++i)
125125
{
126126
if (I.getOperand(i)->getType()->isDoubleTy())
127127
{
128-
ctx->EmitError("double type is not supported on this platform");
128+
ctx->EmitError("double type is not supported on this platform", &I);
129129
m_hasError = true;
130130
return;
131131
}
@@ -150,7 +150,7 @@ void ErrorCheck::visitCallInst(CallInst& CI)
150150
std::string Msg = "Unsupported call to ";
151151
Msg += CI.getCalledFunction() ?
152152
CI.getCalledFunction()->getName() : "indirect function";
153-
Ctx->EmitError(Msg.c_str());
153+
Ctx->EmitError(Msg.c_str(), &CI);
154154
m_hasError = true;
155155
}
156156
break;

IGC/Compiler/Optimizer/OpenCLPasses/ExtenstionFuncs/ExtensionArgAnalysis.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,7 @@ namespace IGC
160160
{
161161
if (m_ExtensionMap[pArg] != expected)
162162
{
163-
getAnalysis<CodeGenContextWrapper>().getCodeGenContext()->EmitError("Inconsistent use of image!");
163+
getAnalysis<CodeGenContextWrapper>().getCodeGenContext()->EmitError("Inconsistent use of image!", &CI);
164164
return;
165165
}
166166
}
@@ -187,7 +187,7 @@ namespace IGC
187187
if (subGroupSize->hasValue())
188188
{
189189
if (subGroupSize->getSIMD_size() != 16)
190-
getAnalysis<CodeGenContextWrapper>().getCodeGenContext()->EmitError("SIMD16 is expected");
190+
getAnalysis<CodeGenContextWrapper>().getCodeGenContext()->EmitError("SIMD16 is expected", &CI);
191191
}
192192
else
193193
subGroupSize->setSIMD_size(16);

IGC/Compiler/Optimizer/OpenCLPasses/SubGroupFuncs/SubGroupFuncsResolution.cpp

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -272,7 +272,7 @@ void SubGroupFuncsResolution::CheckSIMDSize(Instruction& I, StringRef msg)
272272
if ((simdSize == 32 || m_pCtx->getModuleMetaData()->csInfo.forcedSIMDSize == 32)
273273
)
274274
{
275-
m_pCtx->EmitError(std::string(msg).c_str());
275+
m_pCtx->EmitError(std::string(msg).c_str(), &I);
276276
}
277277
}
278278

@@ -360,7 +360,7 @@ void SubGroupFuncsResolution::simdBlockRead(llvm::CallInst& CI)
360360
supportLocal = m_pCtx->platform.supportSLMBlockMessage();
361361
if (AS == ADDRESS_SPACE_LOCAL && !supportLocal)
362362
{
363-
m_pCtx->EmitError("BlockReadLocal not supported!");
363+
m_pCtx->EmitError("BlockReadLocal not supported!", &CI);
364364
return;
365365
}
366366

@@ -431,7 +431,7 @@ void SubGroupFuncsResolution::simdBlockWrite(llvm::CallInst& CI)
431431
supportLocal = m_pCtx->platform.supportSLMBlockMessage();
432432
if (AS == ADDRESS_SPACE_LOCAL && !supportLocal)
433433
{
434-
m_pCtx->EmitError("BlockWriteLocal not supported!");
434+
m_pCtx->EmitError("BlockWriteLocal not supported!", &CI);
435435
return;
436436
}
437437

@@ -775,7 +775,7 @@ void SubGroupFuncsResolution::visitCallInst(CallInst& CI)
775775
blockWidth = ValueTracker::track(&CI, 2);
776776
if (!blockWidth)
777777
{
778-
m_pCtx->EmitError("width argument supplied to intel_media_block_read*() must be constant.");
778+
m_pCtx->EmitError("width argument supplied to intel_media_block_read*() must be constant.", &CI);
779779
return;
780780
}
781781
}
@@ -786,7 +786,7 @@ void SubGroupFuncsResolution::visitCallInst(CallInst& CI)
786786
blockHeight = ValueTracker::track(&CI, 3);
787787
if (!blockHeight)
788788
{
789-
m_pCtx->EmitError("height argument supplied to intel_media_block_read*() must be constant.");
789+
m_pCtx->EmitError("height argument supplied to intel_media_block_read*() must be constant.", &CI);
790790
return;
791791
}
792792
}
@@ -827,7 +827,7 @@ void SubGroupFuncsResolution::visitCallInst(CallInst& CI)
827827
blockWidth = ValueTracker::track(&CI, 2);
828828
if (!blockWidth)
829829
{
830-
m_pCtx->EmitError("width argument supplied to intel_media_block_write*() must be constant.");
830+
m_pCtx->EmitError("width argument supplied to intel_media_block_write*() must be constant.", &CI);
831831
return;
832832
}
833833
}
@@ -838,7 +838,7 @@ void SubGroupFuncsResolution::visitCallInst(CallInst& CI)
838838
blockHeight = ValueTracker::track(&CI, 3);
839839
if (!blockHeight)
840840
{
841-
m_pCtx->EmitError("height argument supplied to intel_media_block_write*() must be constant.");
841+
m_pCtx->EmitError("height argument supplied to intel_media_block_write*() must be constant.", &CI);
842842
return;
843843
}
844844
}
@@ -992,7 +992,7 @@ void SubGroupFuncsResolution::CheckMediaBlockInstError(llvm::GenIntrinsicInst* i
992992
raw_string_ostream S(output);
993993
S << "width for " << builtinPrefix << "*() must be <= " << 32 / typeSize;
994994
S.flush();
995-
m_pCtx->EmitError(output.c_str());
995+
m_pCtx->EmitError(output.c_str(), inst);
996996
return;
997997
}
998998

@@ -1003,7 +1003,7 @@ void SubGroupFuncsResolution::CheckMediaBlockInstError(llvm::GenIntrinsicInst* i
10031003
S << "height for " << widthInBytes << " bytes wide "
10041004
<< builtinPrefix << "*() must be <= " << maxRows;
10051005
S.flush();
1006-
m_pCtx->EmitError(output.c_str());
1006+
m_pCtx->EmitError(output.c_str(), inst);
10071007
return;
10081008
}
10091009

@@ -1018,7 +1018,7 @@ void SubGroupFuncsResolution::CheckMediaBlockInstError(llvm::GenIntrinsicInst* i
10181018
S << builtinPrefix << "*() attempt of " << IOSize <<
10191019
" bytes. Must be <= " << maxIOSize << " bytes.";
10201020
S.flush();
1021-
m_pCtx->EmitError(output.c_str());
1021+
m_pCtx->EmitError(output.c_str(), inst);
10221022
return;
10231023
}
10241024
}
@@ -1036,7 +1036,7 @@ void SubGroupFuncsResolution::CheckMediaBlockInstError(llvm::GenIntrinsicInst* i
10361036
S << builtinPrefix << "_us*() widths must be dual pixel aligned.";
10371037
}
10381038
S.flush();
1039-
m_pCtx->EmitError(output.c_str());
1039+
m_pCtx->EmitError(output.c_str(), inst);
10401040
return;
10411041
}
10421042
}

IGC/Compiler/Optimizer/OpenCLPasses/TransformUnmaskedFunctionsPass.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -261,7 +261,7 @@ bool TransformUnmaskedFunctionsPass::runOnFunction(llvm::Function& F)
261261
stream << "\nDetected non-uniform control flow inside unmasked function '"
262262
<< F.getName().str() << "': '" << result.reason << "'\n";
263263
std::string errorMessage = stream.str();
264-
getAnalysis<CodeGenContextWrapper>().getCodeGenContext()->EmitError(errorMessage.c_str());
264+
getAnalysis<CodeGenContextWrapper>().getCodeGenContext()->EmitError(errorMessage.c_str(), &F);
265265
}
266266

267267
F.removeFnAttr(llvm::Attribute::AlwaysInline);

IGC/Compiler/Optimizer/OpenCLPasses/UndefinedReferences/UndefinedReferencesPass.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,7 @@ bool UndefinedReferencesPass::runOnModule(Module& M)
129129
{
130130
if (!errorMessage.empty())
131131
{
132-
getAnalysis<CodeGenContextWrapper>().getCodeGenContext()->EmitError(errorMessage.c_str());
132+
getAnalysis<CodeGenContextWrapper>().getCodeGenContext()->EmitError(errorMessage.c_str(), nullptr);
133133
}
134134
}
135135

0 commit comments

Comments
 (0)