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