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