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" 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 282cab237bSDimitry Andric Optional<DbgVariableLocation> 292cab237bSDimitry Andric DbgVariableLocation::extractFromMachineInstruction( 302cab237bSDimitry Andric const MachineInstr &Instruction) { 312cab237bSDimitry Andric DbgVariableLocation Location; 322cab237bSDimitry Andric if (!Instruction.isDebugValue()) 332cab237bSDimitry Andric return None; 342cab237bSDimitry Andric if (!Instruction.getOperand(0).isReg()) 352cab237bSDimitry Andric return None; 362cab237bSDimitry Andric Location.Register = Instruction.getOperand(0).getReg(); 372cab237bSDimitry Andric Location.FragmentInfo.reset(); 382cab237bSDimitry Andric // We only handle expressions generated by DIExpression::appendOffset, 392cab237bSDimitry Andric // which doesn't require a full stack machine. 402cab237bSDimitry Andric int64_t Offset = 0; 412cab237bSDimitry Andric const DIExpression *DIExpr = Instruction.getDebugExpression(); 422cab237bSDimitry Andric auto Op = DIExpr->expr_op_begin(); 432cab237bSDimitry Andric while (Op != DIExpr->expr_op_end()) { 442cab237bSDimitry Andric switch (Op->getOp()) { 452cab237bSDimitry Andric case dwarf::DW_OP_constu: { 462cab237bSDimitry Andric int Value = Op->getArg(0); 472cab237bSDimitry Andric ++Op; 482cab237bSDimitry Andric if (Op != DIExpr->expr_op_end()) { 492cab237bSDimitry Andric switch (Op->getOp()) { 502cab237bSDimitry Andric case dwarf::DW_OP_minus: 512cab237bSDimitry Andric Offset -= Value; 522cab237bSDimitry Andric break; 532cab237bSDimitry Andric case dwarf::DW_OP_plus: 542cab237bSDimitry Andric Offset += Value; 552cab237bSDimitry Andric break; 562cab237bSDimitry Andric default: 572cab237bSDimitry Andric continue; 582cab237bSDimitry Andric } 592cab237bSDimitry Andric } 602cab237bSDimitry Andric } break; 612cab237bSDimitry Andric case dwarf::DW_OP_plus_uconst: 622cab237bSDimitry Andric Offset += Op->getArg(0); 632cab237bSDimitry Andric break; 642cab237bSDimitry Andric case dwarf::DW_OP_LLVM_fragment: 652cab237bSDimitry Andric Location.FragmentInfo = {Op->getArg(1), Op->getArg(0)}; 662cab237bSDimitry Andric break; 672cab237bSDimitry Andric case dwarf::DW_OP_deref: 682cab237bSDimitry Andric Location.LoadChain.push_back(Offset); 692cab237bSDimitry Andric Offset = 0; 702cab237bSDimitry Andric break; 712cab237bSDimitry Andric default: 722cab237bSDimitry Andric return None; 732cab237bSDimitry Andric } 742cab237bSDimitry Andric ++Op; 752cab237bSDimitry Andric } 762cab237bSDimitry Andric 772cab237bSDimitry Andric // Do one final implicit DW_OP_deref if this was an indirect DBG_VALUE 782cab237bSDimitry Andric // instruction. 792cab237bSDimitry Andric // FIXME: Replace these with DIExpression. 802cab237bSDimitry Andric if (Instruction.isIndirectDebugValue()) 812cab237bSDimitry Andric Location.LoadChain.push_back(Offset); 822cab237bSDimitry Andric 832cab237bSDimitry Andric return Location; 842cab237bSDimitry Andric } 852cab237bSDimitry Andric 863ca95b02SDimitry Andric DebugHandlerBase::DebugHandlerBase(AsmPrinter *A) : Asm(A), MMI(Asm->MMI) {} 873ca95b02SDimitry Andric 883ca95b02SDimitry Andric // Each LexicalScope has first instruction and last instruction to mark 893ca95b02SDimitry Andric // beginning and end of a scope respectively. Create an inverse map that list 903ca95b02SDimitry Andric // scopes starts (and ends) with an instruction. One instruction may start (or 913ca95b02SDimitry Andric // end) multiple scopes. Ignore scopes that are not reachable. 923ca95b02SDimitry Andric void DebugHandlerBase::identifyScopeMarkers() { 933ca95b02SDimitry Andric SmallVector<LexicalScope *, 4> WorkList; 943ca95b02SDimitry Andric WorkList.push_back(LScopes.getCurrentFunctionScope()); 953ca95b02SDimitry Andric while (!WorkList.empty()) { 963ca95b02SDimitry Andric LexicalScope *S = WorkList.pop_back_val(); 973ca95b02SDimitry Andric 983ca95b02SDimitry Andric const SmallVectorImpl<LexicalScope *> &Children = S->getChildren(); 993ca95b02SDimitry Andric if (!Children.empty()) 1003ca95b02SDimitry Andric WorkList.append(Children.begin(), Children.end()); 1013ca95b02SDimitry Andric 1023ca95b02SDimitry Andric if (S->isAbstractScope()) 1033ca95b02SDimitry Andric continue; 1043ca95b02SDimitry Andric 1053ca95b02SDimitry Andric for (const InsnRange &R : S->getRanges()) { 1063ca95b02SDimitry Andric assert(R.first && "InsnRange does not have first instruction!"); 1073ca95b02SDimitry Andric assert(R.second && "InsnRange does not have second instruction!"); 1083ca95b02SDimitry Andric requestLabelBeforeInsn(R.first); 1093ca95b02SDimitry Andric requestLabelAfterInsn(R.second); 1103ca95b02SDimitry Andric } 1113ca95b02SDimitry Andric } 1123ca95b02SDimitry Andric } 1133ca95b02SDimitry Andric 1143ca95b02SDimitry Andric // Return Label preceding the instruction. 1153ca95b02SDimitry Andric MCSymbol *DebugHandlerBase::getLabelBeforeInsn(const MachineInstr *MI) { 1163ca95b02SDimitry Andric MCSymbol *Label = LabelsBeforeInsn.lookup(MI); 1173ca95b02SDimitry Andric assert(Label && "Didn't insert label before instruction"); 1183ca95b02SDimitry Andric return Label; 1193ca95b02SDimitry Andric } 1203ca95b02SDimitry Andric 1213ca95b02SDimitry Andric // Return Label immediately following the instruction. 1223ca95b02SDimitry Andric MCSymbol *DebugHandlerBase::getLabelAfterInsn(const MachineInstr *MI) { 1233ca95b02SDimitry Andric return LabelsAfterInsn.lookup(MI); 1243ca95b02SDimitry Andric } 1253ca95b02SDimitry Andric 126d88c1a5aSDimitry Andric int DebugHandlerBase::fragmentCmp(const DIExpression *P1, 127d88c1a5aSDimitry Andric const DIExpression *P2) { 128d88c1a5aSDimitry Andric auto Fragment1 = *P1->getFragmentInfo(); 129d88c1a5aSDimitry Andric auto Fragment2 = *P2->getFragmentInfo(); 130d88c1a5aSDimitry Andric unsigned l1 = Fragment1.OffsetInBits; 131d88c1a5aSDimitry Andric unsigned l2 = Fragment2.OffsetInBits; 132d88c1a5aSDimitry Andric unsigned r1 = l1 + Fragment1.SizeInBits; 133d88c1a5aSDimitry Andric unsigned r2 = l2 + Fragment2.SizeInBits; 1343ca95b02SDimitry Andric if (r1 <= l2) 1353ca95b02SDimitry Andric return -1; 1363ca95b02SDimitry Andric else if (r2 <= l1) 1373ca95b02SDimitry Andric return 1; 1383ca95b02SDimitry Andric else 1393ca95b02SDimitry Andric return 0; 1403ca95b02SDimitry Andric } 1413ca95b02SDimitry Andric 142d88c1a5aSDimitry Andric bool DebugHandlerBase::fragmentsOverlap(const DIExpression *P1, 143d88c1a5aSDimitry Andric const DIExpression *P2) { 144d88c1a5aSDimitry Andric if (!P1->isFragment() || !P2->isFragment()) 1453ca95b02SDimitry Andric return true; 146d88c1a5aSDimitry Andric return fragmentCmp(P1, P2) == 0; 1473ca95b02SDimitry Andric } 1483ca95b02SDimitry Andric 1493ca95b02SDimitry Andric /// If this type is derived from a base type then return base type size. 1503ca95b02SDimitry Andric uint64_t DebugHandlerBase::getBaseTypeSize(const DITypeRef TyRef) { 1513ca95b02SDimitry Andric DIType *Ty = TyRef.resolve(); 1523ca95b02SDimitry Andric assert(Ty); 1533ca95b02SDimitry Andric DIDerivedType *DDTy = dyn_cast<DIDerivedType>(Ty); 1543ca95b02SDimitry Andric if (!DDTy) 1553ca95b02SDimitry Andric return Ty->getSizeInBits(); 1563ca95b02SDimitry Andric 1573ca95b02SDimitry Andric unsigned Tag = DDTy->getTag(); 1583ca95b02SDimitry Andric 1593ca95b02SDimitry Andric if (Tag != dwarf::DW_TAG_member && Tag != dwarf::DW_TAG_typedef && 1603ca95b02SDimitry Andric Tag != dwarf::DW_TAG_const_type && Tag != dwarf::DW_TAG_volatile_type && 161d88c1a5aSDimitry Andric Tag != dwarf::DW_TAG_restrict_type && Tag != dwarf::DW_TAG_atomic_type) 1623ca95b02SDimitry Andric return DDTy->getSizeInBits(); 1633ca95b02SDimitry Andric 1643ca95b02SDimitry Andric DIType *BaseType = DDTy->getBaseType().resolve(); 1653ca95b02SDimitry Andric 1663ca95b02SDimitry Andric assert(BaseType && "Unexpected invalid base type"); 1673ca95b02SDimitry Andric 1683ca95b02SDimitry Andric // If this is a derived type, go ahead and get the base type, unless it's a 1693ca95b02SDimitry Andric // reference then it's just the size of the field. Pointer types have no need 1703ca95b02SDimitry Andric // of this since they're a different type of qualification on the type. 1713ca95b02SDimitry Andric if (BaseType->getTag() == dwarf::DW_TAG_reference_type || 1723ca95b02SDimitry Andric BaseType->getTag() == dwarf::DW_TAG_rvalue_reference_type) 1733ca95b02SDimitry Andric return Ty->getSizeInBits(); 1743ca95b02SDimitry Andric 1753ca95b02SDimitry Andric return getBaseTypeSize(BaseType); 1763ca95b02SDimitry Andric } 1773ca95b02SDimitry Andric 178302affcbSDimitry Andric static bool hasDebugInfo(const MachineModuleInfo *MMI, 179302affcbSDimitry Andric const MachineFunction *MF) { 1807a7e6055SDimitry Andric if (!MMI->hasDebugInfo()) 1817a7e6055SDimitry Andric return false; 1822cab237bSDimitry Andric auto *SP = MF->getFunction().getSubprogram(); 1837a7e6055SDimitry Andric if (!SP) 1847a7e6055SDimitry Andric return false; 1857a7e6055SDimitry Andric assert(SP->getUnit()); 1867a7e6055SDimitry Andric auto EK = SP->getUnit()->getEmissionKind(); 1877a7e6055SDimitry Andric if (EK == DICompileUnit::NoDebug) 1887a7e6055SDimitry Andric return false; 1897a7e6055SDimitry Andric return true; 1907a7e6055SDimitry Andric } 1917a7e6055SDimitry Andric 1923ca95b02SDimitry Andric void DebugHandlerBase::beginFunction(const MachineFunction *MF) { 1937a7e6055SDimitry Andric PrevInstBB = nullptr; 1947a7e6055SDimitry Andric 1955517e702SDimitry Andric if (!Asm || !hasDebugInfo(MMI, MF)) { 1967a7e6055SDimitry Andric skippedNonDebugFunction(); 1977a7e6055SDimitry Andric return; 1987a7e6055SDimitry Andric } 1997a7e6055SDimitry Andric 2003ca95b02SDimitry Andric // Grab the lexical scopes for the function, if we don't have any of those 2013ca95b02SDimitry Andric // then we're not going to be able to do anything. 2023ca95b02SDimitry Andric LScopes.initialize(*MF); 2037a7e6055SDimitry Andric if (LScopes.empty()) { 2047a7e6055SDimitry Andric beginFunctionImpl(MF); 2053ca95b02SDimitry Andric return; 2067a7e6055SDimitry Andric } 2073ca95b02SDimitry Andric 2083ca95b02SDimitry Andric // Make sure that each lexical scope will have a begin/end label. 2093ca95b02SDimitry Andric identifyScopeMarkers(); 2103ca95b02SDimitry Andric 2113ca95b02SDimitry Andric // Calculate history for local variables. 2123ca95b02SDimitry Andric assert(DbgValues.empty() && "DbgValues map wasn't cleaned!"); 2133ca95b02SDimitry Andric calculateDbgValueHistory(MF, Asm->MF->getSubtarget().getRegisterInfo(), 2143ca95b02SDimitry Andric DbgValues); 2153ca95b02SDimitry Andric 2163ca95b02SDimitry Andric // Request labels for the full history. 2173ca95b02SDimitry Andric for (const auto &I : DbgValues) { 2183ca95b02SDimitry Andric const auto &Ranges = I.second; 2193ca95b02SDimitry Andric if (Ranges.empty()) 2203ca95b02SDimitry Andric continue; 2213ca95b02SDimitry Andric 2223ca95b02SDimitry Andric // The first mention of a function argument gets the CurrentFnBegin 2233ca95b02SDimitry Andric // label, so arguments are visible when breaking at function entry. 2243ca95b02SDimitry Andric const DILocalVariable *DIVar = Ranges.front().first->getDebugVariable(); 2253ca95b02SDimitry Andric if (DIVar->isParameter() && 2262cab237bSDimitry Andric getDISubprogram(DIVar->getScope())->describes(&MF->getFunction())) { 2273ca95b02SDimitry Andric LabelsBeforeInsn[Ranges.front().first] = Asm->getFunctionBegin(); 228d88c1a5aSDimitry Andric if (Ranges.front().first->getDebugExpression()->isFragment()) { 229d88c1a5aSDimitry Andric // Mark all non-overlapping initial fragments. 2303ca95b02SDimitry Andric for (auto I = Ranges.begin(); I != Ranges.end(); ++I) { 231d88c1a5aSDimitry Andric const DIExpression *Fragment = I->first->getDebugExpression(); 2323ca95b02SDimitry Andric if (std::all_of(Ranges.begin(), I, 2333ca95b02SDimitry Andric [&](DbgValueHistoryMap::InstrRange Pred) { 234d88c1a5aSDimitry Andric return !fragmentsOverlap( 235d88c1a5aSDimitry Andric Fragment, Pred.first->getDebugExpression()); 2363ca95b02SDimitry Andric })) 2373ca95b02SDimitry Andric LabelsBeforeInsn[I->first] = Asm->getFunctionBegin(); 2383ca95b02SDimitry Andric else 2393ca95b02SDimitry Andric break; 2403ca95b02SDimitry Andric } 2413ca95b02SDimitry Andric } 2423ca95b02SDimitry Andric } 2433ca95b02SDimitry Andric 2443ca95b02SDimitry Andric for (const auto &Range : Ranges) { 2453ca95b02SDimitry Andric requestLabelBeforeInsn(Range.first); 2463ca95b02SDimitry Andric if (Range.second) 2473ca95b02SDimitry Andric requestLabelAfterInsn(Range.second); 2483ca95b02SDimitry Andric } 2493ca95b02SDimitry Andric } 2503ca95b02SDimitry Andric 2513ca95b02SDimitry Andric PrevInstLoc = DebugLoc(); 2523ca95b02SDimitry Andric PrevLabel = Asm->getFunctionBegin(); 2537a7e6055SDimitry Andric beginFunctionImpl(MF); 2543ca95b02SDimitry Andric } 2553ca95b02SDimitry Andric 2563ca95b02SDimitry Andric void DebugHandlerBase::beginInstruction(const MachineInstr *MI) { 2573ca95b02SDimitry Andric if (!MMI->hasDebugInfo()) 2583ca95b02SDimitry Andric return; 2593ca95b02SDimitry Andric 2603ca95b02SDimitry Andric assert(CurMI == nullptr); 2613ca95b02SDimitry Andric CurMI = MI; 2623ca95b02SDimitry Andric 2633ca95b02SDimitry Andric // Insert labels where requested. 2643ca95b02SDimitry Andric DenseMap<const MachineInstr *, MCSymbol *>::iterator I = 2653ca95b02SDimitry Andric LabelsBeforeInsn.find(MI); 2663ca95b02SDimitry Andric 2673ca95b02SDimitry Andric // No label needed. 2683ca95b02SDimitry Andric if (I == LabelsBeforeInsn.end()) 2693ca95b02SDimitry Andric return; 2703ca95b02SDimitry Andric 2713ca95b02SDimitry Andric // Label already assigned. 2723ca95b02SDimitry Andric if (I->second) 2733ca95b02SDimitry Andric return; 2743ca95b02SDimitry Andric 2753ca95b02SDimitry Andric if (!PrevLabel) { 2763ca95b02SDimitry Andric PrevLabel = MMI->getContext().createTempSymbol(); 2773ca95b02SDimitry Andric Asm->OutStreamer->EmitLabel(PrevLabel); 2783ca95b02SDimitry Andric } 2793ca95b02SDimitry Andric I->second = PrevLabel; 2803ca95b02SDimitry Andric } 2813ca95b02SDimitry Andric 2823ca95b02SDimitry Andric void DebugHandlerBase::endInstruction() { 2833ca95b02SDimitry Andric if (!MMI->hasDebugInfo()) 2843ca95b02SDimitry Andric return; 2853ca95b02SDimitry Andric 2863ca95b02SDimitry Andric assert(CurMI != nullptr); 287302affcbSDimitry Andric // Don't create a new label after DBG_VALUE and other instructions that don't 288302affcbSDimitry Andric // generate code. 289302affcbSDimitry Andric if (!CurMI->isMetaInstruction()) { 2903ca95b02SDimitry Andric PrevLabel = nullptr; 291d88c1a5aSDimitry Andric PrevInstBB = CurMI->getParent(); 292d88c1a5aSDimitry Andric } 2933ca95b02SDimitry Andric 2943ca95b02SDimitry Andric DenseMap<const MachineInstr *, MCSymbol *>::iterator I = 2953ca95b02SDimitry Andric LabelsAfterInsn.find(CurMI); 2963ca95b02SDimitry Andric CurMI = nullptr; 2973ca95b02SDimitry Andric 2983ca95b02SDimitry Andric // No label needed. 2993ca95b02SDimitry Andric if (I == LabelsAfterInsn.end()) 3003ca95b02SDimitry Andric return; 3013ca95b02SDimitry Andric 3023ca95b02SDimitry Andric // Label already assigned. 3033ca95b02SDimitry Andric if (I->second) 3043ca95b02SDimitry Andric return; 3053ca95b02SDimitry Andric 3063ca95b02SDimitry Andric // We need a label after this instruction. 3073ca95b02SDimitry Andric if (!PrevLabel) { 3083ca95b02SDimitry Andric PrevLabel = MMI->getContext().createTempSymbol(); 3093ca95b02SDimitry Andric Asm->OutStreamer->EmitLabel(PrevLabel); 3103ca95b02SDimitry Andric } 3113ca95b02SDimitry Andric I->second = PrevLabel; 3123ca95b02SDimitry Andric } 3133ca95b02SDimitry Andric 3143ca95b02SDimitry Andric void DebugHandlerBase::endFunction(const MachineFunction *MF) { 3157a7e6055SDimitry Andric if (hasDebugInfo(MMI, MF)) 3167a7e6055SDimitry Andric endFunctionImpl(MF); 3173ca95b02SDimitry Andric DbgValues.clear(); 3183ca95b02SDimitry Andric LabelsBeforeInsn.clear(); 3193ca95b02SDimitry Andric LabelsAfterInsn.clear(); 3203ca95b02SDimitry Andric } 321