@@ -1333,6 +1333,8 @@ void DwarfDebug::collectVariableInfo(const Function* MF, SmallPtrSet<const MDNod
13331333 std::vector<std::tuple<MDNode*, DILocation*, DbgVariable*>> addedEntries;
13341334 std::map<llvm::DIScope*, std::vector<llvm::Instruction*>> instsInScope;
13351335
1336+ TempDotDebugLocEntries.clear ();
1337+
13361338 auto isAdded = [&addedEntries](MDNode* md, DILocation* iat)
13371339 {
13381340 for (auto item : addedEntries)
@@ -1386,9 +1388,13 @@ void DwarfDebug::collectVariableInfo(const Function* MF, SmallPtrSet<const MDNod
13861388 return startEnd;
13871389 };
13881390
1389- auto encodeImm = [&](IGC::DotDebugLocEntry& dotLoc, uint64_t rangeStart, uint64_t rangeEnd,
1391+ auto encodeImm = [&](IGC::DotDebugLocEntry& dotLoc, uint32_t offset,
1392+ llvm::SmallVector<DotDebugLocEntry, 4 >& TempDotDebugLocEntries,
1393+ uint64_t rangeStart, uint64_t rangeEnd,
13901394 uint32_t pointerSize, DbgVariable* RegVar, const ConstantInt* pConstInt)
13911395 {
1396+ auto oldSize = dotLoc.loc .size ();
1397+
13921398 auto op = llvm::dwarf::DW_OP_implicit_value;
13931399 const unsigned int lebSize = 8 ;
13941400 write (dotLoc.loc , (unsigned char *)&rangeStart, pointerSize);
@@ -1406,23 +1412,81 @@ void DwarfDebug::collectVariableInfo(const Function* MF, SmallPtrSet<const MDNod
14061412 int64_t constValue = pConstInt->getSExtValue ();
14071413 write (dotLoc.loc , (unsigned char *)&constValue, lebSize);
14081414 }
1415+ offset += dotLoc.loc .size () - oldSize;
1416+
1417+ TempDotDebugLocEntries.push_back (dotLoc);
14091418 };
14101419
1411- auto encodeReg = [&](IGC::DotDebugLocEntry& dotLoc, uint64_t startRange, uint64_t endRange,
1420+ auto encodeReg = [&](IGC::DotDebugLocEntry& dotLoc, uint32_t offset,
1421+ llvm::SmallVector<DotDebugLocEntry, 4 >& TempDotDebugLocEntries,
1422+ uint64_t startRange, uint64_t endRange,
14121423 uint32_t pointerSize, DbgVariable* RegVar, std::vector<VISAVariableLocation>& Locs,
14131424 DbgDecoder::LiveIntervalsVISA& genIsaRange)
14141425 {
1415- write (dotLoc.loc , (unsigned char *)&startRange, pointerSize);
1416- write (dotLoc.loc , (unsigned char *)&endRange, pointerSize);
1417-
1426+ auto allCallerSave = m_pModule->getAllCallerSave (startRange, endRange, genIsaRange);
14181427 std::vector<DbgDecoder::LiveIntervalsVISA> vars = { genIsaRange };
1428+
1429+ auto oldSize = dotLoc.loc .size ();
1430+ dotLoc.start = startRange;
1431+ TempDotDebugLocEntries.push_back (dotLoc);
1432+ write (TempDotDebugLocEntries.back ().loc , (unsigned char *)&startRange, pointerSize);
1433+
1434+ for (auto it : allCallerSave)
1435+ {
1436+ TempDotDebugLocEntries.back ().end = std::get<0 >(it);
1437+ write (TempDotDebugLocEntries.back ().loc , (unsigned char *)&std::get<0 >(it), pointerSize);
1438+ auto block = FirstCU->buildGeneral (*RegVar, &Locs, &vars);
1439+ std::vector<unsigned char > buffer;
1440+ if (block)
1441+ block->EmitToRawBuffer (buffer);
1442+ write (TempDotDebugLocEntries.back ().loc , (uint16_t )buffer.size ());
1443+ write (TempDotDebugLocEntries.back ().loc , buffer.data (), buffer.size ());
1444+
1445+ offset += TempDotDebugLocEntries.back ().loc .size () - oldSize;
1446+
1447+ DotDebugLocEntry another (dotLoc.getStart (), dotLoc.getEnd (), dotLoc.getDbgInst (), dotLoc.getVariable ());
1448+ another.start = std::get<0 >(it);
1449+ another.end = std::get<1 >(it);
1450+ TempDotDebugLocEntries.push_back (another);
1451+ oldSize = TempDotDebugLocEntries.back ().loc .size ();
1452+ // write actual caller save location
1453+ write (TempDotDebugLocEntries.back ().loc , (unsigned char *)&std::get<0 >(it), pointerSize);
1454+ write (TempDotDebugLocEntries.back ().loc , (unsigned char *)&std::get<1 >(it), pointerSize);
1455+ auto callerSaveVars = vars;
1456+ callerSaveVars.front ().var .physicalType = DbgDecoder::VarAlloc::PhysicalVarType::PhyTypeMemory;
1457+ callerSaveVars.front ().var .mapping .m .isBaseOffBEFP = 0 ;
1458+ callerSaveVars.front ().var .mapping .m .memoryOffset = std::get<2 >(it);
1459+ block = FirstCU->buildGeneral (*RegVar, &Locs, &callerSaveVars);
1460+ buffer.clear ();
1461+ if (block)
1462+ block->EmitToRawBuffer (buffer);
1463+ write (TempDotDebugLocEntries.back ().loc , (uint16_t )buffer.size ());
1464+ write (TempDotDebugLocEntries.back ().loc , buffer.data (), buffer.size ());
1465+
1466+ offset += TempDotDebugLocEntries.back ().loc .size () - oldSize;
1467+
1468+ if (std::get<1 >(it) >= endRange)
1469+ return ;
1470+
1471+ // start new interval with original location
1472+ DotDebugLocEntry yetAnother (dotLoc.getStart (), dotLoc.getEnd (), dotLoc.getDbgInst (), dotLoc.getVariable ());
1473+ yetAnother.start = std::get<1 >(it);
1474+ TempDotDebugLocEntries.push_back (yetAnother);
1475+ oldSize = TempDotDebugLocEntries.back ().loc .size ();
1476+ write (TempDotDebugLocEntries.back ().loc , (unsigned char *)&std::get<1 >(it), pointerSize);
1477+ }
1478+
1479+ TempDotDebugLocEntries.back ().end = endRange;
1480+ write (TempDotDebugLocEntries.back ().loc , (unsigned char *)&endRange, pointerSize);
1481+
14191482 auto block = FirstCU->buildGeneral (*RegVar, &Locs, &vars);
14201483 std::vector<unsigned char > buffer;
14211484 if (block)
14221485 block->EmitToRawBuffer (buffer);
1423- write (dotLoc .loc , (uint16_t )buffer.size ());
1424- write (dotLoc .loc , buffer.data (), buffer.size ());
1486+ write (TempDotDebugLocEntries. back () .loc , (uint16_t )buffer.size ());
1487+ write (TempDotDebugLocEntries. back () .loc , buffer.data (), buffer.size ());
14251488
1489+ offset += TempDotDebugLocEntries.back ().loc .size () - oldSize;
14261490 };
14271491
14281492 unsigned int offset = 0 ;
@@ -1508,7 +1572,8 @@ void DwarfDebug::collectVariableInfo(const Function* MF, SmallPtrSet<const MDNod
15081572 AbsVar->setDbgInst (pInst);
15091573 }
15101574
1511- if (!m_pModule->isDirectElfInput || !EmitSettings.EmitDebugLoc )
1575+ bool needsCallerSave = m_pModule->getCompileUnit ()->cfi .numCallerSaveEntries > 0 ;
1576+ if ((!m_pModule->isDirectElfInput || !EmitSettings.EmitDebugLoc ) && !needsCallerSave)
15121577 continue ;
15131578
15141579 // assume that VISA preserves location thoughout its lifetime
@@ -1540,7 +1605,7 @@ void DwarfDebug::collectVariableInfo(const Function* MF, SmallPtrSet<const MDNod
15401605 auto GenISARange = m_pModule->getGenISARange (InsnRange);
15411606
15421607 // Emit location within the DIE for dbg.declare
1543- if (History.size () == 1 && isa<DbgDeclareInst>(pInst))
1608+ if (History.size () == 1 && isa<DbgDeclareInst>(pInst) && !needsCallerSave )
15441609 continue ;
15451610
15461611 for (auto range : GenISARange)
@@ -1578,22 +1643,20 @@ void DwarfDebug::collectVariableInfo(const Function* MF, SmallPtrSet<const MDNod
15781643 };
15791644
15801645 PrevLoc p;
1581- auto encodePrevLoc = [&](DotDebugLocEntry& dotLoc, unsigned int & offset)
1646+ auto encodePrevLoc = [&](DotDebugLocEntry& dotLoc, llvm::SmallVector<DotDebugLocEntry, 4 >& TempDotDebugLocEntries, unsigned int & offset)
15821647 {
15831648 if (p.dbgVar ->getDotDebugLocOffset () == ~0U )
15841649 {
15851650 p.dbgVar ->setDotDebugLocOffset (offset);
15861651 }
1587- auto oldSize = dotLoc.loc .size ();
15881652 if (p.t == PrevLoc::Type::Imm)
15891653 {
1590- encodeImm (dotLoc, p.start , p.end , pointerSize, p.dbgVar , p.imm );
1654+ encodeImm (dotLoc, offset, TempDotDebugLocEntries, p.start , p.end , pointerSize, p.dbgVar , p.imm );
15911655 }
15921656 else
15931657 {
1594- encodeReg (dotLoc, p.start , p.end , pointerSize, p.dbgVar , p.Locs , p.genIsaRange );
1658+ encodeReg (dotLoc, offset, TempDotDebugLocEntries, p.start , p.end , pointerSize, p.dbgVar , p.Locs , p.genIsaRange );
15951659 }
1596- offset += dotLoc.loc .size () - oldSize;
15971660 p.t = PrevLoc::Type::Empty;
15981661 };
15991662 for (auto & range : d.second )
@@ -1640,8 +1703,7 @@ void DwarfDebug::collectVariableInfo(const Function* MF, SmallPtrSet<const MDNod
16401703 if (p.t != PrevLoc::Type::Empty)
16411704 {
16421705 // Emit previous location to debug_loc
1643- encodePrevLoc (dotLoc, offset);
1644- TempDotDebugLocEntries.push_back (dotLoc);
1706+ encodePrevLoc (dotLoc, TempDotDebugLocEntries, offset);
16451707 }
16461708
16471709 p.t = PrevLoc::Type::Imm;
@@ -1697,8 +1759,7 @@ void DwarfDebug::collectVariableInfo(const Function* MF, SmallPtrSet<const MDNod
16971759
16981760 if (p.t != PrevLoc::Type::Empty)
16991761 {
1700- encodePrevLoc (dotLoc, offset);
1701- TempDotDebugLocEntries.push_back (dotLoc);
1762+ encodePrevLoc (dotLoc, TempDotDebugLocEntries, offset);
17021763 }
17031764
17041765 p.t = PrevLoc::Type::Reg;
@@ -1716,8 +1777,7 @@ void DwarfDebug::collectVariableInfo(const Function* MF, SmallPtrSet<const MDNod
17161777 {
17171778 DotDebugLocEntry dotLoc (p.start , p.end , p.pInst , DV);
17181779 dotLoc.setOffset (offset);
1719- encodePrevLoc (dotLoc, offset);
1720- TempDotDebugLocEntries.push_back (dotLoc);
1780+ encodePrevLoc (dotLoc, TempDotDebugLocEntries, offset);
17211781 }
17221782
17231783 if (TempDotDebugLocEntries.size () > origLocSize)
@@ -1786,7 +1846,6 @@ unsigned int DwarfDebug::CopyDebugLoc(unsigned int o)
17861846 {
17871847 // Append data to DotLocEntries
17881848 DotDebugLocEntries.push_back (TempDotDebugLocEntries[index]);
1789-
17901849 if (TempDotDebugLocEntries[index].isEmpty ())
17911850 {
17921851 done = true ;
0 commit comments