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 
15*b5893f02SDimitry Andric #include "llvm/CodeGen/DebugHandlerBase.h"
162cab237bSDimitry Andric #include "llvm/ADT/Optional.h"
172cab237bSDimitry Andric #include "llvm/ADT/Twine.h"
183ca95b02SDimitry Andric #include "llvm/CodeGen/AsmPrinter.h"
193ca95b02SDimitry Andric #include "llvm/CodeGen/MachineFunction.h"
203ca95b02SDimitry Andric #include "llvm/CodeGen/MachineInstr.h"
213ca95b02SDimitry Andric #include "llvm/CodeGen/MachineModuleInfo.h"
222cab237bSDimitry Andric #include "llvm/CodeGen/TargetSubtargetInfo.h"
233ca95b02SDimitry Andric #include "llvm/IR/DebugInfo.h"
24d88c1a5aSDimitry Andric #include "llvm/MC/MCStreamer.h"
253ca95b02SDimitry Andric 
263ca95b02SDimitry Andric using namespace llvm;
273ca95b02SDimitry Andric 
284ba319b5SDimitry Andric #define DEBUG_TYPE "dwarfdebug"
294ba319b5SDimitry Andric 
302cab237bSDimitry Andric Optional<DbgVariableLocation>
extractFromMachineInstruction(const MachineInstr & Instruction)312cab237bSDimitry Andric DbgVariableLocation::extractFromMachineInstruction(
322cab237bSDimitry Andric     const MachineInstr &Instruction) {
332cab237bSDimitry Andric   DbgVariableLocation Location;
342cab237bSDimitry Andric   if (!Instruction.isDebugValue())
352cab237bSDimitry Andric     return None;
362cab237bSDimitry Andric   if (!Instruction.getOperand(0).isReg())
372cab237bSDimitry Andric     return None;
382cab237bSDimitry Andric   Location.Register = Instruction.getOperand(0).getReg();
392cab237bSDimitry Andric   Location.FragmentInfo.reset();
402cab237bSDimitry Andric   // We only handle expressions generated by DIExpression::appendOffset,
412cab237bSDimitry Andric   // which doesn't require a full stack machine.
422cab237bSDimitry Andric   int64_t Offset = 0;
432cab237bSDimitry Andric   const DIExpression *DIExpr = Instruction.getDebugExpression();
442cab237bSDimitry Andric   auto Op = DIExpr->expr_op_begin();
452cab237bSDimitry Andric   while (Op != DIExpr->expr_op_end()) {
462cab237bSDimitry Andric     switch (Op->getOp()) {
472cab237bSDimitry Andric     case dwarf::DW_OP_constu: {
482cab237bSDimitry Andric       int Value = Op->getArg(0);
492cab237bSDimitry Andric       ++Op;
502cab237bSDimitry Andric       if (Op != DIExpr->expr_op_end()) {
512cab237bSDimitry Andric         switch (Op->getOp()) {
522cab237bSDimitry Andric         case dwarf::DW_OP_minus:
532cab237bSDimitry Andric           Offset -= Value;
542cab237bSDimitry Andric           break;
552cab237bSDimitry Andric         case dwarf::DW_OP_plus:
562cab237bSDimitry Andric           Offset += Value;
572cab237bSDimitry Andric           break;
582cab237bSDimitry Andric         default:
592cab237bSDimitry Andric           continue;
602cab237bSDimitry Andric         }
612cab237bSDimitry Andric       }
622cab237bSDimitry Andric     } break;
632cab237bSDimitry Andric     case dwarf::DW_OP_plus_uconst:
642cab237bSDimitry Andric       Offset += Op->getArg(0);
652cab237bSDimitry Andric       break;
662cab237bSDimitry Andric     case dwarf::DW_OP_LLVM_fragment:
672cab237bSDimitry Andric       Location.FragmentInfo = {Op->getArg(1), Op->getArg(0)};
682cab237bSDimitry Andric       break;
692cab237bSDimitry Andric     case dwarf::DW_OP_deref:
702cab237bSDimitry Andric       Location.LoadChain.push_back(Offset);
712cab237bSDimitry Andric       Offset = 0;
722cab237bSDimitry Andric       break;
732cab237bSDimitry Andric     default:
742cab237bSDimitry Andric       return None;
752cab237bSDimitry Andric     }
762cab237bSDimitry Andric     ++Op;
772cab237bSDimitry Andric   }
782cab237bSDimitry Andric 
792cab237bSDimitry Andric   // Do one final implicit DW_OP_deref if this was an indirect DBG_VALUE
802cab237bSDimitry Andric   // instruction.
812cab237bSDimitry Andric   // FIXME: Replace these with DIExpression.
822cab237bSDimitry Andric   if (Instruction.isIndirectDebugValue())
832cab237bSDimitry Andric     Location.LoadChain.push_back(Offset);
842cab237bSDimitry Andric 
852cab237bSDimitry Andric   return Location;
862cab237bSDimitry Andric }
872cab237bSDimitry Andric 
DebugHandlerBase(AsmPrinter * A)883ca95b02SDimitry Andric DebugHandlerBase::DebugHandlerBase(AsmPrinter *A) : Asm(A), MMI(Asm->MMI) {}
893ca95b02SDimitry Andric 
903ca95b02SDimitry Andric // Each LexicalScope has first instruction and last instruction to mark
913ca95b02SDimitry Andric // beginning and end of a scope respectively. Create an inverse map that list
923ca95b02SDimitry Andric // scopes starts (and ends) with an instruction. One instruction may start (or
933ca95b02SDimitry Andric // end) multiple scopes. Ignore scopes that are not reachable.
identifyScopeMarkers()943ca95b02SDimitry Andric void DebugHandlerBase::identifyScopeMarkers() {
953ca95b02SDimitry Andric   SmallVector<LexicalScope *, 4> WorkList;
963ca95b02SDimitry Andric   WorkList.push_back(LScopes.getCurrentFunctionScope());
973ca95b02SDimitry Andric   while (!WorkList.empty()) {
983ca95b02SDimitry Andric     LexicalScope *S = WorkList.pop_back_val();
993ca95b02SDimitry Andric 
1003ca95b02SDimitry Andric     const SmallVectorImpl<LexicalScope *> &Children = S->getChildren();
1013ca95b02SDimitry Andric     if (!Children.empty())
1023ca95b02SDimitry Andric       WorkList.append(Children.begin(), Children.end());
1033ca95b02SDimitry Andric 
1043ca95b02SDimitry Andric     if (S->isAbstractScope())
1053ca95b02SDimitry Andric       continue;
1063ca95b02SDimitry Andric 
1073ca95b02SDimitry Andric     for (const InsnRange &R : S->getRanges()) {
1083ca95b02SDimitry Andric       assert(R.first && "InsnRange does not have first instruction!");
1093ca95b02SDimitry Andric       assert(R.second && "InsnRange does not have second instruction!");
1103ca95b02SDimitry Andric       requestLabelBeforeInsn(R.first);
1113ca95b02SDimitry Andric       requestLabelAfterInsn(R.second);
1123ca95b02SDimitry Andric     }
1133ca95b02SDimitry Andric   }
1143ca95b02SDimitry Andric }
1153ca95b02SDimitry Andric 
1163ca95b02SDimitry Andric // Return Label preceding the instruction.
getLabelBeforeInsn(const MachineInstr * MI)1173ca95b02SDimitry Andric MCSymbol *DebugHandlerBase::getLabelBeforeInsn(const MachineInstr *MI) {
1183ca95b02SDimitry Andric   MCSymbol *Label = LabelsBeforeInsn.lookup(MI);
1193ca95b02SDimitry Andric   assert(Label && "Didn't insert label before instruction");
1203ca95b02SDimitry Andric   return Label;
1213ca95b02SDimitry Andric }
1223ca95b02SDimitry Andric 
1233ca95b02SDimitry Andric // Return Label immediately following the instruction.
getLabelAfterInsn(const MachineInstr * MI)1243ca95b02SDimitry Andric MCSymbol *DebugHandlerBase::getLabelAfterInsn(const MachineInstr *MI) {
1253ca95b02SDimitry Andric   return LabelsAfterInsn.lookup(MI);
1263ca95b02SDimitry Andric }
1273ca95b02SDimitry Andric 
128*b5893f02SDimitry Andric // Return the function-local offset of an instruction.
129*b5893f02SDimitry Andric const MCExpr *
getFunctionLocalOffsetAfterInsn(const MachineInstr * MI)130*b5893f02SDimitry Andric DebugHandlerBase::getFunctionLocalOffsetAfterInsn(const MachineInstr *MI) {
131*b5893f02SDimitry Andric   MCContext &MC = Asm->OutContext;
132*b5893f02SDimitry Andric 
133*b5893f02SDimitry Andric   MCSymbol *Start = Asm->getFunctionBegin();
134*b5893f02SDimitry Andric   const auto *StartRef = MCSymbolRefExpr::create(Start, MC);
135*b5893f02SDimitry Andric 
136*b5893f02SDimitry Andric   MCSymbol *AfterInsn = getLabelAfterInsn(MI);
137*b5893f02SDimitry Andric   assert(AfterInsn && "Expected label after instruction");
138*b5893f02SDimitry Andric   const auto *AfterRef = MCSymbolRefExpr::create(AfterInsn, MC);
139*b5893f02SDimitry Andric 
140*b5893f02SDimitry Andric   return MCBinaryExpr::createSub(AfterRef, StartRef, MC);
141*b5893f02SDimitry Andric }
142*b5893f02SDimitry Andric 
1433ca95b02SDimitry Andric /// If this type is derived from a base type then return base type size.
getBaseTypeSize(const DITypeRef TyRef)1443ca95b02SDimitry Andric uint64_t DebugHandlerBase::getBaseTypeSize(const DITypeRef TyRef) {
1453ca95b02SDimitry Andric   DIType *Ty = TyRef.resolve();
1463ca95b02SDimitry Andric   assert(Ty);
1473ca95b02SDimitry Andric   DIDerivedType *DDTy = dyn_cast<DIDerivedType>(Ty);
1483ca95b02SDimitry Andric   if (!DDTy)
1493ca95b02SDimitry Andric     return Ty->getSizeInBits();
1503ca95b02SDimitry Andric 
1513ca95b02SDimitry Andric   unsigned Tag = DDTy->getTag();
1523ca95b02SDimitry Andric 
1533ca95b02SDimitry Andric   if (Tag != dwarf::DW_TAG_member && Tag != dwarf::DW_TAG_typedef &&
1543ca95b02SDimitry Andric       Tag != dwarf::DW_TAG_const_type && Tag != dwarf::DW_TAG_volatile_type &&
155d88c1a5aSDimitry Andric       Tag != dwarf::DW_TAG_restrict_type && Tag != dwarf::DW_TAG_atomic_type)
1563ca95b02SDimitry Andric     return DDTy->getSizeInBits();
1573ca95b02SDimitry Andric 
1583ca95b02SDimitry Andric   DIType *BaseType = DDTy->getBaseType().resolve();
1593ca95b02SDimitry Andric 
160954b921dSDimitry Andric   if (!BaseType)
161954b921dSDimitry Andric     return 0;
1623ca95b02SDimitry Andric 
1633ca95b02SDimitry Andric   // If this is a derived type, go ahead and get the base type, unless it's a
1643ca95b02SDimitry Andric   // reference then it's just the size of the field. Pointer types have no need
1653ca95b02SDimitry Andric   // of this since they're a different type of qualification on the type.
1663ca95b02SDimitry Andric   if (BaseType->getTag() == dwarf::DW_TAG_reference_type ||
1673ca95b02SDimitry Andric       BaseType->getTag() == dwarf::DW_TAG_rvalue_reference_type)
1683ca95b02SDimitry Andric     return Ty->getSizeInBits();
1693ca95b02SDimitry Andric 
1703ca95b02SDimitry Andric   return getBaseTypeSize(BaseType);
1713ca95b02SDimitry Andric }
1723ca95b02SDimitry Andric 
hasDebugInfo(const MachineModuleInfo * MMI,const MachineFunction * MF)173302affcbSDimitry Andric static bool hasDebugInfo(const MachineModuleInfo *MMI,
174302affcbSDimitry Andric                          const MachineFunction *MF) {
1757a7e6055SDimitry Andric   if (!MMI->hasDebugInfo())
1767a7e6055SDimitry Andric     return false;
1772cab237bSDimitry Andric   auto *SP = MF->getFunction().getSubprogram();
1787a7e6055SDimitry Andric   if (!SP)
1797a7e6055SDimitry Andric     return false;
1807a7e6055SDimitry Andric   assert(SP->getUnit());
1817a7e6055SDimitry Andric   auto EK = SP->getUnit()->getEmissionKind();
1827a7e6055SDimitry Andric   if (EK == DICompileUnit::NoDebug)
1837a7e6055SDimitry Andric     return false;
1847a7e6055SDimitry Andric   return true;
1857a7e6055SDimitry Andric }
1867a7e6055SDimitry Andric 
beginFunction(const MachineFunction * MF)1873ca95b02SDimitry Andric void DebugHandlerBase::beginFunction(const MachineFunction *MF) {
1887a7e6055SDimitry Andric   PrevInstBB = nullptr;
1897a7e6055SDimitry Andric 
1905517e702SDimitry Andric   if (!Asm || !hasDebugInfo(MMI, MF)) {
1917a7e6055SDimitry Andric     skippedNonDebugFunction();
1927a7e6055SDimitry Andric     return;
1937a7e6055SDimitry Andric   }
1947a7e6055SDimitry Andric 
1953ca95b02SDimitry Andric   // Grab the lexical scopes for the function, if we don't have any of those
1963ca95b02SDimitry Andric   // then we're not going to be able to do anything.
1973ca95b02SDimitry Andric   LScopes.initialize(*MF);
1987a7e6055SDimitry Andric   if (LScopes.empty()) {
1997a7e6055SDimitry Andric     beginFunctionImpl(MF);
2003ca95b02SDimitry Andric     return;
2017a7e6055SDimitry Andric   }
2023ca95b02SDimitry Andric 
2033ca95b02SDimitry Andric   // Make sure that each lexical scope will have a begin/end label.
2043ca95b02SDimitry Andric   identifyScopeMarkers();
2053ca95b02SDimitry Andric 
2063ca95b02SDimitry Andric   // Calculate history for local variables.
2073ca95b02SDimitry Andric   assert(DbgValues.empty() && "DbgValues map wasn't cleaned!");
208*b5893f02SDimitry Andric   assert(DbgLabels.empty() && "DbgLabels map wasn't cleaned!");
209*b5893f02SDimitry Andric   calculateDbgEntityHistory(MF, Asm->MF->getSubtarget().getRegisterInfo(),
210*b5893f02SDimitry Andric                             DbgValues, DbgLabels);
2114ba319b5SDimitry Andric   LLVM_DEBUG(DbgValues.dump());
2123ca95b02SDimitry Andric 
2133ca95b02SDimitry Andric   // Request labels for the full history.
2143ca95b02SDimitry Andric   for (const auto &I : DbgValues) {
2153ca95b02SDimitry Andric     const auto &Ranges = I.second;
2163ca95b02SDimitry Andric     if (Ranges.empty())
2173ca95b02SDimitry Andric       continue;
2183ca95b02SDimitry Andric 
2193ca95b02SDimitry Andric     // The first mention of a function argument gets the CurrentFnBegin
2203ca95b02SDimitry Andric     // label, so arguments are visible when breaking at function entry.
2213ca95b02SDimitry Andric     const DILocalVariable *DIVar = Ranges.front().first->getDebugVariable();
2223ca95b02SDimitry Andric     if (DIVar->isParameter() &&
2232cab237bSDimitry Andric         getDISubprogram(DIVar->getScope())->describes(&MF->getFunction())) {
2243ca95b02SDimitry Andric       LabelsBeforeInsn[Ranges.front().first] = Asm->getFunctionBegin();
225d88c1a5aSDimitry Andric       if (Ranges.front().first->getDebugExpression()->isFragment()) {
226d88c1a5aSDimitry Andric         // Mark all non-overlapping initial fragments.
2273ca95b02SDimitry Andric         for (auto I = Ranges.begin(); I != Ranges.end(); ++I) {
228d88c1a5aSDimitry Andric           const DIExpression *Fragment = I->first->getDebugExpression();
2293ca95b02SDimitry Andric           if (std::all_of(Ranges.begin(), I,
2303ca95b02SDimitry Andric                           [&](DbgValueHistoryMap::InstrRange Pred) {
2314ba319b5SDimitry Andric                             return !Fragment->fragmentsOverlap(
2324ba319b5SDimitry Andric                                 Pred.first->getDebugExpression());
2333ca95b02SDimitry Andric                           }))
2343ca95b02SDimitry Andric             LabelsBeforeInsn[I->first] = Asm->getFunctionBegin();
2353ca95b02SDimitry Andric           else
2363ca95b02SDimitry Andric             break;
2373ca95b02SDimitry Andric         }
2383ca95b02SDimitry Andric       }
2393ca95b02SDimitry Andric     }
2403ca95b02SDimitry Andric 
2413ca95b02SDimitry Andric     for (const auto &Range : Ranges) {
2423ca95b02SDimitry Andric       requestLabelBeforeInsn(Range.first);
2433ca95b02SDimitry Andric       if (Range.second)
2443ca95b02SDimitry Andric         requestLabelAfterInsn(Range.second);
2453ca95b02SDimitry Andric     }
2463ca95b02SDimitry Andric   }
2473ca95b02SDimitry Andric 
248*b5893f02SDimitry Andric   // Ensure there is a symbol before DBG_LABEL.
249*b5893f02SDimitry Andric   for (const auto &I : DbgLabels) {
250*b5893f02SDimitry Andric     const MachineInstr *MI = I.second;
251*b5893f02SDimitry Andric     requestLabelBeforeInsn(MI);
252*b5893f02SDimitry Andric   }
253*b5893f02SDimitry Andric 
2543ca95b02SDimitry Andric   PrevInstLoc = DebugLoc();
2553ca95b02SDimitry Andric   PrevLabel = Asm->getFunctionBegin();
2567a7e6055SDimitry Andric   beginFunctionImpl(MF);
2573ca95b02SDimitry Andric }
2583ca95b02SDimitry Andric 
beginInstruction(const MachineInstr * MI)2593ca95b02SDimitry Andric void DebugHandlerBase::beginInstruction(const MachineInstr *MI) {
2603ca95b02SDimitry Andric   if (!MMI->hasDebugInfo())
2613ca95b02SDimitry Andric     return;
2623ca95b02SDimitry Andric 
2633ca95b02SDimitry Andric   assert(CurMI == nullptr);
2643ca95b02SDimitry Andric   CurMI = MI;
2653ca95b02SDimitry Andric 
2663ca95b02SDimitry Andric   // Insert labels where requested.
2673ca95b02SDimitry Andric   DenseMap<const MachineInstr *, MCSymbol *>::iterator I =
2683ca95b02SDimitry Andric       LabelsBeforeInsn.find(MI);
2693ca95b02SDimitry Andric 
2703ca95b02SDimitry Andric   // No label needed.
2713ca95b02SDimitry Andric   if (I == LabelsBeforeInsn.end())
2723ca95b02SDimitry Andric     return;
2733ca95b02SDimitry Andric 
2743ca95b02SDimitry Andric   // Label already assigned.
2753ca95b02SDimitry Andric   if (I->second)
2763ca95b02SDimitry Andric     return;
2773ca95b02SDimitry Andric 
2783ca95b02SDimitry Andric   if (!PrevLabel) {
2793ca95b02SDimitry Andric     PrevLabel = MMI->getContext().createTempSymbol();
2803ca95b02SDimitry Andric     Asm->OutStreamer->EmitLabel(PrevLabel);
2813ca95b02SDimitry Andric   }
2823ca95b02SDimitry Andric   I->second = PrevLabel;
2833ca95b02SDimitry Andric }
2843ca95b02SDimitry Andric 
endInstruction()2853ca95b02SDimitry Andric void DebugHandlerBase::endInstruction() {
2863ca95b02SDimitry Andric   if (!MMI->hasDebugInfo())
2873ca95b02SDimitry Andric     return;
2883ca95b02SDimitry Andric 
2893ca95b02SDimitry Andric   assert(CurMI != nullptr);
290302affcbSDimitry Andric   // Don't create a new label after DBG_VALUE and other instructions that don't
291302affcbSDimitry Andric   // generate code.
292302affcbSDimitry Andric   if (!CurMI->isMetaInstruction()) {
2933ca95b02SDimitry Andric     PrevLabel = nullptr;
294d88c1a5aSDimitry Andric     PrevInstBB = CurMI->getParent();
295d88c1a5aSDimitry Andric   }
2963ca95b02SDimitry Andric 
2973ca95b02SDimitry Andric   DenseMap<const MachineInstr *, MCSymbol *>::iterator I =
2983ca95b02SDimitry Andric       LabelsAfterInsn.find(CurMI);
2993ca95b02SDimitry Andric   CurMI = nullptr;
3003ca95b02SDimitry Andric 
3013ca95b02SDimitry Andric   // No label needed.
3023ca95b02SDimitry Andric   if (I == LabelsAfterInsn.end())
3033ca95b02SDimitry Andric     return;
3043ca95b02SDimitry Andric 
3053ca95b02SDimitry Andric   // Label already assigned.
3063ca95b02SDimitry Andric   if (I->second)
3073ca95b02SDimitry Andric     return;
3083ca95b02SDimitry Andric 
3093ca95b02SDimitry Andric   // We need a label after this instruction.
3103ca95b02SDimitry Andric   if (!PrevLabel) {
3113ca95b02SDimitry Andric     PrevLabel = MMI->getContext().createTempSymbol();
3123ca95b02SDimitry Andric     Asm->OutStreamer->EmitLabel(PrevLabel);
3133ca95b02SDimitry Andric   }
3143ca95b02SDimitry Andric   I->second = PrevLabel;
3153ca95b02SDimitry Andric }
3163ca95b02SDimitry Andric 
endFunction(const MachineFunction * MF)3173ca95b02SDimitry Andric void DebugHandlerBase::endFunction(const MachineFunction *MF) {
3187a7e6055SDimitry Andric   if (hasDebugInfo(MMI, MF))
3197a7e6055SDimitry Andric     endFunctionImpl(MF);
3203ca95b02SDimitry Andric   DbgValues.clear();
321*b5893f02SDimitry Andric   DbgLabels.clear();
3223ca95b02SDimitry Andric   LabelsBeforeInsn.clear();
3233ca95b02SDimitry Andric   LabelsAfterInsn.clear();
3243ca95b02SDimitry Andric }
325