@@ -2061,9 +2061,7 @@ void DwarfDebug::beginInstruction(const MachineInstr *MI) {
2061
2061
unsigned LastAsmLine =
2062
2062
Asm->OutStreamer ->getContext ().getCurrentDwarfLoc ().getLine ();
2063
2063
2064
- bool PrevInstInDiffBB = PrevInstBB && PrevInstBB != MI->getParent ();
2065
- bool ForceIsStmt =
2066
- PrevInstInDiffBB && MBBsStartingWithIsStmt.contains (MI->getParent ());
2064
+ bool ForceIsStmt = ForceIsStmtInstrs.contains (MI);
2067
2065
if (DL == PrevInstLoc && !ForceIsStmt) {
2068
2066
// If we have an ongoing unspecified location, nothing to do here.
2069
2067
if (!DL)
@@ -2093,8 +2091,8 @@ void DwarfDebug::beginInstruction(const MachineInstr *MI) {
2093
2091
// possibly debug information; we want it to have a source location.
2094
2092
// - Instruction is at the top of a block; we don't want to inherit the
2095
2093
// location from the physically previous (maybe unrelated) block.
2096
- if (UnknownLocations == Enable || PrevLabel ||
2097
- (PrevInstBB && PrevInstBB != MI-> getParent ()) ) {
2094
+ bool PrevInstInDiffBB = PrevInstBB && PrevInstBB != MI-> getParent ();
2095
+ if (UnknownLocations == Enable || PrevLabel || PrevInstInDiffBB ) {
2098
2096
// Preserve the file and column numbers, if we can, to save space in
2099
2097
// the encoded line table.
2100
2098
// Do not update PrevInstLoc, it remembers the last non-0 line.
@@ -2250,7 +2248,7 @@ void DwarfDebug::beginFunctionImpl(const MachineFunction *MF) {
2250
2248
// We also don't need to make this calculation for any block that doesn't have
2251
2249
// a non-0 line number on its first instruction, as we will always emit line 0
2252
2250
// without is_stmt for that block regardless.
2253
- MBBsStartingWithIsStmt .clear ();
2251
+ ForceIsStmtInstrs .clear ();
2254
2252
2255
2253
// First, collect the last stepped line for each MBB.
2256
2254
SmallDenseMap<std::pair<const MachineBasicBlock *, const MachineBasicBlock *>,
@@ -2262,16 +2260,18 @@ void DwarfDebug::beginFunctionImpl(const MachineFunction *MF) {
2262
2260
// We use const_cast even though we won't actually modify MF, because some
2263
2261
// methods we need take a non-const MBB.
2264
2262
SetVector<MachineBasicBlock *> PredMBBsToExamine;
2265
- SmallVector <MachineBasicBlock *> PotentialIsStmtMBBs ;
2263
+ SmallDenseMap <MachineBasicBlock *, MachineInstr *> PotentialIsStmtMBBInstrs ;
2266
2264
for (auto &MBB : *const_cast <MachineFunction *>(MF)) {
2267
- if (MBB.pred_empty () || ! MBB.begin ()-> getDebugLoc ())
2265
+ if (MBB.empty () || MBB.pred_empty ())
2268
2266
continue ;
2269
- unsigned StartLine = MBB.begin ()->getDebugLoc ()->getLine ();
2270
- if (StartLine == 0 )
2271
- continue ;
2272
- PotentialIsStmtMBBs.push_back (&MBB);
2273
- for (auto Pred : MBB.predecessors ())
2274
- PredMBBsToExamine.insert (&*Pred);
2267
+ for (auto &MI : MBB) {
2268
+ if (MI.getDebugLoc () && MI.getDebugLoc ()->getLine ()) {
2269
+ for (auto Pred : MBB.predecessors ())
2270
+ PredMBBsToExamine.insert (&*Pred);
2271
+ PotentialIsStmtMBBInstrs.insert ({&MBB, &MI});
2272
+ break ;
2273
+ }
2274
+ }
2275
2275
}
2276
2276
2277
2277
// For each predecessor MBB, we examine the last DebugLoc seen before each
@@ -2281,66 +2281,71 @@ void DwarfDebug::beginFunctionImpl(const MachineFunction *MF) {
2281
2281
// this rule is mainly intended to avoid excessive stepping on lines that
2282
2282
// expand to many lines of code.
2283
2283
for (auto *MBB : PredMBBsToExamine) {
2284
- assert (!MBB->empty () && " Shouldn't be processing empty blocks here." );
2285
- MachineBasicBlock *TBB = nullptr , *FBB = nullptr ;
2286
- SmallVector<MachineOperand, 4 > Cond;
2287
- if (TII->analyzeBranch (*MBB, TBB, FBB, Cond)) {
2288
- // We can't determine what DLs this branch's successors use, so skip it.
2284
+ auto CheckMBBEdge = [&](MachineBasicBlock *Succ, unsigned OutgoingLine) {
2285
+ auto MBBInstrIt = PotentialIsStmtMBBInstrs.find (Succ);
2286
+ if (MBBInstrIt == PotentialIsStmtMBBInstrs.end ())
2287
+ return ;
2288
+ MachineInstr *MI = MBBInstrIt->second ;
2289
+ if (MI->getDebugLoc ()->getLine () == OutgoingLine)
2290
+ return ;
2291
+ PotentialIsStmtMBBInstrs.erase (MBBInstrIt);
2292
+ ForceIsStmtInstrs.insert (MI);
2293
+ };
2294
+ // If this block is empty, it technically has a fall through but we should
2295
+ // assume it is irrelevant for the purposes of calculating is_stmt.
2296
+ if (MBB->empty ())
2289
2297
continue ;
2290
- }
2291
- assert (TBB && " Bad result from analyzeBranch?" );
2292
- auto MI = MBB->rbegin ();
2293
- // For a conditional branch followed by unconditional branch where the
2294
- // unconditional branch has a DebugLoc, that loc is the outgoing loc to the
2295
- // false destination only; otherwise, both destinations share an outgoing
2296
- // loc.
2297
- if (!Cond.empty () && FBB != nullptr && MBB->back ().getDebugLoc ()) {
2298
- assert (MI->isBranch () && " Bad result from analyzeBranch?" );
2299
- MBBExitLines.insert ({{MBB, FBB}, MBB->back ().getDebugLoc ()->getLine ()});
2300
- FBB = nullptr ;
2301
- ++MI;
2302
- } else if (!Cond.empty () && !FBB) {
2303
- // For a conditional branch that falls through to the next block, the
2304
- // fallthrough block is the false branch.
2305
- FBB = MBB->getLogicalFallThrough ();
2306
- assert (FBB &&
2307
- " Block ending with just a conditional branch should fallthrough." );
2298
+ // If we can't determine what DLs this branch's successors use, just treat
2299
+ // all the successors as coming from the last DebugLoc.
2300
+ SmallVector<MachineBasicBlock *, 2 > SuccessorBBs;
2301
+ auto MIIt = MBB->rbegin ();
2302
+ {
2303
+ MachineBasicBlock *TBB = nullptr , *FBB = nullptr ;
2304
+ SmallVector<MachineOperand, 4 > Cond;
2305
+ bool AnalyzeFailed = TII->analyzeBranch (*MBB, TBB, FBB, Cond);
2306
+ // For a conditional branch followed by unconditional branch where the
2307
+ // unconditional branch has a DebugLoc, that loc is the outgoing loc to
2308
+ // the the false destination only; otherwise, both destinations share an
2309
+ // outgoing loc.
2310
+ if (!AnalyzeFailed && !Cond.empty () && FBB != nullptr &&
2311
+ MBB->back ().getDebugLoc () && MBB->back ().getDebugLoc ()->getLine ()) {
2312
+ unsigned FBBLine = MBB->back ().getDebugLoc ()->getLine ();
2313
+ assert (MIIt->isBranch () && " Bad result from analyzeBranch?" );
2314
+ CheckMBBEdge (FBB, FBBLine);
2315
+ FBB = nullptr ;
2316
+ ++MIIt;
2317
+ SuccessorBBs.push_back (TBB);
2318
+ } else {
2319
+ // For all other cases, all successors share the last outgoing DebugLoc.
2320
+ SuccessorBBs.assign (MBB->succ_begin (), MBB->succ_end ());
2321
+ }
2308
2322
}
2309
2323
2310
2324
// If we don't find an outgoing loc, this block will start with a line 0.
2325
+ // It is possible that we have a block that has no DebugLoc, but acts as a
2326
+ // simple passthrough between two blocks that end and start with the same
2327
+ // line, e.g.:
2328
+ // bb.1:
2329
+ // JMP %bb.2, debug-location !10
2330
+ // bb.2:
2331
+ // JMP %bb.3
2332
+ // bb.3:
2333
+ // $r1 = ADD $r2, $r3, debug-location !10
2334
+ // If these blocks were merged into a single block, we would not attach
2335
+ // is_stmt to the ADD, but with this logic that only checks the immediate
2336
+ // predecessor, we will; we make this tradeoff because doing a full dataflow
2337
+ // analysis would be expensive, and these situations are probably not common
2338
+ // enough for this to be worthwhile.
2311
2339
unsigned LastLine = 0 ;
2312
- while (MI != MBB->rend ()) {
2313
- if (auto DL = MI ->getDebugLoc ()) {
2340
+ while (MIIt != MBB->rend ()) {
2341
+ if (auto DL = MIIt ->getDebugLoc (); DL && DL-> getLine ()) {
2314
2342
LastLine = DL->getLine ();
2315
2343
break ;
2316
2344
}
2317
- ++MI;
2318
- }
2319
- MBBExitLines.insert ({{MBB, TBB}, LastLine});
2320
- if (FBB)
2321
- MBBExitLines.insert ({{MBB, FBB}, LastLine});
2322
- }
2323
-
2324
- // Now use the outgoing values to determine the incoming values for each
2325
- // block.
2326
- MBBsStartingWithIsStmt.insert (&*MF->begin ());
2327
- for (auto *MBB : PotentialIsStmtMBBs) {
2328
- assert (!MBB->empty () && " Shouldn't be processing empty blocks here." );
2329
- if (!MBB->begin ()->getDebugLoc ())
2330
- continue ;
2331
- unsigned StartLine = MBB->begin ()->getDebugLoc ()->getLine ();
2332
- if (StartLine == 0 )
2333
- continue ;
2334
- for (auto Pred : MBB->predecessors ()) {
2335
- auto LineIt = MBBExitLines.find ({&*Pred, MBB});
2336
- // If there is no entry, it means there's a branch here that we couldn't
2337
- // track, so we can't be sure about what line we're arriving from;
2338
- // therefore assume that we should use is_stmt.
2339
- if (LineIt == MBBExitLines.end () || LineIt->second != StartLine) {
2340
- MBBsStartingWithIsStmt.insert (MBB);
2341
- break ;
2342
- }
2345
+ ++MIIt;
2343
2346
}
2347
+ for (auto Succ : SuccessorBBs)
2348
+ CheckMBBEdge (Succ, LastLine);
2344
2349
}
2345
2350
}
2346
2351
0 commit comments