13ca95b02SDimitry Andric //===-- llvm/lib/CodeGen/AsmPrinter/DebugHandlerBase.cpp -------*- C++ -*--===//
23ca95b02SDimitry Andric //
33ca95b02SDimitry Andric //                     The LLVM Compiler Infrastructure
43ca95b02SDimitry Andric //
53ca95b02SDimitry Andric // This file is distributed under the University of Illinois Open Source
63ca95b02SDimitry Andric // License. See LICENSE.TXT for details.
73ca95b02SDimitry Andric //
83ca95b02SDimitry Andric //===----------------------------------------------------------------------===//
93ca95b02SDimitry Andric //
103ca95b02SDimitry Andric // Common functionality for different debug information format backends.
113ca95b02SDimitry Andric // LLVM currently supports DWARF and CodeView.
123ca95b02SDimitry Andric //
133ca95b02SDimitry Andric //===----------------------------------------------------------------------===//
143ca95b02SDimitry Andric 
153ca95b02SDimitry Andric #include "DebugHandlerBase.h"
163ca95b02SDimitry Andric #include "llvm/CodeGen/AsmPrinter.h"
173ca95b02SDimitry Andric #include "llvm/CodeGen/MachineFunction.h"
183ca95b02SDimitry Andric #include "llvm/CodeGen/MachineInstr.h"
193ca95b02SDimitry Andric #include "llvm/CodeGen/MachineModuleInfo.h"
203ca95b02SDimitry Andric #include "llvm/IR/DebugInfo.h"
21d88c1a5aSDimitry Andric #include "llvm/MC/MCStreamer.h"
223ca95b02SDimitry Andric #include "llvm/Target/TargetSubtargetInfo.h"
233ca95b02SDimitry Andric 
243ca95b02SDimitry Andric using namespace llvm;
253ca95b02SDimitry Andric 
263ca95b02SDimitry Andric DebugHandlerBase::DebugHandlerBase(AsmPrinter *A) : Asm(A), MMI(Asm->MMI) {}
273ca95b02SDimitry Andric 
283ca95b02SDimitry Andric // Each LexicalScope has first instruction and last instruction to mark
293ca95b02SDimitry Andric // beginning and end of a scope respectively. Create an inverse map that list
303ca95b02SDimitry Andric // scopes starts (and ends) with an instruction. One instruction may start (or
313ca95b02SDimitry Andric // end) multiple scopes. Ignore scopes that are not reachable.
323ca95b02SDimitry Andric void DebugHandlerBase::identifyScopeMarkers() {
333ca95b02SDimitry Andric   SmallVector<LexicalScope *, 4> WorkList;
343ca95b02SDimitry Andric   WorkList.push_back(LScopes.getCurrentFunctionScope());
353ca95b02SDimitry Andric   while (!WorkList.empty()) {
363ca95b02SDimitry Andric     LexicalScope *S = WorkList.pop_back_val();
373ca95b02SDimitry Andric 
383ca95b02SDimitry Andric     const SmallVectorImpl<LexicalScope *> &Children = S->getChildren();
393ca95b02SDimitry Andric     if (!Children.empty())
403ca95b02SDimitry Andric       WorkList.append(Children.begin(), Children.end());
413ca95b02SDimitry Andric 
423ca95b02SDimitry Andric     if (S->isAbstractScope())
433ca95b02SDimitry Andric       continue;
443ca95b02SDimitry Andric 
453ca95b02SDimitry Andric     for (const InsnRange &R : S->getRanges()) {
463ca95b02SDimitry Andric       assert(R.first && "InsnRange does not have first instruction!");
473ca95b02SDimitry Andric       assert(R.second && "InsnRange does not have second instruction!");
483ca95b02SDimitry Andric       requestLabelBeforeInsn(R.first);
493ca95b02SDimitry Andric       requestLabelAfterInsn(R.second);
503ca95b02SDimitry Andric     }
513ca95b02SDimitry Andric   }
523ca95b02SDimitry Andric }
533ca95b02SDimitry Andric 
543ca95b02SDimitry Andric // Return Label preceding the instruction.
553ca95b02SDimitry Andric MCSymbol *DebugHandlerBase::getLabelBeforeInsn(const MachineInstr *MI) {
563ca95b02SDimitry Andric   MCSymbol *Label = LabelsBeforeInsn.lookup(MI);
573ca95b02SDimitry Andric   assert(Label && "Didn't insert label before instruction");
583ca95b02SDimitry Andric   return Label;
593ca95b02SDimitry Andric }
603ca95b02SDimitry Andric 
613ca95b02SDimitry Andric // Return Label immediately following the instruction.
623ca95b02SDimitry Andric MCSymbol *DebugHandlerBase::getLabelAfterInsn(const MachineInstr *MI) {
633ca95b02SDimitry Andric   return LabelsAfterInsn.lookup(MI);
643ca95b02SDimitry Andric }
653ca95b02SDimitry Andric 
66d88c1a5aSDimitry Andric int DebugHandlerBase::fragmentCmp(const DIExpression *P1,
67d88c1a5aSDimitry Andric                                   const DIExpression *P2) {
68d88c1a5aSDimitry Andric   auto Fragment1 = *P1->getFragmentInfo();
69d88c1a5aSDimitry Andric   auto Fragment2 = *P2->getFragmentInfo();
70d88c1a5aSDimitry Andric   unsigned l1 = Fragment1.OffsetInBits;
71d88c1a5aSDimitry Andric   unsigned l2 = Fragment2.OffsetInBits;
72d88c1a5aSDimitry Andric   unsigned r1 = l1 + Fragment1.SizeInBits;
73d88c1a5aSDimitry Andric   unsigned r2 = l2 + Fragment2.SizeInBits;
743ca95b02SDimitry Andric   if (r1 <= l2)
753ca95b02SDimitry Andric     return -1;
763ca95b02SDimitry Andric   else if (r2 <= l1)
773ca95b02SDimitry Andric     return 1;
783ca95b02SDimitry Andric   else
793ca95b02SDimitry Andric     return 0;
803ca95b02SDimitry Andric }
813ca95b02SDimitry Andric 
82d88c1a5aSDimitry Andric bool DebugHandlerBase::fragmentsOverlap(const DIExpression *P1,
83d88c1a5aSDimitry Andric                                         const DIExpression *P2) {
84d88c1a5aSDimitry Andric   if (!P1->isFragment() || !P2->isFragment())
853ca95b02SDimitry Andric     return true;
86d88c1a5aSDimitry Andric   return fragmentCmp(P1, P2) == 0;
873ca95b02SDimitry Andric }
883ca95b02SDimitry Andric 
893ca95b02SDimitry Andric /// If this type is derived from a base type then return base type size.
903ca95b02SDimitry Andric uint64_t DebugHandlerBase::getBaseTypeSize(const DITypeRef TyRef) {
913ca95b02SDimitry Andric   DIType *Ty = TyRef.resolve();
923ca95b02SDimitry Andric   assert(Ty);
933ca95b02SDimitry Andric   DIDerivedType *DDTy = dyn_cast<DIDerivedType>(Ty);
943ca95b02SDimitry Andric   if (!DDTy)
953ca95b02SDimitry Andric     return Ty->getSizeInBits();
963ca95b02SDimitry Andric 
973ca95b02SDimitry Andric   unsigned Tag = DDTy->getTag();
983ca95b02SDimitry Andric 
993ca95b02SDimitry Andric   if (Tag != dwarf::DW_TAG_member && Tag != dwarf::DW_TAG_typedef &&
1003ca95b02SDimitry Andric       Tag != dwarf::DW_TAG_const_type && Tag != dwarf::DW_TAG_volatile_type &&
101d88c1a5aSDimitry Andric       Tag != dwarf::DW_TAG_restrict_type && Tag != dwarf::DW_TAG_atomic_type)
1023ca95b02SDimitry Andric     return DDTy->getSizeInBits();
1033ca95b02SDimitry Andric 
1043ca95b02SDimitry Andric   DIType *BaseType = DDTy->getBaseType().resolve();
1053ca95b02SDimitry Andric 
1063ca95b02SDimitry Andric   assert(BaseType && "Unexpected invalid base type");
1073ca95b02SDimitry Andric 
1083ca95b02SDimitry Andric   // If this is a derived type, go ahead and get the base type, unless it's a
1093ca95b02SDimitry Andric   // reference then it's just the size of the field. Pointer types have no need
1103ca95b02SDimitry Andric   // of this since they're a different type of qualification on the type.
1113ca95b02SDimitry Andric   if (BaseType->getTag() == dwarf::DW_TAG_reference_type ||
1123ca95b02SDimitry Andric       BaseType->getTag() == dwarf::DW_TAG_rvalue_reference_type)
1133ca95b02SDimitry Andric     return Ty->getSizeInBits();
1143ca95b02SDimitry Andric 
1153ca95b02SDimitry Andric   return getBaseTypeSize(BaseType);
1163ca95b02SDimitry Andric }
1173ca95b02SDimitry Andric 
118302affcbSDimitry Andric static bool hasDebugInfo(const MachineModuleInfo *MMI,
119302affcbSDimitry Andric                          const MachineFunction *MF) {
1207a7e6055SDimitry Andric   if (!MMI->hasDebugInfo())
1217a7e6055SDimitry Andric     return false;
1227a7e6055SDimitry Andric   auto *SP = MF->getFunction()->getSubprogram();
1237a7e6055SDimitry Andric   if (!SP)
1247a7e6055SDimitry Andric     return false;
1257a7e6055SDimitry Andric   assert(SP->getUnit());
1267a7e6055SDimitry Andric   auto EK = SP->getUnit()->getEmissionKind();
1277a7e6055SDimitry Andric   if (EK == DICompileUnit::NoDebug)
1287a7e6055SDimitry Andric     return false;
1297a7e6055SDimitry Andric   return true;
1307a7e6055SDimitry Andric }
1317a7e6055SDimitry Andric 
1323ca95b02SDimitry Andric void DebugHandlerBase::beginFunction(const MachineFunction *MF) {
1337a7e6055SDimitry Andric   PrevInstBB = nullptr;
1347a7e6055SDimitry Andric 
1355517e702SDimitry Andric   if (!Asm || !hasDebugInfo(MMI, MF)) {
1367a7e6055SDimitry Andric     skippedNonDebugFunction();
1377a7e6055SDimitry Andric     return;
1387a7e6055SDimitry Andric   }
1397a7e6055SDimitry Andric 
1403ca95b02SDimitry Andric   // Grab the lexical scopes for the function, if we don't have any of those
1413ca95b02SDimitry Andric   // then we're not going to be able to do anything.
1423ca95b02SDimitry Andric   LScopes.initialize(*MF);
1437a7e6055SDimitry Andric   if (LScopes.empty()) {
1447a7e6055SDimitry Andric     beginFunctionImpl(MF);
1453ca95b02SDimitry Andric     return;
1467a7e6055SDimitry Andric   }
1473ca95b02SDimitry Andric 
1483ca95b02SDimitry Andric   // Make sure that each lexical scope will have a begin/end label.
1493ca95b02SDimitry Andric   identifyScopeMarkers();
1503ca95b02SDimitry Andric 
1513ca95b02SDimitry Andric   // Calculate history for local variables.
1523ca95b02SDimitry Andric   assert(DbgValues.empty() && "DbgValues map wasn't cleaned!");
1533ca95b02SDimitry Andric   calculateDbgValueHistory(MF, Asm->MF->getSubtarget().getRegisterInfo(),
1543ca95b02SDimitry Andric                            DbgValues);
1553ca95b02SDimitry Andric 
1563ca95b02SDimitry Andric   // Request labels for the full history.
1573ca95b02SDimitry Andric   for (const auto &I : DbgValues) {
1583ca95b02SDimitry Andric     const auto &Ranges = I.second;
1593ca95b02SDimitry Andric     if (Ranges.empty())
1603ca95b02SDimitry Andric       continue;
1613ca95b02SDimitry Andric 
1623ca95b02SDimitry Andric     // The first mention of a function argument gets the CurrentFnBegin
1633ca95b02SDimitry Andric     // label, so arguments are visible when breaking at function entry.
1643ca95b02SDimitry Andric     const DILocalVariable *DIVar = Ranges.front().first->getDebugVariable();
1653ca95b02SDimitry Andric     if (DIVar->isParameter() &&
1663ca95b02SDimitry Andric         getDISubprogram(DIVar->getScope())->describes(MF->getFunction())) {
1673ca95b02SDimitry Andric       LabelsBeforeInsn[Ranges.front().first] = Asm->getFunctionBegin();
168d88c1a5aSDimitry Andric       if (Ranges.front().first->getDebugExpression()->isFragment()) {
169d88c1a5aSDimitry Andric         // Mark all non-overlapping initial fragments.
1703ca95b02SDimitry Andric         for (auto I = Ranges.begin(); I != Ranges.end(); ++I) {
171d88c1a5aSDimitry Andric           const DIExpression *Fragment = I->first->getDebugExpression();
1723ca95b02SDimitry Andric           if (std::all_of(Ranges.begin(), I,
1733ca95b02SDimitry Andric                           [&](DbgValueHistoryMap::InstrRange Pred) {
174d88c1a5aSDimitry Andric                             return !fragmentsOverlap(
175d88c1a5aSDimitry Andric                                 Fragment, Pred.first->getDebugExpression());
1763ca95b02SDimitry Andric                           }))
1773ca95b02SDimitry Andric             LabelsBeforeInsn[I->first] = Asm->getFunctionBegin();
1783ca95b02SDimitry Andric           else
1793ca95b02SDimitry Andric             break;
1803ca95b02SDimitry Andric         }
1813ca95b02SDimitry Andric       }
1823ca95b02SDimitry Andric     }
1833ca95b02SDimitry Andric 
1843ca95b02SDimitry Andric     for (const auto &Range : Ranges) {
1853ca95b02SDimitry Andric       requestLabelBeforeInsn(Range.first);
1863ca95b02SDimitry Andric       if (Range.second)
1873ca95b02SDimitry Andric         requestLabelAfterInsn(Range.second);
1883ca95b02SDimitry Andric     }
1893ca95b02SDimitry Andric   }
1903ca95b02SDimitry Andric 
1913ca95b02SDimitry Andric   PrevInstLoc = DebugLoc();
1923ca95b02SDimitry Andric   PrevLabel = Asm->getFunctionBegin();
1937a7e6055SDimitry Andric   beginFunctionImpl(MF);
1943ca95b02SDimitry Andric }
1953ca95b02SDimitry Andric 
1963ca95b02SDimitry Andric void DebugHandlerBase::beginInstruction(const MachineInstr *MI) {
1973ca95b02SDimitry Andric   if (!MMI->hasDebugInfo())
1983ca95b02SDimitry Andric     return;
1993ca95b02SDimitry Andric 
2003ca95b02SDimitry Andric   assert(CurMI == nullptr);
2013ca95b02SDimitry Andric   CurMI = MI;
2023ca95b02SDimitry Andric 
2033ca95b02SDimitry Andric   // Insert labels where requested.
2043ca95b02SDimitry Andric   DenseMap<const MachineInstr *, MCSymbol *>::iterator I =
2053ca95b02SDimitry Andric       LabelsBeforeInsn.find(MI);
2063ca95b02SDimitry Andric 
2073ca95b02SDimitry Andric   // No label needed.
2083ca95b02SDimitry Andric   if (I == LabelsBeforeInsn.end())
2093ca95b02SDimitry Andric     return;
2103ca95b02SDimitry Andric 
2113ca95b02SDimitry Andric   // Label already assigned.
2123ca95b02SDimitry Andric   if (I->second)
2133ca95b02SDimitry Andric     return;
2143ca95b02SDimitry Andric 
2153ca95b02SDimitry Andric   if (!PrevLabel) {
2163ca95b02SDimitry Andric     PrevLabel = MMI->getContext().createTempSymbol();
2173ca95b02SDimitry Andric     Asm->OutStreamer->EmitLabel(PrevLabel);
2183ca95b02SDimitry Andric   }
2193ca95b02SDimitry Andric   I->second = PrevLabel;
2203ca95b02SDimitry Andric }
2213ca95b02SDimitry Andric 
2223ca95b02SDimitry Andric void DebugHandlerBase::endInstruction() {
2233ca95b02SDimitry Andric   if (!MMI->hasDebugInfo())
2243ca95b02SDimitry Andric     return;
2253ca95b02SDimitry Andric 
2263ca95b02SDimitry Andric   assert(CurMI != nullptr);
227302affcbSDimitry Andric   // Don't create a new label after DBG_VALUE and other instructions that don't
228302affcbSDimitry Andric   // generate code.
229302affcbSDimitry Andric   if (!CurMI->isMetaInstruction()) {
2303ca95b02SDimitry Andric     PrevLabel = nullptr;
231d88c1a5aSDimitry Andric     PrevInstBB = CurMI->getParent();
232d88c1a5aSDimitry Andric   }
2333ca95b02SDimitry Andric 
2343ca95b02SDimitry Andric   DenseMap<const MachineInstr *, MCSymbol *>::iterator I =
2353ca95b02SDimitry Andric       LabelsAfterInsn.find(CurMI);
2363ca95b02SDimitry Andric   CurMI = nullptr;
2373ca95b02SDimitry Andric 
2383ca95b02SDimitry Andric   // No label needed.
2393ca95b02SDimitry Andric   if (I == LabelsAfterInsn.end())
2403ca95b02SDimitry Andric     return;
2413ca95b02SDimitry Andric 
2423ca95b02SDimitry Andric   // Label already assigned.
2433ca95b02SDimitry Andric   if (I->second)
2443ca95b02SDimitry Andric     return;
2453ca95b02SDimitry Andric 
2463ca95b02SDimitry Andric   // We need a label after this instruction.
2473ca95b02SDimitry Andric   if (!PrevLabel) {
2483ca95b02SDimitry Andric     PrevLabel = MMI->getContext().createTempSymbol();
2493ca95b02SDimitry Andric     Asm->OutStreamer->EmitLabel(PrevLabel);
2503ca95b02SDimitry Andric   }
2513ca95b02SDimitry Andric   I->second = PrevLabel;
2523ca95b02SDimitry Andric }
2533ca95b02SDimitry Andric 
2543ca95b02SDimitry Andric void DebugHandlerBase::endFunction(const MachineFunction *MF) {
2557a7e6055SDimitry Andric   if (hasDebugInfo(MMI, MF))
2567a7e6055SDimitry Andric     endFunctionImpl(MF);
2573ca95b02SDimitry Andric   DbgValues.clear();
2583ca95b02SDimitry Andric   LabelsBeforeInsn.clear();
2593ca95b02SDimitry Andric   LabelsAfterInsn.clear();
2603ca95b02SDimitry Andric }
261