LCOV - code coverage report
Current view: top level - lib/CodeGen/AsmPrinter - DebugHandlerBase.cpp (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 118 125 94.4 %
Date: 2018-06-17 00:07:59 Functions: 12 12 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : //===-- llvm/lib/CodeGen/AsmPrinter/DebugHandlerBase.cpp -------*- C++ -*--===//
       2             : //
       3             : //                     The LLVM Compiler Infrastructure
       4             : //
       5             : // This file is distributed under the University of Illinois Open Source
       6             : // License. See LICENSE.TXT for details.
       7             : //
       8             : //===----------------------------------------------------------------------===//
       9             : //
      10             : // Common functionality for different debug information format backends.
      11             : // LLVM currently supports DWARF and CodeView.
      12             : //
      13             : //===----------------------------------------------------------------------===//
      14             : 
      15             : #include "DebugHandlerBase.h"
      16             : #include "llvm/ADT/Optional.h"
      17             : #include "llvm/ADT/Twine.h"
      18             : #include "llvm/CodeGen/AsmPrinter.h"
      19             : #include "llvm/CodeGen/MachineFunction.h"
      20             : #include "llvm/CodeGen/MachineInstr.h"
      21             : #include "llvm/CodeGen/MachineModuleInfo.h"
      22             : #include "llvm/CodeGen/TargetSubtargetInfo.h"
      23             : #include "llvm/IR/DebugInfo.h"
      24             : #include "llvm/MC/MCStreamer.h"
      25             : 
      26             : using namespace llvm;
      27             : 
      28             : #define DEBUG_TYPE "dwarfdebug"
      29             : 
      30             : Optional<DbgVariableLocation>
      31         139 : DbgVariableLocation::extractFromMachineInstruction(
      32             :     const MachineInstr &Instruction) {
      33             :   DbgVariableLocation Location;
      34         139 :   if (!Instruction.isDebugValue())
      35             :     return None;
      36         278 :   if (!Instruction.getOperand(0).isReg())
      37             :     return None;
      38         130 :   Location.Register = Instruction.getOperand(0).getReg();
      39             :   Location.FragmentInfo.reset();
      40             :   // We only handle expressions generated by DIExpression::appendOffset,
      41             :   // which doesn't require a full stack machine.
      42         130 :   int64_t Offset = 0;
      43         130 :   const DIExpression *DIExpr = Instruction.getDebugExpression();
      44         130 :   auto Op = DIExpr->expr_op_begin();
      45         180 :   while (Op != DIExpr->expr_op_end()) {
      46          50 :     switch (Op->getOp()) {
      47             :     case dwarf::DW_OP_constu: {
      48           2 :       int Value = Op->getArg(0);
      49             :       ++Op;
      50           2 :       if (Op != DIExpr->expr_op_end()) {
      51           2 :         switch (Op->getOp()) {
      52           2 :         case dwarf::DW_OP_minus:
      53           2 :           Offset -= Value;
      54           2 :           break;
      55           0 :         case dwarf::DW_OP_plus:
      56           0 :           Offset += Value;
      57           0 :           break;
      58           0 :         default:
      59           0 :           continue;
      60             :         }
      61             :       }
      62             :     } break;
      63             :     case dwarf::DW_OP_plus_uconst:
      64          21 :       Offset += Op->getArg(0);
      65          21 :       break;
      66             :     case dwarf::DW_OP_LLVM_fragment:
      67             :       Location.FragmentInfo = {Op->getArg(1), Op->getArg(0)};
      68             :       break;
      69          11 :     case dwarf::DW_OP_deref:
      70          11 :       Location.LoadChain.push_back(Offset);
      71          11 :       Offset = 0;
      72          11 :       break;
      73             :     default:
      74             :       return None;
      75             :     }
      76             :     ++Op;
      77             :   }
      78             : 
      79             :   // Do one final implicit DW_OP_deref if this was an indirect DBG_VALUE
      80             :   // instruction.
      81             :   // FIXME: Replace these with DIExpression.
      82             :   if (Instruction.isIndirectDebugValue())
      83          31 :     Location.LoadChain.push_back(Offset);
      84             : 
      85             :   return Location;
      86             : }
      87             : 
      88      134856 : DebugHandlerBase::DebugHandlerBase(AsmPrinter *A) : Asm(A), MMI(Asm->MMI) {}
      89             : 
      90             : // Each LexicalScope has first instruction and last instruction to mark
      91             : // beginning and end of a scope respectively. Create an inverse map that list
      92             : // scopes starts (and ends) with an instruction. One instruction may start (or
      93             : // end) multiple scopes. Ignore scopes that are not reachable.
      94       44647 : void DebugHandlerBase::identifyScopeMarkers() {
      95             :   SmallVector<LexicalScope *, 4> WorkList;
      96       44647 :   WorkList.push_back(LScopes.getCurrentFunctionScope());
      97      209850 :   while (!WorkList.empty()) {
      98             :     LexicalScope *S = WorkList.pop_back_val();
      99             : 
     100             :     const SmallVectorImpl<LexicalScope *> &Children = S->getChildren();
     101      165203 :     if (!Children.empty())
     102       70645 :       WorkList.append(Children.begin(), Children.end());
     103             : 
     104      165203 :     if (S->isAbstractScope())
     105           0 :       continue;
     106             : 
     107      752895 :     for (const InsnRange &R : S->getRanges()) {
     108             :       assert(R.first && "InsnRange does not have first instruction!");
     109             :       assert(R.second && "InsnRange does not have second instruction!");
     110      293846 :       requestLabelBeforeInsn(R.first);
     111      293846 :       requestLabelAfterInsn(R.second);
     112             :     }
     113             :   }
     114       44647 : }
     115             : 
     116             : // Return Label preceding the instruction.
     117      285057 : MCSymbol *DebugHandlerBase::getLabelBeforeInsn(const MachineInstr *MI) {
     118      285057 :   MCSymbol *Label = LabelsBeforeInsn.lookup(MI);
     119             :   assert(Label && "Didn't insert label before instruction");
     120      285057 :   return Label;
     121             : }
     122             : 
     123             : // Return Label immediately following the instruction.
     124      283597 : MCSymbol *DebugHandlerBase::getLabelAfterInsn(const MachineInstr *MI) {
     125      567194 :   return LabelsAfterInsn.lookup(MI);
     126             : }
     127             : 
     128             : /// If this type is derived from a base type then return base type size.
     129      133550 : uint64_t DebugHandlerBase::getBaseTypeSize(const DITypeRef TyRef) {
     130             :   DIType *Ty = TyRef.resolve();
     131             :   assert(Ty);
     132             :   DIDerivedType *DDTy = dyn_cast<DIDerivedType>(Ty);
     133             :   if (!DDTy)
     134       35386 :     return Ty->getSizeInBits();
     135             : 
     136       98164 :   unsigned Tag = DDTy->getTag();
     137             : 
     138       98164 :   if (Tag != dwarf::DW_TAG_member && Tag != dwarf::DW_TAG_typedef &&
     139       29470 :       Tag != dwarf::DW_TAG_const_type && Tag != dwarf::DW_TAG_volatile_type &&
     140       29431 :       Tag != dwarf::DW_TAG_restrict_type && Tag != dwarf::DW_TAG_atomic_type)
     141       29431 :     return DDTy->getSizeInBits();
     142             : 
     143             :   DIType *BaseType = DDTy->getBaseType().resolve();
     144             : 
     145             :   if (!BaseType)
     146             :     return 0;
     147             : 
     148             :   // If this is a derived type, go ahead and get the base type, unless it's a
     149             :   // reference then it's just the size of the field. Pointer types have no need
     150             :   // of this since they're a different type of qualification on the type.
     151      137464 :   if (BaseType->getTag() == dwarf::DW_TAG_reference_type ||
     152             :       BaseType->getTag() == dwarf::DW_TAG_rvalue_reference_type)
     153         122 :     return Ty->getSizeInBits();
     154             : 
     155       68610 :   return getBaseTypeSize(BaseType);
     156             : }
     157             : 
     158      453033 : static bool hasDebugInfo(const MachineModuleInfo *MMI,
     159             :                          const MachineFunction *MF) {
     160      453033 :   if (!MMI->hasDebugInfo())
     161             :     return false;
     162       92672 :   auto *SP = MF->getFunction().getSubprogram();
     163       92672 :   if (!SP)
     164             :     return false;
     165             :   assert(SP->getUnit());
     166       89416 :   auto EK = SP->getUnit()->getEmissionKind();
     167       89416 :   if (EK == DICompileUnit::NoDebug)
     168             :     return false;
     169       89410 :   return true;
     170             : }
     171             : 
     172      226517 : void DebugHandlerBase::beginFunction(const MachineFunction *MF) {
     173      226517 :   PrevInstBB = nullptr;
     174             : 
     175      226517 :   if (!Asm || !hasDebugInfo(MMI, MF)) {
     176      181812 :     skippedNonDebugFunction();
     177      181812 :     return;
     178             :   }
     179             : 
     180             :   // Grab the lexical scopes for the function, if we don't have any of those
     181             :   // then we're not going to be able to do anything.
     182       44705 :   LScopes.initialize(*MF);
     183       44705 :   if (LScopes.empty()) {
     184          58 :     beginFunctionImpl(MF);
     185          58 :     return;
     186             :   }
     187             : 
     188             :   // Make sure that each lexical scope will have a begin/end label.
     189       44647 :   identifyScopeMarkers();
     190             : 
     191             :   // Calculate history for local variables.
     192             :   assert(DbgValues.empty() && "DbgValues map wasn't cleaned!");
     193       44647 :   calculateDbgValueHistory(MF, Asm->MF->getSubtarget().getRegisterInfo(),
     194             :                            DbgValues);
     195             :   LLVM_DEBUG(DbgValues.dump());
     196             : 
     197             :   // Request labels for the full history.
     198       63931 :   for (const auto &I : DbgValues) {
     199             :     const auto &Ranges = I.second;
     200       19284 :     if (Ranges.empty())
     201           0 :       continue;
     202             : 
     203             :     // The first mention of a function argument gets the CurrentFnBegin
     204             :     // label, so arguments are visible when breaking at function entry.
     205       19284 :     const DILocalVariable *DIVar = Ranges.front().first->getDebugVariable();
     206       35706 :     if (DIVar->isParameter() &&
     207       16422 :         getDISubprogram(DIVar->getScope())->describes(&MF->getFunction())) {
     208        2918 :       LabelsBeforeInsn[Ranges.front().first] = Asm->getFunctionBegin();
     209        2918 :       if (Ranges.front().first->getDebugExpression()->isFragment()) {
     210             :         // Mark all non-overlapping initial fragments.
     211          56 :         for (auto I = Ranges.begin(); I != Ranges.end(); ++I) {
     212          26 :           const DIExpression *Fragment = I->first->getDebugExpression();
     213          26 :           if (std::all_of(Ranges.begin(), I,
     214          22 :                           [&](DbgValueHistoryMap::InstrRange Pred) {
     215          44 :                             return !Fragment->fragmentsOverlap(
     216          22 :                                 Pred.first->getDebugExpression());
     217          22 :                           }))
     218          44 :             LabelsBeforeInsn[I->first] = Asm->getFunctionBegin();
     219             :           else
     220             :             break;
     221             :         }
     222             :       }
     223             :     }
     224             : 
     225      149704 :     for (const auto &Range : Ranges) {
     226       65210 :       requestLabelBeforeInsn(Range.first);
     227       65210 :       if (Range.second)
     228             :         requestLabelAfterInsn(Range.second);
     229             :     }
     230             :   }
     231             : 
     232       89294 :   PrevInstLoc = DebugLoc();
     233       44647 :   PrevLabel = Asm->getFunctionBegin();
     234       44647 :   beginFunctionImpl(MF);
     235             : }
     236             : 
     237     2474794 : void DebugHandlerBase::beginInstruction(const MachineInstr *MI) {
     238     2474794 :   if (!MMI->hasDebugInfo())
     239     2180814 :     return;
     240             : 
     241             :   assert(CurMI == nullptr);
     242     2474794 :   CurMI = MI;
     243             : 
     244             :   // Insert labels where requested.
     245             :   DenseMap<const MachineInstr *, MCSymbol *>::iterator I =
     246     2474794 :       LabelsBeforeInsn.find(MI);
     247             : 
     248             :   // No label needed.
     249     2474794 :   if (I == LabelsBeforeInsn.end())
     250             :     return;
     251             : 
     252             :   // Label already assigned.
     253      295449 :   if (I->second)
     254             :     return;
     255             : 
     256      293980 :   if (!PrevLabel) {
     257      355120 :     PrevLabel = MMI->getContext().createTempSymbol();
     258      355120 :     Asm->OutStreamer->EmitLabel(PrevLabel);
     259             :   }
     260      293980 :   I->second = PrevLabel;
     261             : }
     262             : 
     263     2474794 : void DebugHandlerBase::endInstruction() {
     264     2474794 :   if (!MMI->hasDebugInfo())
     265     2252052 :     return;
     266             : 
     267             :   assert(CurMI != nullptr);
     268             :   // Don't create a new label after DBG_VALUE and other instructions that don't
     269             :   // generate code.
     270     2474794 :   if (!CurMI->isMetaInstruction()) {
     271     2036388 :     PrevLabel = nullptr;
     272     2036388 :     PrevInstBB = CurMI->getParent();
     273             :   }
     274             : 
     275             :   DenseMap<const MachineInstr *, MCSymbol *>::iterator I =
     276     2474794 :       LabelsAfterInsn.find(CurMI);
     277     2474794 :   CurMI = nullptr;
     278             : 
     279             :   // No label needed.
     280     2474794 :   if (I == LabelsAfterInsn.end())
     281             :     return;
     282             : 
     283             :   // Label already assigned.
     284      222742 :   if (I->second)
     285             :     return;
     286             : 
     287             :   // We need a label after this instruction.
     288      222742 :   if (!PrevLabel) {
     289      444554 :     PrevLabel = MMI->getContext().createTempSymbol();
     290      444554 :     Asm->OutStreamer->EmitLabel(PrevLabel);
     291             :   }
     292      222742 :   I->second = PrevLabel;
     293             : }
     294             : 
     295      226517 : void DebugHandlerBase::endFunction(const MachineFunction *MF) {
     296      226517 :   if (hasDebugInfo(MMI, MF))
     297       44705 :     endFunctionImpl(MF);
     298             :   DbgValues.clear();
     299      226517 :   LabelsBeforeInsn.clear();
     300      226517 :   LabelsAfterInsn.clear();
     301      226517 : }

Generated by: LCOV version 1.13