1*0b57cec5SDimitry Andric //===-- llvm/lib/CodeGen/AsmPrinter/DebugHandlerBase.cpp -------*- C++ -*--===// 2*0b57cec5SDimitry Andric // 3*0b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*0b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 5*0b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6*0b57cec5SDimitry Andric // 7*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 8*0b57cec5SDimitry Andric // 9*0b57cec5SDimitry Andric // Common functionality for different debug information format backends. 10*0b57cec5SDimitry Andric // LLVM currently supports DWARF and CodeView. 11*0b57cec5SDimitry Andric // 12*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 13*0b57cec5SDimitry Andric 14*0b57cec5SDimitry Andric #include "llvm/CodeGen/DebugHandlerBase.h" 15*0b57cec5SDimitry Andric #include "llvm/ADT/Optional.h" 16*0b57cec5SDimitry Andric #include "llvm/ADT/Twine.h" 17*0b57cec5SDimitry Andric #include "llvm/CodeGen/AsmPrinter.h" 18*0b57cec5SDimitry Andric #include "llvm/CodeGen/MachineFunction.h" 19*0b57cec5SDimitry Andric #include "llvm/CodeGen/MachineInstr.h" 20*0b57cec5SDimitry Andric #include "llvm/CodeGen/MachineModuleInfo.h" 21*0b57cec5SDimitry Andric #include "llvm/CodeGen/TargetSubtargetInfo.h" 22*0b57cec5SDimitry Andric #include "llvm/IR/DebugInfo.h" 23*0b57cec5SDimitry Andric #include "llvm/MC/MCStreamer.h" 24*0b57cec5SDimitry Andric 25*0b57cec5SDimitry Andric using namespace llvm; 26*0b57cec5SDimitry Andric 27*0b57cec5SDimitry Andric #define DEBUG_TYPE "dwarfdebug" 28*0b57cec5SDimitry Andric 29*0b57cec5SDimitry Andric Optional<DbgVariableLocation> 30*0b57cec5SDimitry Andric DbgVariableLocation::extractFromMachineInstruction( 31*0b57cec5SDimitry Andric const MachineInstr &Instruction) { 32*0b57cec5SDimitry Andric DbgVariableLocation Location; 33*0b57cec5SDimitry Andric if (!Instruction.isDebugValue()) 34*0b57cec5SDimitry Andric return None; 35*0b57cec5SDimitry Andric if (!Instruction.getOperand(0).isReg()) 36*0b57cec5SDimitry Andric return None; 37*0b57cec5SDimitry Andric Location.Register = Instruction.getOperand(0).getReg(); 38*0b57cec5SDimitry Andric Location.FragmentInfo.reset(); 39*0b57cec5SDimitry Andric // We only handle expressions generated by DIExpression::appendOffset, 40*0b57cec5SDimitry Andric // which doesn't require a full stack machine. 41*0b57cec5SDimitry Andric int64_t Offset = 0; 42*0b57cec5SDimitry Andric const DIExpression *DIExpr = Instruction.getDebugExpression(); 43*0b57cec5SDimitry Andric auto Op = DIExpr->expr_op_begin(); 44*0b57cec5SDimitry Andric while (Op != DIExpr->expr_op_end()) { 45*0b57cec5SDimitry Andric switch (Op->getOp()) { 46*0b57cec5SDimitry Andric case dwarf::DW_OP_constu: { 47*0b57cec5SDimitry Andric int Value = Op->getArg(0); 48*0b57cec5SDimitry Andric ++Op; 49*0b57cec5SDimitry Andric if (Op != DIExpr->expr_op_end()) { 50*0b57cec5SDimitry Andric switch (Op->getOp()) { 51*0b57cec5SDimitry Andric case dwarf::DW_OP_minus: 52*0b57cec5SDimitry Andric Offset -= Value; 53*0b57cec5SDimitry Andric break; 54*0b57cec5SDimitry Andric case dwarf::DW_OP_plus: 55*0b57cec5SDimitry Andric Offset += Value; 56*0b57cec5SDimitry Andric break; 57*0b57cec5SDimitry Andric default: 58*0b57cec5SDimitry Andric continue; 59*0b57cec5SDimitry Andric } 60*0b57cec5SDimitry Andric } 61*0b57cec5SDimitry Andric } break; 62*0b57cec5SDimitry Andric case dwarf::DW_OP_plus_uconst: 63*0b57cec5SDimitry Andric Offset += Op->getArg(0); 64*0b57cec5SDimitry Andric break; 65*0b57cec5SDimitry Andric case dwarf::DW_OP_LLVM_fragment: 66*0b57cec5SDimitry Andric Location.FragmentInfo = {Op->getArg(1), Op->getArg(0)}; 67*0b57cec5SDimitry Andric break; 68*0b57cec5SDimitry Andric case dwarf::DW_OP_deref: 69*0b57cec5SDimitry Andric Location.LoadChain.push_back(Offset); 70*0b57cec5SDimitry Andric Offset = 0; 71*0b57cec5SDimitry Andric break; 72*0b57cec5SDimitry Andric default: 73*0b57cec5SDimitry Andric return None; 74*0b57cec5SDimitry Andric } 75*0b57cec5SDimitry Andric ++Op; 76*0b57cec5SDimitry Andric } 77*0b57cec5SDimitry Andric 78*0b57cec5SDimitry Andric // Do one final implicit DW_OP_deref if this was an indirect DBG_VALUE 79*0b57cec5SDimitry Andric // instruction. 80*0b57cec5SDimitry Andric // FIXME: Replace these with DIExpression. 81*0b57cec5SDimitry Andric if (Instruction.isIndirectDebugValue()) 82*0b57cec5SDimitry Andric Location.LoadChain.push_back(Offset); 83*0b57cec5SDimitry Andric 84*0b57cec5SDimitry Andric return Location; 85*0b57cec5SDimitry Andric } 86*0b57cec5SDimitry Andric 87*0b57cec5SDimitry Andric DebugHandlerBase::DebugHandlerBase(AsmPrinter *A) : Asm(A), MMI(Asm->MMI) {} 88*0b57cec5SDimitry Andric 89*0b57cec5SDimitry Andric // Each LexicalScope has first instruction and last instruction to mark 90*0b57cec5SDimitry Andric // beginning and end of a scope respectively. Create an inverse map that list 91*0b57cec5SDimitry Andric // scopes starts (and ends) with an instruction. One instruction may start (or 92*0b57cec5SDimitry Andric // end) multiple scopes. Ignore scopes that are not reachable. 93*0b57cec5SDimitry Andric void DebugHandlerBase::identifyScopeMarkers() { 94*0b57cec5SDimitry Andric SmallVector<LexicalScope *, 4> WorkList; 95*0b57cec5SDimitry Andric WorkList.push_back(LScopes.getCurrentFunctionScope()); 96*0b57cec5SDimitry Andric while (!WorkList.empty()) { 97*0b57cec5SDimitry Andric LexicalScope *S = WorkList.pop_back_val(); 98*0b57cec5SDimitry Andric 99*0b57cec5SDimitry Andric const SmallVectorImpl<LexicalScope *> &Children = S->getChildren(); 100*0b57cec5SDimitry Andric if (!Children.empty()) 101*0b57cec5SDimitry Andric WorkList.append(Children.begin(), Children.end()); 102*0b57cec5SDimitry Andric 103*0b57cec5SDimitry Andric if (S->isAbstractScope()) 104*0b57cec5SDimitry Andric continue; 105*0b57cec5SDimitry Andric 106*0b57cec5SDimitry Andric for (const InsnRange &R : S->getRanges()) { 107*0b57cec5SDimitry Andric assert(R.first && "InsnRange does not have first instruction!"); 108*0b57cec5SDimitry Andric assert(R.second && "InsnRange does not have second instruction!"); 109*0b57cec5SDimitry Andric requestLabelBeforeInsn(R.first); 110*0b57cec5SDimitry Andric requestLabelAfterInsn(R.second); 111*0b57cec5SDimitry Andric } 112*0b57cec5SDimitry Andric } 113*0b57cec5SDimitry Andric } 114*0b57cec5SDimitry Andric 115*0b57cec5SDimitry Andric // Return Label preceding the instruction. 116*0b57cec5SDimitry Andric MCSymbol *DebugHandlerBase::getLabelBeforeInsn(const MachineInstr *MI) { 117*0b57cec5SDimitry Andric MCSymbol *Label = LabelsBeforeInsn.lookup(MI); 118*0b57cec5SDimitry Andric assert(Label && "Didn't insert label before instruction"); 119*0b57cec5SDimitry Andric return Label; 120*0b57cec5SDimitry Andric } 121*0b57cec5SDimitry Andric 122*0b57cec5SDimitry Andric // Return Label immediately following the instruction. 123*0b57cec5SDimitry Andric MCSymbol *DebugHandlerBase::getLabelAfterInsn(const MachineInstr *MI) { 124*0b57cec5SDimitry Andric return LabelsAfterInsn.lookup(MI); 125*0b57cec5SDimitry Andric } 126*0b57cec5SDimitry Andric 127*0b57cec5SDimitry Andric // Return the function-local offset of an instruction. 128*0b57cec5SDimitry Andric const MCExpr * 129*0b57cec5SDimitry Andric DebugHandlerBase::getFunctionLocalOffsetAfterInsn(const MachineInstr *MI) { 130*0b57cec5SDimitry Andric MCContext &MC = Asm->OutContext; 131*0b57cec5SDimitry Andric 132*0b57cec5SDimitry Andric MCSymbol *Start = Asm->getFunctionBegin(); 133*0b57cec5SDimitry Andric const auto *StartRef = MCSymbolRefExpr::create(Start, MC); 134*0b57cec5SDimitry Andric 135*0b57cec5SDimitry Andric MCSymbol *AfterInsn = getLabelAfterInsn(MI); 136*0b57cec5SDimitry Andric assert(AfterInsn && "Expected label after instruction"); 137*0b57cec5SDimitry Andric const auto *AfterRef = MCSymbolRefExpr::create(AfterInsn, MC); 138*0b57cec5SDimitry Andric 139*0b57cec5SDimitry Andric return MCBinaryExpr::createSub(AfterRef, StartRef, MC); 140*0b57cec5SDimitry Andric } 141*0b57cec5SDimitry Andric 142*0b57cec5SDimitry Andric /// If this type is derived from a base type then return base type size. 143*0b57cec5SDimitry Andric uint64_t DebugHandlerBase::getBaseTypeSize(const DIType *Ty) { 144*0b57cec5SDimitry Andric assert(Ty); 145*0b57cec5SDimitry Andric const DIDerivedType *DDTy = dyn_cast<DIDerivedType>(Ty); 146*0b57cec5SDimitry Andric if (!DDTy) 147*0b57cec5SDimitry Andric return Ty->getSizeInBits(); 148*0b57cec5SDimitry Andric 149*0b57cec5SDimitry Andric unsigned Tag = DDTy->getTag(); 150*0b57cec5SDimitry Andric 151*0b57cec5SDimitry Andric if (Tag != dwarf::DW_TAG_member && Tag != dwarf::DW_TAG_typedef && 152*0b57cec5SDimitry Andric Tag != dwarf::DW_TAG_const_type && Tag != dwarf::DW_TAG_volatile_type && 153*0b57cec5SDimitry Andric Tag != dwarf::DW_TAG_restrict_type && Tag != dwarf::DW_TAG_atomic_type) 154*0b57cec5SDimitry Andric return DDTy->getSizeInBits(); 155*0b57cec5SDimitry Andric 156*0b57cec5SDimitry Andric DIType *BaseType = DDTy->getBaseType(); 157*0b57cec5SDimitry Andric 158*0b57cec5SDimitry Andric if (!BaseType) 159*0b57cec5SDimitry Andric return 0; 160*0b57cec5SDimitry Andric 161*0b57cec5SDimitry Andric // If this is a derived type, go ahead and get the base type, unless it's a 162*0b57cec5SDimitry Andric // reference then it's just the size of the field. Pointer types have no need 163*0b57cec5SDimitry Andric // of this since they're a different type of qualification on the type. 164*0b57cec5SDimitry Andric if (BaseType->getTag() == dwarf::DW_TAG_reference_type || 165*0b57cec5SDimitry Andric BaseType->getTag() == dwarf::DW_TAG_rvalue_reference_type) 166*0b57cec5SDimitry Andric return Ty->getSizeInBits(); 167*0b57cec5SDimitry Andric 168*0b57cec5SDimitry Andric return getBaseTypeSize(BaseType); 169*0b57cec5SDimitry Andric } 170*0b57cec5SDimitry Andric 171*0b57cec5SDimitry Andric static bool hasDebugInfo(const MachineModuleInfo *MMI, 172*0b57cec5SDimitry Andric const MachineFunction *MF) { 173*0b57cec5SDimitry Andric if (!MMI->hasDebugInfo()) 174*0b57cec5SDimitry Andric return false; 175*0b57cec5SDimitry Andric auto *SP = MF->getFunction().getSubprogram(); 176*0b57cec5SDimitry Andric if (!SP) 177*0b57cec5SDimitry Andric return false; 178*0b57cec5SDimitry Andric assert(SP->getUnit()); 179*0b57cec5SDimitry Andric auto EK = SP->getUnit()->getEmissionKind(); 180*0b57cec5SDimitry Andric if (EK == DICompileUnit::NoDebug) 181*0b57cec5SDimitry Andric return false; 182*0b57cec5SDimitry Andric return true; 183*0b57cec5SDimitry Andric } 184*0b57cec5SDimitry Andric 185*0b57cec5SDimitry Andric void DebugHandlerBase::beginFunction(const MachineFunction *MF) { 186*0b57cec5SDimitry Andric PrevInstBB = nullptr; 187*0b57cec5SDimitry Andric 188*0b57cec5SDimitry Andric if (!Asm || !hasDebugInfo(MMI, MF)) { 189*0b57cec5SDimitry Andric skippedNonDebugFunction(); 190*0b57cec5SDimitry Andric return; 191*0b57cec5SDimitry Andric } 192*0b57cec5SDimitry Andric 193*0b57cec5SDimitry Andric // Grab the lexical scopes for the function, if we don't have any of those 194*0b57cec5SDimitry Andric // then we're not going to be able to do anything. 195*0b57cec5SDimitry Andric LScopes.initialize(*MF); 196*0b57cec5SDimitry Andric if (LScopes.empty()) { 197*0b57cec5SDimitry Andric beginFunctionImpl(MF); 198*0b57cec5SDimitry Andric return; 199*0b57cec5SDimitry Andric } 200*0b57cec5SDimitry Andric 201*0b57cec5SDimitry Andric // Make sure that each lexical scope will have a begin/end label. 202*0b57cec5SDimitry Andric identifyScopeMarkers(); 203*0b57cec5SDimitry Andric 204*0b57cec5SDimitry Andric // Calculate history for local variables. 205*0b57cec5SDimitry Andric assert(DbgValues.empty() && "DbgValues map wasn't cleaned!"); 206*0b57cec5SDimitry Andric assert(DbgLabels.empty() && "DbgLabels map wasn't cleaned!"); 207*0b57cec5SDimitry Andric calculateDbgEntityHistory(MF, Asm->MF->getSubtarget().getRegisterInfo(), 208*0b57cec5SDimitry Andric DbgValues, DbgLabels); 209*0b57cec5SDimitry Andric LLVM_DEBUG(DbgValues.dump()); 210*0b57cec5SDimitry Andric 211*0b57cec5SDimitry Andric // Request labels for the full history. 212*0b57cec5SDimitry Andric for (const auto &I : DbgValues) { 213*0b57cec5SDimitry Andric const auto &Entries = I.second; 214*0b57cec5SDimitry Andric if (Entries.empty()) 215*0b57cec5SDimitry Andric continue; 216*0b57cec5SDimitry Andric 217*0b57cec5SDimitry Andric auto IsDescribedByReg = [](const MachineInstr *MI) { 218*0b57cec5SDimitry Andric return MI->getOperand(0).isReg() && MI->getOperand(0).getReg(); 219*0b57cec5SDimitry Andric }; 220*0b57cec5SDimitry Andric 221*0b57cec5SDimitry Andric // The first mention of a function argument gets the CurrentFnBegin label, 222*0b57cec5SDimitry Andric // so arguments are visible when breaking at function entry. 223*0b57cec5SDimitry Andric // 224*0b57cec5SDimitry Andric // We do not change the label for values that are described by registers, 225*0b57cec5SDimitry Andric // as that could place them above their defining instructions. We should 226*0b57cec5SDimitry Andric // ideally not change the labels for constant debug values either, since 227*0b57cec5SDimitry Andric // doing that violates the ranges that are calculated in the history map. 228*0b57cec5SDimitry Andric // However, we currently do not emit debug values for constant arguments 229*0b57cec5SDimitry Andric // directly at the start of the function, so this code is still useful. 230*0b57cec5SDimitry Andric const DILocalVariable *DIVar = 231*0b57cec5SDimitry Andric Entries.front().getInstr()->getDebugVariable(); 232*0b57cec5SDimitry Andric if (DIVar->isParameter() && 233*0b57cec5SDimitry Andric getDISubprogram(DIVar->getScope())->describes(&MF->getFunction())) { 234*0b57cec5SDimitry Andric if (!IsDescribedByReg(Entries.front().getInstr())) 235*0b57cec5SDimitry Andric LabelsBeforeInsn[Entries.front().getInstr()] = Asm->getFunctionBegin(); 236*0b57cec5SDimitry Andric if (Entries.front().getInstr()->getDebugExpression()->isFragment()) { 237*0b57cec5SDimitry Andric // Mark all non-overlapping initial fragments. 238*0b57cec5SDimitry Andric for (auto I = Entries.begin(); I != Entries.end(); ++I) { 239*0b57cec5SDimitry Andric if (!I->isDbgValue()) 240*0b57cec5SDimitry Andric continue; 241*0b57cec5SDimitry Andric const DIExpression *Fragment = I->getInstr()->getDebugExpression(); 242*0b57cec5SDimitry Andric if (std::any_of(Entries.begin(), I, 243*0b57cec5SDimitry Andric [&](DbgValueHistoryMap::Entry Pred) { 244*0b57cec5SDimitry Andric return Pred.isDbgValue() && 245*0b57cec5SDimitry Andric Fragment->fragmentsOverlap( 246*0b57cec5SDimitry Andric Pred.getInstr()->getDebugExpression()); 247*0b57cec5SDimitry Andric })) 248*0b57cec5SDimitry Andric break; 249*0b57cec5SDimitry Andric // The code that generates location lists for DWARF assumes that the 250*0b57cec5SDimitry Andric // entries' start labels are monotonically increasing, and since we 251*0b57cec5SDimitry Andric // don't change the label for fragments that are described by 252*0b57cec5SDimitry Andric // registers, we must bail out when encountering such a fragment. 253*0b57cec5SDimitry Andric if (IsDescribedByReg(I->getInstr())) 254*0b57cec5SDimitry Andric break; 255*0b57cec5SDimitry Andric LabelsBeforeInsn[I->getInstr()] = Asm->getFunctionBegin(); 256*0b57cec5SDimitry Andric } 257*0b57cec5SDimitry Andric } 258*0b57cec5SDimitry Andric } 259*0b57cec5SDimitry Andric 260*0b57cec5SDimitry Andric for (const auto &Entry : Entries) { 261*0b57cec5SDimitry Andric if (Entry.isDbgValue()) 262*0b57cec5SDimitry Andric requestLabelBeforeInsn(Entry.getInstr()); 263*0b57cec5SDimitry Andric else 264*0b57cec5SDimitry Andric requestLabelAfterInsn(Entry.getInstr()); 265*0b57cec5SDimitry Andric } 266*0b57cec5SDimitry Andric } 267*0b57cec5SDimitry Andric 268*0b57cec5SDimitry Andric // Ensure there is a symbol before DBG_LABEL. 269*0b57cec5SDimitry Andric for (const auto &I : DbgLabels) { 270*0b57cec5SDimitry Andric const MachineInstr *MI = I.second; 271*0b57cec5SDimitry Andric requestLabelBeforeInsn(MI); 272*0b57cec5SDimitry Andric } 273*0b57cec5SDimitry Andric 274*0b57cec5SDimitry Andric PrevInstLoc = DebugLoc(); 275*0b57cec5SDimitry Andric PrevLabel = Asm->getFunctionBegin(); 276*0b57cec5SDimitry Andric beginFunctionImpl(MF); 277*0b57cec5SDimitry Andric } 278*0b57cec5SDimitry Andric 279*0b57cec5SDimitry Andric void DebugHandlerBase::beginInstruction(const MachineInstr *MI) { 280*0b57cec5SDimitry Andric if (!MMI->hasDebugInfo()) 281*0b57cec5SDimitry Andric return; 282*0b57cec5SDimitry Andric 283*0b57cec5SDimitry Andric assert(CurMI == nullptr); 284*0b57cec5SDimitry Andric CurMI = MI; 285*0b57cec5SDimitry Andric 286*0b57cec5SDimitry Andric // Insert labels where requested. 287*0b57cec5SDimitry Andric DenseMap<const MachineInstr *, MCSymbol *>::iterator I = 288*0b57cec5SDimitry Andric LabelsBeforeInsn.find(MI); 289*0b57cec5SDimitry Andric 290*0b57cec5SDimitry Andric // No label needed. 291*0b57cec5SDimitry Andric if (I == LabelsBeforeInsn.end()) 292*0b57cec5SDimitry Andric return; 293*0b57cec5SDimitry Andric 294*0b57cec5SDimitry Andric // Label already assigned. 295*0b57cec5SDimitry Andric if (I->second) 296*0b57cec5SDimitry Andric return; 297*0b57cec5SDimitry Andric 298*0b57cec5SDimitry Andric if (!PrevLabel) { 299*0b57cec5SDimitry Andric PrevLabel = MMI->getContext().createTempSymbol(); 300*0b57cec5SDimitry Andric Asm->OutStreamer->EmitLabel(PrevLabel); 301*0b57cec5SDimitry Andric } 302*0b57cec5SDimitry Andric I->second = PrevLabel; 303*0b57cec5SDimitry Andric } 304*0b57cec5SDimitry Andric 305*0b57cec5SDimitry Andric void DebugHandlerBase::endInstruction() { 306*0b57cec5SDimitry Andric if (!MMI->hasDebugInfo()) 307*0b57cec5SDimitry Andric return; 308*0b57cec5SDimitry Andric 309*0b57cec5SDimitry Andric assert(CurMI != nullptr); 310*0b57cec5SDimitry Andric // Don't create a new label after DBG_VALUE and other instructions that don't 311*0b57cec5SDimitry Andric // generate code. 312*0b57cec5SDimitry Andric if (!CurMI->isMetaInstruction()) { 313*0b57cec5SDimitry Andric PrevLabel = nullptr; 314*0b57cec5SDimitry Andric PrevInstBB = CurMI->getParent(); 315*0b57cec5SDimitry Andric } 316*0b57cec5SDimitry Andric 317*0b57cec5SDimitry Andric DenseMap<const MachineInstr *, MCSymbol *>::iterator I = 318*0b57cec5SDimitry Andric LabelsAfterInsn.find(CurMI); 319*0b57cec5SDimitry Andric CurMI = nullptr; 320*0b57cec5SDimitry Andric 321*0b57cec5SDimitry Andric // No label needed. 322*0b57cec5SDimitry Andric if (I == LabelsAfterInsn.end()) 323*0b57cec5SDimitry Andric return; 324*0b57cec5SDimitry Andric 325*0b57cec5SDimitry Andric // Label already assigned. 326*0b57cec5SDimitry Andric if (I->second) 327*0b57cec5SDimitry Andric return; 328*0b57cec5SDimitry Andric 329*0b57cec5SDimitry Andric // We need a label after this instruction. 330*0b57cec5SDimitry Andric if (!PrevLabel) { 331*0b57cec5SDimitry Andric PrevLabel = MMI->getContext().createTempSymbol(); 332*0b57cec5SDimitry Andric Asm->OutStreamer->EmitLabel(PrevLabel); 333*0b57cec5SDimitry Andric } 334*0b57cec5SDimitry Andric I->second = PrevLabel; 335*0b57cec5SDimitry Andric } 336*0b57cec5SDimitry Andric 337*0b57cec5SDimitry Andric void DebugHandlerBase::endFunction(const MachineFunction *MF) { 338*0b57cec5SDimitry Andric if (hasDebugInfo(MMI, MF)) 339*0b57cec5SDimitry Andric endFunctionImpl(MF); 340*0b57cec5SDimitry Andric DbgValues.clear(); 341*0b57cec5SDimitry Andric DbgLabels.clear(); 342*0b57cec5SDimitry Andric LabelsBeforeInsn.clear(); 343*0b57cec5SDimitry Andric LabelsAfterInsn.clear(); 344*0b57cec5SDimitry Andric } 345