llvm.org GIT mirror llvm / ac07cd5
Reland 196270 "Generalize debug info / EH emission in AsmPrinter" Addressing the existense AMDGPUAsmPrinter and other subclasses of AsmPrinter git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@196288 91177308-0d34-0410-b5e6-96231b3b80d8 Timur Iskhodzhanov 5 years ago
11 changed file(s) with 184 addition(s) and 86 deletion(s). Raw diff Collapse all Expand all
2121 #include "llvm/Support/ErrorHandling.h"
2222
2323 namespace llvm {
24 class AsmPrinterHandler;
2425 class BlockAddress;
2526 class GCStrategy;
2627 class Constant;
109110 /// function.
110111 MachineLoopInfo *LI;
111112
113 struct HandlerInfo {
114 AsmPrinterHandler *Handler;
115 const char *TimerName, *TimerGroupName;
116 HandlerInfo(AsmPrinterHandler *Handler, const char *TimerName,
117 const char *TimerGroupName)
118 : Handler(Handler), TimerName(TimerName),
119 TimerGroupName(TimerGroupName) {}
120 };
121 /// Handlers - a vector of all debug/EH info emitters we should use.
122 /// This vector maintains ownership of the emitters.
123 SmallVector Handlers;
124
112125 /// DD - If the target supports dwarf debug info, this pointer is non-null.
113126 DwarfDebug *DD;
114
115 /// DE - If the target supports dwarf exception info, this pointer is
116 /// non-null.
117 DwarfException *DE;
118127
119128 protected:
120129 explicit AsmPrinter(TargetMachine &TM, MCStreamer &Streamer);
6565
6666 /// endFunction - Gather and emit post-function exception information.
6767 ///
68 void ARMException::endFunction() {
68 void ARMException::endFunction(const MachineFunction *) {
6969 ARMTargetStreamer &ATS = getTargetStreamer();
7070 if (!Asm->MF->getFunction()->needsUnwindTableEntry())
7171 ATS.emitCantUnwind();
9898 OutContext(Streamer.getContext()),
9999 OutStreamer(Streamer),
100100 LastMI(0), LastFn(0), Counter(~0U), SetCounter(0) {
101 DD = 0; DE = 0; MMI = 0; LI = 0; MF = 0;
101 DD = 0; MMI = 0; LI = 0; MF = 0;
102102 CurrentFnSym = CurrentFnSymForSize = 0;
103103 GCMetadataPrinters = 0;
104104 VerboseAsm = Streamer.isVerboseAsm();
105105 }
106106
107107 AsmPrinter::~AsmPrinter() {
108 assert(DD == 0 && DE == 0 && "Debug/EH info didn't get finalized");
108 assert(DD == 0 && Handlers.empty() && "Debug/EH info didn't get finalized");
109109
110110 if (GCMetadataPrinters != 0) {
111111 gcp_map_type &GCMap = getGCMap(GCMetadataPrinters);
191191 OutStreamer.AddBlankLine();
192192 }
193193
194 if (MAI->doesSupportDebugInformation())
194 if (MAI->doesSupportDebugInformation()) {
195195 DD = new DwarfDebug(this, &M);
196
196 Handlers.push_back(HandlerInfo(DD, DbgTimerName, DWARFGroupName));
197 }
198
199 DwarfException *DE = 0;
197200 switch (MAI->getExceptionHandlingType()) {
198201 case ExceptionHandling::None:
199 return false;
202 break;
200203 case ExceptionHandling::SjLj:
201204 case ExceptionHandling::DwarfCFI:
202205 DE = new DwarfCFIException(this);
203 return false;
206 break;
204207 case ExceptionHandling::ARM:
205208 DE = new ARMException(this);
206 return false;
209 break;
207210 case ExceptionHandling::Win64:
208211 DE = new Win64Exception(this);
209 return false;
210 }
211
212 llvm_unreachable("Unknown exception type.");
212 break;
213 }
214 if (DE)
215 Handlers.push_back(HandlerInfo(DE, EHTimerName, DWARFGroupName));
216 return false;
213217 }
214218
215219 void AsmPrinter::EmitLinkage(const GlobalValue *GV, MCSymbol *GVSym) const {
310314 // sections and expected to be contiguous (e.g. ObjC metadata).
311315 unsigned AlignLog = getGVAlignmentLog2(GV, *DL);
312316
313 if (DD)
314 DD->setSymbolSize(GVSym, Size);
317 for (unsigned I = 0, E = Handlers.size(); I != E; ++I) {
318 const HandlerInfo &OI = Handlers[I];
319 NamedRegionTimer T(OI.TimerName, OI.TimerGroupName, TimePassesIsEnabled);
320 OI.Handler->setSymbolSize(GVSym, Size);
321 }
315322
316323 // Handle common and BSS local symbols (.lcomm).
317324 if (GVKind.isCommon() || GVKind.isBSSLocal()) {
481488 }
482489
483490 // Emit pre-function debug and/or EH information.
484 if (DE) {
485 NamedRegionTimer T(EHTimerName, DWARFGroupName, TimePassesIsEnabled);
486 DE->beginFunction(MF);
487 }
488 if (DD) {
489 NamedRegionTimer T(DbgTimerName, DWARFGroupName, TimePassesIsEnabled);
490 DD->beginFunction(MF);
491 for (unsigned I = 0, E = Handlers.size(); I != E; ++I) {
492 const HandlerInfo &OI = Handlers[I];
493 NamedRegionTimer T(OI.TimerName, OI.TimerGroupName, TimePassesIsEnabled);
494 OI.Handler->beginFunction(MF);
491495 }
492496
493497 // Emit the prefix data.
692696 // Emit target-specific gunk before the function body.
693697 EmitFunctionBodyStart();
694698
695 bool ShouldPrintDebugScopes = DD && MMI->hasDebugInfo();
699 bool ShouldPrintDebugScopes = MMI->hasDebugInfo();
696700
697701 // Print out code for the function.
698702 bool HasAnyRealCode = false;
713717 }
714718
715719 if (ShouldPrintDebugScopes) {
716 NamedRegionTimer T(DbgTimerName, DWARFGroupName, TimePassesIsEnabled);
717 DD->beginInstruction(II);
720 for (unsigned III = 0, EEE = Handlers.size(); III != EEE; ++III) {
721 const HandlerInfo &OI = Handlers[III];
722 NamedRegionTimer T(OI.TimerName, OI.TimerGroupName,
723 TimePassesIsEnabled);
724 OI.Handler->beginInstruction(II);
725 }
718726 }
719727
720728 if (isVerbose())
753761 }
754762
755763 if (ShouldPrintDebugScopes) {
756 NamedRegionTimer T(DbgTimerName, DWARFGroupName, TimePassesIsEnabled);
757 DD->endInstruction(II);
764 for (unsigned III = 0, EEE = Handlers.size(); III != EEE; ++III) {
765 const HandlerInfo &OI = Handlers[III];
766 NamedRegionTimer T(OI.TimerName, OI.TimerGroupName,
767 TimePassesIsEnabled);
768 OI.Handler->endInstruction();
769 }
758770 }
759771 }
760772 }
810822 OutStreamer.EmitELFSize(CurrentFnSym, SizeExp);
811823 }
812824
813 // Emit post-function debug information.
814 if (DD) {
815 NamedRegionTimer T(DbgTimerName, DWARFGroupName, TimePassesIsEnabled);
816 DD->endFunction(MF);
817 }
818 if (DE) {
819 NamedRegionTimer T(EHTimerName, DWARFGroupName, TimePassesIsEnabled);
820 DE->endFunction();
825 // Emit post-function debug and/or EH information.
826 for (unsigned I = 0, E = Handlers.size(); I != E; ++I) {
827 const HandlerInfo &OI = Handlers[I];
828 NamedRegionTimer T(OI.TimerName, OI.TimerGroupName, TimePassesIsEnabled);
829 OI.Handler->endFunction(MF);
821830 }
822831 MMI->EndFunction();
823832
906915 OutStreamer.Flush();
907916
908917 // Finalize debug and EH information.
909 if (DE) {
910 {
911 NamedRegionTimer T(EHTimerName, DWARFGroupName, TimePassesIsEnabled);
912 DE->endModule();
913 }
914 delete DE; DE = 0;
915 }
916 if (DD) {
917 {
918 NamedRegionTimer T(DbgTimerName, DWARFGroupName, TimePassesIsEnabled);
919 DD->endModule();
920 }
921 delete DD; DD = 0;
922 }
918 for (unsigned I = 0, E = Handlers.size(); I != E; ++I) {
919 const HandlerInfo &OI = Handlers[I];
920 NamedRegionTimer T(OI.TimerName, OI.TimerGroupName,
921 TimePassesIsEnabled);
922 OI.Handler->endModule();
923 delete OI.Handler;
924 }
925 Handlers.clear();
926 DD = 0;
923927
924928 // If the target wants to know about weak references, print them all.
925929 if (MAI->getWeakRefDirective()) {
0 //===-- lib/CodeGen/AsmPrinter/AsmPrinterHandler.h -------------*- C++ -*--===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file contains a generic interface for AsmPrinter handlers,
10 // like debug and EH info emitters.
11 //
12 //===----------------------------------------------------------------------===//
13
14 #ifndef CODEGEN_ASMPRINTER_ASMPRINTERHANDLER_H__
15 #define CODEGEN_ASMPRINTER_ASMPRINTERHANDLER_H__
16
17 #include "llvm/Support/DataTypes.h"
18
19 namespace llvm {
20
21 class MachineFunction;
22 class MachineInstr;
23 class MCSymbol;
24
25 /// \brief Collects and handles AsmPrinter objects required to build debug
26 /// or EH information.
27 class AsmPrinterHandler {
28 public:
29 virtual ~AsmPrinterHandler() {}
30
31 /// \brief For symbols that have a size designated (e.g. common symbols),
32 /// this tracks that size.
33 virtual void setSymbolSize(const MCSymbol *Sym, uint64_t Size) = 0;
34
35 /// \brief Emit all sections that should come after the content.
36 virtual void endModule() = 0;
37
38 /// \brief Gather pre-function debug information.
39 /// Every beginFunction(MF) call should be followed by an endFunction(MF) call.
40 virtual void beginFunction(const MachineFunction *MF) = 0;
41
42 /// \brief Gather post-function debug information.
43 /// Please note that some AsmPrinter implementationss may not call
44 /// beginFunction at all.
45 virtual void endFunction(const MachineFunction *MF) = 0;
46
47 /// \brief Process beginning of an instruction.
48 virtual void beginInstruction(const MachineInstr *MI) = 0;
49
50 /// \brief Process end of an instruction.
51 virtual void endInstruction() = 0;
52 };
53 } // End of namespace llvm
54
55 #endif
389389 // specified to be four bytes in the DWARF 32-bit format and eight bytes
390390 // in the DWARF 64-bit format, while DWARF Version 2 specifies that such
391391 // references have the same size as an address on the target system.
392 if (AP->getDwarfDebug()->getDwarfVersion() == 2)
392 const DwarfDebug *DD = AP->getDwarfDebug();
393 assert(DD && "Expected Dwarf Debug info to be available");
394 if (DD->getDwarfVersion() == 2)
393395 return AP->getDataLayout().getPointerSize();
394396 return sizeof(int32_t);
395397 }
136136
137137 /// endFunction - Gather and emit post-function exception information.
138138 ///
139 void DwarfCFIException::endFunction() {
139 void DwarfCFIException::endFunction(const MachineFunction *) {
140140 if (!shouldEmitPersonality && !shouldEmitMoves)
141141 return;
142142
196196 DwarfAddrSectionSym = 0;
197197 DwarfAbbrevDWOSectionSym = DwarfStrDWOSectionSym = 0;
198198 FunctionBeginSym = FunctionEndSym = 0;
199 CurFn = 0; CurMI = 0;
199200
200201 // Turn on accelerator tables for Darwin by default, pubnames by
201202 // default for non-Darwin, and handle split dwarf.
11431144
11441145 // Emit all Dwarf sections that should come after the content.
11451146 void DwarfDebug::endModule() {
1147 assert(CurFn == 0);
1148 assert(CurMI == 0);
11461149
11471150 if (!FirstCU)
11481151 return;
12241227 }
12251228
12261229 // If Var is a current function argument then add it to CurrentFnArguments list.
1227 bool DwarfDebug::addCurrentFnArgument(const MachineFunction *MF,
1228 DbgVariable *Var, LexicalScope *Scope) {
1230 bool DwarfDebug::addCurrentFnArgument(DbgVariable *Var, LexicalScope *Scope) {
12291231 if (!LScopes.isCurrentFunctionScope(Scope))
12301232 return false;
12311233 DIVariable DV = Var->getVariable();
12371239
12381240 size_t Size = CurrentFnArguments.size();
12391241 if (Size == 0)
1240 CurrentFnArguments.resize(MF->getFunction()->arg_size());
1242 CurrentFnArguments.resize(CurFn->getFunction()->arg_size());
12411243 // llvm::Function argument size is not good indicator of how many
12421244 // arguments does the function have at source level.
12431245 if (ArgNo > Size)
12481250
12491251 // Collect variable information from side table maintained by MMI.
12501252 void DwarfDebug::collectVariableInfoFromMMITable(
1251 const MachineFunction *MF, SmallPtrSet &Processed) {
1253 SmallPtrSet &Processed) {
12521254 MachineModuleInfo::VariableDbgInfoMapTy &VMap = MMI->getVariableDbgInfo();
12531255 for (MachineModuleInfo::VariableDbgInfoMapTy::iterator VI = VMap.begin(),
12541256 VE = VMap.end();
12691271 DbgVariable *AbsDbgVariable = findAbstractVariable(DV, VP.second);
12701272 DbgVariable *RegVar = new DbgVariable(DV, AbsDbgVariable, this);
12711273 RegVar->setFrameIndex(VP.first);
1272 if (!addCurrentFnArgument(MF, RegVar, Scope))
1274 if (!addCurrentFnArgument(RegVar, Scope))
12731275 addScopeVariable(Scope, RegVar);
12741276 if (AbsDbgVariable)
12751277 AbsDbgVariable->setFrameIndex(VP.first);
13161318
13171319 // Find variables for each lexical scope.
13181320 void
1319 DwarfDebug::collectVariableInfo(const MachineFunction *MF,
1320 SmallPtrSet &Processed) {
1321 DwarfDebug::collectVariableInfo(SmallPtrSet &Processed) {
13211322
13221323 // Grab the variable info that was squirreled away in the MMI side-table.
1323 collectVariableInfoFromMMITable(MF, Processed);
1324 collectVariableInfoFromMMITable(Processed);
13241325
13251326 for (SmallVectorImpl::const_iterator
13261327 UVI = UserVariables.begin(),
13401341 DIVariable DV(Var);
13411342 LexicalScope *Scope = NULL;
13421343 if (DV.getTag() == dwarf::DW_TAG_arg_variable &&
1343 DISubprogram(DV.getContext()).describes(MF->getFunction()))
1344 DISubprogram(DV.getContext()).describes(CurFn->getFunction()))
13441345 Scope = LScopes.getCurrentFunctionScope();
13451346 else if (MDNode *IA = DV.getInlinedAt())
13461347 Scope = LScopes.findInlinedScope(DebugLoc::getFromDILocation(IA));
13541355 assert(MInsn->isDebugValue() && "History must begin with debug value");
13551356 DbgVariable *AbsVar = findAbstractVariable(DV, MInsn->getDebugLoc());
13561357 DbgVariable *RegVar = new DbgVariable(DV, AbsVar, this);
1357 if (!addCurrentFnArgument(MF, RegVar, Scope))
1358 if (!addCurrentFnArgument(RegVar, Scope))
13581359 addScopeVariable(Scope, RegVar);
13591360 if (AbsVar)
13601361 AbsVar->setMInsn(MInsn);
14361437
14371438 // Process beginning of an instruction.
14381439 void DwarfDebug::beginInstruction(const MachineInstr *MI) {
1440 assert(CurMI == 0);
1441 CurMI = MI;
14391442 // Check if source location changes, but ignore DBG_VALUE locations.
14401443 if (!MI->isDebugValue()) {
14411444 DebugLoc DL = MI->getDebugLoc();
14771480 }
14781481
14791482 // Process end of an instruction.
1480 void DwarfDebug::endInstruction(const MachineInstr *MI) {
1483 void DwarfDebug::endInstruction() {
1484 assert(CurMI != 0);
14811485 // Don't create a new label after DBG_VALUE instructions.
14821486 // They don't generate code.
1483 if (!MI->isDebugValue())
1487 if (!CurMI->isDebugValue())
14841488 PrevLabel = 0;
14851489
14861490 DenseMap::iterator I =
1487 LabelsAfterInsn.find(MI);
1491 LabelsAfterInsn.find(CurMI);
1492 CurMI = 0;
14881493
14891494 // No label needed.
14901495 if (I == LabelsAfterInsn.end())
15641569 // Gather pre-function debug information. Assumes being called immediately
15651570 // after the function entry point has been emitted.
15661571 void DwarfDebug::beginFunction(const MachineFunction *MF) {
1572 CurFn = MF;
15671573
15681574 // If there's no debug info for the function we're not going to do anything.
15691575 if (!MMI->hasDebugInfo())
17911797
17921798 // Gather and emit post-function debug information.
17931799 void DwarfDebug::endFunction(const MachineFunction *MF) {
1794 if (!MMI->hasDebugInfo() || LScopes.empty())
1800 // Every beginFunction(MF) call should be followed by an endFunction(MF) call,
1801 // though the beginFunction may not be called at all.
1802 // We should handle both cases.
1803 if (CurFn == 0)
1804 CurFn = MF;
1805 else
1806 assert(CurFn == MF);
1807 assert(CurFn != 0);
1808
1809 if (!MMI->hasDebugInfo() || LScopes.empty()) {
1810 CurFn = 0;
17951811 return;
1812 }
17961813
17971814 // Define end label for subprogram.
17981815 FunctionEndSym = Asm->GetTempSymbol("func_end", Asm->getFunctionNumber());
18021819 Asm->OutStreamer.getContext().setDwarfCompileUnitID(0);
18031820
18041821 SmallPtrSet ProcessedVars;
1805 collectVariableInfo(MF, ProcessedVars);
1822 collectVariableInfo(ProcessedVars);
18061823
18071824 LexicalScope *FnScope = LScopes.getCurrentFunctionScope();
18081825 CompileUnit *TheCU = SPMap.lookup(FnScope->getScopeNode());
18361853
18371854 DIE *CurFnDIE = constructScopeDIE(TheCU, FnScope);
18381855
1839 if (!MF->getTarget().Options.DisableFramePointerElim(*MF))
1856 if (!CurFn->getTarget().Options.DisableFramePointerElim(*CurFn))
18401857 TheCU->addFlag(CurFnDIE, dwarf::DW_AT_APPLE_omit_frame_ptr);
18411858
18421859 // Clear debug info
18521869 LabelsBeforeInsn.clear();
18531870 LabelsAfterInsn.clear();
18541871 PrevLabel = NULL;
1872 CurFn = 0;
18551873 }
18561874
18571875 // Register a source line with debug info. Returns the unique label that was
1313 #ifndef CODEGEN_ASMPRINTER_DWARFDEBUG_H__
1414 #define CODEGEN_ASMPRINTER_DWARFDEBUG_H__
1515
16 #include "AsmPrinterHandler.h"
1617 #include "DIE.h"
1718 #include "llvm/ADT/DenseMap.h"
1819 #include "llvm/ADT/FoldingSet.h"
315316 };
316317
317318 /// \brief Collects and handles dwarf debug information.
318 class DwarfDebug {
319 class DwarfDebug : public AsmPrinterHandler {
319320 // Target of Dwarf emission.
320321 AsmPrinter *Asm;
321322
416417 // This location indicates end of function prologue and beginning of function
417418 // body.
418419 DebugLoc PrologEndLoc;
420
421 // If nonnull, stores the current machine function we're processing.
422 const MachineFunction *CurFn;
423
424 // If nonnull, stores the current machine instruction we're processing.
425 const MachineInstr *CurMI;
419426
420427 // Section Symbols: these are assembler temporary labels that are emitted at
421428 // the beginning of each supported dwarf section. These are used to form
647654
648655 /// \brief If Var is an current function argument that add it in
649656 /// CurrentFnArguments list.
650 bool addCurrentFnArgument(const MachineFunction *MF,
651 DbgVariable *Var, LexicalScope *Scope);
657 bool addCurrentFnArgument(DbgVariable *Var, LexicalScope *Scope);
652658
653659 /// \brief Populate LexicalScope entries with variables' info.
654 void collectVariableInfo(const MachineFunction *,
655 SmallPtrSet &ProcessedVars);
660 void collectVariableInfo(SmallPtrSet &ProcessedVars);
656661
657662 /// \brief Collect variable information from the side table maintained
658663 /// by MMI.
659 void collectVariableInfoFromMMITable(const MachineFunction * MF,
660 SmallPtrSet &P);
664 void collectVariableInfoFromMMITable(SmallPtrSet &P);
661665
662666 /// \brief Ensure that a label will be emitted before MI.
663667 void requestLabelBeforeInsn(const MachineInstr *MI) {
705709 void beginInstruction(const MachineInstr *MI);
706710
707711 /// \brief Process end of an instruction.
708 void endInstruction(const MachineInstr *MI);
712 void endInstruction();
709713
710714 /// \brief Add a DIE to the set of types that we're going to pull into
711715 /// type units.
729729 }
730730
731731 /// endFunction - Gather and emit post-function exception information.
732 ///
733 void DwarfException::endFunction() {
732 void DwarfException::endFunction(const MachineFunction *) {
734733 llvm_unreachable("Should be implemented");
735734 }
1313 #ifndef LLVM_CODEGEN_ASMPRINTER_DWARFEXCEPTION_H
1414 #define LLVM_CODEGEN_ASMPRINTER_DWARFEXCEPTION_H
1515
16 #include "AsmPrinterHandler.h"
1617 #include "llvm/ADT/DenseMap.h"
1718 #include "llvm/CodeGen/AsmPrinter.h"
1819 #include
3435 //===----------------------------------------------------------------------===//
3536 /// DwarfException - Emits Dwarf exception handling directives.
3637 ///
37 class DwarfException {
38 class DwarfException : public AsmPrinterHandler {
3839 protected:
3940 /// Asm - Target of Dwarf emission.
4041 AsmPrinter *Asm;
138139 virtual void beginFunction(const MachineFunction *MF);
139140
140141 /// endFunction - Gather and emit post-function exception information.
141 virtual void endFunction();
142 virtual void endFunction(const MachineFunction *);
143
144 // We don't need these.
145 virtual void setSymbolSize(const MCSymbol *Sym, uint64_t Size) {}
146 virtual void beginInstruction(const MachineInstr *MI) {}
147 virtual void endInstruction() {}
142148 };
143149
144150 class DwarfCFIException : public DwarfException {
172178 virtual void beginFunction(const MachineFunction *MF);
173179
174180 /// endFunction - Gather and emit post-function exception information.
175 virtual void endFunction();
181 virtual void endFunction(const MachineFunction *);
176182 };
177183
178184 class ARMException : public DwarfException {
195201 virtual void beginFunction(const MachineFunction *MF);
196202
197203 /// endFunction - Gather and emit post-function exception information.
198 virtual void endFunction();
204 virtual void endFunction(const MachineFunction *);
199205 };
200206
201207 class Win64Exception : public DwarfException {
227233 virtual void beginFunction(const MachineFunction *MF);
228234
229235 /// endFunction - Gather and emit post-function exception information.
230 virtual void endFunction();
236 virtual void endFunction(const MachineFunction *);
231237 };
232238
233239 } // End of namespace llvm
8787
8888 /// endFunction - Gather and emit post-function exception information.
8989 ///
90 void Win64Exception::endFunction() {
90 void Win64Exception::endFunction(const MachineFunction *) {
9191 if (!shouldEmitPersonality && !shouldEmitMoves)
9292 return;
9393