Skip to content

Commit 9efef8f

Browse files
mtargowsigcbot
authored andcommitted
Location expressions improvements
1 parent 1efc048 commit 9efef8f

File tree

7 files changed

+138
-35
lines changed

7 files changed

+138
-35
lines changed

IGC/Compiler/CISACodeGen/DebugInfo.cpp

Lines changed: 24 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
2727
#include "GenCodeGenModule.h"
2828
#include "common/Types.hpp"
2929
#include "Probe/Assertion.h"
30+
#include "Compiler/DebugInfo/ScalarVISAModule.h"
3031

3132
using namespace llvm;
3233
using namespace IGC;
@@ -357,7 +358,9 @@ void DebugInfoData::markOutputVar(CShader* pShader, IDebugEmitter* pDebugEmitter
357358

358359
void DebugInfoData::markOutput(llvm::Function& F, CShader* pShader, IDebugEmitter* pDebugEmitter)
359360
{
360-
markOutputPrivateBase(pShader); // Mark privateBase aka ImplicitArg::PRIVATE_BASE as Output for debugging
361+
IGC_ASSERT_MESSAGE(pDebugEmitter, "Missing debug emitter");
362+
VISAModule* visaModule = pDebugEmitter->GetVISAModule();
363+
IGC_ASSERT_MESSAGE(visaModule, "Missing visa module");
361364

362365
for (auto& bb : F)
363366
{
@@ -368,17 +371,28 @@ void DebugInfoData::markOutput(llvm::Function& F, CShader* pShader, IDebugEmitte
368371
// Per Thread Offset non-debug instruction must have 'Output' attribute
369372
// added in the function to be called.
370373
markOutputVar(pShader, pDebugEmitter, &pInst, "perThreadOffset");
371-
IGC_ASSERT_MESSAGE(pDebugEmitter, "Missing debug emitter");
372-
if (VISAModule* visaModule = pDebugEmitter->GetVISAModule())
373-
{
374-
visaModule->setPerThreadOffset(&pInst);
375-
}
374+
markOutputPrivateBase(pShader); // Mark privateBase aka ImplicitArg::PRIVATE_BASE as Output for debugging
375+
ScalarVisaModule* scVISAModule = (ScalarVisaModule*)visaModule;
376+
IGC_ASSERT_MESSAGE(scVISAModule->getPerThreadOffset()==nullptr, "setPerThreadOffset was set earlier");
377+
scVISAModule->setPerThreadOffset(&pInst);
378+
376379
if (((OpenCLProgramContext*)(pShader->GetContext()))->m_InternalOptions.KernelDebugEnable == false)
377380
{
378381
return;
379382
}
380383
}
381-
else if (((OpenCLProgramContext*)(pShader->GetContext()))->m_InternalOptions.KernelDebugEnable)
384+
}
385+
}
386+
387+
if (((OpenCLProgramContext*)(pShader->GetContext()))->m_InternalOptions.KernelDebugEnable)
388+
{
389+
// Compute thread and group identification instructions will be marked here
390+
// regardless of stack calls detection in this shader, so not only when per thread offset
391+
// as well as a private base have been marked as Output earlier in this function.
392+
// When stack calls are in use then only these group ID instructions are marked as Output.
393+
for (auto& bb : F)
394+
{
395+
for (auto& pInst : bb)
382396
{
383397
if (MDNode* implicitGlobalIDMD = pInst.getMetadata("implicitGlobalID"))
384398
{
@@ -393,8 +407,6 @@ void DebugInfoData::markOutput(llvm::Function& F, CShader* pShader, IDebugEmitte
393407

394408
void DebugInfoData::markOutput(llvm::Function& F, CShader* m_currShader)
395409
{
396-
IGC_ASSERT_MESSAGE(IGC_IS_FLAG_DISABLED(UseOffsetInLocation), "UseOffsetInLocation not disabled");
397-
398410
for (auto& bb : F)
399411
{
400412
for (auto& pInst : bb)
@@ -447,8 +459,9 @@ void DebugInfoData::markOutputVars(const llvm::Instruction* pInst)
447459
CVariable* pVar = m_pShader->GetSymbol(pValue);
448460
if (pVar->GetVarType() == EVARTYPE_GENERAL)
449461
{
450-
// We want to attach "Output" attribute to all variables
451-
// (if UseOffsetInLocation is disabled)
462+
// We want to attach "Output" attribute to all variables:
463+
// - if UseOffsetInLocation is disabled, or
464+
// - if UseOffsetInLocation is enabled but there is a stack call in use,
452465
// so that finalizer can extend their liveness to end of
453466
// the program. This will help debugger examine their
454467
// values anywhere in the code till they are in scope.

IGC/Compiler/CISACodeGen/EmitVISAPass.cpp

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -933,7 +933,18 @@ bool EmitPass::runOnFunction(llvm::Function& F)
933933

934934
if (IGC_IS_FLAG_ENABLED(UseOffsetInLocation))
935935
{
936-
DebugInfoData::markOutput(F, m_currShader, m_pDebugEmitter);
936+
if ((IGC_GET_FLAG_VALUE(FunctionControl) < FLAG_FCALL_FORCE_STACKCALL) ||
937+
((OpenCLProgramContext*)(m_currShader->GetContext()))->m_InternalOptions.KernelDebugEnable)
938+
{
939+
DebugInfoData::markOutput(F, m_currShader, m_pDebugEmitter);
940+
}
941+
ScalarVisaModule* scVISAMod = (ScalarVisaModule*)(m_pDebugEmitter->GetVISAModule());
942+
if (!scVISAMod->getPerThreadOffset())
943+
{
944+
// Stack calls in use. Nothing is needed to be marked as Output.
945+
// Just setting frame pointer is required for debug info when stack calls are in use.
946+
m_pDebugEmitter->GetVISAModule()->setFramePtr(m_currShader->GetFP());
947+
}
937948
}
938949
else
939950
{
@@ -9798,7 +9809,7 @@ void EmitPass::emitStackAlloca(GenIntrinsicInst* GII)
97989809
// If we have written the previous FP to the current frame's start, the start of
97999810
// private memory will be offset by 16 bytes
98009811
CVariable* tempFP = m_currShader->GetNewVariable(pFP);
9801-
emitAddPointer(tempFP, pFP, m_currShader->ImmToVariable(SIZE_OWORD, ISA_TYPE_UD));
9812+
emitAddPointer(tempFP, pFP, m_currShader->ImmToVariable(getFPOffset(), ISA_TYPE_UD));
98029813
pFP = tempFP;
98039814
}
98049815
CVariable* pOffset = m_currShader->GetSymbol(GII->getOperand(0));

IGC/Compiler/CISACodeGen/EmitVISAPass.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -252,6 +252,7 @@ class EmitPass : public llvm::FunctionPass
252252
void emitFlushSamplerCache();
253253
void emitSurfaceInfo(llvm::GenIntrinsicInst* intrinsic);
254254

255+
static uint64_t getFPOffset() { return SIZE_OWORD; }
255256
void emitStackAlloca(llvm::GenIntrinsicInst* intrinsic);
256257
void emitVLAStackAlloca(llvm::GenIntrinsicInst* intrinsic);
257258

IGC/Compiler/DebugInfo/ScalarVISAModule.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,15 @@ class ScalarVisaModule final : public IGC::VISAModule {
9696
return m_pShader->GetEncoder().GetVISAKernel()->getDeclarationID(pVar->visaGenVariable[varId]);
9797
}
9898

99+
void setPerThreadOffset(llvm::Instruction* perThreadOffset) {
100+
IGC_ASSERT_MESSAGE(perThreadOffset, "Clear perThreadOffset");
101+
m_perThreadOffset = perThreadOffset;
102+
}
103+
104+
llvm::Instruction* getPerThreadOffset() {
105+
return m_perThreadOffset;
106+
}
107+
99108
private:
100109
/// @brief Constructor.
101110
/// @param m_pShader holds the processed entry point function and generated VISA code.
@@ -109,6 +118,7 @@ class ScalarVisaModule final : public IGC::VISAModule {
109118

110119
CShader* m_pShader;
111120

121+
llvm::Instruction* m_perThreadOffset = nullptr;
112122
};
113123

114124
}

IGC/Compiler/Optimizer/OpenCLPasses/PrivateMemory/PrivateMemoryResolution.cpp

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -871,6 +871,11 @@ bool PrivateMemoryResolution::resolveAllocaInstructions(bool privateOnStack)
871871
// Attach metadata to instruction containing offset of storage
872872
auto OffsetMD = MDNode::get(builder.getContext(), ConstantAsMetadata::get(builder.getInt32(scalarBufferOffset)));
873873
DbgDcl->setMetadata("StorageOffset", OffsetMD);
874+
if (IGC_IS_FLAG_ENABLED(UseOffsetInLocation))
875+
{
876+
auto SizeMD = MDNode::get(builder.getContext(), ConstantAsMetadata::get(builder.getInt32(bufferSize)));
877+
DbgDcl->setMetadata("StorageSize", SizeMD);
878+
}
874879
}
875880
}
876881
}
@@ -1010,15 +1015,16 @@ bool PrivateMemoryResolution::resolveAllocaInstructions(bool privateOnStack)
10101015
Value* perThreadOffset = entryBuilder.CreateMul(threadId, totalPrivateMemPerThread, VALUE_NAME("perThreadOffset"));
10111016
auto perThreadOffsetInst = dyn_cast_or_null<Instruction>(perThreadOffset);
10121017

1013-
if (IGC_IS_FLAG_ENABLED(UseOffsetInLocation))
1018+
if (IGC_IS_FLAG_ENABLED(UseOffsetInLocation) &&
1019+
(privateOnStack == false) &&
1020+
(IGC_GET_FLAG_VALUE(FunctionControl) < FLAG_FCALL_FORCE_STACKCALL))
10141021
{
10151022
IGC_ASSERT_MESSAGE(perThreadOffsetInst, "perThreadOffset will not be marked as Output");
10161023
if (perThreadOffsetInst)
10171024
{
10181025
// Note: for debugging purposes privateMemArg, as well as privateMemArg (aka ImplicitArg::PRIVATE_BASE)
10191026
// will be marked as Output to keep its liveness all time
1020-
auto perThreadOffsetMD = MDNode::get(entryBuilder.getContext(), ConstantAsMetadata::get(entryBuilder.getInt32(1)));
1021-
1027+
auto perThreadOffsetMD = MDNode::get(entryBuilder.getContext(), nullptr); // ConstantAsMetadata::get(entryBuilder.getInt32(1)));
10221028
perThreadOffsetInst->setMetadata("perThreadOffset", perThreadOffsetMD);
10231029
}
10241030
}

IGC/DebugInfo/DwarfCompileUnit.cpp

Lines changed: 75 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
6363
#include "Version.hpp"
6464

6565
#include "Compiler/CISACodeGen/messageEncoding.hpp"
66+
#include "Compiler/CISACodeGen/EmitVISAPass.hpp"
6667
#include "Compiler/DebugInfo/ScalarVISAModule.h"
6768

6869
#include "Probe/Assertion.h"
@@ -2505,25 +2506,29 @@ IGC::DIEBlock* CompileUnit::buildGeneral(DbgVariable& var, std::vector<VISAVaria
25052506
auto storageMD = var.getDbgInst()->getMetadata("StorageOffset");
25062507
auto VISAMod = const_cast<VISAModule*>(loc->GetVISAModule());
25072508
VISAVariableLocation V(VISAMod);
2508-
if (storageMD && (EmitSettings.EmitOffsetInDbgLoc || EmitSettings.UseOffsetInLocation))
2509+
ScalarVisaModule* scVISAMod = (ScalarVisaModule*)VISAMod;
2510+
IGC_ASSERT_MESSAGE(scVISAMod, "ScalarVisaModule error");
2511+
2512+
Instruction* perThreadOffsetInst = scVISAMod->getPerThreadOffset();
2513+
2514+
if (storageMD && (EmitSettings.EmitOffsetInDbgLoc || EmitSettings.UseOffsetInLocation) && perThreadOffsetInst)
25092515
{
2510-
// This is executed only when llvm.dbg.declare still exists.
2516+
// This is executed only when llvm.dbg.declare still exists and no stack call is supported.
25112517
// With mem2reg run, data is stored in GRFs and this wont be
25122518
// executed.
2513-
Instruction* perThreadOffsetInst = VISAMod->getPerThreadOffset();
2514-
ScalarVisaModule* scVMod = (ScalarVisaModule*)VISAMod;
2515-
IGC_ASSERT_MESSAGE(scVMod, "ScalarVisaModule error");
2519+
2520+
IGC_ASSERT_MESSAGE(perThreadOffsetInst, "perThreadOffsetInst not passed");
25162521

25172522
Value* pValPTO = dyn_cast_or_null<Value>(perThreadOffsetInst);
25182523
IGC_ASSERT_MESSAGE(pValPTO, "pValPTO error");
25192524

25202525
// At this point we expect only a register
2521-
CVariable* pVarPTO = scVMod->GetSymbol(perThreadOffsetInst, pValPTO);
2526+
CVariable* pVarPTO = scVISAMod->GetSymbol(perThreadOffsetInst, pValPTO);
25222527

25232528
IGC_ASSERT_MESSAGE(pVarPTO, "Per Thread Offset variable does not exist");
25242529
IGC_ASSERT_MESSAGE(pVarPTO->GetVarType() == EVARTYPE_GENERAL, "Unexpected VISA register type!");
25252530

2526-
int regPTO = scVMod->getDeclarationID(pVarPTO, false);
2531+
int regPTO = scVISAMod->getDeclarationID(pVarPTO, false);
25272532
auto privateBaseRegNum = loc->GetVISAModule()->getPrivateBaseReg();
25282533
if (privateBaseRegNum) // FIX ME if 0 is allowed
25292534
{
@@ -2583,11 +2588,11 @@ IGC::DIEBlock* CompileUnit::buildGeneral(DbgVariable& var, std::vector<VISAVaria
25832588

25842589
DbgDecoder::VarInfo varInfoPerThOff;
25852590
// Rely on getVarInfo result here.
2586-
auto regNumPerThOff = regPTO; // loc->GetRegister();
2591+
auto regNumPerThOff = regPTO;
25872592
VISAMod->getVarInfo("V", regNumPerThOff, varInfoPerThOff);
25882593

25892594
IGC_ASSERT_MESSAGE(varInfoPerThOff.lrs.front().isGRF() || varInfoPerThOff.lrs.front().isSpill(),
2590-
"Unexpected location of variable");
2595+
"Unexpected location of variable");
25912596
if (varInfoPerThOff.lrs.front().isGRF())
25922597
{
25932598
uint16_t grfRegNumPTO = varInfoPerThOff.lrs.front().getGRF().regNum;
@@ -2636,6 +2641,66 @@ IGC::DIEBlock* CompileUnit::buildGeneral(DbgVariable& var, std::vector<VISAVaria
26362641
}
26372642
}
26382643

2644+
auto sizeMD = var.getDbgInst()->getMetadata("StorageSize");
2645+
if (storageMD && (EmitSettings.EmitOffsetInDbgLoc || EmitSettings.UseOffsetInLocation) && sizeMD)
2646+
{
2647+
emitLocation = true;
2648+
auto simdSize = VISAMod->GetSIMDSize();
2649+
uint64_t storageOffset = simdSize * dyn_cast<ConstantAsMetadata>(storageMD->getOperand(0))->getValue()->getUniqueInteger().getSExtValue();
2650+
uint64_t storageSize = dyn_cast<ConstantAsMetadata>(sizeMD->getOperand(0))->getValue()->getUniqueInteger().getSExtValue();
2651+
// There is a private value in the current stack frame
2652+
// 1 DW_OP_constu <Frame Pointer reg encoded>
2653+
// 2 DW_OP_INTEL_regs , i.e. Frame Pointer
2654+
// 3 DW_OP_const1u <bit-offset to Frame Pointer reg>
2655+
// 4 DW_OP_const1u 64 , i.e. size in bits
2656+
// 5 DW_OP_INTEL_push_bit_piece_stack
2657+
// 6 DW_OP_const1u SIZE_OWORD // i.e. 0x10 taken from getFPOffset(); same as emitted in EmitPass::emitStackAlloca()
2658+
// 7 DW_OP_plus
2659+
// 8 DW_OP_push_simd_lane
2660+
// 9 DW_OP_const1u/2u/4u/8u storageSize // MD: StorageSize; the size of the variable
2661+
// 10 DW_OP_mul
2662+
// 11 DW_OP_plus
2663+
// 12 DW_OP_const1u/2u/4u/8u storageOffset // MD: StorageOffset; the offset where each variable is stored in the current stack frame
2664+
// 13 DW_OP_plus
2665+
2666+
CVariable *framePtr = VISAMod->getFramePtr();
2667+
ScalarVisaModule* scVISAMod = (ScalarVisaModule*)VISAMod;
2668+
int regFP = scVISAMod->getDeclarationID(framePtr, false);
2669+
DbgDecoder::VarInfo varInfoFP;
2670+
// Rely on getVarInfo result here.
2671+
auto regNumFP = regFP;
2672+
VISAMod->getVarInfo("V", regNumFP, varInfoFP);
2673+
uint16_t grfRegNumFP = varInfoFP.lrs.front().getGRF().regNum;
2674+
uint16_t grfSubRegNumFP = varInfoFP.lrs.front().getGRF().subRegNum;
2675+
auto bitOffsetToFPReg = grfSubRegNumFP * 8; // Bit-offset to GRF with Frame Pointer
2676+
auto DWRegFPEncoded = GetEncodedRegNum<RegisterNumbering::GRFBase>(
2677+
grfRegNumFP, EmitSettings.UseNewRegisterEncoding);
2678+
2679+
addUInt(Block, dwarf::DW_FORM_data1, dwarf::DW_OP_constu); // 1 DW_OP_constu <Frame Pointer reg encoded>
2680+
addUInt(Block, dwarf::DW_FORM_udata, DWRegFPEncoded); // Register ID is shifted by offset
2681+
addUInt(Block, dwarf::DW_FORM_data1, DW_OP_INTEL_regs); // 2 DW_OP_INTEL_regs , i.e. Frame Pointer
2682+
addUInt(Block, dwarf::DW_FORM_data1, dwarf::DW_OP_const1u); // 3 DW_OP_const1u <bit-offset to Frame Pointer reg>
2683+
addUInt(Block, dwarf::DW_FORM_data1, bitOffsetToFPReg);
2684+
addUInt(Block, dwarf::DW_FORM_data1, dwarf::DW_OP_const1u); // 4 DW_OP_const1u 64 , i.e. size in bits
2685+
addUInt(Block, dwarf::DW_FORM_data1, 64);
2686+
addUInt(Block, dwarf::DW_FORM_data1, DW_OP_INTEL_push_bit_piece_stack); // 5 DW_OP_INTEL_push_bit_piece_stack
2687+
2688+
addUInt(Block, dwarf::DW_FORM_data1, dwarf::DW_OP_const1u); // 6 DW_OP_const1u SIZE_OWORD (taken from getFPOffset())
2689+
addUInt(Block, dwarf::DW_FORM_data1, EmitPass::getFPOffset());
2690+
addUInt(Block, dwarf::DW_FORM_data1, dwarf::DW_OP_plus); // 7 DW_OP_plus
2691+
addUInt(Block, dwarf::DW_FORM_data1, DW_OP_INTEL_push_simd_lane); // 8 DW_OP_INTEL_push_simd_lane
2692+
addConstantUValue(Block, storageSize); // 9 DW_OP_const1u/2u/4u/8u storageSize
2693+
addUInt(Block, dwarf::DW_FORM_data1, dwarf::DW_OP_mul); // 10 DW_OP_mul
2694+
addUInt(Block, dwarf::DW_FORM_data1, dwarf::DW_OP_plus); // 11 DW_OP_plus
2695+
addConstantUValue(Block, storageOffset); // 12 DW_OP_const1u/2u/4u/8u storageOffset
2696+
addUInt(Block, dwarf::DW_FORM_data1, dwarf::DW_OP_plus); // 13 DW_OP_plus
2697+
2698+
// As long as for debugging there is no slicing of variables handled above,
2699+
// 2nd run of this loop is not needed in SIMD32, because opcodes above describe
2700+
// location for all 32 lanes.
2701+
break;
2702+
}
2703+
26392704
if (EmitSettings.EnableSIMDLaneDebugging && isSliced)
26402705
{
26412706
// DW_OP_push_simd_lane
@@ -2668,6 +2733,7 @@ IGC::DIEBlock* CompileUnit::buildGeneral(DbgVariable& var, std::vector<VISAVaria
26682733
cast<DIEInteger>(secondHalfOff)->setValue(offsetTaken - offsetNotTaken);
26692734
}
26702735
}
2736+
26712737
DbgDecoder::VarInfo varInfo;
26722738
if (!vars)
26732739
{

IGC/DebugInfo/VISAModule.hpp

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
3636
#include "VISAIDebugEmitter.hpp"
3737
#include "LexicalScopes.hpp"
3838

39+
#include "Compiler/CISACodeGen/CVariable.hpp"
40+
3941
#include <vector>
4042
#include <map>
4143
#include <string>
@@ -524,18 +526,12 @@ namespace IGC
524526
// This function coalesces GenISARange which is a vector of <start ip, end ip>
525527
static void coalesceRanges(std::vector<std::pair<unsigned int, unsigned int>>& GenISARange);
526528

527-
void setPerThreadOffset(llvm::Instruction* perThreadOffset)
528-
{
529-
IGC_ASSERT_MESSAGE(perThreadOffset, "Clear perThreadOffset");
530-
m_perThreadOffset = perThreadOffset;
531-
}
532529
void dump() const { print(llvm::dbgs()); }
533530
void print (llvm::raw_ostream &OS) const;
534531

535-
llvm::Instruction* getPerThreadOffset()
536-
{
537-
return m_perThreadOffset;
538-
}
532+
void setFramePtr(CVariable* pFP) { m_framePtr = pFP; }
533+
534+
CVariable* getFramePtr() { return m_framePtr; }
539535

540536
uint64_t GetFuncId() const { return (uint64_t)m_pEntryFunc; }
541537

@@ -558,7 +554,7 @@ namespace IGC
558554

559555
ObjectType m_objectType = ObjectType::UNKNOWN;
560556

561-
llvm::Instruction* m_perThreadOffset = nullptr;
557+
CVariable* m_framePtr = nullptr;
562558

563559
public:
564560
/// Constants represents VISA register encoding in DWARF

0 commit comments

Comments
 (0)