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-07-13 00:08:38 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         143 : DbgVariableLocation::extractFromMachineInstruction(
      32             :     const MachineInstr &Instruction) {
      33             :   DbgVariableLocation Location;
      34         143 :   if (!Instruction.isDebugValue())
      35             :     return None;
      36         286 :   if (!Instruction.getOperand(0).isReg())
      37             :     return None;
      38         134 :   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         134 :   int64_t Offset = 0;
      43         134 :   const DIExpression *DIExpr = Instruction.getDebugExpression();
      44         134 :   auto Op = DIExpr->expr_op_begin();
      45         186 :   while (Op != DIExpr->expr_op_end()) {
      46          54 :     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          23 :       Offset += Op->getArg(0);
      65          23 :       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      131478 : 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       36158 : void DebugHandlerBase::identifyScopeMarkers() {
      95             :   SmallVector<LexicalScope *, 4> WorkList;
      96       36158 :   WorkList.push_back(LScopes.getCurrentFunctionScope());
      97      190271 :   while (!WorkList.empty()) {
      98             :     LexicalScope *S = WorkList.pop_back_val();
      99             : 
     100             :     const SmallVectorImpl<LexicalScope *> &Children = S->getChildren();
     101      154113 :     if (!Children.empty())
     102       68363 :       WorkList.append(Children.begin(), Children.end());
     103             : 
     104      154113 :     if (S->isAbstractScope())
     105           0 :       continue;
     106             : 
     107      716265 :     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      281076 :       requestLabelBeforeInsn(R.first);
     111      281076 :       requestLabelAfterInsn(R.second);
     112             :     }
     113             :   }
     114       36158 : }
     115             : 
     116             : // Return Label preceding the instruction.
     117      282351 : MCSymbol *DebugHandlerBase::getLabelBeforeInsn(const MachineInstr *MI) {
     118      282351 :   MCSymbol *Label = LabelsBeforeInsn.lookup(MI);
     119             :   assert(Label && "Didn't insert label before instruction");
     120      282351 :   return Label;
     121             : }
     122             : 
     123             : // Return Label immediately following the instruction.
     124      279618 : MCSymbol *DebugHandlerBase::getLabelAfterInsn(const MachineInstr *MI) {
     125      559236 :   return LabelsAfterInsn.lookup(MI);
     126             : }
     127             : 
     128             : /// If this type is derived from a base type then return base type size.
     129      117859 : 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       30852 :     return Ty->getSizeInBits();
     135             : 
     136       87007 :   unsigned Tag = DDTy->getTag();
     137             : 
     138       87007 :   if (Tag != dwarf::DW_TAG_member && Tag != dwarf::DW_TAG_typedef &&
     139       26335 :       Tag != dwarf::DW_TAG_const_type && Tag != dwarf::DW_TAG_volatile_type &&
     140       26304 :       Tag != dwarf::DW_TAG_restrict_type && Tag != dwarf::DW_TAG_atomic_type)
     141       26304 :     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      121404 :   if (BaseType->getTag() == dwarf::DW_TAG_reference_type ||
     152             :       BaseType->getTag() == dwarf::DW_TAG_rvalue_reference_type)
     153         102 :     return Ty->getSizeInBits();
     154             : 
     155       60600 :   return getBaseTypeSize(BaseType);
     156             : }
     157             : 
     158      441503 : static bool hasDebugInfo(const MachineModuleInfo *MMI,
     159             :                          const MachineFunction *MF) {
     160      441503 :   if (!MMI->hasDebugInfo())
     161             :     return false;
     162       75596 :   auto *SP = MF->getFunction().getSubprogram();
     163       75596 :   if (!SP)
     164             :     return false;
     165             :   assert(SP->getUnit());
     166       72444 :   auto EK = SP->getUnit()->getEmissionKind();
     167       72444 :   if (EK == DICompileUnit::NoDebug)
     168             :     return false;
     169       72438 :   return true;
     170             : }
     171             : 
     172      220752 : void DebugHandlerBase::beginFunction(const MachineFunction *MF) {
     173      220752 :   PrevInstBB = nullptr;
     174             : 
     175      220752 :   if (!Asm || !hasDebugInfo(MMI, MF)) {
     176      184533 :     skippedNonDebugFunction();
     177      184533 :     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       36219 :   LScopes.initialize(*MF);
     183       36219 :   if (LScopes.empty()) {
     184          61 :     beginFunctionImpl(MF);
     185          61 :     return;
     186             :   }
     187             : 
     188             :   // Make sure that each lexical scope will have a begin/end label.
     189       36158 :   identifyScopeMarkers();
     190             : 
     191             :   // Calculate history for local variables.
     192             :   assert(DbgValues.empty() && "DbgValues map wasn't cleaned!");
     193       36158 :   calculateDbgValueHistory(MF, Asm->MF->getSubtarget().getRegisterInfo(),
     194             :                            DbgValues);
     195             :   LLVM_DEBUG(DbgValues.dump());
     196             : 
     197             :   // Request labels for the full history.
     198       59558 :   for (const auto &I : DbgValues) {
     199             :     const auto &Ranges = I.second;
     200       23400 :     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       23400 :     const DILocalVariable *DIVar = Ranges.front().first->getDebugVariable();
     206       43747 :     if (DIVar->isParameter() &&
     207       20347 :         getDISubprogram(DIVar->getScope())->describes(&MF->getFunction())) {
     208        3022 :       LabelsBeforeInsn[Ranges.front().first] = Asm->getFunctionBegin();
     209        3022 :       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      159328 :     for (const auto &Range : Ranges) {
     226       67964 :       requestLabelBeforeInsn(Range.first);
     227       67964 :       if (Range.second)
     228             :         requestLabelAfterInsn(Range.second);
     229             :     }
     230             :   }
     231             : 
     232       72316 :   PrevInstLoc = DebugLoc();
     233       36158 :   PrevLabel = Asm->getFunctionBegin();
     234       36158 :   beginFunctionImpl(MF);
     235             : }
     236             : 
     237     2281405 : void DebugHandlerBase::beginInstruction(const MachineInstr *MI) {
     238     2281405 :   if (!MMI->hasDebugInfo())
     239     1995940 :     return;
     240             : 
     241             :   assert(CurMI == nullptr);
     242     2281405 :   CurMI = MI;
     243             : 
     244             :   // Insert labels where requested.
     245             :   DenseMap<const MachineInstr *, MCSymbol *>::iterator I =
     246     2281405 :       LabelsBeforeInsn.find(MI);
     247             : 
     248             :   // No label needed.
     249     2281405 :   if (I == LabelsBeforeInsn.end())
     250             :     return;
     251             : 
     252             :   // Label already assigned.
     253      286986 :   if (I->second)
     254             :     return;
     255             : 
     256      285465 :   if (!PrevLabel) {
     257      333384 :     PrevLabel = MMI->getContext().createTempSymbol();
     258      333384 :     Asm->OutStreamer->EmitLabel(PrevLabel);
     259             :   }
     260      285465 :   I->second = PrevLabel;
     261             : }
     262             : 
     263     2281405 : void DebugHandlerBase::endInstruction() {
     264     2281405 :   if (!MMI->hasDebugInfo())
     265     2070817 :     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     2281405 :   if (!CurMI->isMetaInstruction()) {
     271     1879134 :     PrevLabel = nullptr;
     272     1879134 :     PrevInstBB = CurMI->getParent();
     273             :   }
     274             : 
     275             :   DenseMap<const MachineInstr *, MCSymbol *>::iterator I =
     276     2281405 :       LabelsAfterInsn.find(CurMI);
     277     2281405 :   CurMI = nullptr;
     278             : 
     279             :   // No label needed.
     280     2281405 :   if (I == LabelsAfterInsn.end())
     281             :     return;
     282             : 
     283             :   // Label already assigned.
     284      210588 :   if (I->second)
     285             :     return;
     286             : 
     287             :   // We need a label after this instruction.
     288      210588 :   if (!PrevLabel) {
     289      420210 :     PrevLabel = MMI->getContext().createTempSymbol();
     290      420210 :     Asm->OutStreamer->EmitLabel(PrevLabel);
     291             :   }
     292      210588 :   I->second = PrevLabel;
     293             : }
     294             : 
     295      220752 : void DebugHandlerBase::endFunction(const MachineFunction *MF) {
     296      220752 :   if (hasDebugInfo(MMI, MF))
     297       36219 :     endFunctionImpl(MF);
     298             :   DbgValues.clear();
     299      220752 :   LabelsBeforeInsn.clear();
     300      220752 :   LabelsAfterInsn.clear();
     301      220752 : }

Generated by: LCOV version 1.13