Skip to content

Commit 2019c58

Browse files
igorban-inteligcbot
authored andcommitted
Propagate dbg-data through rdregion in GenXDebugInfo
Propagate dbg-data through rdregion in GenXDebugInfo
1 parent c13a4e5 commit 2019c58

File tree

6 files changed

+172
-43
lines changed

6 files changed

+172
-43
lines changed

IGC/DebugInfo/DwarfCompileUnit.cpp

Lines changed: 36 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ See LICENSE.TXT for details.
2525
#include "llvm/IR/DIBuilder.h"
2626
#include "llvm/IR/Constants.h"
2727
#include "llvm/IR/Instruction.h"
28+
#include "llvm/Support/Debug.h"
2829
#if LLVM_VERSION_MAJOR >= 11
2930
#include "llvm/CodeGen/DIE.h"
3031
#endif
@@ -1702,6 +1703,30 @@ void CompileUnit::addSimdLaneScalar(IGC::DIEBlock* Block, const DbgVariable& DV,
17021703
}
17031704
}
17041705

1706+
// addSimdLaneRegionBase - add a sequence of attributes to calculate location of region base address
1707+
// variable for vc-backend
1708+
void CompileUnit::addSimdLaneRegionBase(IGC::DIEBlock* Block, const DbgVariable& DV,
1709+
const VISAVariableLocation& Loc,
1710+
const DbgDecoder::LiveIntervalsVISA* lr)
1711+
{
1712+
auto OffsetsCount = Loc.GetRegionOffsetsCount();
1713+
IGC_ASSERT(OffsetsCount);
1714+
// Calculate size of register piece
1715+
auto PieceSizeInBits = DV.getRegisterValueSizeInBits(DD) / OffsetsCount;
1716+
if (DD->getEmitterSettings().EnableDebugInfoValidation)
1717+
DD->getStreamEmitter().verifyRegisterLocationExpr(DV, *DD);
1718+
LLVM_DEBUG(dbgs() << " addSimdLaneRegionBase(PieceSizeInBits: " << PieceSizeInBits << ")\n");
1719+
// TODO Support special logic for "sequential" regions
1720+
for (size_t i = 0; i < OffsetsCount; ++i) {
1721+
const auto Offset = Loc.GetRegionOffset(i);
1722+
IGC_ASSERT(Offset < Loc.GetVISAModule()->getGRFSizeInBits());
1723+
// Generate piece for each element of address:
1724+
// DW_OP_reg N; DW_OP_bit_piece: size: Size offset: Offset ;
1725+
addRegisterLoc(Block, lr->getGRF().regNum, 0, DV.getDbgInst());
1726+
addBitPiece(Block, PieceSizeInBits, Offset);
1727+
}
1728+
}
1729+
17051730
/// getParentContextString - Walks the metadata parent chain in a language
17061731
/// specific manner (using the compile unit language) and returns
17071732
/// it as a string. This is done at the metadata level because DIEs may
@@ -3079,12 +3104,17 @@ bool CompileUnit::buildValidVar(const DbgVariable& var, IGC::DIEBlock* Block,
30793104

30803105
if (loc.IsVectorized() == false)
30813106
{
3082-
unsigned int subReg = lrToUse.getGRF().subRegNum;
3083-
addRegisterLoc(Block, regNum, 0, var.getDbgInst());
3084-
// Emit GT-relative location expression
3085-
isSLM = addGTRelativeLocation(Block, var, loc);
3086-
if (!isSLM && loc.IsRegister())
3087-
addSimdLaneScalar(Block, var, loc, &lrToUse, subReg);
3107+
if (loc.isRegionBasedAddress()) {
3108+
// VC-backend specific addressing model
3109+
addSimdLaneRegionBase(Block, var, loc, &lrToUse);
3110+
} else {
3111+
unsigned int subReg = lrToUse.getGRF().subRegNum;
3112+
addRegisterLoc(Block, regNum, 0, var.getDbgInst());
3113+
// Emit GT-relative location expression
3114+
isSLM = addGTRelativeLocation(Block, var, loc);
3115+
if (!isSLM && loc.IsRegister())
3116+
addSimdLaneScalar(Block, var, loc, &lrToUse, subReg);
3117+
}
30883118
var.emitExpression(this, Block);
30893119
return false;
30903120
}

IGC/DebugInfo/DwarfCompileUnit.hpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -308,6 +308,12 @@ namespace IGC
308308
const DbgDecoder::LiveIntervalsVISA& lr,
309309
uint64_t varSizeInBits, uint64_t offsetInBits);
310310

311+
// addSimdLaneRegionBase - add a sequence of attributes to calculate location of region base
312+
// address variable for vc-backend
313+
void addSimdLaneRegionBase(IGC::DIEBlock* Block, const DbgVariable& DV,
314+
const VISAVariableLocation& Loc,
315+
const DbgDecoder::LiveIntervalsVISA* lr);
316+
311317
// Decode line number, file name and location from a string, where a line no. and file name
312318
// (including directory) are separated by '-' character: lineNumber-fileNameIncludingDirectory
313319
// There is a workaround for DIModule creation in earlier LLVM versions, where a line and a file

IGC/DebugInfo/VISAModule.hpp

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,21 @@ namespace IGC
124124
m_pVISAModule = m;
125125
}
126126

127+
/// @brief Constructor. Creates register location with possible region-based addressing.
128+
/// VC-backend specific constructor.
129+
/// @param locationValue value indicates the address/register of the location.
130+
/// @param offsets list of offsets for each piece of location
131+
/// @param m points to VISAModule corresponding to this location
132+
VISAVariableLocation(unsigned int locationValue, llvm::SmallVector<unsigned, 0> &&offsets,
133+
const VISAModule* m) : m_offsets(std::move(offsets))
134+
{
135+
m_hasLocation = true;
136+
m_isRegister = true;
137+
m_locationReg = locationValue;
138+
m_vectorNumElements = offsets.size();
139+
m_pVISAModule = m;
140+
}
141+
127142
/// @brief Copy Constructor.
128143
/// @param copied value.
129144
VISAVariableLocation(const VISAVariableLocation&) = default;
@@ -163,6 +178,11 @@ namespace IGC
163178
bool HasLocationSecondReg() const { return m_locationSecondReg != ~0; }
164179
unsigned int GetSecondReg() const { IGC_ASSERT(HasLocationSecondReg()); return m_locationSecondReg; }
165180

181+
// Regon-base addressing data (vc-backend specific)
182+
bool isRegionBasedAddress() const { return m_offsets.size() > 0; }
183+
unsigned GetRegionOffset(size_t i) const { IGC_ASSERT(m_offsets.size() > i); return m_offsets[i];}
184+
size_t GetRegionOffsetsCount() const { return m_offsets.size(); }
185+
166186
void dump() const;
167187
void print (llvm::raw_ostream &OS) const;
168188

@@ -185,6 +205,8 @@ namespace IGC
185205
unsigned int m_locationOffset = ~0;
186206
unsigned int m_vectorNumElements = ~0;
187207
const VISAModule* m_pVISAModule = nullptr;
208+
// Regon-base addressing info (vc-backend specific)
209+
llvm::SmallVector<unsigned, 0> m_offsets;
188210
};
189211

190212
typedef uint64_t GfxAddress;

IGC/VectorCompiler/lib/GenXCodeGen/GenXBaling.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1990,7 +1990,7 @@ void GenXBaling::print(raw_ostream &OS) const {
19901990
/***********************************************************************
19911991
* getBaleParent : return the instruction baled into, 0 if none
19921992
*/
1993-
Instruction *GenXBaling::getBaleParent(Instruction *Inst) const {
1993+
Instruction *GenXBaling::getBaleParent(const Instruction *Inst) const {
19941994
// We can rely on the fact that a baled in instruction always has exactly
19951995
// one use. The exception is llvm.genx.simdcf.goto/join, which is baled in
19961996
// to the extractvalue that extracts the !any(EM) value. Rather than check

IGC/VectorCompiler/lib/GenXCodeGen/GenXBaling.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -410,9 +410,9 @@ class GenXBaling {
410410
void setBaleInfo(const Instruction *Inst, genx::BaleInfo BI);
411411
// isBaled : test whether all uses of an instruction would be baled in to
412412
// users
413-
bool isBaled(Instruction *Inst) const { return getBaleParent(Inst); }
413+
bool isBaled(const Instruction *Inst) const { return getBaleParent(Inst); }
414414
// getBaleParent : return the instruction baled into, 0 if none
415-
Instruction *getBaleParent(Instruction *Inst) const;
415+
Instruction *getBaleParent(const Instruction *Inst) const;
416416
// unbale : unbale an instruction from its bale parent
417417
void unbale(Instruction *Inst);
418418
// getBaleHead : return the head of the bale containing this instruction

IGC/VectorCompiler/lib/GenXCodeGen/GenXDebugInfo.cpp

Lines changed: 105 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ SPDX-License-Identifier: MIT
1818

1919
#include "visa/include/visaBuilder_interface.h"
2020

21+
#include "DebugInfo/DwarfCompileUnit.hpp"
2122
#include "DebugInfo/StreamEmitter.hpp"
2223
#include "DebugInfo/VISAIDebugEmitter.hpp"
2324
#include "DebugInfo/VISAModule.hpp"
@@ -835,11 +836,12 @@ class GenXFunction final : public IGC::VISAModule {
835836

836837
public:
837838
GenXFunction(const GenXSubtarget &STIn, const GenXVisaRegAlloc &RAIn,
838-
const Function &F, CompiledVisaWrapper &&CW,
839-
const genx::di::VisaMapping &V2I,
839+
const GenXBaling &BAn, const Function &F,
840+
CompiledVisaWrapper &&CW, const genx::di::VisaMapping &V2I,
840841
const ModuleToVisaTransformInfo &MVTI, bool IsPrimary)
841-
: F{F}, ST{STIn}, VisaMapping{V2I}, CompiledVisa{std::move(CW)}, RA{RAIn},
842-
MVTI(MVTI), VISAModule(const_cast<Function *>(&F), IsPrimary) {
842+
: F{F}, ST{STIn}, VisaMapping{V2I},
843+
CompiledVisa{std::move(CW)}, RA{RAIn}, BA{BAn}, MVTI(MVTI),
844+
VISAModule(const_cast<Function *>(&F), IsPrimary) {
843845

844846
if (MVTI.isSubroutine(&F))
845847
SetType(ObjectType::SUBROUTINE);
@@ -913,34 +915,98 @@ class GenXFunction final : public IGC::VISAModule {
913915

914916
const genx::di::VisaMapping &getVisaMapping() const { return VisaMapping; }
915917

918+
static constexpr unsigned RdIndex =
919+
GenXIntrinsic::GenXRegion::RdIndexOperandNum;
920+
static constexpr unsigned RdVstride =
921+
GenXIntrinsic::GenXRegion::RdVStrideOperandNum;
922+
static constexpr unsigned RdWidth =
923+
GenXIntrinsic::GenXRegion::RdWidthOperandNum;
924+
static constexpr unsigned RdStride =
925+
GenXIntrinsic::GenXRegion::RdStrideOperandNum;
926+
static constexpr unsigned RdNumOp =
927+
GenXIntrinsic::GenXRegion::OldValueOperandNum;
928+
929+
static const Value *
930+
CalculateBaledLocation(const CallInst *UseInst,
931+
llvm::SmallVector<unsigned, 0> *Offsets,
932+
const GenXBaling &BA, const DataLayout &DL) {
933+
IGC_ASSERT(UseInst);
934+
IGC_ASSERT(Offsets);
935+
if (!GenXIntrinsic::isRdRegion(UseInst))
936+
return UseInst;
937+
auto BI = BA.getBaleInfo(UseInst);
938+
939+
if (BI.Type != genx::BaleInfo::RDREGION ||
940+
!dyn_cast<ConstantInt>(UseInst->getOperand(RdIndex)) ||
941+
BI.isOperandBaled(RdNumOp) || !BA.isBaled(UseInst))
942+
return UseInst;
943+
944+
auto getSignConstant = [](Value *operand) {
945+
auto *CI = cast<ConstantInt>(operand);
946+
return CI->getSExtValue();
947+
};
948+
949+
// In this place comes rdregion, whose operand is not baled - here we
950+
// build location for its operand
951+
LLVM_DEBUG(dbgs() << " Found Bale candidate for propagation:\n";
952+
UseInst->dump(););
953+
auto *VTy = dyn_cast<IGCLLVM::FixedVectorType>(UseInst->getType());
954+
// TODO: Investigate scalar
955+
if (!VTy)
956+
return UseInst;
957+
auto Vstride = getSignConstant(UseInst->getOperand(RdVstride));
958+
auto Width = getSignConstant(UseInst->getOperand(RdWidth));
959+
auto Stride = getSignConstant(UseInst->getOperand(RdStride));
960+
auto StartIdx = getSignConstant(UseInst->getOperand(RdIndex));
961+
auto ElSize = vc::getTypeSize(VTy->getElementType(), &DL).inBits();
962+
IGC_ASSERT(Width);
963+
unsigned NumElements = VTy->getNumElements() / Width;
964+
965+
for (unsigned i = 0; i < NumElements; ++i) {
966+
for (unsigned j = 0; j < Width; ++j) {
967+
auto CurrOffset = StartIdx + i * Vstride * ElSize + j * Stride * ElSize;
968+
// Check type overflow
969+
IGC_ASSERT(CurrOffset <= std::numeric_limits<unsigned>::max());
970+
Offsets->push_back(CurrOffset);
971+
}
972+
}
973+
// Replace value to source of rdregion
974+
return UseInst->getOperand(RdNumOp);
975+
}
976+
916977
IGC::VISAVariableLocation
917978
GetVariableLocation(const Instruction *DbgInst) const override {
918-
919979
using Location = IGC::VISAVariableLocation;
920980
auto EmptyLoc = [this](StringRef Reason) {
921981
LLVM_DEBUG(dbgs() << " Empty Location Returned (" << Reason
922982
<< ")\n <<<\n");
923983
return Location(this);
924984
};
925-
auto ConstantLoc = [this](const Constant *C) {
926-
LLVM_DEBUG(dbgs() << " ConstantLoc\n <<<\n");
927-
return Location(C, this);
928-
};
929985

930986
IGC_ASSERT(isa<DbgInfoIntrinsic>(DbgInst));
931987

932988
LLVM_DEBUG(dbgs() << " >>>\n GetVariableLocation for " << *DbgInst << "\n");
933-
const Value *DbgValue = nullptr;
934989
const DIVariable *VarDescr = nullptr;
935990
if (const auto *pDbgAddrInst = dyn_cast<DbgDeclareInst>(DbgInst)) {
936-
DbgValue = pDbgAddrInst->getAddress();
937991
VarDescr = pDbgAddrInst->getVariable();
938992
} else if (const auto *pDbgValInst = dyn_cast<DbgValueInst>(DbgInst)) {
939-
DbgValue = pDbgValInst->getValue();
940993
VarDescr = pDbgValInst->getVariable();
941994
} else {
942995
return EmptyLoc("unsupported Debug Intrinsic");
943996
}
997+
const Value *DbgValue =
998+
IGCLLVM::getVariableLocation(cast<DbgVariableIntrinsic>(DbgInst));
999+
1000+
llvm::SmallVector<unsigned, 0> Offsets;
1001+
if (auto *UseInst = dyn_cast_or_null<CallInst>(DbgValue)) {
1002+
DbgValue = CalculateBaledLocation(UseInst, &Offsets, BA,
1003+
F.getParent()->getDataLayout());
1004+
if (!Offsets.empty() &&
1005+
!std::any_of(Offsets.begin(), Offsets.end(),
1006+
[&](auto off) { return off < getGRFSizeInBits(); })) {
1007+
return EmptyLoc("Unsupported cross-GRF offset\n");
1008+
}
1009+
}
9441010

9451011
IGC_ASSERT(VarDescr);
9461012
if (!DbgValue) {
@@ -957,23 +1023,16 @@ class GenXFunction final : public IGC::VISAModule {
9571023
return EmptyLoc("UndefValue");
9581024
}
9591025
if (auto *ConstVal = dyn_cast<Constant>(DbgValue)) {
960-
return ConstantLoc(ConstVal);
1026+
LLVM_DEBUG(dbgs() << " ConstantLoc\n <<<\n");
1027+
return Location(ConstVal, this);
9611028
}
9621029

9631030
auto *Reg = getRegisterForValue(DbgValue);
9641031
if (!Reg) {
9651032
return EmptyLoc("could not find virtual register");
9661033
}
9671034

968-
const bool IsRegister = true;
969-
const bool IsMemory = false;
970-
const bool IsGlobalASI = false;
971-
auto *VTy = dyn_cast<IGCLLVM::FixedVectorType>(DbgValue->getType());
972-
unsigned NumElements = VTy ? VTy->getNumElements() : 1;
973-
const bool IsVectorized = false;
974-
975-
return Location(Reg->Num, IsRegister, IsMemory, NumElements, IsVectorized,
976-
IsGlobalASI, this);
1035+
return Location(Reg->Num, std::move(Offsets), this);
9771036
}
9781037

9791038
void UpdateVisaId() override {
@@ -1063,6 +1122,7 @@ class GenXFunction final : public IGC::VISAModule {
10631122
const genx::di::VisaMapping &VisaMapping;
10641123
CompiledVisaWrapper CompiledVisa;
10651124
const GenXVisaRegAlloc &RA;
1125+
const GenXBaling &BA;
10661126
const ModuleToVisaTransformInfo &MVTI;
10671127
};
10681128

@@ -1146,7 +1206,8 @@ GenXObjectHolder buildGenXFunctionObject(const ModuleToVisaTransformInfo &MVTI,
11461206
const GenObjectWrapper &GOW,
11471207
const ProgramInfo::FunctionInfo &FI,
11481208
const GenXSubtarget &ST,
1149-
const GenXVisaRegAlloc &RA) {
1209+
const GenXVisaRegAlloc &RA,
1210+
const GenXBaling &BA) {
11501211
StringRef CompiledObjectName = FI.F.getName();
11511212
if (MVTI.isSubroutine(&FI.F))
11521213
CompiledObjectName = MVTI.getSubroutineOwner(&FI.F)->getName();
@@ -1157,22 +1218,26 @@ GenXObjectHolder buildGenXFunctionObject(const ModuleToVisaTransformInfo &MVTI,
11571218

11581219
bool IsPrimaryFunction = &GOW.getEntryPoint() == &FI.F;
11591220
return std::make_unique<GenXFunction>(
1160-
ST, RA, FI.F, std::move(CW), FI.VisaMapping, MVTI, IsPrimaryFunction);
1221+
ST, RA, BA, FI.F, std::move(CW), FI.VisaMapping, MVTI, IsPrimaryFunction);
11611222
}
11621223

11631224
using GenXObjectHolderList = std::vector<GenXObjectHolder>;
11641225
GenXObjectHolderList translateProgramInfoToGenXFunctionObjects(
11651226
const GenObjectWrapper &GOW, const ProgramInfo &PI, const GenXSubtarget &ST,
1166-
const std::vector<const GenXVisaRegAlloc *> &RAs) {
1227+
const std::vector<const GenXVisaRegAlloc *> &RAs,
1228+
const std::vector<const GenXBaling *> &BAs) {
11671229
const auto &MVTI = PI.MVTI;
11681230
GenXObjectHolderList GenXFunctionHolders;
11691231
IGC_ASSERT(PI.FIs.size() == RAs.size());
1170-
std::transform(
1171-
PI.FIs.begin(), PI.FIs.end(), RAs.begin(),
1172-
std::back_inserter(GenXFunctionHolders),
1173-
[&ST, &MVTI, &GOW](const auto &FI, const GenXVisaRegAlloc *const RA) {
1174-
return buildGenXFunctionObject(MVTI, GOW, FI, ST, *RA);
1175-
});
1232+
IGC_ASSERT(BAs.size() == RAs.size());
1233+
auto Zippy = llvm::zip(RAs, BAs);
1234+
std::transform(PI.FIs.begin(), PI.FIs.end(), Zippy.begin(),
1235+
std::back_inserter(GenXFunctionHolders),
1236+
[&ST, &MVTI, &GOW](const auto &FI, const auto &ZIP) {
1237+
const GenXVisaRegAlloc *RA = std::get<0>(ZIP);
1238+
const GenXBaling *BA = std::get<1>(ZIP);
1239+
return buildGenXFunctionObject(MVTI, GOW, FI, ST, *RA, *BA);
1240+
});
11761241
return GenXFunctionHolders;
11771242
}
11781243

@@ -1365,15 +1430,20 @@ void GenXDebugInfo::processKernel(const IGC::DebugEmitterOpts &DebugOpts,
13651430
.getGenXSubtarget();
13661431
auto *FGA = &getAnalysis<FunctionGroupAnalysis>();
13671432
std::vector<const GenXVisaRegAlloc *> VisaRegAllocs;
1433+
std::vector<const GenXBaling *> BalingList;
13681434
for (const auto &FP : PI.FIs) {
13691435
FunctionGroup *currentFG = FGA->getAnyGroup(&FP.F);
13701436
VisaRegAllocs.push_back(
13711437
&(getAnalysis<GenXVisaRegAllocWrapper>().getFGPassImpl(currentFG)));
1438+
GenXBaling *Baling =
1439+
&(getAnalysis<GenXGroupBalingWrapper>().getFGPassImpl(currentFG));
1440+
BalingList.push_back(Baling);
13721441
}
13731442

1374-
GenXFunctionPtrList GFPointers = initializeDebugEmitter(
1375-
*Emitter, DebugOpts, PI,
1376-
translateProgramInfoToGenXFunctionObjects(GOW, PI, ST, VisaRegAllocs));
1443+
GenXFunctionPtrList GFPointers =
1444+
initializeDebugEmitter(*Emitter, DebugOpts, PI,
1445+
translateProgramInfoToGenXFunctionObjects(
1446+
GOW, PI, ST, VisaRegAllocs, BalingList));
13771447

13781448
auto &KF = GOW.getEntryPoint();
13791449
IGC_ASSERT(ElfOutputs.count(&KF) == 0);
@@ -1421,6 +1491,7 @@ void GenXDebugInfo::getAnalysisUsage(AnalysisUsage &AU) const {
14211491
AU.addRequired<TargetPassConfig>();
14221492
AU.addRequired<GenXVisaRegAllocWrapper>();
14231493
AU.addRequired<CallGraphWrapperPass>();
1494+
AU.addRequired<GenXGroupBaling>();
14241495
AU.setPreservesAll();
14251496
}
14261497

0 commit comments

Comments
 (0)