Skip to content

Commit 5a791ee

Browse files
committedMar 15, 2018
Re-land r327620 "[CodeView] Initial support for emitting S_BLOCK32 symbols for lexical scopes"
This is safe to land now that we don't copy FunctionInfo when rehashing the DenseMap. llvm-svn: 327670
1 parent e9dc30d commit 5a791ee

File tree

5 files changed

+514
-14
lines changed

5 files changed

+514
-14
lines changed
 

‎llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp

+141-6
Original file line numberDiff line numberDiff line change
@@ -365,15 +365,15 @@ unsigned CodeViewDebug::getPointerSizeInBytes() {
365365
}
366366

367367
void CodeViewDebug::recordLocalVariable(LocalVariable &&Var,
368-
const DILocation *InlinedAt) {
369-
if (InlinedAt) {
368+
const LexicalScope *LS) {
369+
if (const DILocation *InlinedAt = LS->getInlinedAt()) {
370370
// This variable was inlined. Associate it with the InlineSite.
371371
const DISubprogram *Inlinee = Var.DIVar->getScope()->getSubprogram();
372372
InlineSite &Site = getInlineSite(InlinedAt, Inlinee);
373373
Site.InlinedLocals.emplace_back(Var);
374374
} else {
375-
// This variable goes in the main ProcSym.
376-
CurFn->Locals.emplace_back(Var);
375+
// This variable goes into the corresponding lexical scope.
376+
ScopeVariables[LS].emplace_back(Var);
377377
}
378378
}
379379

@@ -905,6 +905,7 @@ void CodeViewDebug::emitDebugInfoForFunction(const Function *GV,
905905
OS.EmitLabel(ProcRecordEnd);
906906

907907
emitLocalVariableList(FI.Locals);
908+
emitLexicalBlockList(FI.ChildBlocks, FI);
908909

909910
// Emit inlined call site information. Only emit functions inlined directly
910911
// into the parent function. We'll emit the other sites recursively as part
@@ -1025,7 +1026,7 @@ void CodeViewDebug::collectVariableInfoFromMFTable(
10251026
LocalVariable Var;
10261027
Var.DIVar = VI.Var;
10271028
Var.DefRanges.emplace_back(std::move(DefRange));
1028-
recordLocalVariable(std::move(Var), VI.Loc->getInlinedAt());
1029+
recordLocalVariable(std::move(Var), Scope);
10291030
}
10301031
}
10311032

@@ -1156,7 +1157,7 @@ void CodeViewDebug::collectVariableInfo(const DISubprogram *SP) {
11561157
Var.DIVar = DIVar;
11571158

11581159
calculateRanges(Var, Ranges);
1159-
recordLocalVariable(std::move(Var), InlinedAt);
1160+
recordLocalVariable(std::move(Var), Scope);
11601161
}
11611162
}
11621163

@@ -2363,13 +2364,147 @@ void CodeViewDebug::emitLocalVariable(const LocalVariable &Var) {
23632364
}
23642365
}
23652366

2367+
void CodeViewDebug::emitLexicalBlockList(ArrayRef<LexicalBlock *> Blocks,
2368+
const FunctionInfo& FI) {
2369+
for (LexicalBlock *Block : Blocks)
2370+
emitLexicalBlock(*Block, FI);
2371+
}
2372+
2373+
/// Emit an S_BLOCK32 and S_END record pair delimiting the contents of a
2374+
/// lexical block scope.
2375+
void CodeViewDebug::emitLexicalBlock(const LexicalBlock &Block,
2376+
const FunctionInfo& FI) {
2377+
MCSymbol *RecordBegin = MMI->getContext().createTempSymbol(),
2378+
*RecordEnd = MMI->getContext().createTempSymbol();
2379+
2380+
// Lexical block symbol record.
2381+
OS.AddComment("Record length");
2382+
OS.emitAbsoluteSymbolDiff(RecordEnd, RecordBegin, 2); // Record Length
2383+
OS.EmitLabel(RecordBegin);
2384+
OS.AddComment("Record kind: S_BLOCK32");
2385+
OS.EmitIntValue(SymbolKind::S_BLOCK32, 2); // Record Kind
2386+
OS.AddComment("PtrParent");
2387+
OS.EmitIntValue(0, 4); // PtrParent
2388+
OS.AddComment("PtrEnd");
2389+
OS.EmitIntValue(0, 4); // PtrEnd
2390+
OS.AddComment("Code size");
2391+
OS.emitAbsoluteSymbolDiff(Block.End, Block.Begin, 4); // Code Size
2392+
OS.AddComment("Function section relative address");
2393+
OS.EmitCOFFSecRel32(Block.Begin, /*Offset=*/0); // Func Offset
2394+
OS.AddComment("Function section index");
2395+
OS.EmitCOFFSectionIndex(FI.Begin); // Func Symbol
2396+
OS.AddComment("Lexical block name");
2397+
emitNullTerminatedSymbolName(OS, Block.Name); // Name
2398+
OS.EmitLabel(RecordEnd);
2399+
2400+
// Emit variables local to this lexical block.
2401+
emitLocalVariableList(Block.Locals);
2402+
2403+
// Emit lexical blocks contained within this block.
2404+
emitLexicalBlockList(Block.Children, FI);
2405+
2406+
// Close the lexical block scope.
2407+
OS.AddComment("Record length");
2408+
OS.EmitIntValue(2, 2); // Record Length
2409+
OS.AddComment("Record kind: S_END");
2410+
OS.EmitIntValue(SymbolKind::S_END, 2); // Record Kind
2411+
}
2412+
2413+
/// Convenience routine for collecting lexical block information for a list
2414+
/// of lexical scopes.
2415+
void CodeViewDebug::collectLexicalBlockInfo(
2416+
SmallVectorImpl<LexicalScope *> &Scopes,
2417+
SmallVectorImpl<LexicalBlock *> &Blocks,
2418+
SmallVectorImpl<LocalVariable> &Locals) {
2419+
for (LexicalScope *Scope : Scopes)
2420+
collectLexicalBlockInfo(*Scope, Blocks, Locals);
2421+
}
2422+
2423+
/// Populate the lexical blocks and local variable lists of the parent with
2424+
/// information about the specified lexical scope.
2425+
void CodeViewDebug::collectLexicalBlockInfo(
2426+
LexicalScope &Scope,
2427+
SmallVectorImpl<LexicalBlock *> &ParentBlocks,
2428+
SmallVectorImpl<LocalVariable> &ParentLocals) {
2429+
if (Scope.isAbstractScope())
2430+
return;
2431+
2432+
auto LocalsIter = ScopeVariables.find(&Scope);
2433+
if (LocalsIter == ScopeVariables.end()) {
2434+
// This scope does not contain variables and can be eliminated.
2435+
collectLexicalBlockInfo(Scope.getChildren(), ParentBlocks, ParentLocals);
2436+
return;
2437+
}
2438+
SmallVectorImpl<LocalVariable> &Locals = LocalsIter->second;
2439+
2440+
const DILexicalBlock *DILB = dyn_cast<DILexicalBlock>(Scope.getScopeNode());
2441+
if (!DILB) {
2442+
// This scope is not a lexical block and can be eliminated, but keep any
2443+
// local variables it contains.
2444+
ParentLocals.append(Locals.begin(), Locals.end());
2445+
collectLexicalBlockInfo(Scope.getChildren(), ParentBlocks, ParentLocals);
2446+
return;
2447+
}
2448+
2449+
const SmallVectorImpl<InsnRange> &Ranges = Scope.getRanges();
2450+
if (Ranges.size() != 1 || !getLabelAfterInsn(Ranges.front().second)) {
2451+
// This lexical block scope has too many address ranges to represent in the
2452+
// current CodeView format or does not have a valid address range.
2453+
// Eliminate this lexical scope and promote any locals it contains to the
2454+
// parent scope.
2455+
//
2456+
// For lexical scopes with multiple address ranges you may be tempted to
2457+
// construct a single range covering every instruction where the block is
2458+
// live and everything in between. Unfortunately, Visual Studio only
2459+
// displays variables from the first matching lexical block scope. If the
2460+
// first lexical block contains exception handling code or cold code which
2461+
// is moved to the bottom of the routine creating a single range covering
2462+
// nearly the entire routine, then it will hide all other lexical blocks
2463+
// and the variables they contain.
2464+
//
2465+
ParentLocals.append(Locals.begin(), Locals.end());
2466+
collectLexicalBlockInfo(Scope.getChildren(), ParentBlocks, ParentLocals);
2467+
return;
2468+
}
2469+
2470+
// Create a new CodeView lexical block for this lexical scope. If we've
2471+
// seen this DILexicalBlock before then the scope tree is malformed and
2472+
// we can handle this gracefully by not processing it a second time.
2473+
auto BlockInsertion = CurFn->LexicalBlocks.insert({DILB, LexicalBlock()});
2474+
if (!BlockInsertion.second)
2475+
return;
2476+
2477+
// Create a lexical block containing the local variables and collect the
2478+
// the lexical block information for the children.
2479+
const InsnRange &Range = Ranges.front();
2480+
assert(Range.first && Range.second);
2481+
LexicalBlock &Block = BlockInsertion.first->second;
2482+
Block.Begin = getLabelBeforeInsn(Range.first);
2483+
Block.End = getLabelAfterInsn(Range.second);
2484+
assert(Block.Begin && "missing label for scope begin");
2485+
assert(Block.End && "missing label for scope end");
2486+
Block.Name = DILB->getName();
2487+
Block.Locals = std::move(Locals);
2488+
ParentBlocks.push_back(&Block);
2489+
collectLexicalBlockInfo(Scope.getChildren(), Block.Children, Block.Locals);
2490+
}
2491+
23662492
void CodeViewDebug::endFunctionImpl(const MachineFunction *MF) {
23672493
const Function &GV = MF->getFunction();
23682494
assert(FnDebugInfo.count(&GV));
23692495
assert(CurFn == FnDebugInfo[&GV].get());
23702496

23712497
collectVariableInfo(GV.getSubprogram());
23722498

2499+
// Build the lexical block structure to emit for this routine.
2500+
if (LexicalScope *CFS = LScopes.getCurrentFunctionScope())
2501+
collectLexicalBlockInfo(*CFS, CurFn->ChildBlocks, CurFn->Locals);
2502+
2503+
// Clear the scope and variable information from the map which will not be
2504+
// valid after we have finished processing this routine. This also prepares
2505+
// the map for the subsequent routine.
2506+
ScopeVariables.clear();
2507+
23732508
// Don't emit anything if we don't have any line tables.
23742509
if (!CurFn->HaveLineInfo) {
23752510
FnDebugInfo.erase(&GV);

‎llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.h

+37-1
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,15 @@ class LLVM_LIBRARY_VISIBILITY CodeViewDebug : public DebugHandlerBase {
107107
unsigned SiteFuncId = 0;
108108
};
109109

110+
// Combines information from DILexicalBlock and LexicalScope.
111+
struct LexicalBlock {
112+
SmallVector<LocalVariable, 1> Locals;
113+
SmallVector<LexicalBlock *, 1> Children;
114+
const MCSymbol *Begin;
115+
const MCSymbol *End;
116+
StringRef Name;
117+
};
118+
110119
// For each function, store a vector of labels to its instructions, as well as
111120
// to the end of the function.
112121
struct FunctionInfo {
@@ -124,6 +133,11 @@ class LLVM_LIBRARY_VISIBILITY CodeViewDebug : public DebugHandlerBase {
124133

125134
SmallVector<LocalVariable, 1> Locals;
126135

136+
std::unordered_map<const DILexicalBlockBase*, LexicalBlock> LexicalBlocks;
137+
138+
// Lexical blocks containing local variables.
139+
SmallVector<LexicalBlock *, 1> ChildBlocks;
140+
127141
std::vector<std::pair<MCSymbol *, MDNode *>> Annotations;
128142

129143
const MCSymbol *Begin = nullptr;
@@ -134,6 +148,12 @@ class LLVM_LIBRARY_VISIBILITY CodeViewDebug : public DebugHandlerBase {
134148
};
135149
FunctionInfo *CurFn = nullptr;
136150

151+
// Map used to seperate variables according to the lexical scope they belong
152+
// in. This is populated by recordLocalVariable() before
153+
// collectLexicalBlocks() separates the variables between the FunctionInfo
154+
// and LexicalBlocks.
155+
DenseMap<const LexicalScope *, SmallVector<LocalVariable, 1>> ScopeVariables;
156+
137157
/// The set of comdat .debug$S sections that we've seen so far. Each section
138158
/// must start with a magic version number that must only be emitted once.
139159
/// This set tracks which sections we've already opened.
@@ -258,16 +278,32 @@ class LLVM_LIBRARY_VISIBILITY CodeViewDebug : public DebugHandlerBase {
258278

259279
void collectVariableInfoFromMFTable(DenseSet<InlinedVariable> &Processed);
260280

281+
// Construct the lexical block tree for a routine, pruning emptpy lexical
282+
// scopes, and populate it with local variables.
283+
void collectLexicalBlockInfo(SmallVectorImpl<LexicalScope *> &Scopes,
284+
SmallVectorImpl<LexicalBlock *> &Blocks,
285+
SmallVectorImpl<LocalVariable> &Locals);
286+
void collectLexicalBlockInfo(LexicalScope &Scope,
287+
SmallVectorImpl<LexicalBlock *> &ParentBlocks,
288+
SmallVectorImpl<LocalVariable> &ParentLocals);
289+
261290
/// Records information about a local variable in the appropriate scope. In
262291
/// particular, locals from inlined code live inside the inlining site.
263-
void recordLocalVariable(LocalVariable &&Var, const DILocation *Loc);
292+
void recordLocalVariable(LocalVariable &&Var, const LexicalScope *LS);
264293

265294
/// Emits local variables in the appropriate order.
266295
void emitLocalVariableList(ArrayRef<LocalVariable> Locals);
267296

268297
/// Emits an S_LOCAL record and its associated defined ranges.
269298
void emitLocalVariable(const LocalVariable &Var);
270299

300+
/// Emits a sequence of lexical block scopes and their children.
301+
void emitLexicalBlockList(ArrayRef<LexicalBlock *> Blocks,
302+
const FunctionInfo& FI);
303+
304+
/// Emit a lexical block scope and its children.
305+
void emitLexicalBlock(const LexicalBlock &Block, const FunctionInfo& FI);
306+
271307
/// Translates the DIType to codeview if necessary and returns a type index
272308
/// for it.
273309
codeview::TypeIndex getTypeIndex(DITypeRef TypeRef,

‎llvm/lib/MC/MCObjectStreamer.cpp

+1
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ void MCObjectStreamer::flushPendingLabels(MCFragment *F, uint64_t FOffset) {
5555
// tree for (Hi - Lo) when Hi and Lo are offsets into the same fragment.
5656
static Optional<uint64_t> absoluteSymbolDiff(const MCSymbol *Hi,
5757
const MCSymbol *Lo) {
58+
assert(Hi && Lo);
5859
if (!Hi->getFragment() || Hi->getFragment() != Lo->getFragment() ||
5960
Hi->isVariable() || Lo->isVariable())
6061
return None;

0 commit comments

Comments
 (0)