LCOV - code coverage report
Current view: top level - lib/CodeGen/AsmPrinter - DebugHandlerBase.cpp (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 118 121 97.5 %
Date: 2018-10-20 13:21:21 Functions: 11 11 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         145 : DbgVariableLocation::extractFromMachineInstruction(
      32             :     const MachineInstr &Instruction) {
      33             :   DbgVariableLocation Location;
      34         145 :   if (!Instruction.isDebugValue())
      35             :     return None;
      36         290 :   if (!Instruction.getOperand(0).isReg())
      37             :     return None;
      38         136 :   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         136 :   int64_t Offset = 0;
      43         136 :   const DIExpression *DIExpr = Instruction.getDebugExpression();
      44         136 :   auto Op = DIExpr->expr_op_begin();
      45         188 :   while (Op != DIExpr->expr_op_end()) {
      46          54 :     switch (Op->getOp()) {
      47             :     case dwarf::DW_OP_constu: {
      48           1 :       int Value = Op->getArg(0);
      49             :       ++Op;
      50           1 :       if (Op != DIExpr->expr_op_end()) {
      51             :         switch (Op->getOp()) {
      52           1 :         case dwarf::DW_OP_minus:
      53           1 :           Offset -= Value;
      54           1 :           break;
      55           0 :         case dwarf::DW_OP_plus:
      56           0 :           Offset += Value;
      57           0 :           break;
      58             :         default:
      59             :           continue;
      60             :         }
      61             :       }
      62             :     } break;
      63             :     case dwarf::DW_OP_plus_uconst:
      64          26 :       Offset += Op->getArg(0);
      65          26 :       break;
      66             :     case dwarf::DW_OP_LLVM_fragment:
      67             :       Location.FragmentInfo = {Op->getArg(1), Op->getArg(0)};
      68          16 :       break;
      69           9 :     case dwarf::DW_OP_deref:
      70           9 :       Location.LoadChain.push_back(Offset);
      71           9 :       Offset = 0;
      72           9 :       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          30 :     Location.LoadChain.push_back(Offset);
      84             : 
      85             :   return Location;
      86             : }
      87             : 
      88      108456 : 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        9611 : void DebugHandlerBase::identifyScopeMarkers() {
      95             :   SmallVector<LexicalScope *, 4> WorkList;
      96        9611 :   WorkList.push_back(LScopes.getCurrentFunctionScope());
      97      203109 :   while (!WorkList.empty()) {
      98             :     LexicalScope *S = WorkList.pop_back_val();
      99             : 
     100             :     const SmallVectorImpl<LexicalScope *> &Children = S->getChildren();
     101      193498 :     if (!Children.empty())
     102      108893 :       WorkList.append(Children.begin(), Children.end());
     103             : 
     104      193498 :     if (S->isAbstractScope())
     105             :       continue;
     106             : 
     107      561194 :     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      367696 :       requestLabelBeforeInsn(R.first);
     111      367696 :       requestLabelAfterInsn(R.second);
     112             :     }
     113             :   }
     114        9611 : }
     115             : 
     116             : // Return Label preceding the instruction.
     117      537670 : MCSymbol *DebugHandlerBase::getLabelBeforeInsn(const MachineInstr *MI) {
     118      537670 :   MCSymbol *Label = LabelsBeforeInsn.lookup(MI);
     119             :   assert(Label && "Didn't insert label before instruction");
     120      537670 :   return Label;
     121             : }
     122             : 
     123             : // Return Label immediately following the instruction.
     124      509237 : MCSymbol *DebugHandlerBase::getLabelAfterInsn(const MachineInstr *MI) {
     125      509237 :   return LabelsAfterInsn.lookup(MI);
     126             : }
     127             : 
     128             : /// If this type is derived from a base type then return base type size.
     129       16675 : uint64_t DebugHandlerBase::getBaseTypeSize(const DITypeRef TyRef) {
     130       16675 :   DIType *Ty = TyRef.resolve();
     131             :   assert(Ty);
     132             :   DIDerivedType *DDTy = dyn_cast<DIDerivedType>(Ty);
     133             :   if (!DDTy)
     134        4085 :     return Ty->getSizeInBits();
     135             : 
     136       12590 :   unsigned Tag = DDTy->getTag();
     137             : 
     138       12590 :   if (Tag != dwarf::DW_TAG_member && Tag != dwarf::DW_TAG_typedef &&
     139        3495 :       Tag != dwarf::DW_TAG_const_type && Tag != dwarf::DW_TAG_volatile_type &&
     140        3456 :       Tag != dwarf::DW_TAG_restrict_type && Tag != dwarf::DW_TAG_atomic_type)
     141        3453 :     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       18272 :   if (BaseType->getTag() == dwarf::DW_TAG_reference_type ||
     152             :       BaseType->getTag() == dwarf::DW_TAG_rvalue_reference_type)
     153         119 :     return Ty->getSizeInBits();
     154             : 
     155        9017 :   return getBaseTypeSize(BaseType);
     156             : }
     157             : 
     158      810805 : static bool hasDebugInfo(const MachineModuleInfo *MMI,
     159             :                          const MachineFunction *MF) {
     160      810805 :   if (!MMI->hasDebugInfo())
     161             :     return false;
     162       22058 :   auto *SP = MF->getFunction().getSubprogram();
     163       22058 :   if (!SP)
     164             :     return false;
     165             :   assert(SP->getUnit());
     166       19352 :   auto EK = SP->getUnit()->getEmissionKind();
     167       19352 :   if (EK == DICompileUnit::NoDebug)
     168           6 :     return false;
     169             :   return true;
     170             : }
     171             : 
     172      405403 : void DebugHandlerBase::beginFunction(const MachineFunction *MF) {
     173      405403 :   PrevInstBB = nullptr;
     174             : 
     175      405403 :   if (!Asm || !hasDebugInfo(MMI, MF)) {
     176      395730 :     skippedNonDebugFunction();
     177      395730 :     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        9673 :   LScopes.initialize(*MF);
     183        9673 :   if (LScopes.empty()) {
     184          62 :     beginFunctionImpl(MF);
     185          62 :     return;
     186             :   }
     187             : 
     188             :   // Make sure that each lexical scope will have a begin/end label.
     189        9611 :   identifyScopeMarkers();
     190             : 
     191             :   // Calculate history for local variables.
     192             :   assert(DbgValues.empty() && "DbgValues map wasn't cleaned!");
     193             :   assert(DbgLabels.empty() && "DbgLabels map wasn't cleaned!");
     194        9611 :   calculateDbgEntityHistory(MF, Asm->MF->getSubtarget().getRegisterInfo(),
     195        9611 :                             DbgValues, DbgLabels);
     196             :   LLVM_DEBUG(DbgValues.dump());
     197             : 
     198             :   // Request labels for the full history.
     199       86755 :   for (const auto &I : DbgValues) {
     200             :     const auto &Ranges = I.second;
     201       77144 :     if (Ranges.empty())
     202             :       continue;
     203             : 
     204             :     // The first mention of a function argument gets the CurrentFnBegin
     205             :     // label, so arguments are visible when breaking at function entry.
     206       77144 :     const DILocalVariable *DIVar = Ranges.front().first->getDebugVariable();
     207      144412 :     if (DIVar->isParameter() &&
     208       67268 :         getDISubprogram(DIVar->getScope())->describes(&MF->getFunction())) {
     209        7115 :       LabelsBeforeInsn[Ranges.front().first] = Asm->getFunctionBegin();
     210       14230 :       if (Ranges.front().first->getDebugExpression()->isFragment()) {
     211             :         // Mark all non-overlapping initial fragments.
     212          76 :         for (auto I = Ranges.begin(); I != Ranges.end(); ++I) {
     213          65 :           const DIExpression *Fragment = I->first->getDebugExpression();
     214          65 :           if (std::all_of(Ranges.begin(), I,
     215             :                           [&](DbgValueHistoryMap::InstrRange Pred) {
     216             :                             return !Fragment->fragmentsOverlap(
     217             :                                 Pred.first->getDebugExpression());
     218             :                           }))
     219          50 :             LabelsBeforeInsn[I->first] = Asm->getFunctionBegin();
     220             :           else
     221             :             break;
     222             :         }
     223             :       }
     224             :     }
     225             : 
     226      354133 :     for (const auto &Range : Ranges) {
     227      276989 :       requestLabelBeforeInsn(Range.first);
     228      276989 :       if (Range.second)
     229             :         requestLabelAfterInsn(Range.second);
     230             :     }
     231             :   }
     232             : 
     233             :   // Ensure there is a symbol before DBG_LABEL.
     234        9617 :   for (const auto &I : DbgLabels) {
     235           6 :     const MachineInstr *MI = I.second;
     236             :     requestLabelBeforeInsn(MI);
     237             :   }
     238             : 
     239        9611 :   PrevInstLoc = DebugLoc();
     240        9611 :   PrevLabel = Asm->getFunctionBegin();
     241        9611 :   beginFunctionImpl(MF);
     242             : }
     243             : 
     244     2073950 : void DebugHandlerBase::beginInstruction(const MachineInstr *MI) {
     245     2073950 :   if (!MMI->hasDebugInfo())
     246     1546918 :     return;
     247             : 
     248             :   assert(CurMI == nullptr);
     249     2073951 :   CurMI = MI;
     250             : 
     251             :   // Insert labels where requested.
     252             :   DenseMap<const MachineInstr *, MCSymbol *>::iterator I =
     253     2073951 :       LabelsBeforeInsn.find(MI);
     254             : 
     255             :   // No label needed.
     256     2073951 :   if (I == LabelsBeforeInsn.end())
     257             :     return;
     258             : 
     259             :   // Label already assigned.
     260      534171 :   if (I->second)
     261             :     return;
     262             : 
     263      527032 :   if (!PrevLabel) {
     264      350714 :     PrevLabel = MMI->getContext().createTempSymbol();
     265      350714 :     Asm->OutStreamer->EmitLabel(PrevLabel);
     266             :   }
     267      527032 :   I->second = PrevLabel;
     268             : }
     269             : 
     270     2073951 : void DebugHandlerBase::endInstruction() {
     271     2073951 :   if (!MMI->hasDebugInfo())
     272     1815851 :     return;
     273             : 
     274             :   assert(CurMI != nullptr);
     275             :   // Don't create a new label after DBG_VALUE and other instructions that don't
     276             :   // generate code.
     277     2073951 :   if (!CurMI->isMetaInstruction()) {
     278     1541608 :     PrevLabel = nullptr;
     279     1541608 :     PrevInstBB = CurMI->getParent();
     280             :   }
     281             : 
     282             :   DenseMap<const MachineInstr *, MCSymbol *>::iterator I =
     283     2073951 :       LabelsAfterInsn.find(CurMI);
     284     2073951 :   CurMI = nullptr;
     285             : 
     286             :   // No label needed.
     287     2073951 :   if (I == LabelsAfterInsn.end())
     288             :     return;
     289             : 
     290             :   // Label already assigned.
     291      258100 :   if (I->second)
     292             :     return;
     293             : 
     294             :   // We need a label after this instruction.
     295      258100 :   if (!PrevLabel) {
     296      511380 :     PrevLabel = MMI->getContext().createTempSymbol();
     297      511380 :     Asm->OutStreamer->EmitLabel(PrevLabel);
     298             :   }
     299      258100 :   I->second = PrevLabel;
     300             : }
     301             : 
     302      405403 : void DebugHandlerBase::endFunction(const MachineFunction *MF) {
     303      405403 :   if (hasDebugInfo(MMI, MF))
     304        9673 :     endFunctionImpl(MF);
     305             :   DbgValues.clear();
     306             :   DbgLabels.clear();
     307      405403 :   LabelsBeforeInsn.clear();
     308      405403 :   LabelsAfterInsn.clear();
     309      405403 : }

Generated by: LCOV version 1.13