diff options
Diffstat (limited to 'lib/CodeGen')
27 files changed, 899 insertions, 986 deletions
diff --git a/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/lib/CodeGen/AsmPrinter/AsmPrinter.cpp index bd2b1b6..4978fba 100644 --- a/lib/CodeGen/AsmPrinter/AsmPrinter.cpp +++ b/lib/CodeGen/AsmPrinter/AsmPrinter.cpp @@ -61,7 +61,7 @@ AsmPrinter::AsmPrinter(formatted_raw_ostream &o, TargetMachine &tm, : MachineFunctionPass(&ID), O(o), TM(tm), MAI(T), TRI(tm.getRegisterInfo()), OutContext(Ctx), OutStreamer(Streamer), - LastMI(0), LastFn(0), Counter(~0U), PrevDLT(NULL) { + LastMI(0), LastFn(0), Counter(~0U), SetCounter(0), PrevDLT(NULL) { DW = 0; MMI = 0; VerboseAsm = Streamer.isVerboseAsm(); } @@ -335,7 +335,7 @@ static void EmitComments(const MachineInstr &MI, raw_ostream &CommentOS) { // Print source line info. DIScope Scope = DLT.getScope(); // Omit the directory, because it's likely to be long and uninteresting. - if (!Scope.isNull()) + if (Scope.Verify()) CommentOS << Scope.getFilename(); else CommentOS << "<unknown>"; @@ -893,6 +893,31 @@ void AsmPrinter::EmitInt64(uint64_t Value) const { OutStreamer.EmitIntValue(Value, 8, 0/*addrspace*/); } +/// EmitLabelDifference - Emit something like ".long Hi-Lo" where the size +/// in bytes of the directive is specified by Size and Hi/Lo specify the +/// labels. This implicitly uses .set if it is available. +void AsmPrinter::EmitLabelDifference(const MCSymbol *Hi, const MCSymbol *Lo, + unsigned Size) const { + // Get the Hi-Lo expression. + const MCExpr *Diff = + MCBinaryExpr::CreateSub(MCSymbolRefExpr::Create(Hi, OutContext), + MCSymbolRefExpr::Create(Lo, OutContext), + OutContext); + + if (!MAI->hasSetDirective()) { + OutStreamer.EmitValue(Diff, Size, 0/*AddrSpace*/); + return; + } + + // Otherwise, emit with .set (aka assignment). + MCSymbol *SetLabel = + OutContext.GetOrCreateTemporarySymbol(Twine(MAI->getPrivateGlobalPrefix()) + + "set" + Twine(SetCounter++)); + OutStreamer.EmitAssignment(SetLabel, Diff); + OutStreamer.EmitSymbolValue(SetLabel, Size, 0/*AddrSpace*/); +} + + //===----------------------------------------------------------------------===// // EmitAlignment - Emit an alignment directive to the specified power of @@ -1287,18 +1312,16 @@ void AsmPrinter::processDebugLoc(const MachineInstr *MI, if (DL.isUnknown()) return; DILocation CurDLT = MF->getDILocation(DL); - if (CurDLT.getScope().isNull()) + if (!CurDLT.getScope().Verify()) return; if (!BeforePrintingInsn) { // After printing instruction DW->EndScope(MI); } else if (CurDLT.getNode() != PrevDLT) { - unsigned L = DW->RecordSourceLine(CurDLT.getLineNumber(), - CurDLT.getColumnNumber(), - CurDLT.getScope().getNode()); - printLabel(L); - O << '\n'; + MCSymbol *L = DW->RecordSourceLine(CurDLT.getLineNumber(), + CurDLT.getColumnNumber(), + CurDLT.getScope().getNode()); DW->BeginScope(MI, L); PrevDLT = CurDLT.getNode(); } @@ -1529,12 +1552,17 @@ void AsmPrinter::printKill(const MachineInstr *MI) const { /// printLabel - This method prints a local label used by debug and /// exception handling tables. void AsmPrinter::printLabelInst(const MachineInstr *MI) const { - printLabel(MI->getOperand(0).getImm()); - OutStreamer.AddBlankLine(); + MCSymbol *Sym = + OutContext.GetOrCreateTemporarySymbol(Twine(MAI->getPrivateGlobalPrefix()) + + "label" + Twine(MI->getOperand(0).getImm())); + OutStreamer.EmitLabel(Sym); } void AsmPrinter::printLabel(unsigned Id) const { - O << MAI->getPrivateGlobalPrefix() << "label" << Id << ':'; + MCSymbol *Sym = + OutContext.GetOrCreateTemporarySymbol(Twine(MAI->getPrivateGlobalPrefix()) + + "label" + Twine(Id)); + OutStreamer.EmitLabel(Sym); } /// PrintAsmOperand - Print the specified operand of MI, an INLINEASM @@ -1575,15 +1603,14 @@ MCSymbol *AsmPrinter::GetBlockAddressSymbol(const Function *F, "_" + FnName.str() + "_" + BB->getName(), Mangler::Private); - return OutContext.GetOrCreateSymbol(NameResult.str()); + return OutContext.GetOrCreateTemporarySymbol(NameResult.str()); } /// GetCPISymbol - Return the symbol for the specified constant pool entry. MCSymbol *AsmPrinter::GetCPISymbol(unsigned CPID) const { - SmallString<60> Name; - raw_svector_ostream(Name) << MAI->getPrivateGlobalPrefix() << "CPI" - << getFunctionNumber() << '_' << CPID; - return OutContext.GetOrCreateSymbol(Name.str()); + return OutContext.GetOrCreateTemporarySymbol + (Twine(MAI->getPrivateGlobalPrefix()) + "CPI" + Twine(getFunctionNumber()) + + "_" + Twine(CPID)); } /// GetJTISymbol - Return the symbol for the specified jump table entry. @@ -1594,10 +1621,9 @@ MCSymbol *AsmPrinter::GetJTISymbol(unsigned JTID, bool isLinkerPrivate) const { /// GetJTSetSymbol - Return the symbol for the specified jump table .set /// FIXME: privatize to AsmPrinter. MCSymbol *AsmPrinter::GetJTSetSymbol(unsigned UID, unsigned MBBID) const { - SmallString<60> Name; - raw_svector_ostream(Name) << MAI->getPrivateGlobalPrefix() - << getFunctionNumber() << '_' << UID << "_set_" << MBBID; - return OutContext.GetOrCreateSymbol(Name.str()); + return OutContext.GetOrCreateTemporarySymbol + (Twine(MAI->getPrivateGlobalPrefix()) + Twine(getFunctionNumber()) + "_" + + Twine(UID) + "_set_" + Twine(MBBID)); } /// GetGlobalValueSymbol - Return the MCSymbol for the specified global @@ -1605,7 +1631,10 @@ MCSymbol *AsmPrinter::GetJTSetSymbol(unsigned UID, unsigned MBBID) const { MCSymbol *AsmPrinter::GetGlobalValueSymbol(const GlobalValue *GV) const { SmallString<60> NameStr; Mang->getNameWithPrefix(NameStr, GV, false); - return OutContext.GetOrCreateSymbol(NameStr.str()); + + if (!GV->hasPrivateLinkage()) + return OutContext.GetOrCreateSymbol(NameStr.str()); + return OutContext.GetOrCreateTemporarySymbol(NameStr.str()); } /// GetSymbolWithGlobalValueBase - Return the MCSymbol for a symbol with @@ -1617,7 +1646,9 @@ MCSymbol *AsmPrinter::GetSymbolWithGlobalValueBase(const GlobalValue *GV, SmallString<60> NameStr; Mang->getNameWithPrefix(NameStr, GV, ForcePrivate); NameStr.append(Suffix.begin(), Suffix.end()); - return OutContext.GetOrCreateSymbol(NameStr.str()); + if (!GV->hasPrivateLinkage() && !ForcePrivate) + return OutContext.GetOrCreateSymbol(NameStr.str()); + return OutContext.GetOrCreateTemporarySymbol(NameStr.str()); } /// GetExternalSymbolSymbol - Return the MCSymbol for the specified diff --git a/lib/CodeGen/AsmPrinter/CMakeLists.txt b/lib/CodeGen/AsmPrinter/CMakeLists.txt index 066aaab..7dc1fb5 100644 --- a/lib/CodeGen/AsmPrinter/CMakeLists.txt +++ b/lib/CodeGen/AsmPrinter/CMakeLists.txt @@ -3,7 +3,6 @@ add_llvm_library(LLVMAsmPrinter DIE.cpp DwarfDebug.cpp DwarfException.cpp - DwarfLabel.cpp DwarfPrinter.cpp DwarfWriter.cpp OcamlGCPrinter.cpp diff --git a/lib/CodeGen/AsmPrinter/DIE.cpp b/lib/CodeGen/AsmPrinter/DIE.cpp index 63360c0..e97754e 100644 --- a/lib/CodeGen/AsmPrinter/DIE.cpp +++ b/lib/CodeGen/AsmPrinter/DIE.cpp @@ -131,17 +131,15 @@ void DIE::print(raw_ostream &O, unsigned IncIndent) { << "Die: " << format("0x%lx", (long)(intptr_t)this) << ", Offset: " << Offset - << ", Size: " << Size - << "\n"; + << ", Size: " << Size << "\n"; O << Indent << dwarf::TagString(Abbrev.getTag()) << " " - << dwarf::ChildrenString(Abbrev.getChildrenFlag()); + << dwarf::ChildrenString(Abbrev.getChildrenFlag()) << "\n"; } else { - O << "Size: " << Size; + O << "Size: " << Size << "\n"; } - O << "\n"; const SmallVector<DIEAbbrevData, 8> &Data = Abbrev.getData(); @@ -254,51 +252,27 @@ void DIEString::print(raw_ostream &O) { #endif //===----------------------------------------------------------------------===// -// DIEDwarfLabel Implementation +// DIELabel Implementation //===----------------------------------------------------------------------===// /// EmitValue - Emit label value. /// -void DIEDwarfLabel::EmitValue(DwarfPrinter *D, unsigned Form) const { +void DIELabel::EmitValue(DwarfPrinter *D, unsigned Form) const { bool IsSmall = Form == dwarf::DW_FORM_data4; - D->EmitReference(Label, false, IsSmall); + unsigned Size = IsSmall ? 4 : D->getTargetData()->getPointerSize(); + D->getAsm()->OutStreamer.EmitSymbolValue(Label, Size, 0/*AddrSpace*/); } /// SizeOf - Determine size of label value in bytes. /// -unsigned DIEDwarfLabel::SizeOf(const TargetData *TD, unsigned Form) const { +unsigned DIELabel::SizeOf(const TargetData *TD, unsigned Form) const { if (Form == dwarf::DW_FORM_data4) return 4; return TD->getPointerSize(); } #ifndef NDEBUG -void DIEDwarfLabel::print(raw_ostream &O) { - O << "Lbl: "; - Label.print(O); -} -#endif - -//===----------------------------------------------------------------------===// -// DIEObjectLabel Implementation -//===----------------------------------------------------------------------===// - -/// EmitValue - Emit label value. -/// -void DIEObjectLabel::EmitValue(DwarfPrinter *D, unsigned Form) const { - bool IsSmall = Form == dwarf::DW_FORM_data4; - D->EmitReference(Sym, false, IsSmall); -} - -/// SizeOf - Determine size of label value in bytes. -/// -unsigned DIEObjectLabel::SizeOf(const TargetData *TD, unsigned Form) const { - if (Form == dwarf::DW_FORM_data4) return 4; - return TD->getPointerSize(); -} - -#ifndef NDEBUG -void DIEObjectLabel::print(raw_ostream &O) { - O << "Obj: " << Sym->getName(); +void DIELabel::print(raw_ostream &O) { + O << "Lbl: " << Label->getName(); } #endif @@ -310,10 +284,7 @@ void DIEObjectLabel::print(raw_ostream &O) { /// void DIESectionOffset::EmitValue(DwarfPrinter *D, unsigned Form) const { bool IsSmall = Form == dwarf::DW_FORM_data4; - D->EmitSectionOffset(Label.getTag(), Section.getTag(), - Label.getNumber(), Section.getNumber(), - IsSmall, IsEH, UseSet); - D->getAsm()->O << '\n'; // FIXME: Necesssary? + D->EmitSectionOffset(Label, Section, IsSmall, IsEH); } /// SizeOf - Determine size of delta value in bytes. @@ -325,11 +296,8 @@ unsigned DIESectionOffset::SizeOf(const TargetData *TD, unsigned Form) const { #ifndef NDEBUG void DIESectionOffset::print(raw_ostream &O) { - O << "Off: "; - Label.print(O); - O << "-"; - Section.print(O); - O << "-" << IsEH << "-" << UseSet; + O << "Off: " << Label->getName() << "-" << Section->getName() + << "-" << IsEH; } #endif @@ -353,10 +321,7 @@ unsigned DIEDelta::SizeOf(const TargetData *TD, unsigned Form) const { #ifndef NDEBUG void DIEDelta::print(raw_ostream &O) { - O << "Del: "; - LabelHi.print(O); - O << "-"; - LabelLo.print(O); + O << "Del: " << LabelHi->getName() << "-" << LabelLo->getName(); } #endif @@ -400,15 +365,13 @@ void DIEBlock::EmitValue(DwarfPrinter *D, unsigned Form) const { case dwarf::DW_FORM_block1: Asm->EmitInt8(Size); break; case dwarf::DW_FORM_block2: Asm->EmitInt16(Size); break; case dwarf::DW_FORM_block4: Asm->EmitInt32(Size); break; - case dwarf::DW_FORM_block: D->EmitULEB128(Size); break; - default: llvm_unreachable("Improper form for block"); break; + case dwarf::DW_FORM_block: D->EmitULEB128(Size); break; + default: llvm_unreachable("Improper form for block"); break; } const SmallVector<DIEAbbrevData, 8> &AbbrevData = Abbrev.getData(); - for (unsigned i = 0, N = Values.size(); i < N; ++i) { - Asm->O << '\n'; + for (unsigned i = 0, N = Values.size(); i < N; ++i) Values[i]->EmitValue(D, AbbrevData[i].getForm()); - } } /// SizeOf - Determine size of block data in bytes. diff --git a/lib/CodeGen/AsmPrinter/DIE.h b/lib/CodeGen/AsmPrinter/DIE.h index af90289..e08d748 100644 --- a/lib/CodeGen/AsmPrinter/DIE.h +++ b/lib/CodeGen/AsmPrinter/DIE.h @@ -14,7 +14,6 @@ #ifndef CODEGEN_ASMPRINTER_DIE_H__ #define CODEGEN_ASMPRINTER_DIE_H__ -#include "DwarfLabel.h" #include "llvm/ADT/FoldingSet.h" #include "llvm/ADT/SmallVector.h" #include "llvm/Support/Compiler.h" @@ -26,6 +25,7 @@ namespace llvm { class DwarfPrinter; class TargetData; class MCSymbol; + class raw_ostream; //===--------------------------------------------------------------------===// /// DIEAbbrevData - Dwarf abbreviation data, describes the one attribute of a @@ -203,7 +203,6 @@ namespace llvm { isInteger, isString, isLabel, - isAsIsLabel, isSectionOffset, isDelta, isEntry, @@ -306,12 +305,12 @@ namespace llvm { }; //===--------------------------------------------------------------------===// - /// DIEDwarfLabel - A Dwarf internal label expression DIE. + /// DIELabel - A label expression DIE. // - class DIEDwarfLabel : public DIEValue { - const DWLabel Label; + class DIELabel : public DIEValue { + const MCSymbol *Label; public: - explicit DIEDwarfLabel(const DWLabel &L) : DIEValue(isLabel), Label(L) {} + explicit DIELabel(const MCSymbol *L) : DIEValue(isLabel), Label(L) {} /// EmitValue - Emit label value. /// @@ -322,7 +321,7 @@ namespace llvm { virtual unsigned SizeOf(const TargetData *TD, unsigned Form) const; // Implement isa/cast/dyncast. - static bool classof(const DIEDwarfLabel *) { return true; } + static bool classof(const DIELabel *) { return true; } static bool classof(const DIEValue *L) { return L->getType() == isLabel; } #ifndef NDEBUG @@ -331,46 +330,17 @@ namespace llvm { }; //===--------------------------------------------------------------------===// - /// DIEObjectLabel - A label to an object in code or data. - // - class DIEObjectLabel : public DIEValue { - const MCSymbol *Sym; - public: - explicit DIEObjectLabel(const MCSymbol *S) - : DIEValue(isAsIsLabel), Sym(S) {} - - /// EmitValue - Emit label value. - /// - virtual void EmitValue(DwarfPrinter *D, unsigned Form) const; - - /// SizeOf - Determine size of label value in bytes. - /// - virtual unsigned SizeOf(const TargetData *TD, unsigned Form) const; - - // Implement isa/cast/dyncast. - static bool classof(const DIEObjectLabel *) { return true; } - static bool classof(const DIEValue *L) { - return L->getType() == isAsIsLabel; - } - -#ifndef NDEBUG - virtual void print(raw_ostream &O); -#endif - }; - - //===--------------------------------------------------------------------===// /// DIESectionOffset - A section offset DIE. /// class DIESectionOffset : public DIEValue { - const DWLabel Label; - const DWLabel Section; + const MCSymbol *Label; + const MCSymbol *Section; bool IsEH : 1; - bool UseSet : 1; public: - DIESectionOffset(const DWLabel &Lab, const DWLabel &Sec, - bool isEH = false, bool useSet = true) + DIESectionOffset(const MCSymbol *Lab, const MCSymbol *Sec, + bool isEH = false) : DIEValue(isSectionOffset), Label(Lab), Section(Sec), - IsEH(isEH), UseSet(useSet) {} + IsEH(isEH) {} /// EmitValue - Emit section offset. /// @@ -395,10 +365,10 @@ namespace llvm { /// DIEDelta - A simple label difference DIE. /// class DIEDelta : public DIEValue { - const DWLabel LabelHi; - const DWLabel LabelLo; + const MCSymbol *LabelHi; + const MCSymbol *LabelLo; public: - DIEDelta(const DWLabel &Hi, const DWLabel &Lo) + DIEDelta(const MCSymbol *Hi, const MCSymbol *Lo) : DIEValue(isDelta), LabelHi(Hi), LabelLo(Lo) {} /// EmitValue - Emit delta value. diff --git a/lib/CodeGen/AsmPrinter/DwarfDebug.cpp b/lib/CodeGen/AsmPrinter/DwarfDebug.cpp index 5ad1e5e..36be5b9 100644 --- a/lib/CodeGen/AsmPrinter/DwarfDebug.cpp +++ b/lib/CodeGen/AsmPrinter/DwarfDebug.cpp @@ -10,14 +10,16 @@ // This file contains support for writing dwarf debug info into asm files. // //===----------------------------------------------------------------------===// + #define DEBUG_TYPE "dwarfdebug" #include "DwarfDebug.h" #include "llvm/Module.h" #include "llvm/CodeGen/MachineFunction.h" #include "llvm/CodeGen/MachineModuleInfo.h" +#include "llvm/MC/MCAsmInfo.h" #include "llvm/MC/MCSection.h" #include "llvm/MC/MCStreamer.h" -#include "llvm/MC/MCAsmInfo.h" +#include "llvm/MC/MCSymbol.h" #include "llvm/Target/Mangler.h" #include "llvm/Target/TargetData.h" #include "llvm/Target/TargetFrameInfo.h" @@ -170,8 +172,8 @@ class DbgScope { // Location at which this scope is inlined. AssertingVH<MDNode> InlinedAtLocation; bool AbstractScope; // Abstract Scope - unsigned StartLabelID; // Label ID of the beginning of scope. - unsigned EndLabelID; // Label ID of the end of scope. + MCSymbol *StartLabel; // Label ID of the beginning of scope. + MCSymbol *EndLabel; // Label ID of the end of scope. const MachineInstr *LastInsn; // Last instruction of this scope. const MachineInstr *FirstInsn; // First instruction of this scope. SmallVector<DbgScope *, 4> Scopes; // Scopes defined in scope. @@ -182,7 +184,7 @@ class DbgScope { public: DbgScope(DbgScope *P, DIDescriptor D, MDNode *I = 0) : Parent(P), Desc(D), InlinedAtLocation(I), AbstractScope(false), - StartLabelID(0), EndLabelID(0), + StartLabel(0), EndLabel(0), LastInsn(0), FirstInsn(0), IndentLevel(0) {} virtual ~DbgScope(); @@ -194,12 +196,12 @@ public: return InlinedAtLocation; } MDNode *getScopeNode() const { return Desc.getNode(); } - unsigned getStartLabelID() const { return StartLabelID; } - unsigned getEndLabelID() const { return EndLabelID; } + MCSymbol *getStartLabel() const { return StartLabel; } + MCSymbol *getEndLabel() const { return EndLabel; } SmallVector<DbgScope *, 4> &getScopes() { return Scopes; } SmallVector<DbgVariable *, 8> &getVariables() { return Variables; } - void setStartLabelID(unsigned S) { StartLabelID = S; } - void setEndLabelID(unsigned E) { EndLabelID = E; } + void setStartLabel(MCSymbol *S) { StartLabel = S; } + void setEndLabel(MCSymbol *E) { EndLabel = E; } void setLastInsn(const MachineInstr *MI) { LastInsn = MI; } const MachineInstr *getLastInsn() { return LastInsn; } void setFirstInsn(const MachineInstr *MI) { FirstInsn = MI; } @@ -263,7 +265,7 @@ void DbgScope::dump() const { err.indent(IndentLevel); MDNode *N = Desc.getNode(); N->dump(); - err << " [" << StartLabelID << ", " << EndLabelID << "]\n"; + err << " [" << StartLabel << ", " << EndLabel << "]\n"; if (AbstractScope) err << "Abstract Scope\n"; @@ -288,7 +290,7 @@ DbgScope::~DbgScope() { } // end llvm namespace DwarfDebug::DwarfDebug(raw_ostream &OS, AsmPrinter *A, const MCAsmInfo *T) - : DwarfPrinter(OS, A, T, "dbg"), ModuleCU(0), + : DwarfPrinter(OS, A, T), ModuleCU(0), AbbreviationsSet(InitAbbreviationsSetSize), Abbreviations(), DIEValues(), StringPool(), SectionSourceLines(), didInitial(false), shouldEmit(false), @@ -366,17 +368,8 @@ void DwarfDebug::addString(DIE *Die, unsigned Attribute, unsigned Form, /// addLabel - Add a Dwarf label attribute data and value. /// void DwarfDebug::addLabel(DIE *Die, unsigned Attribute, unsigned Form, - const DWLabel &Label) { - DIEValue *Value = new DIEDwarfLabel(Label); - DIEValues.push_back(Value); - Die->addValue(Attribute, Form, Value); -} - -/// addObjectLabel - Add an non-Dwarf label attribute data and value. -/// -void DwarfDebug::addObjectLabel(DIE *Die, unsigned Attribute, unsigned Form, - const MCSymbol *Sym) { - DIEValue *Value = new DIEObjectLabel(Sym); + const MCSymbol *Label) { + DIEValue *Value = new DIELabel(Label); DIEValues.push_back(Value); Die->addValue(Attribute, Form, Value); } @@ -384,9 +377,9 @@ void DwarfDebug::addObjectLabel(DIE *Die, unsigned Attribute, unsigned Form, /// addSectionOffset - Add a section offset label attribute data and value. /// void DwarfDebug::addSectionOffset(DIE *Die, unsigned Attribute, unsigned Form, - const DWLabel &Label, const DWLabel &Section, - bool isEH, bool useSet) { - DIEValue *Value = new DIESectionOffset(Label, Section, isEH, useSet); + const MCSymbol *Label,const MCSymbol *Section, + bool isEH) { + DIEValue *Value = new DIESectionOffset(Label, Section, isEH); DIEValues.push_back(Value); Die->addValue(Attribute, Form, Value); } @@ -394,7 +387,7 @@ void DwarfDebug::addSectionOffset(DIE *Die, unsigned Attribute, unsigned Form, /// addDelta - Add a label delta attribute data and value. /// void DwarfDebug::addDelta(DIE *Die, unsigned Attribute, unsigned Form, - const DWLabel &Hi, const DWLabel &Lo) { + const MCSymbol *Hi, const MCSymbol *Lo) { DIEValue *Value = new DIEDelta(Hi, Lo); DIEValues.push_back(Value); Die->addValue(Attribute, Form, Value); @@ -413,11 +406,12 @@ void DwarfDebug::addBlock(DIE *Die, unsigned Attribute, unsigned Form, /// entry. void DwarfDebug::addSourceLine(DIE *Die, const DIVariable *V) { // If there is no compile unit specified, don't add a line #. - if (V->getCompileUnit().isNull()) + if (!V->getCompileUnit().Verify()) return; unsigned Line = V->getLineNumber(); - unsigned FileID = findCompileUnit(V->getCompileUnit())->getID(); + unsigned FileID = GetOrCreateSourceID(V->getContext().getDirectory(), + V->getContext().getFilename()); assert(FileID && "Invalid file id"); addUInt(Die, dwarf::DW_AT_decl_file, 0, FileID); addUInt(Die, dwarf::DW_AT_decl_line, 0, Line); @@ -427,11 +421,12 @@ void DwarfDebug::addSourceLine(DIE *Die, const DIVariable *V) { /// entry. void DwarfDebug::addSourceLine(DIE *Die, const DIGlobal *G) { // If there is no compile unit specified, don't add a line #. - if (G->getCompileUnit().isNull()) + if (!G->getCompileUnit().Verify()) return; unsigned Line = G->getLineNumber(); - unsigned FileID = findCompileUnit(G->getCompileUnit())->getID(); + unsigned FileID = GetOrCreateSourceID(G->getContext().getDirectory(), + G->getContext().getFilename()); assert(FileID && "Invalid file id"); addUInt(Die, dwarf::DW_AT_decl_file, 0, FileID); addUInt(Die, dwarf::DW_AT_decl_line, 0, Line); @@ -441,15 +436,17 @@ void DwarfDebug::addSourceLine(DIE *Die, const DIGlobal *G) { /// entry. void DwarfDebug::addSourceLine(DIE *Die, const DISubprogram *SP) { // If there is no compile unit specified, don't add a line #. - if (SP->getCompileUnit().isNull()) + if (!SP->getCompileUnit().Verify()) return; // If the line number is 0, don't add it. if (SP->getLineNumber() == 0) return; - unsigned Line = SP->getLineNumber(); - unsigned FileID = findCompileUnit(SP->getCompileUnit())->getID(); + if (!SP->getContext().Verify()) + return; + unsigned FileID = GetOrCreateSourceID(SP->getContext().getDirectory(), + SP->getContext().getFilename()); assert(FileID && "Invalid file id"); addUInt(Die, dwarf::DW_AT_decl_file, 0, FileID); addUInt(Die, dwarf::DW_AT_decl_line, 0, Line); @@ -460,11 +457,14 @@ void DwarfDebug::addSourceLine(DIE *Die, const DISubprogram *SP) { void DwarfDebug::addSourceLine(DIE *Die, const DIType *Ty) { // If there is no compile unit specified, don't add a line #. DICompileUnit CU = Ty->getCompileUnit(); - if (CU.isNull()) + if (!CU.Verify()) return; unsigned Line = Ty->getLineNumber(); - unsigned FileID = findCompileUnit(CU)->getID(); + if (!Ty->getContext().Verify()) + return; + unsigned FileID = GetOrCreateSourceID(Ty->getContext().getDirectory(), + Ty->getContext().getFilename()); assert(FileID && "Invalid file id"); addUInt(Die, dwarf::DW_AT_decl_file, 0, FileID); addUInt(Die, dwarf::DW_AT_decl_line, 0, Line); @@ -474,7 +474,7 @@ void DwarfDebug::addSourceLine(DIE *Die, const DIType *Ty) { /// entry. void DwarfDebug::addSourceLine(DIE *Die, const DINameSpace *NS) { // If there is no compile unit specified, don't add a line #. - if (NS->getCompileUnit().isNull()) + if (!NS->getCompileUnit().Verify()) return; unsigned Line = NS->getLineNumber(); @@ -526,12 +526,8 @@ DIType DwarfDebug::getBlockByrefType(DIType Ty, std::string Name) { } DICompositeType blockStruct = DICompositeType(subType.getNode()); - DIArray Elements = blockStruct.getTypeArray(); - if (Elements.isNull()) - return Ty; - for (unsigned i = 0, N = Elements.getNumElements(); i < N; ++i) { DIDescriptor Element = Elements.getElement(i); DIDerivedType DT = DIDerivedType(Element.getNode()); @@ -677,7 +673,6 @@ void DwarfDebug::addBlockByrefAddress(DbgVariable *&DV, DIE *Die, DIDescriptor varField = DIDescriptor(); DIDescriptor forwardingField = DIDescriptor(); - for (unsigned i = 0, N = Fields.getNumElements(); i < N; ++i) { DIDescriptor Element = Fields.getElement(i); DIDerivedType DT = DIDerivedType(Element.getNode()); @@ -688,10 +683,6 @@ void DwarfDebug::addBlockByrefAddress(DbgVariable *&DV, DIE *Die, varField = Element; } - assert(!varField.isNull() && "Can't find byref variable in Block struct"); - assert(!forwardingField.isNull() - && "Can't find forwarding field in Block struct"); - // Get the offsets for the forwarding field and the variable field. unsigned int forwardingFieldOffset = DIDerivedType(forwardingField.getNode()).getOffsetInBits() >> 3; @@ -781,9 +772,7 @@ void DwarfDebug::addAddress(DIE *Die, unsigned Attribute, /// addToContextOwner - Add Die into the list of its context owner's children. void DwarfDebug::addToContextOwner(DIE *Die, DIDescriptor Context) { - if (Context.isNull()) - ModuleCU->addDie(Die); - else if (Context.isType()) { + if (Context.isType()) { DIE *ContextDIE = getOrCreateTypeDIE(DIType(Context.getNode())); ContextDIE->addChild(Die); } else if (Context.isNameSpace()) { @@ -820,7 +809,7 @@ DIE *DwarfDebug::getOrCreateTypeDIE(DIType Ty) { /// addType - Add a new type attribute to the specified entity. void DwarfDebug::addType(DIE *Entity, DIType Ty) { - if (Ty.isNull()) + if (!Ty.isValid()) return; // Check for pre-existence. @@ -906,9 +895,9 @@ void DwarfDebug::constructTypeDIE(DIE &Buffer, DICompositeType CTy) { // Add enumerators to enumeration type. for (unsigned i = 0, N = Elements.getNumElements(); i < N; ++i) { DIE *ElemDie = NULL; - DIEnumerator Enum(Elements.getElement(i).getNode()); - if (!Enum.isNull()) { - ElemDie = constructEnumTypeDIE(&Enum); + DIDescriptor Enum(Elements.getElement(i).getNode()); + if (Enum.isEnumerator()) { + ElemDie = constructEnumTypeDIE(DIEnumerator(Enum.getNode())); Buffer.addChild(ElemDie); } } @@ -939,18 +928,17 @@ void DwarfDebug::constructTypeDIE(DIE &Buffer, DICompositeType CTy) { DIArray Elements = CTy.getTypeArray(); // A forward struct declared type may not have elements available. - if (Elements.isNull()) + unsigned N = Elements.getNumElements(); + if (N == 0) break; // Add elements to structure type. - for (unsigned i = 0, N = Elements.getNumElements(); i < N; ++i) { + for (unsigned i = 0; i < N; ++i) { DIDescriptor Element = Elements.getElement(i); - if (Element.isNull()) - continue; DIE *ElemDie = NULL; - if (Element.getTag() == dwarf::DW_TAG_subprogram) + if (Element.isSubprogram()) ElemDie = createSubprogramDIE(DISubprogram(Element.getNode())); - else if (Element.getTag() == dwarf::DW_TAG_auto_variable) { + else if (Element.isVariable()) { DIVariable DV(Element.getNode()); ElemDie = new DIE(dwarf::DW_TAG_variable); addString(ElemDie, dwarf::DW_AT_name, dwarf::DW_FORM_string, @@ -959,8 +947,10 @@ void DwarfDebug::constructTypeDIE(DIE &Buffer, DICompositeType CTy) { addUInt(ElemDie, dwarf::DW_AT_declaration, dwarf::DW_FORM_flag, 1); addUInt(ElemDie, dwarf::DW_AT_external, dwarf::DW_FORM_flag, 1); addSourceLine(ElemDie, &DV); - } else + } else if (Element.isDerivedType()) ElemDie = createMemberDIE(DIDerivedType(Element.getNode())); + else + continue; Buffer.addChild(ElemDie); } @@ -973,7 +963,7 @@ void DwarfDebug::constructTypeDIE(DIE &Buffer, DICompositeType CTy) { dwarf::DW_FORM_data1, RLang); DICompositeType ContainingType = CTy.getContainingType(); - if (!ContainingType.isNull()) + if (DIDescriptor(ContainingType.getNode()).isCompositeType()) addDIEEntry(&Buffer, dwarf::DW_AT_containing_type, dwarf::DW_FORM_ref4, getOrCreateTypeDIE(DIType(ContainingType.getNode()))); break; @@ -1051,11 +1041,11 @@ void DwarfDebug::constructArrayTypeDIE(DIE &Buffer, } /// constructEnumTypeDIE - Construct enum type DIE from DIEnumerator. -DIE *DwarfDebug::constructEnumTypeDIE(DIEnumerator *ETy) { +DIE *DwarfDebug::constructEnumTypeDIE(DIEnumerator ETy) { DIE *Enumerator = new DIE(dwarf::DW_TAG_enumerator); - StringRef Name = ETy->getName(); + StringRef Name = ETy.getName(); addString(Enumerator, dwarf::DW_AT_name, dwarf::DW_FORM_string, Name); - int64_t Value = ETy->getEnumValue(); + int64_t Value = ETy.getEnumValue(); addSInt(Enumerator, dwarf::DW_AT_const_value, dwarf::DW_FORM_sdata, Value); return Enumerator; } @@ -1199,7 +1189,7 @@ DIE *DwarfDebug::createSubprogramDIE(const DISubprogram &SP, bool MakeDecl) { DIArray Args = SPTy.getTypeArray(); unsigned SPTag = SPTy.getTag(); - if (Args.isNull() || SPTag != dwarf::DW_TAG_subroutine_type) + if (Args.getNumElements() == 0 || SPTag != dwarf::DW_TAG_subroutine_type) addType(SPDie, SPTy); else addType(SPDie, DIType(Args.getElement(0).getNode())); @@ -1243,16 +1233,6 @@ DIE *DwarfDebug::createSubprogramDIE(const DISubprogram &SP, bool MakeDecl) { return SPDie; } -/// findCompileUnit - Get the compile unit for the given descriptor. -/// -CompileUnit *DwarfDebug::findCompileUnit(DICompileUnit Unit) { - DenseMap<Value *, CompileUnit *>::const_iterator I = - CompileUnitMap.find(Unit.getNode()); - if (I == CompileUnitMap.end()) - return constructCompileUnit(Unit.getNode()); - return I->second; -} - /// getUpdatedDbgScope - Find or create DbgScope assicated with the instruction. /// Initialize scope and update scope hierarchy. DbgScope *DwarfDebug::getUpdatedDbgScope(MDNode *N, const MachineInstr *MI, @@ -1282,11 +1262,9 @@ DbgScope *DwarfDebug::getUpdatedDbgScope(MDNode *N, const MachineInstr *MI, Parent->addScope(NScope); } else if (DIDescriptor(N).isLexicalBlock()) { DILexicalBlock DB(N); - if (!DB.getContext().isNull()) { - Parent = getUpdatedDbgScope(DB.getContext().getNode(), MI, InlinedAt); - NScope->setParent(Parent); - Parent->addScope(NScope); - } + Parent = getUpdatedDbgScope(DB.getContext().getNode(), MI, InlinedAt); + NScope->setParent(Parent); + Parent->addScope(NScope); } NScope->setFirstInsn(MI); @@ -1318,8 +1296,7 @@ DbgScope *DwarfDebug::getOrCreateAbstractScope(MDNode *N) { if (Scope.isLexicalBlock()) { DILexicalBlock DB(N); DIDescriptor ParentDesc = DB.getContext(); - if (!ParentDesc.isNull()) - Parent = getOrCreateAbstractScope(ParentDesc.getNode()); + Parent = getOrCreateAbstractScope(ParentDesc.getNode()); } AScope = new DbgScope(Parent, DIDescriptor(N), NULL); @@ -1371,9 +1348,9 @@ DIE *DwarfDebug::updateSubprogramScopeDIE(MDNode *SPNode) { } addLabel(SPDie, dwarf::DW_AT_low_pc, dwarf::DW_FORM_addr, - DWLabel("func_begin", SubprogramCount)); + getDWLabel("func_begin", SubprogramCount)); addLabel(SPDie, dwarf::DW_AT_high_pc, dwarf::DW_FORM_addr, - DWLabel("func_end", SubprogramCount)); + getDWLabel("func_end", SubprogramCount)); MachineLocation Location(RI->getFrameRegister(*MF)); addAddress(SPDie, dwarf::DW_AT_frame_base, Location); @@ -1386,27 +1363,21 @@ DIE *DwarfDebug::updateSubprogramScopeDIE(MDNode *SPNode) { /// constructLexicalScope - Construct new DW_TAG_lexical_block /// for this scope and attach DW_AT_low_pc/DW_AT_high_pc labels. DIE *DwarfDebug::constructLexicalScopeDIE(DbgScope *Scope) { - unsigned StartID = MMI->MappedLabel(Scope->getStartLabelID()); - unsigned EndID = MMI->MappedLabel(Scope->getEndLabelID()); - - // Ignore empty scopes. - if (StartID == EndID && StartID != 0) - return NULL; + MCSymbol *Start = Scope->getStartLabel(); + MCSymbol *End = Scope->getEndLabel(); + if (Start == 0) return 0; + assert(Start->isDefined() && "Invalid starting label for an inlined scope!"); + assert(End->isDefined() && "Invalid end label for an inlined scope!"); + DIE *ScopeDIE = new DIE(dwarf::DW_TAG_lexical_block); if (Scope->isAbstractScope()) return ScopeDIE; addLabel(ScopeDIE, dwarf::DW_AT_low_pc, dwarf::DW_FORM_addr, - StartID ? - DWLabel("label", StartID) - : DWLabel("func_begin", SubprogramCount)); + Start ? Start : getDWLabel("func_begin", SubprogramCount)); addLabel(ScopeDIE, dwarf::DW_AT_high_pc, dwarf::DW_FORM_addr, - EndID ? - DWLabel("label", EndID) - : DWLabel("func_end", SubprogramCount)); - - + End ? End : getDWLabel("func_end", SubprogramCount)); return ScopeDIE; } @@ -1415,17 +1386,17 @@ DIE *DwarfDebug::constructLexicalScopeDIE(DbgScope *Scope) { /// a function. Construct DIE to represent this concrete inlined copy /// of the function. DIE *DwarfDebug::constructInlinedScopeDIE(DbgScope *Scope) { - unsigned StartID = MMI->MappedLabel(Scope->getStartLabelID()); - unsigned EndID = MMI->MappedLabel(Scope->getEndLabelID()); - assert (StartID && "Invalid starting label for an inlined scope!"); - assert (EndID && "Invalid end label for an inlined scope!"); - // Ignore empty scopes. - if (StartID == EndID && StartID != 0) + MCSymbol *StartLabel = Scope->getStartLabel(); + MCSymbol *EndLabel = Scope->getEndLabel(); + if (StartLabel == 0) return 0; + + assert(StartLabel->isDefined() && + "Invalid starting label for an inlined scope!"); + assert(EndLabel->isDefined() && + "Invalid end label for an inlined scope!"); + if (!Scope->getScopeNode()) return NULL; - DIScope DS(Scope->getScopeNode()); - if (DS.isNull()) - return NULL; DIE *ScopeDIE = new DIE(dwarf::DW_TAG_inlined_subroutine); DISubprogram InlinedSP = getDISubprogram(DS.getNode()); @@ -1434,10 +1405,8 @@ DIE *DwarfDebug::constructInlinedScopeDIE(DbgScope *Scope) { addDIEEntry(ScopeDIE, dwarf::DW_AT_abstract_origin, dwarf::DW_FORM_ref4, OriginDIE); - addLabel(ScopeDIE, dwarf::DW_AT_low_pc, dwarf::DW_FORM_addr, - DWLabel("label", StartID)); - addLabel(ScopeDIE, dwarf::DW_AT_high_pc, dwarf::DW_FORM_addr, - DWLabel("label", EndID)); + addLabel(ScopeDIE, dwarf::DW_AT_low_pc, dwarf::DW_FORM_addr, StartLabel); + addLabel(ScopeDIE, dwarf::DW_AT_high_pc, dwarf::DW_FORM_addr, EndLabel); InlinedSubprogramDIEs.insert(OriginDIE); @@ -1446,11 +1415,11 @@ DIE *DwarfDebug::constructInlinedScopeDIE(DbgScope *Scope) { I = InlineInfo.find(InlinedSP.getNode()); if (I == InlineInfo.end()) { - InlineInfo[InlinedSP.getNode()].push_back(std::make_pair(StartID, + InlineInfo[InlinedSP.getNode()].push_back(std::make_pair(StartLabel, ScopeDIE)); InlinedSPNodes.push_back(InlinedSP.getNode()); } else - I->second.push_back(std::make_pair(StartID, ScopeDIE)); + I->second.push_back(std::make_pair(StartLabel, ScopeDIE)); StringPool.insert(InlinedSP.getName()); StringPool.insert(getRealLinkageName(InlinedSP.getLinkageName())); @@ -1547,15 +1516,12 @@ void DwarfDebug::addPubTypes(DISubprogram SP) { return; DIArray Args = SPTy.getTypeArray(); - if (Args.isNull()) - return; - for (unsigned i = 0, e = Args.getNumElements(); i != e; ++i) { DIType ATy(Args.getElement(i).getNode()); - if (ATy.isNull()) + if (!ATy.isValid()) continue; DICompositeType CATy = getDICompositeType(ATy); - if (!CATy.isNull() && !CATy.getName().empty()) { + if (DIDescriptor(CATy.getNode()).Verify() && !CATy.getName().empty()) { if (DIEEntry *Entry = ModuleCU->getDIEEntry(CATy.getNode())) ModuleCU->addGlobalType(CATy.getName(), Entry->getEntry()); } @@ -1564,26 +1530,24 @@ void DwarfDebug::addPubTypes(DISubprogram SP) { /// constructScopeDIE - Construct a DIE for this scope. DIE *DwarfDebug::constructScopeDIE(DbgScope *Scope) { - if (!Scope) - return NULL; - DIScope DS(Scope->getScopeNode()); - if (DS.isNull()) - return NULL; - - DIE *ScopeDIE = NULL; - if (Scope->getInlinedAt()) - ScopeDIE = constructInlinedScopeDIE(Scope); - else if (DS.isSubprogram()) { - if (Scope->isAbstractScope()) - ScopeDIE = ModuleCU->getDIE(DS.getNode()); - else - ScopeDIE = updateSubprogramScopeDIE(DS.getNode()); - } - else { - ScopeDIE = constructLexicalScopeDIE(Scope); - if (!ScopeDIE) return NULL; - } - + if (!Scope || !Scope->getScopeNode()) + return NULL; + + DIScope DS(Scope->getScopeNode()); + DIE *ScopeDIE = NULL; + if (Scope->getInlinedAt()) + ScopeDIE = constructInlinedScopeDIE(Scope); + else if (DS.isSubprogram()) { + if (Scope->isAbstractScope()) + ScopeDIE = ModuleCU->getDIE(DS.getNode()); + else + ScopeDIE = updateSubprogramScopeDIE(DS.getNode()); + } + else { + ScopeDIE = constructLexicalScopeDIE(Scope); + if (!ScopeDIE) return NULL; + } + // Add variables to scope. SmallVector<DbgVariable *, 8> &Variables = Scope->getVariables(); for (unsigned i = 0, N = Variables.size(); i < N; ++i) { @@ -1665,8 +1629,9 @@ CompileUnit *DwarfDebug::constructCompileUnit(MDNode *N) { unsigned ID = GetOrCreateSourceID(Dir, FN); DIE *Die = new DIE(dwarf::DW_TAG_compile_unit); + // FIXME: Why getting the delta between two identical labels?? addSectionOffset(Die, dwarf::DW_AT_stmt_list, dwarf::DW_FORM_data4, - DWLabel("section_line", 0), DWLabel("section_line", 0), + getTempLabel("section_line"), getTempLabel("section_line"), false); addString(Die, dwarf::DW_AT_producer, dwarf::DW_FORM_string, DIUnit.getProducer()); @@ -1695,8 +1660,6 @@ CompileUnit *DwarfDebug::constructCompileUnit(MDNode *N) { ModuleCU = Unit; } - CompileUnitMap[DIUnit.getNode()] = Unit; - CompileUnits.push_back(Unit); return Unit; } @@ -1730,16 +1693,16 @@ void DwarfDebug::constructGlobalVariableDIE(MDNode *N) { dwarf::DW_FORM_ref4, VariableDie); DIEBlock *Block = new DIEBlock(); addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_addr); - addObjectLabel(Block, 0, dwarf::DW_FORM_udata, - Asm->GetGlobalValueSymbol(DI_GV.getGlobal())); + addLabel(Block, 0, dwarf::DW_FORM_udata, + Asm->GetGlobalValueSymbol(DI_GV.getGlobal())); addBlock(VariableSpecDIE, dwarf::DW_AT_location, 0, Block); addUInt(VariableDie, dwarf::DW_AT_declaration, dwarf::DW_FORM_flag, 1); ModuleCU->addDie(VariableSpecDIE); } else { DIEBlock *Block = new DIEBlock(); addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_addr); - addObjectLabel(Block, 0, dwarf::DW_FORM_udata, - Asm->GetGlobalValueSymbol(DI_GV.getGlobal())); + addLabel(Block, 0, dwarf::DW_FORM_udata, + Asm->GetGlobalValueSymbol(DI_GV.getGlobal())); addBlock(VariableDie, dwarf::DW_AT_location, 0, Block); } addToContextOwner(VariableDie, GVContext); @@ -1802,17 +1765,8 @@ void DwarfDebug::beginModule(Module *M, MachineModuleInfo *mmi) { E = DbgFinder.compile_unit_end(); I != E; ++I) constructCompileUnit(*I); - if (CompileUnits.empty()) { - if (TimePassesIsEnabled) - DebugTimer->stopTimer(); - - return; - } - - // If main compile unit for this module is not seen than randomly - // select first compile unit. if (!ModuleCU) - ModuleCU = CompileUnits[0]; + return; // Create DIEs for each subprogram. for (DebugInfoFinder::iterator I = DbgFinder.subprogram_begin(), @@ -1890,14 +1844,14 @@ void DwarfDebug::endModule() { // Standard sections final addresses. Asm->OutStreamer.SwitchSection(Asm->getObjFileLowering().getTextSection()); - EmitLabel("text_end", 0); + Asm->OutStreamer.EmitLabel(getTempLabel("text_end")); Asm->OutStreamer.SwitchSection(Asm->getObjFileLowering().getDataSection()); - EmitLabel("data_end", 0); + Asm->OutStreamer.EmitLabel(getTempLabel("data_end")); // End text sections. for (unsigned i = 1, N = SectionMap.size(); i <= N; ++i) { Asm->OutStreamer.SwitchSection(SectionMap[i]); - EmitLabel("section_end", i); + Asm->OutStreamer.EmitLabel(getDWLabel("section_end", i)); } // Emit common frame information. @@ -1997,14 +1951,14 @@ void DwarfDebug::collectVariableInfo() { } /// beginScope - Process beginning of a scope starting at Label. -void DwarfDebug::beginScope(const MachineInstr *MI, unsigned Label) { +void DwarfDebug::beginScope(const MachineInstr *MI, MCSymbol *Label) { InsnToDbgScopeMapTy::iterator I = DbgScopeBeginMap.find(MI); if (I == DbgScopeBeginMap.end()) return; ScopeVector &SD = I->second; for (ScopeVector::iterator SDI = SD.begin(), SDE = SD.end(); SDI != SDE; ++SDI) - (*SDI)->setStartLabelID(Label); + (*SDI)->setStartLabel(Label); } /// endScope - Process end of a scope. @@ -2013,14 +1967,13 @@ void DwarfDebug::endScope(const MachineInstr *MI) { if (I == DbgScopeEndMap.end()) return; - unsigned Label = MMI->NextLabelID(); - Asm->printLabel(Label); - O << '\n'; + MCSymbol *Label = getDWLabel("label", MMI->NextLabelID()); + Asm->OutStreamer.EmitLabel(Label); - SmallVector<DbgScope *, 2> &SD = I->second; + SmallVector<DbgScope*, 2> &SD = I->second; for (SmallVector<DbgScope *, 2>::iterator SDI = SD.begin(), SDE = SD.end(); SDI != SDE; ++SDI) - (*SDI)->setEndLabelID(Label); + (*SDI)->setEndLabel(Label); return; } @@ -2069,7 +2022,6 @@ bool DwarfDebug::extractScopeInformation() { if (DL.isUnknown()) continue; DILocation DLT = MF->getDILocation(DL); DIScope DLTScope = DLT.getScope(); - if (DLTScope.isNull()) continue; // There is no need to create another DIE for compile unit. For all // other scopes, create one DbgScope now. This will be translated // into a scope DIE at the end. @@ -2089,7 +2041,6 @@ bool DwarfDebug::extractScopeInformation() { if (DL.isUnknown()) continue; DILocation DLT = MF->getDILocation(DL); DIScope DLTScope = DLT.getScope(); - if (DLTScope.isNull()) continue; // There is no need to create another DIE for compile unit. For all // other scopes, create one DbgScope now. This will be translated // into a scope DIE at the end. @@ -2159,24 +2110,24 @@ void DwarfDebug::beginFunction(const MachineFunction *MF) { collectVariableInfo(); // Assumes in correct section after the entry point. - EmitLabel("func_begin", ++SubprogramCount); + Asm->OutStreamer.EmitLabel(getDWLabel("func_begin", ++SubprogramCount)); // Emit label for the implicitly defined dbg.stoppoint at the start of the // function. DebugLoc FDL = MF->getDefaultDebugLoc(); if (!FDL.isUnknown()) { DILocation DLT = MF->getDILocation(FDL); - unsigned LabelID = 0; DISubprogram SP = getDISubprogram(DLT.getScope().getNode()); - if (!SP.isNull()) - LabelID = recordSourceLine(SP.getLineNumber(), 0, - DLT.getScope().getNode()); - else - LabelID = recordSourceLine(DLT.getLineNumber(), - DLT.getColumnNumber(), - DLT.getScope().getNode()); - Asm->printLabel(LabelID); - O << '\n'; + unsigned Line, Col; + if (SP.Verify()) { + Line = SP.getLineNumber(); + Col = 0; + } else { + Line = DLT.getLineNumber(); + Col = DLT.getColumnNumber(); + } + + recordSourceLine(Line, Col, DLT.getScope().getNode()); } if (TimePassesIsEnabled) DebugTimer->stopTimer(); @@ -2195,7 +2146,7 @@ void DwarfDebug::endFunction(const MachineFunction *MF) { if (CurrentFnDbgScope) { // Define end label for subprogram. - EmitLabel("func_end", SubprogramCount); + Asm->OutStreamer.EmitLabel(getDWLabel("func_end", SubprogramCount)); // Get function line info. if (!Lines.empty()) { @@ -2232,11 +2183,10 @@ void DwarfDebug::endFunction(const MachineFunction *MF) { DebugTimer->stopTimer(); } -/// recordSourceLine - Records location information and associates it with a -/// label. Returns a unique label ID used to generate a label and provide -/// correspondence to the source line list. -unsigned DwarfDebug::recordSourceLine(unsigned Line, unsigned Col, - MDNode *S) { +/// recordSourceLine - Register a source line with debug info. Returns the +/// unique label that was emitted and which provides correspondence to +/// the source line list. +MCSymbol *DwarfDebug::recordSourceLine(unsigned Line, unsigned Col, MDNode *S) { if (!MMI) return 0; @@ -2269,7 +2219,9 @@ unsigned DwarfDebug::recordSourceLine(unsigned Line, unsigned Col, if (TimePassesIsEnabled) DebugTimer->stopTimer(); - return ID; + MCSymbol *Label = getDWLabel("label", ID); + Asm->OutStreamer.EmitLabel(Label); + return Label; } /// getOrCreateSourceID - Public version of GetOrCreateSourceID. This can be @@ -2367,38 +2319,38 @@ void DwarfDebug::emitInitial() { // Dwarf sections base addresses. if (MAI->doesDwarfRequireFrameSection()) { Asm->OutStreamer.SwitchSection(TLOF.getDwarfFrameSection()); - EmitLabel("section_debug_frame", 0); + Asm->OutStreamer.EmitLabel(getTempLabel("section_debug_frame")); } Asm->OutStreamer.SwitchSection(TLOF.getDwarfInfoSection()); - EmitLabel("section_info", 0); + Asm->OutStreamer.EmitLabel(getTempLabel("section_info")); Asm->OutStreamer.SwitchSection(TLOF.getDwarfAbbrevSection()); - EmitLabel("section_abbrev", 0); + Asm->OutStreamer.EmitLabel(getTempLabel("section_abbrev")); Asm->OutStreamer.SwitchSection(TLOF.getDwarfARangesSection()); - EmitLabel("section_aranges", 0); + Asm->OutStreamer.EmitLabel(getTempLabel("section_aranges")); if (const MCSection *LineInfoDirective = TLOF.getDwarfMacroInfoSection()) { Asm->OutStreamer.SwitchSection(LineInfoDirective); - EmitLabel("section_macinfo", 0); + Asm->OutStreamer.EmitLabel(getTempLabel("section_macinfo")); } Asm->OutStreamer.SwitchSection(TLOF.getDwarfLineSection()); - EmitLabel("section_line", 0); + Asm->OutStreamer.EmitLabel(getTempLabel("section_line")); Asm->OutStreamer.SwitchSection(TLOF.getDwarfLocSection()); - EmitLabel("section_loc", 0); + Asm->OutStreamer.EmitLabel(getTempLabel("section_loc")); Asm->OutStreamer.SwitchSection(TLOF.getDwarfPubNamesSection()); - EmitLabel("section_pubnames", 0); + Asm->OutStreamer.EmitLabel(getTempLabel("section_pubnames")); Asm->OutStreamer.SwitchSection(TLOF.getDwarfPubTypesSection()); - EmitLabel("section_pubtypes", 0); + Asm->OutStreamer.EmitLabel(getTempLabel("section_pubtypes")); Asm->OutStreamer.SwitchSection(TLOF.getDwarfStrSection()); - EmitLabel("section_str", 0); + Asm->OutStreamer.EmitLabel(getTempLabel("section_str")); Asm->OutStreamer.SwitchSection(TLOF.getDwarfRangesSection()); - EmitLabel("section_ranges", 0); + Asm->OutStreamer.EmitLabel(getTempLabel("section_ranges")); Asm->OutStreamer.SwitchSection(TLOF.getTextSection()); - EmitLabel("text_begin", 0); + Asm->OutStreamer.EmitLabel(getTempLabel("text_begin")); Asm->OutStreamer.SwitchSection(TLOF.getDataSection()); - EmitLabel("data_begin", 0); + Asm->OutStreamer.EmitLabel(getTempLabel("data_begin")); } /// emitDIE - Recusively Emits a debug information entry. @@ -2408,8 +2360,6 @@ void DwarfDebug::emitDIE(DIE *Die) { unsigned AbbrevNumber = Die->getAbbrevNumber(); const DIEAbbrev *Abbrev = Abbreviations[AbbrevNumber - 1]; - Asm->O << '\n'; - // Emit the code (index) for the abbreviation. if (Asm->VerboseAsm) Asm->OutStreamer.AddComment("Abbrev [" + Twine(AbbrevNumber) + "] 0x" + @@ -2444,7 +2394,6 @@ void DwarfDebug::emitDIE(DIE *Die) { default: // Emit an attribute using the defined form. Values[i]->EmitValue(this, Form); - O << "\n"; // REMOVE This once all EmitValue impls emit their own newline. break; } } @@ -2456,7 +2405,9 @@ void DwarfDebug::emitDIE(DIE *Die) { for (unsigned j = 0, M = Children.size(); j < M; ++j) emitDIE(Children[j]); - Asm->EmitInt8(0); EOL("End Of Children Mark"); + if (Asm->VerboseAsm) + Asm->OutStreamer.AddComment("End Of Children Mark"); + Asm->EmitInt8(0); } } @@ -2469,7 +2420,7 @@ void DwarfDebug::emitDebugInfo() { DIE *Die = ModuleCU->getCUDie(); // Emit the compile units header. - EmitLabel("info_begin", ModuleCU->getID()); + Asm->OutStreamer.EmitLabel(getDWLabel("info_begin", ModuleCU->getID())); // Emit size of content not including length itself unsigned ContentSize = Die->getSize() + @@ -2478,20 +2429,24 @@ void DwarfDebug::emitDebugInfo() { sizeof(int8_t) + // Pointer Size (in bytes) sizeof(int32_t); // FIXME - extra pad for gdb bug. - Asm->EmitInt32(ContentSize); EOL("Length of Compilation Unit Info"); - Asm->EmitInt16(dwarf::DWARF_VERSION); EOL("DWARF version number"); - EmitSectionOffset("abbrev_begin", "section_abbrev", 0, 0, true, false); - EOL("Offset Into Abbrev. Section"); - Asm->EmitInt8(TD->getPointerSize()); EOL("Address Size (in bytes)"); + Asm->OutStreamer.AddComment("Length of Compilation Unit Info"); + Asm->EmitInt32(ContentSize); + Asm->OutStreamer.AddComment("DWARF version number"); + Asm->EmitInt16(dwarf::DWARF_VERSION); + Asm->OutStreamer.AddComment("Offset Into Abbrev. Section"); + EmitSectionOffset(getTempLabel("abbrev_begin"),getTempLabel("section_abbrev"), + true, false); + Asm->OutStreamer.AddComment("Address Size (in bytes)"); + Asm->EmitInt8(TD->getPointerSize()); emitDIE(Die); // FIXME - extra padding for gdb bug. - Asm->EmitInt8(0); EOL("Extra Pad For GDB"); - Asm->EmitInt8(0); EOL("Extra Pad For GDB"); - Asm->EmitInt8(0); EOL("Extra Pad For GDB"); - Asm->EmitInt8(0); EOL("Extra Pad For GDB"); - EmitLabel("info_end", ModuleCU->getID()); - Asm->O << '\n'; + Asm->OutStreamer.AddComment("4 extra padding bytes for GDB"); + Asm->EmitInt8(0); + Asm->EmitInt8(0); + Asm->EmitInt8(0); + Asm->EmitInt8(0); + Asm->OutStreamer.EmitLabel(getDWLabel("info_end", ModuleCU->getID())); } /// emitAbbreviations - Emit the abbreviation section. @@ -2503,7 +2458,7 @@ void DwarfDebug::emitAbbreviations() const { Asm->OutStreamer.SwitchSection( Asm->getObjFileLowering().getDwarfAbbrevSection()); - EmitLabel("abbrev_begin", 0); + Asm->OutStreamer.EmitLabel(getTempLabel("abbrev_begin")); // For each abbrevation. for (unsigned i = 0, N = Abbreviations.size(); i < N; ++i) { @@ -2515,14 +2470,12 @@ void DwarfDebug::emitAbbreviations() const { // Emit the abbreviations data. Abbrev->Emit(this); - Asm->O << '\n'; } // Mark end of abbreviations. EmitULEB128(0, "EOM(3)"); - EmitLabel("abbrev_end", 0); - Asm->O << '\n'; + Asm->OutStreamer.EmitLabel(getTempLabel("abbrev_end")); } } @@ -2531,13 +2484,22 @@ void DwarfDebug::emitAbbreviations() const { /// void DwarfDebug::emitEndOfLineMatrix(unsigned SectionEnd) { // Define last address of section. - Asm->EmitInt8(0); EOL("Extended Op"); - Asm->EmitInt8(TD->getPointerSize() + 1); EOL("Op size"); - Asm->EmitInt8(dwarf::DW_LNE_set_address); EOL("DW_LNE_set_address"); - EmitReference("section_end", SectionEnd); EOL("Section end label"); + Asm->OutStreamer.AddComment("Extended Op"); + Asm->EmitInt8(0); + + Asm->OutStreamer.AddComment("Op size"); + Asm->EmitInt8(TD->getPointerSize() + 1); + Asm->OutStreamer.AddComment("DW_LNE_set_address"); + Asm->EmitInt8(dwarf::DW_LNE_set_address); + + Asm->OutStreamer.AddComment("Section end label"); + + Asm->OutStreamer.EmitSymbolValue(getDWLabel("section_end", SectionEnd), + TD->getPointerSize(), 0/*AddrSpace*/); // Mark end of matrix. - Asm->EmitInt8(0); EOL("DW_LNE_end_sequence"); + Asm->OutStreamer.AddComment("DW_LNE_end_sequence"); + Asm->EmitInt8(0); Asm->EmitInt8(1); Asm->EmitInt8(1); } @@ -2560,32 +2522,48 @@ void DwarfDebug::emitDebugLines() { Asm->getObjFileLowering().getDwarfLineSection()); // Construct the section header. - EmitDifference("line_end", 0, "line_begin", 0, true); - EOL("Length of Source Line Info"); - EmitLabel("line_begin", 0); + Asm->OutStreamer.AddComment("Length of Source Line Info"); + EmitDifference(getTempLabel("line_end"), getTempLabel("line_begin"), true); + Asm->OutStreamer.EmitLabel(getTempLabel("line_begin")); - Asm->EmitInt16(dwarf::DWARF_VERSION); EOL("DWARF version number"); + Asm->OutStreamer.AddComment("DWARF version number"); + Asm->EmitInt16(dwarf::DWARF_VERSION); - EmitDifference("line_prolog_end", 0, "line_prolog_begin", 0, true); - EOL("Prolog Length"); - EmitLabel("line_prolog_begin", 0); + Asm->OutStreamer.AddComment("Prolog Length"); + EmitDifference(getTempLabel("line_prolog_end"), + getTempLabel("line_prolog_begin"), true); + Asm->OutStreamer.EmitLabel(getTempLabel("line_prolog_begin")); - Asm->EmitInt8(1); EOL("Minimum Instruction Length"); - Asm->EmitInt8(1); EOL("Default is_stmt_start flag"); - Asm->EmitInt8(MinLineDelta); EOL("Line Base Value (Special Opcodes)"); - Asm->EmitInt8(MaxLineDelta); EOL("Line Range Value (Special Opcodes)"); - Asm->EmitInt8(-MinLineDelta); EOL("Special Opcode Base"); + Asm->OutStreamer.AddComment("Minimum Instruction Length"); + Asm->EmitInt8(1); + Asm->OutStreamer.AddComment("Default is_stmt_start flag"); + Asm->EmitInt8(1); + Asm->OutStreamer.AddComment("Line Base Value (Special Opcodes)"); + Asm->EmitInt8(MinLineDelta); + Asm->OutStreamer.AddComment("Line Range Value (Special Opcodes)"); + Asm->EmitInt8(MaxLineDelta); + Asm->OutStreamer.AddComment("Special Opcode Base"); + Asm->EmitInt8(-MinLineDelta); // Line number standard opcode encodings argument count - Asm->EmitInt8(0); EOL("DW_LNS_copy arg count"); - Asm->EmitInt8(1); EOL("DW_LNS_advance_pc arg count"); - Asm->EmitInt8(1); EOL("DW_LNS_advance_line arg count"); - Asm->EmitInt8(1); EOL("DW_LNS_set_file arg count"); - Asm->EmitInt8(1); EOL("DW_LNS_set_column arg count"); - Asm->EmitInt8(0); EOL("DW_LNS_negate_stmt arg count"); - Asm->EmitInt8(0); EOL("DW_LNS_set_basic_block arg count"); - Asm->EmitInt8(0); EOL("DW_LNS_const_add_pc arg count"); - Asm->EmitInt8(1); EOL("DW_LNS_fixed_advance_pc arg count"); + Asm->OutStreamer.AddComment("DW_LNS_copy arg count"); + Asm->EmitInt8(0); + Asm->OutStreamer.AddComment("DW_LNS_advance_pc arg count"); + Asm->EmitInt8(1); + Asm->OutStreamer.AddComment("DW_LNS_advance_line arg count"); + Asm->EmitInt8(1); + Asm->OutStreamer.AddComment("DW_LNS_set_file arg count"); + Asm->EmitInt8(1); + Asm->OutStreamer.AddComment("DW_LNS_set_column arg count"); + Asm->EmitInt8(1); + Asm->OutStreamer.AddComment("DW_LNS_negate_stmt arg count"); + Asm->EmitInt8(0); + Asm->OutStreamer.AddComment("DW_LNS_set_basic_block arg count"); + Asm->EmitInt8(0); + Asm->OutStreamer.AddComment("DW_LNS_const_add_pc arg count"); + Asm->EmitInt8(0); + Asm->OutStreamer.AddComment("DW_LNS_fixed_advance_pc arg count"); + Asm->EmitInt8(1); // Emit directories. for (unsigned DI = 1, DE = getNumSourceDirectories()+1; DI != DE; ++DI) { @@ -2594,7 +2572,8 @@ void DwarfDebug::emitDebugLines() { Asm->OutStreamer.EmitBytes(StringRef(Dir.c_str(), Dir.size()+1), 0); } - Asm->EmitInt8(0); EOL("End of directories"); + Asm->OutStreamer.AddComment("End of directories"); + Asm->EmitInt8(0); // Emit files. for (unsigned SI = 1, SE = getNumSourceIds()+1; SI != SE; ++SI) { @@ -2609,9 +2588,10 @@ void DwarfDebug::emitDebugLines() { EmitULEB128(0, "File size"); } - Asm->EmitInt8(0); EOL("End of files"); + Asm->OutStreamer.AddComment("End of files"); + Asm->EmitInt8(0); - EmitLabel("line_prolog_end", 0); + Asm->OutStreamer.EmitLabel(getTempLabel("line_prolog_end")); // A sequence for each text section. unsigned SecSrcLinesSize = SectionSourceLines.size(); @@ -2620,13 +2600,6 @@ void DwarfDebug::emitDebugLines() { // Isolate current sections line info. const std::vector<SrcLineInfo> &LineInfos = SectionSourceLines[j]; - /*if (Asm->isVerbose()) { - const MCSection *S = SectionMap[j + 1]; - O << '\t' << MAI->getCommentString() << " Section" - << S->getName() << '\n'; - }*/ - Asm->O << '\n'; - // Dwarf assumes we start with first line of first source file. unsigned Source = 1; unsigned Line = 1; @@ -2634,32 +2607,38 @@ void DwarfDebug::emitDebugLines() { // Construct rows of the address, source, line, column matrix. for (unsigned i = 0, N = LineInfos.size(); i < N; ++i) { const SrcLineInfo &LineInfo = LineInfos[i]; - unsigned LabelID = MMI->MappedLabel(LineInfo.getLabelID()); - if (!LabelID) continue; + unsigned LabelID = LineInfo.getLabelID(); + if (MMI->isLabelDeleted(LabelID)) continue; if (LineInfo.getLine() == 0) continue; - if (!Asm->isVerbose()) - Asm->O << '\n'; - else { - std::pair<unsigned, unsigned> SourceID = + if (Asm->isVerbose()) { + std::pair<unsigned, unsigned> SrcID = getSourceDirectoryAndFileIds(LineInfo.getSourceID()); - O << '\t' << MAI->getCommentString() << ' ' - << getSourceDirectoryName(SourceID.first) << '/' - << getSourceFileName(SourceID.second) - << ':' << utostr_32(LineInfo.getLine()) << '\n'; + Asm->OutStreamer.AddComment(Twine(getSourceDirectoryName(SrcID.first)) + + "/" + + Twine(getSourceFileName(SrcID.second)) + + ":" + Twine(LineInfo.getLine())); } // Define the line address. - Asm->EmitInt8(0); EOL("Extended Op"); - Asm->EmitInt8(TD->getPointerSize() + 1); EOL("Op size"); - Asm->EmitInt8(dwarf::DW_LNE_set_address); EOL("DW_LNE_set_address"); - EmitReference("label", LabelID); EOL("Location label"); - + Asm->OutStreamer.AddComment("Extended Op"); + Asm->EmitInt8(0); + Asm->OutStreamer.AddComment("Op size"); + Asm->EmitInt8(TD->getPointerSize() + 1); + + Asm->OutStreamer.AddComment("DW_LNE_set_address"); + Asm->EmitInt8(dwarf::DW_LNE_set_address); + + Asm->OutStreamer.AddComment("Location label"); + Asm->OutStreamer.EmitSymbolValue(getDWLabel("label", LabelID), + TD->getPointerSize(), 0/*AddrSpace*/); + // If change of source, then switch to the new source. if (Source != LineInfo.getSourceID()) { Source = LineInfo.getSourceID(); - Asm->EmitInt8(dwarf::DW_LNS_set_file); EOL("DW_LNS_set_file"); + Asm->OutStreamer.AddComment("DW_LNS_set_file"); + Asm->EmitInt8(dwarf::DW_LNS_set_file); EmitULEB128(Source, "New Source"); } @@ -2675,17 +2654,20 @@ void DwarfDebug::emitDebugLines() { // If delta is small enough and in range... if (Delta >= 0 && Delta < (MaxLineDelta - 1)) { // ... then use fast opcode. - Asm->EmitInt8(Delta - MinLineDelta); EOL("Line Delta"); + Asm->OutStreamer.AddComment("Line Delta"); + Asm->EmitInt8(Delta - MinLineDelta); } else { // ... otherwise use long hand. + Asm->OutStreamer.AddComment("DW_LNS_advance_line"); Asm->EmitInt8(dwarf::DW_LNS_advance_line); - EOL("DW_LNS_advance_line"); EmitSLEB128(Offset, "Line Offset"); - Asm->EmitInt8(dwarf::DW_LNS_copy); EOL("DW_LNS_copy"); + Asm->OutStreamer.AddComment("DW_LNS_copy"); + Asm->EmitInt8(dwarf::DW_LNS_copy); } } else { // Copy the previous row (different address or source) - Asm->EmitInt8(dwarf::DW_LNS_copy); EOL("DW_LNS_copy"); + Asm->OutStreamer.AddComment("DW_LNS_copy"); + Asm->EmitInt8(dwarf::DW_LNS_copy); } } @@ -2698,8 +2680,7 @@ void DwarfDebug::emitDebugLines() { // put into it, emit an empty table. emitEndOfLineMatrix(1); - EmitLabel("line_end", 0); - Asm->O << '\n'; + Asm->OutStreamer.EmitLabel(getTempLabel("line_end")); } /// emitCommonDebugFrame - Emit common frame info into a debug frame section. @@ -2717,22 +2698,22 @@ void DwarfDebug::emitCommonDebugFrame() { Asm->OutStreamer.SwitchSection( Asm->getObjFileLowering().getDwarfFrameSection()); - EmitLabel("debug_frame_common", 0); - EmitDifference("debug_frame_common_end", 0, - "debug_frame_common_begin", 0, true); - EOL("Length of Common Information Entry"); + Asm->OutStreamer.EmitLabel(getTempLabel("debug_frame_common")); + Asm->OutStreamer.AddComment("Length of Common Information Entry"); + EmitDifference(getTempLabel("debug_frame_common_end"), + getTempLabel("debug_frame_common_begin"), true); - EmitLabel("debug_frame_common_begin", 0); + Asm->OutStreamer.EmitLabel(getTempLabel("debug_frame_common_begin")); + Asm->OutStreamer.AddComment("CIE Identifier Tag"); Asm->EmitInt32((int)dwarf::DW_CIE_ID); - EOL("CIE Identifier Tag"); + Asm->OutStreamer.AddComment("CIE Version"); Asm->EmitInt8(dwarf::DW_CIE_VERSION); - EOL("CIE Version"); + Asm->OutStreamer.AddComment("CIE Augmentation"); Asm->OutStreamer.EmitIntValue(0, 1, /*addrspace*/0); // nul terminator. - EOL("CIE Augmentation"); EmitULEB128(1, "CIE Code Alignment Factor"); EmitSLEB128(stackGrowth, "CIE Data Alignment Factor"); + Asm->OutStreamer.AddComment("CIE RA Column"); Asm->EmitInt8(RI->getDwarfRegNum(RI->getRARegister(), false)); - EOL("CIE RA Column"); std::vector<MachineMove> Moves; RI->getInitialFrameState(Moves); @@ -2740,8 +2721,7 @@ void DwarfDebug::emitCommonDebugFrame() { EmitFrameMoves(NULL, 0, Moves, false); Asm->EmitAlignment(2, 0, 0, false); - EmitLabel("debug_frame_common_end", 0); - Asm->O << '\n'; + Asm->OutStreamer.EmitLabel(getTempLabel("debug_frame_common_end")); } /// emitFunctionDebugFrame - Emit per function frame info into a debug frame @@ -2755,28 +2735,34 @@ DwarfDebug::emitFunctionDebugFrame(const FunctionDebugFrameInfo&DebugFrameInfo){ Asm->OutStreamer.SwitchSection( Asm->getObjFileLowering().getDwarfFrameSection()); - EmitDifference("debug_frame_end", DebugFrameInfo.Number, - "debug_frame_begin", DebugFrameInfo.Number, true); - EOL("Length of Frame Information Entry"); + Asm->OutStreamer.AddComment("Length of Frame Information Entry"); + EmitDifference(getDWLabel("debug_frame_end", DebugFrameInfo.Number), + getDWLabel("debug_frame_begin", DebugFrameInfo.Number), true); - EmitLabel("debug_frame_begin", DebugFrameInfo.Number); + Asm->OutStreamer.EmitLabel(getDWLabel("debug_frame_begin", + DebugFrameInfo.Number)); - EmitSectionOffset("debug_frame_common", "section_debug_frame", - 0, 0, true, false); - EOL("FDE CIE offset"); + Asm->OutStreamer.AddComment("FDE CIE offset"); + EmitSectionOffset(getTempLabel("debug_frame_common"), + getTempLabel("section_debug_frame"), true, false); - EmitReference("func_begin", DebugFrameInfo.Number); - EOL("FDE initial location"); - EmitDifference("func_end", DebugFrameInfo.Number, - "func_begin", DebugFrameInfo.Number); - EOL("FDE address range"); + Asm->OutStreamer.AddComment("FDE initial location"); + Asm->OutStreamer.EmitSymbolValue(getDWLabel("func_begin", + DebugFrameInfo.Number), + TD->getPointerSize(), 0/*AddrSpace*/); + + + + Asm->OutStreamer.AddComment("FDE address range"); + EmitDifference(getDWLabel("func_end", DebugFrameInfo.Number), + getDWLabel("func_begin", DebugFrameInfo.Number)); EmitFrameMoves("func_begin", DebugFrameInfo.Number, DebugFrameInfo.Moves, false); Asm->EmitAlignment(2, 0, 0, false); - EmitLabel("debug_frame_end", DebugFrameInfo.Number); - Asm->O << '\n'; + Asm->OutStreamer.EmitLabel(getDWLabel("debug_frame_end", + DebugFrameInfo.Number)); } /// emitDebugPubNames - Emit visible names into a debug pubnames section. @@ -2786,60 +2772,65 @@ void DwarfDebug::emitDebugPubNames() { Asm->OutStreamer.SwitchSection( Asm->getObjFileLowering().getDwarfPubNamesSection()); - EmitDifference("pubnames_end", ModuleCU->getID(), - "pubnames_begin", ModuleCU->getID(), true); - EOL("Length of Public Names Info"); + Asm->OutStreamer.AddComment("Length of Public Names Info"); + EmitDifference(getDWLabel("pubnames_end", ModuleCU->getID()), + getDWLabel("pubnames_begin", ModuleCU->getID()), true); - EmitLabel("pubnames_begin", ModuleCU->getID()); + Asm->OutStreamer.EmitLabel(getDWLabel("pubnames_begin", ModuleCU->getID())); - Asm->EmitInt16(dwarf::DWARF_VERSION); EOL("DWARF Version"); + Asm->OutStreamer.AddComment("DWARF Version"); + Asm->EmitInt16(dwarf::DWARF_VERSION); - EmitSectionOffset("info_begin", "section_info", - ModuleCU->getID(), 0, true, false); - EOL("Offset of Compilation Unit Info"); + Asm->OutStreamer.AddComment("Offset of Compilation Unit Info"); + EmitSectionOffset(getDWLabel("info_begin", ModuleCU->getID()), + getTempLabel("section_info"), + true, false); - EmitDifference("info_end", ModuleCU->getID(), "info_begin", ModuleCU->getID(), + Asm->OutStreamer.AddComment("Compilation Unit Length"); + EmitDifference(getDWLabel("info_end", ModuleCU->getID()), + getDWLabel("info_begin", ModuleCU->getID()), true); - EOL("Compilation Unit Length"); const StringMap<DIE*> &Globals = ModuleCU->getGlobals(); for (StringMap<DIE*>::const_iterator GI = Globals.begin(), GE = Globals.end(); GI != GE; ++GI) { const char *Name = GI->getKeyData(); - DIE * Entity = GI->second; + DIE *Entity = GI->second; - Asm->EmitInt32(Entity->getOffset()); EOL("DIE offset"); + Asm->OutStreamer.AddComment("DIE offset"); + Asm->EmitInt32(Entity->getOffset()); if (Asm->VerboseAsm) Asm->OutStreamer.AddComment("External Name"); Asm->OutStreamer.EmitBytes(StringRef(Name, strlen(Name)+1), 0); } - Asm->EmitInt32(0); EOL("End Mark"); - EmitLabel("pubnames_end", ModuleCU->getID()); - Asm->O << '\n'; + Asm->OutStreamer.AddComment("End Mark"); + Asm->EmitInt32(0); + Asm->OutStreamer.EmitLabel(getDWLabel("pubnames_end", ModuleCU->getID())); } void DwarfDebug::emitDebugPubTypes() { // Start the dwarf pubnames section. Asm->OutStreamer.SwitchSection( Asm->getObjFileLowering().getDwarfPubTypesSection()); - EmitDifference("pubtypes_end", ModuleCU->getID(), - "pubtypes_begin", ModuleCU->getID(), true); - EOL("Length of Public Types Info"); + Asm->OutStreamer.AddComment("Length of Public Types Info"); + EmitDifference(getDWLabel("pubtypes_end", ModuleCU->getID()), + getDWLabel("pubtypes_begin", ModuleCU->getID()), true); - EmitLabel("pubtypes_begin", ModuleCU->getID()); + Asm->OutStreamer.EmitLabel(getDWLabel("pubtypes_begin", ModuleCU->getID())); if (Asm->VerboseAsm) Asm->OutStreamer.AddComment("DWARF Version"); Asm->EmitInt16(dwarf::DWARF_VERSION); - EmitSectionOffset("info_begin", "section_info", - ModuleCU->getID(), 0, true, false); - EOL("Offset of Compilation ModuleCU Info"); + Asm->OutStreamer.AddComment("Offset of Compilation ModuleCU Info"); + EmitSectionOffset(getDWLabel("info_begin", ModuleCU->getID()), + getTempLabel("section_info"), true, false); - EmitDifference("info_end", ModuleCU->getID(), "info_begin", ModuleCU->getID(), + Asm->OutStreamer.AddComment("Compilation ModuleCU Length"); + EmitDifference(getDWLabel("info_end", ModuleCU->getID()), + getDWLabel("info_begin", ModuleCU->getID()), true); - EOL("Compilation ModuleCU Length"); const StringMap<DIE*> &Globals = ModuleCU->getGlobalTypes(); for (StringMap<DIE*>::const_iterator @@ -2854,32 +2845,29 @@ void DwarfDebug::emitDebugPubTypes() { Asm->OutStreamer.EmitBytes(StringRef(Name, GI->getKeyLength()+1), 0); } - Asm->EmitInt32(0); EOL("End Mark"); - EmitLabel("pubtypes_end", ModuleCU->getID()); - Asm->O << '\n'; + Asm->OutStreamer.AddComment("End Mark"); + Asm->EmitInt32(0); + Asm->OutStreamer.EmitLabel(getDWLabel("pubtypes_end", ModuleCU->getID())); } /// emitDebugStr - Emit visible names into a debug str section. /// void DwarfDebug::emitDebugStr() { // Check to see if it is worth the effort. - if (!StringPool.empty()) { - // Start the dwarf str section. - Asm->OutStreamer.SwitchSection( + if (StringPool.empty()) return; + + // Start the dwarf str section. + Asm->OutStreamer.SwitchSection( Asm->getObjFileLowering().getDwarfStrSection()); - // For each of strings in the string pool. - for (unsigned StringID = 1, N = StringPool.size(); - StringID <= N; ++StringID) { - // Emit a label for reference from debug information entries. - EmitLabel("string", StringID); - - // Emit the string itself. - const std::string &String = StringPool[StringID]; - Asm->OutStreamer.EmitBytes(StringRef(String.c_str(), String.size()+1), 0); - } - - Asm->O << '\n'; + // For each of strings in the string pool. + for (unsigned StringID = 1, N = StringPool.size(); StringID <= N; ++StringID){ + // Emit a label for reference from debug information entries. + Asm->OutStreamer.EmitLabel(getDWLabel("string", StringID)); + + // Emit the string itself. + const std::string &String = StringPool[StringID]; + Asm->OutStreamer.EmitBytes(StringRef(String.c_str(), String.size()+1), 0); } } @@ -2897,33 +2885,6 @@ void DwarfDebug::EmitDebugARanges() { // Start the dwarf aranges section. Asm->OutStreamer.SwitchSection( Asm->getObjFileLowering().getDwarfARangesSection()); - - // FIXME - Mock up -#if 0 - CompileUnit *Unit = GetBaseCompileUnit(); - - // Don't include size of length - Asm->EmitInt32(0x1c); EOL("Length of Address Ranges Info"); - - Asm->EmitInt16(dwarf::DWARF_VERSION); EOL("Dwarf Version"); - - EmitReference("info_begin", Unit->getID()); - EOL("Offset of Compilation Unit Info"); - - Asm->EmitInt8(TD->getPointerSize()); EOL("Size of Address"); - - Asm->EmitInt8(0); EOL("Size of Segment Descriptor"); - - Asm->EmitInt16(0); EOL("Pad (1)"); - Asm->EmitInt16(0); EOL("Pad (2)"); - - // Range 1 - EmitReference("text_begin", 0); EOL("Address"); - EmitDifference("text_end", 0, "text_begin", 0, true); EOL("Length"); - - Asm->EmitInt32(0); EOL("EOM (1)"); - Asm->EmitInt32(0); EOL("EOM (2)"); -#endif } /// emitDebugRanges - Emit visible names into a debug ranges section. @@ -2972,14 +2933,16 @@ void DwarfDebug::emitDebugInlineInfo() { Asm->OutStreamer.SwitchSection( Asm->getObjFileLowering().getDwarfDebugInlineSection()); - EmitDifference("debug_inlined_end", 1, - "debug_inlined_begin", 1, true); - EOL("Length of Debug Inlined Information Entry"); + Asm->OutStreamer.AddComment("Length of Debug Inlined Information Entry"); + EmitDifference(getDWLabel("debug_inlined_end", 1), + getDWLabel("debug_inlined_begin", 1), true); - EmitLabel("debug_inlined_begin", 1); + Asm->OutStreamer.EmitLabel(getDWLabel("debug_inlined_begin", 1)); - Asm->EmitInt16(dwarf::DWARF_VERSION); EOL("Dwarf Version"); - Asm->EmitInt8(TD->getPointerSize()); EOL("Address Size (in bytes)"); + Asm->OutStreamer.AddComment("Dwarf Version"); + Asm->EmitInt16(dwarf::DWARF_VERSION); + Asm->OutStreamer.AddComment("Address Size (in bytes)"); + Asm->EmitInt8(TD->getPointerSize()); for (SmallVector<MDNode *, 4>::iterator I = InlinedSPNodes.begin(), E = InlinedSPNodes.end(); I != E; ++I) { @@ -2992,33 +2955,29 @@ void DwarfDebug::emitDebugInlineInfo() { StringRef LName = SP.getLinkageName(); StringRef Name = SP.getName(); + Asm->OutStreamer.AddComment("MIPS linkage name"); if (LName.empty()) { Asm->OutStreamer.EmitBytes(Name, 0); Asm->OutStreamer.EmitIntValue(0, 1, 0); // nul terminator. } else - EmitSectionOffset("string", "section_str", - StringPool.idFor(getRealLinkageName(LName)), false, true); + EmitSectionOffset(getDWLabel("string", + StringPool.idFor(getRealLinkageName(LName))), + getTempLabel("section_str"), true); - EOL("MIPS linkage name"); - EmitSectionOffset("string", "section_str", - StringPool.idFor(Name), false, true); - EOL("Function name"); + Asm->OutStreamer.AddComment("Function name"); + EmitSectionOffset(getDWLabel("string", StringPool.idFor(Name)), + getTempLabel("section_str"), false, true); EmitULEB128(Labels.size(), "Inline count"); for (SmallVector<InlineInfoLabels, 4>::iterator LI = Labels.begin(), LE = Labels.end(); LI != LE; ++LI) { - DIE *SP = LI->second; - Asm->EmitInt32(SP->getOffset()); EOL("DIE offset"); - - if (TD->getPointerSize() == sizeof(int32_t)) - O << MAI->getData32bitsDirective(); - else - O << MAI->getData64bitsDirective(); + if (Asm->VerboseAsm) Asm->OutStreamer.AddComment("DIE offset"); + Asm->EmitInt32(LI->second->getOffset()); - PrintLabelName("label", LI->first); EOL("low_pc"); + if (Asm->VerboseAsm) Asm->OutStreamer.AddComment("low_pc"); + Asm->OutStreamer.EmitSymbolValue(LI->first, TD->getPointerSize(), 0); } } - EmitLabel("debug_inlined_end", 1); - Asm->O << '\n'; + Asm->OutStreamer.EmitLabel(getDWLabel("debug_inlined_end", 1)); } diff --git a/lib/CodeGen/AsmPrinter/DwarfDebug.h b/lib/CodeGen/AsmPrinter/DwarfDebug.h index 55baa92..40d1d64 100644 --- a/lib/CodeGen/AsmPrinter/DwarfDebug.h +++ b/lib/CodeGen/AsmPrinter/DwarfDebug.h @@ -62,14 +62,6 @@ class DwarfDebug : public DwarfPrinter { // Attributes used to construct specific Dwarf sections. // - /// CompileUnitMap - A map of global variables representing compile units to - /// compile units. - DenseMap<Value *, CompileUnit *> CompileUnitMap; - - /// CompileUnits - All the compile units in this module. - /// - SmallVector<CompileUnit *, 8> CompileUnits; - /// ModuleCU - All DIEs are inserted in ModuleCU. CompileUnit *ModuleCU; @@ -175,8 +167,8 @@ class DwarfDebug : public DwarfPrinter { /// InlineInfo - Keep track of inlined functions and their location. This /// information is used to populate debug_inlined section. - typedef std::pair<unsigned, DIE *> InlineInfoLabels; - DenseMap<MDNode *, SmallVector<InlineInfoLabels, 4> > InlineInfo; + typedef std::pair<MCSymbol*, DIE *> InlineInfoLabels; + DenseMap<MDNode*, SmallVector<InlineInfoLabels, 4> > InlineInfo; SmallVector<MDNode *, 4> InlinedSPNodes; /// CompileUnitOffsets - A vector of the offsets of the compile units. This is @@ -251,23 +243,18 @@ class DwarfDebug : public DwarfPrinter { /// addLabel - Add a Dwarf label attribute data and value. /// void addLabel(DIE *Die, unsigned Attribute, unsigned Form, - const DWLabel &Label); - - /// addObjectLabel - Add an non-Dwarf label attribute data and value. - /// - void addObjectLabel(DIE *Die, unsigned Attribute, unsigned Form, - const MCSymbol *Sym); + const MCSymbol *Label); /// addSectionOffset - Add a section offset label attribute data and value. /// void addSectionOffset(DIE *Die, unsigned Attribute, unsigned Form, - const DWLabel &Label, const DWLabel &Section, - bool isEH = false, bool useSet = true); + const MCSymbol *Label, const MCSymbol *Section, + bool isEH = false); /// addDelta - Add a label delta attribute data and value. /// void addDelta(DIE *Die, unsigned Attribute, unsigned Form, - const DWLabel &Hi, const DWLabel &Lo); + const MCSymbol *Hi, const MCSymbol *Lo); /// addDIEEntry - Add a DIE attribute data and value. /// @@ -346,7 +333,7 @@ class DwarfDebug : public DwarfPrinter { DICompositeType *CTy); /// constructEnumTypeDIE - Construct enum type DIE from DIEnumerator. - DIE *constructEnumTypeDIE(DIEnumerator *ETy); + DIE *constructEnumTypeDIE(DIEnumerator ETy); /// createGlobalVariableDIE - Create new DIE using GV. DIE *createGlobalVariableDIE(const DIGlobalVariable &GV); @@ -357,10 +344,6 @@ class DwarfDebug : public DwarfPrinter { /// createSubprogramDIE - Create new DIE using SP. DIE *createSubprogramDIE(const DISubprogram &SP, bool MakeDecl = false); - /// findCompileUnit - Get the compile unit for the given descriptor. - /// - CompileUnit *findCompileUnit(DICompileUnit Unit); - /// getUpdatedDbgScope - Find or create DbgScope assicated with /// the instruction. Initialize scope and update scope hierarchy. DbgScope *getUpdatedDbgScope(MDNode *N, const MachineInstr *MI, MDNode *InlinedAt); @@ -529,10 +512,10 @@ public: /// void endFunction(const MachineFunction *MF); - /// recordSourceLine - Records location information and associates it with a - /// label. Returns a unique label ID used to generate a label and provide - /// correspondence to the source line list. - unsigned recordSourceLine(unsigned Line, unsigned Col, MDNode *Scope); + /// recordSourceLine - Register a source line with debug info. Returns the + /// unique label that was emitted and which provides correspondence to + /// the source line list. + MCSymbol *recordSourceLine(unsigned Line, unsigned Col, MDNode *Scope); /// getSourceLineCount - Return the number of source lines in the debug /// info. @@ -556,7 +539,7 @@ public: void collectVariableInfo(); /// beginScope - Process beginning of a scope starting at Label. - void beginScope(const MachineInstr *MI, unsigned Label); + void beginScope(const MachineInstr *MI, MCSymbol *Label); /// endScope - Prcess end of a scope. void endScope(const MachineInstr *MI); diff --git a/lib/CodeGen/AsmPrinter/DwarfException.cpp b/lib/CodeGen/AsmPrinter/DwarfException.cpp index 2b08ba4..11a01fe 100644 --- a/lib/CodeGen/AsmPrinter/DwarfException.cpp +++ b/lib/CodeGen/AsmPrinter/DwarfException.cpp @@ -39,7 +39,7 @@ using namespace llvm; DwarfException::DwarfException(raw_ostream &OS, AsmPrinter *A, const MCAsmInfo *T) - : DwarfPrinter(OS, A, T, "eh"), shouldEmitTable(false),shouldEmitMoves(false), + : DwarfPrinter(OS, A, T), shouldEmitTable(false),shouldEmitMoves(false), shouldEmitTableModule(false), shouldEmitMovesModule(false), ExceptionTimer(0) { if (TimePassesIsEnabled) @@ -60,7 +60,7 @@ const MCExpr *DwarfException::CreateLabelDiff(const MCExpr *ExprRef, raw_svector_ostream(Name) << MAI->getPrivateGlobalPrefix() << LabelName << Asm->getFunctionNumber() << "_" << Index; - MCSymbol *DotSym = Asm->OutContext.GetOrCreateSymbol(Name.str()); + MCSymbol *DotSym = Asm->OutContext.GetOrCreateTemporarySymbol(Name.str()); Asm->OutStreamer.EmitLabel(DotSym); return MCBinaryExpr::CreateSub(ExprRef, @@ -84,25 +84,29 @@ void DwarfException::EmitCIE(const Function *PersonalityFn, unsigned Index) { // Begin eh frame section. Asm->OutStreamer.SwitchSection(TLOF.getEHFrameSection()); - if (MAI->is_EHSymbolPrivate()) - O << MAI->getPrivateGlobalPrefix(); - O << "EH_frame" << Index << ":\n"; + MCSymbol *EHFrameSym; + if (TLOF.isFunctionEHFrameSymbolPrivate()) + EHFrameSym = getDWLabel("EH_frame", Index); + else + EHFrameSym = Asm->OutContext.GetOrCreateSymbol(Twine("EH_frame") + + Twine(Index)); + Asm->OutStreamer.EmitLabel(EHFrameSym); - EmitLabel("section_eh_frame", Index); + Asm->OutStreamer.EmitLabel(getDWLabel("section_eh_frame", Index)); // Define base labels. - EmitLabel("eh_frame_common", Index); + Asm->OutStreamer.EmitLabel(getDWLabel("eh_frame_common", Index)); // Define the eh frame length. - EmitDifference("eh_frame_common_end", Index, - "eh_frame_common_begin", Index, true); - EOL("Length of Common Information Entry"); + Asm->OutStreamer.AddComment("Length of Common Information Entry"); + EmitDifference(getDWLabel("eh_frame_common_end", Index), + getDWLabel("eh_frame_common_begin", Index), true); // EH frame header. - EmitLabel("eh_frame_common_begin", Index); - if (Asm->VerboseAsm) Asm->OutStreamer.AddComment("CIE Identifier Tag"); + Asm->OutStreamer.EmitLabel(getDWLabel("eh_frame_common_begin", Index)); + Asm->OutStreamer.AddComment("CIE Identifier Tag"); Asm->OutStreamer.EmitIntValue(0, 4/*size*/, 0/*addrspace*/); - if (Asm->VerboseAsm) Asm->OutStreamer.AddComment("DW_CIE_VERSION"); + Asm->OutStreamer.AddComment("DW_CIE_VERSION"); Asm->OutStreamer.EmitIntValue(dwarf::DW_CIE_VERSION, 1/*size*/, 0/*addr*/); // The personality presence indicates that language specific information will @@ -138,14 +142,14 @@ void DwarfException::EmitCIE(const Function *PersonalityFn, unsigned Index) { if (APtr != Augmentation + 1) Augmentation[0] = 'z'; + Asm->OutStreamer.AddComment("CIE Augmentation"); Asm->OutStreamer.EmitBytes(StringRef(Augmentation, strlen(Augmentation)+1),0); - EOL("CIE Augmentation"); // Round out reader. EmitULEB128(1, "CIE Code Alignment Factor"); EmitSLEB128(stackGrowth, "CIE Data Alignment Factor"); + Asm->OutStreamer.AddComment("CIE Return Address Column"); Asm->EmitInt8(RI->getDwarfRegNum(RI->getRARegister(), true)); - EOL("CIE Return Address Column"); if (Augmentation[0]) { EmitULEB128(AugmentationSize, "Augmentation Size"); @@ -153,8 +157,8 @@ void DwarfException::EmitCIE(const Function *PersonalityFn, unsigned Index) { // If there is a personality, we need to indicate the function's location. if (PersonalityFn) { EmitEncodingByte(PerEncoding, "Personality"); + Asm->OutStreamer.AddComment("Personality"); EmitReference(PersonalityFn, PerEncoding); - EOL("Personality"); } if (UsesLSDA[Index]) EmitEncodingByte(LSDAEncoding, "LSDA"); @@ -171,8 +175,7 @@ void DwarfException::EmitCIE(const Function *PersonalityFn, unsigned Index) { // be 8-byte on 64-bit targets to match what gcc does. Otherwise you get // holes which confuse readers of eh_frame. Asm->EmitAlignment(TD->getPointerSize() == 4 ? 2 : 3, 0, 0, false); - EmitLabel("eh_frame_common_end", Index); - Asm->O << '\n'; + Asm->OutStreamer.EmitLabel(getDWLabel("eh_frame_common_end", Index)); } /// EmitFDE - Emit the Frame Description Entry (FDE) for the function. @@ -190,13 +193,13 @@ void DwarfException::EmitFDE(const FunctionEHFrameInfo &EHFrameInfo) { // Externally visible entry into the functions eh frame info. If the // corresponding function is static, this should not be externally visible. - if (!TheFunc->hasLocalLinkage()) - if (const char *GlobalEHDirective = MAI->getGlobalEHDirective()) - O << GlobalEHDirective << *EHFrameInfo.FunctionEHSym << '\n'; + if (!TheFunc->hasLocalLinkage() && TLOF.isFunctionEHSymbolGlobal()) + Asm->OutStreamer.EmitSymbolAttribute(EHFrameInfo.FunctionEHSym,MCSA_Global); // If corresponding function is weak definition, this should be too. if (TheFunc->isWeakForLinker() && MAI->getWeakDefDirective()) - O << MAI->getWeakDefDirective() << *EHFrameInfo.FunctionEHSym << '\n'; + Asm->OutStreamer.EmitSymbolAttribute(EHFrameInfo.FunctionEHSym, + MCSA_WeakDefinition); // If corresponding function is hidden, this should be too. if (TheFunc->hasHiddenVisibility()) @@ -211,8 +214,9 @@ void DwarfException::EmitFDE(const FunctionEHFrameInfo &EHFrameInfo) { if (!EHFrameInfo.hasCalls && !UnwindTablesMandatory && (!TheFunc->isWeakForLinker() || !MAI->getWeakDefDirective() || - MAI->getSupportsWeakOmittedEHFrame())) { - O << *EHFrameInfo.FunctionEHSym << " = 0\n"; + TLOF.getSupportsWeakOmittedEHFrame())) { + Asm->OutStreamer.EmitAssignment(EHFrameInfo.FunctionEHSym, + MCConstantExpr::Create(0, Asm->OutContext)); // This name has no connection to the function, so it might get // dead-stripped when the function is not, erroneously. Prohibit // dead-stripping unconditionally. @@ -220,28 +224,29 @@ void DwarfException::EmitFDE(const FunctionEHFrameInfo &EHFrameInfo) { Asm->OutStreamer.EmitSymbolAttribute(EHFrameInfo.FunctionEHSym, MCSA_NoDeadStrip); } else { - O << *EHFrameInfo.FunctionEHSym << ":\n"; + Asm->OutStreamer.EmitLabel(EHFrameInfo.FunctionEHSym); // EH frame header. - EmitDifference("eh_frame_end", EHFrameInfo.Number, - "eh_frame_begin", EHFrameInfo.Number, + Asm->OutStreamer.AddComment("Length of Frame Information Entry"); + EmitDifference(getDWLabel("eh_frame_end", EHFrameInfo.Number), + getDWLabel("eh_frame_begin", EHFrameInfo.Number), true); - EOL("Length of Frame Information Entry"); - EmitLabel("eh_frame_begin", EHFrameInfo.Number); + Asm->OutStreamer.EmitLabel(getDWLabel("eh_frame_begin",EHFrameInfo.Number)); - EmitSectionOffset("eh_frame_begin", "eh_frame_common", - EHFrameInfo.Number, EHFrameInfo.PersonalityIndex, - true, true, false); + Asm->OutStreamer.AddComment("FDE CIE offset"); + EmitSectionOffset(getDWLabel("eh_frame_begin", EHFrameInfo.Number), + getDWLabel("eh_frame_common", + EHFrameInfo.PersonalityIndex), + true, true); - EOL("FDE CIE offset"); - EmitReference("eh_func_begin", EHFrameInfo.Number, FDEEncoding); - EOL("FDE initial location"); - EmitDifference("eh_func_end", EHFrameInfo.Number, - "eh_func_begin", EHFrameInfo.Number, + Asm->OutStreamer.AddComment("FDE initial location"); + EmitReference(getDWLabel("eh_func_begin", EHFrameInfo.Number), FDEEncoding); + Asm->OutStreamer.AddComment("FDE address range"); + EmitDifference(getDWLabel("eh_func_end", EHFrameInfo.Number), + getDWLabel("eh_func_begin", EHFrameInfo.Number), SizeOfEncodedValue(FDEEncoding) == 4); - EOL("FDE address range"); // If there is a personality and landing pads then point to the language // specific data area in the exception table. @@ -249,12 +254,12 @@ void DwarfException::EmitFDE(const FunctionEHFrameInfo &EHFrameInfo) { unsigned Size = SizeOfEncodedValue(LSDAEncoding); EmitULEB128(Size, "Augmentation size"); + Asm->OutStreamer.AddComment("Language Specific Data Area"); if (EHFrameInfo.hasLandingPads) - EmitReference("exception", EHFrameInfo.Number, LSDAEncoding); + EmitReference(getDWLabel("exception", EHFrameInfo.Number),LSDAEncoding); else Asm->OutStreamer.EmitIntValue(0, Size/*size*/, 0/*addrspace*/); - EOL("Language Specific Data Area"); } else { EmitULEB128(0, "Augmentation size"); } @@ -268,7 +273,7 @@ void DwarfException::EmitFDE(const FunctionEHFrameInfo &EHFrameInfo) { // get holes which confuse readers of eh_frame. Asm->EmitAlignment(TD->getPointerSize() == sizeof(int32_t) ? 2 : 3, 0, 0, false); - EmitLabel("eh_frame_end", EHFrameInfo.Number); + Asm->OutStreamer.EmitLabel(getDWLabel("eh_frame_end", EHFrameInfo.Number)); // If the function is marked used, this table should be also. We cannot // make the mark unconditional in this case, since retaining the table also @@ -280,7 +285,7 @@ void DwarfException::EmitFDE(const FunctionEHFrameInfo &EHFrameInfo) { Asm->OutStreamer.EmitSymbolAttribute(EHFrameInfo.FunctionEHSym, MCSA_NoDeadStrip); } - Asm->O << '\n'; + Asm->OutStreamer.AddBlankLine(); } /// SharedTypeIds - How many leading type ids two landing pads have in common. @@ -699,15 +704,14 @@ void DwarfException::EmitExceptionTable() { Asm->EmitAlignment(2, 0, 0, false); // Emit the LSDA. - O << "GCC_except_table" << SubprogramCount << ":\n"; - EmitLabel("exception", SubprogramCount); + MCSymbol *GCCETSym = + Asm->OutContext.GetOrCreateSymbol(Twine("GCC_except_table")+ + Twine(SubprogramCount)); + Asm->OutStreamer.EmitLabel(GCCETSym); + Asm->OutStreamer.EmitLabel(getDWLabel("exception", SubprogramCount)); - if (IsSJLJ) { - SmallString<16> LSDAName; - raw_svector_ostream(LSDAName) << MAI->getPrivateGlobalPrefix() << - "_LSDA_" << Asm->getFunctionNumber(); - O << LSDAName.str() << ":\n"; - } + if (IsSJLJ) + Asm->OutStreamer.EmitLabel(getDWLabel("_LSDA_", Asm->getFunctionNumber())); // Emit the LSDA header. EmitEncodingByte(dwarf::DW_EH_PE_omit, "@LPStart"); @@ -819,27 +823,30 @@ void DwarfException::EmitExceptionTable() { // Offset of the call site relative to the previous call site, counted in // number of 16-byte bundles. The first call site is counted relative to // the start of the procedure fragment. - EmitSectionOffset(BeginTag, "eh_func_begin", BeginNumber, SubprogramCount, + Asm->OutStreamer.AddComment("Region start"); + EmitSectionOffset(getDWLabel(BeginTag, BeginNumber), + getDWLabel("eh_func_begin", SubprogramCount), true, true); - EOL("Region start"); + Asm->OutStreamer.AddComment("Region length"); if (!S.EndLabel) - EmitDifference("eh_func_end", SubprogramCount, BeginTag, BeginNumber, + EmitDifference(getDWLabel("eh_func_end", SubprogramCount), + getDWLabel(BeginTag, BeginNumber), true); else - EmitDifference("label", S.EndLabel, BeginTag, BeginNumber, true); + EmitDifference(getDWLabel("label", S.EndLabel), + getDWLabel(BeginTag, BeginNumber), true); - EOL("Region length"); // Offset of the landing pad, counted in 16-byte bundles relative to the // @LPStart address. + Asm->OutStreamer.AddComment("Landing pad"); if (!S.PadLabel) { - Asm->OutStreamer.AddComment("Landing pad"); Asm->OutStreamer.EmitIntValue(0, 4/*size*/, 0/*addrspace*/); } else { - EmitSectionOffset("label", "eh_func_begin", S.PadLabel, SubprogramCount, + EmitSectionOffset(getDWLabel("label", S.PadLabel), + getDWLabel("eh_func_begin", SubprogramCount), true, true); - EOL("Landing pad"); } // Offset of the first associated action record, relative to the start of @@ -850,11 +857,16 @@ void DwarfException::EmitExceptionTable() { } // Emit the Action Table. - if (Actions.size() != 0) EOL("-- Action Record Table --"); + if (Actions.size() != 0) { + Asm->OutStreamer.AddComment("-- Action Record Table --"); + Asm->OutStreamer.AddBlankLine(); + } + for (SmallVectorImpl<ActionEntry>::const_iterator I = Actions.begin(), E = Actions.end(); I != E; ++I) { const ActionEntry &Action = *I; - EOL("Action Record:"); + Asm->OutStreamer.AddComment("Action Record"); + Asm->OutStreamer.AddBlankLine(); // Type Filter // @@ -870,23 +882,26 @@ void DwarfException::EmitExceptionTable() { } // Emit the Catch TypeInfos. - if (!TypeInfos.empty()) EOL("-- Catch TypeInfos --"); + if (!TypeInfos.empty()) { + Asm->OutStreamer.AddComment("-- Catch TypeInfos --"); + Asm->OutStreamer.AddBlankLine(); + } for (std::vector<GlobalVariable *>::const_reverse_iterator I = TypeInfos.rbegin(), E = TypeInfos.rend(); I != E; ++I) { const GlobalVariable *GV = *I; - if (GV) { + Asm->OutStreamer.AddComment("TypeInfo"); + if (GV) EmitReference(GV, TTypeEncoding); - EOL("TypeInfo"); - } else { - PrintRelDirective(TTypeEncoding); - O << "0x0"; - EOL(""); - } + else + Asm->OutStreamer.EmitIntValue(0, SizeOfEncodedValue(TTypeEncoding), 0); } // Emit the Exception Specifications. - if (!FilterIds.empty()) EOL("-- Filter IDs --"); + if (!FilterIds.empty()) { + Asm->OutStreamer.AddComment("-- Filter IDs --"); + Asm->OutStreamer.AddBlankLine(); + } for (std::vector<unsigned>::const_iterator I = FilterIds.begin(), E = FilterIds.end(); I < E; ++I) { unsigned TypeID = *I; @@ -945,7 +960,7 @@ void DwarfException::BeginFunction(const MachineFunction *MF) { if (shouldEmitMoves || shouldEmitTable) // Assumes in correct section after the entry point. - EmitLabel("eh_func_begin", ++SubprogramCount); + Asm->OutStreamer.EmitLabel(getDWLabel("eh_func_begin", ++SubprogramCount)); shouldEmitTableModule |= shouldEmitTable; shouldEmitMovesModule |= shouldEmitMoves; @@ -962,12 +977,13 @@ void DwarfException::EndFunction() { if (TimePassesIsEnabled) ExceptionTimer->startTimer(); - EmitLabel("eh_func_end", SubprogramCount); + Asm->OutStreamer.EmitLabel(getDWLabel("eh_func_end", SubprogramCount)); EmitExceptionTable(); + const TargetLoweringObjectFile &TLOF = Asm->getObjFileLowering(); MCSymbol *FunctionEHSym = Asm->GetSymbolWithGlobalValueBase(MF->getFunction(), ".eh", - Asm->MAI->is_EHSymbolPrivate()); + TLOF.isFunctionEHFrameSymbolPrivate()); // Save EH frame information EHFrames.push_back(FunctionEHFrameInfo(FunctionEHSym, SubprogramCount, diff --git a/lib/CodeGen/AsmPrinter/DwarfLabel.cpp b/lib/CodeGen/AsmPrinter/DwarfLabel.cpp deleted file mode 100644 index 6e9293a..0000000 --- a/lib/CodeGen/AsmPrinter/DwarfLabel.cpp +++ /dev/null @@ -1,32 +0,0 @@ -//===--- lib/CodeGen/DwarfLabel.cpp - Dwarf Label -------------------------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// DWARF Labels -// -//===----------------------------------------------------------------------===// - -#include "DwarfLabel.h" -#include "llvm/ADT/FoldingSet.h" -#include "llvm/Support/raw_ostream.h" - -using namespace llvm; - -/// Profile - Used to gather unique data for the folding set. -/// -void DWLabel::Profile(FoldingSetNodeID &ID) const { - ID.AddString(Tag); - ID.AddInteger(Number); -} - -#ifndef NDEBUG -void DWLabel::print(raw_ostream &O) const { - O << "." << Tag; - if (Number) O << Number; -} -#endif diff --git a/lib/CodeGen/AsmPrinter/DwarfLabel.h b/lib/CodeGen/AsmPrinter/DwarfLabel.h deleted file mode 100644 index 0c0cc4b..0000000 --- a/lib/CodeGen/AsmPrinter/DwarfLabel.h +++ /dev/null @@ -1,52 +0,0 @@ -//===--- lib/CodeGen/DwarfLabel.h - Dwarf Label -----------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// DWARF Labels. -// -//===----------------------------------------------------------------------===// - -#ifndef CODEGEN_ASMPRINTER_DWARFLABEL_H__ -#define CODEGEN_ASMPRINTER_DWARFLABEL_H__ - -namespace llvm { - class FoldingSetNodeID; - class raw_ostream; - - //===--------------------------------------------------------------------===// - /// DWLabel - Labels are used to track locations in the assembler file. - /// Labels appear in the form @verbatim <prefix><Tag><Number> @endverbatim, - /// where the tag is a category of label (Ex. location) and number is a value - /// unique in that category. - class DWLabel { - /// Tag - Label category tag. Should always be a statically declared C - /// string. - /// - const char *Tag; - - /// Number - Value to make label unique. - /// - unsigned Number; - public: - DWLabel(const char *T, unsigned N) : Tag(T), Number(N) {} - - // Accessors. - const char *getTag() const { return Tag; } - unsigned getNumber() const { return Number; } - - /// Profile - Used to gather unique data for the folding set. - /// - void Profile(FoldingSetNodeID &ID) const; - -#ifndef NDEBUG - void print(raw_ostream &O) const; -#endif - }; -} // end llvm namespace - -#endif diff --git a/lib/CodeGen/AsmPrinter/DwarfPrinter.cpp b/lib/CodeGen/AsmPrinter/DwarfPrinter.cpp index 28ff0eb..7890e5c 100644 --- a/lib/CodeGen/AsmPrinter/DwarfPrinter.cpp +++ b/lib/CodeGen/AsmPrinter/DwarfPrinter.cpp @@ -31,11 +31,31 @@ #include "llvm/ADT/SmallString.h" using namespace llvm; -DwarfPrinter::DwarfPrinter(raw_ostream &OS, AsmPrinter *A, const MCAsmInfo *T, - const char *flavor) +DwarfPrinter::DwarfPrinter(raw_ostream &OS, AsmPrinter *A, const MCAsmInfo *T) : O(OS), Asm(A), MAI(T), TD(Asm->TM.getTargetData()), RI(Asm->TM.getRegisterInfo()), M(NULL), MF(NULL), MMI(NULL), - SubprogramCount(0), Flavor(flavor), SetCounter(1) {} + SubprogramCount(0) {} + + +/// getDWLabel - Return the MCSymbol corresponding to the assembler temporary +/// label with the specified stem and unique ID. +MCSymbol *DwarfPrinter::getDWLabel(const char *Name, unsigned ID) const { + // FIXME: REMOVE this. However, there is stuff in EH that passes counters in + // here that can be zero. + + //assert(ID && "Should use getTempLabel if no ID"); + if (ID == 0) return getTempLabel(Name); + return Asm->OutContext.GetOrCreateTemporarySymbol + (Twine(MAI->getPrivateGlobalPrefix()) + Twine(Name) + Twine(ID)); +} + +/// getTempLabel - Return the MCSymbol corresponding to the assembler temporary +/// label with the specified name. +MCSymbol *DwarfPrinter::getTempLabel(const char *Name) const { + return Asm->OutContext.GetOrCreateTemporarySymbol + (Twine(MAI->getPrivateGlobalPrefix()) + Name); +} + /// SizeOfEncodedValue - Return the size of the encoding in bytes. unsigned DwarfPrinter::SizeOfEncodedValue(unsigned Encoding) const { @@ -57,33 +77,6 @@ unsigned DwarfPrinter::SizeOfEncodedValue(unsigned Encoding) const { return 0; } -void DwarfPrinter::PrintRelDirective(bool Force32Bit, bool isInSection) const { - if (isInSection && MAI->getDwarfSectionOffsetDirective()) - O << MAI->getDwarfSectionOffsetDirective(); - else if (Force32Bit || TD->getPointerSize() == sizeof(int32_t)) - O << MAI->getData32bitsDirective(); - else - O << MAI->getData64bitsDirective(); -} - -void DwarfPrinter::PrintRelDirective(unsigned Encoding) const { - unsigned Size = SizeOfEncodedValue(Encoding); - assert((Size == 4 || Size == 8) && "Do not support other types or rels!"); - - O << (Size == 4 ? - MAI->getData32bitsDirective() : MAI->getData64bitsDirective()); -} - -/// EOL - Print a newline character to asm stream. If a comment is present -/// then it will be printed first. Comments should not contain '\n'. -void DwarfPrinter::EOL(const Twine &Comment) const { - if (Asm->VerboseAsm && !Comment.isTriviallyEmpty()) { - Asm->O.PadToColumn(MAI->getCommentColumn()); - Asm->O << Asm->MAI->getCommentString() << ' ' << Comment; - } - Asm->O << '\n'; -} - static const char *DecodeDWARFEncoding(unsigned Encoding) { switch (Encoding) { case dwarf::DW_EH_PE_absptr: return "absptr"; @@ -145,6 +138,7 @@ void DwarfPrinter::EmitSLEB128(int Value, const char *Desc) const { Asm->OutStreamer.AddComment(Desc); if (MAI->hasLEB128()) { + // FIXME: MCize. O << "\t.sleb128\t" << Value; Asm->OutStreamer.AddBlankLine(); return; @@ -170,6 +164,7 @@ void DwarfPrinter::EmitULEB128(unsigned Value, const char *Desc, Asm->OutStreamer.AddComment(Desc); if (MAI->hasLEB128() && PadTo == 0) { + // FIXME: MCize. O << "\t.uleb128\t" << Value; Asm->OutStreamer.AddBlankLine(); return; @@ -191,134 +186,48 @@ void DwarfPrinter::EmitULEB128(unsigned Value, const char *Desc, } -/// PrintLabelName - Print label name in form used by Dwarf writer. -/// -void DwarfPrinter::PrintLabelName(const char *Tag, unsigned Number) const { - O << MAI->getPrivateGlobalPrefix() << Tag; - if (Number) O << Number; -} -void DwarfPrinter::PrintLabelName(const char *Tag, unsigned Number, - const char *Suffix) const { - O << MAI->getPrivateGlobalPrefix() << Tag; - if (Number) O << Number; - O << Suffix; -} - -/// EmitLabel - Emit location label for internal use by Dwarf. -/// -void DwarfPrinter::EmitLabel(const char *Tag, unsigned Number) const { - PrintLabelName(Tag, Number); - O << ":\n"; -} - -/// EmitReference - Emit a reference to a label. -/// -void DwarfPrinter::EmitReference(const char *Tag, unsigned Number, - bool IsPCRelative, bool Force32Bit) const { - PrintRelDirective(Force32Bit); - PrintLabelName(Tag, Number); - if (IsPCRelative) O << "-" << MAI->getPCSymbol(); -} -void DwarfPrinter::EmitReference(const std::string &Name, bool IsPCRelative, - bool Force32Bit) const { - PrintRelDirective(Force32Bit); - O << Name; - if (IsPCRelative) O << "-" << MAI->getPCSymbol(); -} - -void DwarfPrinter::EmitReference(const MCSymbol *Sym, bool IsPCRelative, - bool Force32Bit) const { - PrintRelDirective(Force32Bit); - O << *Sym; - if (IsPCRelative) O << "-" << MAI->getPCSymbol(); -} - -void DwarfPrinter::EmitReference(const char *Tag, unsigned Number, - unsigned Encoding) const { - SmallString<64> Name; - raw_svector_ostream(Name) << MAI->getPrivateGlobalPrefix() - << Tag << Number; - - MCSymbol *Sym = Asm->OutContext.GetOrCreateSymbol(Name.str()); - EmitReference(Sym, Encoding); -} - void DwarfPrinter::EmitReference(const MCSymbol *Sym, unsigned Encoding) const { const TargetLoweringObjectFile &TLOF = Asm->getObjFileLowering(); - PrintRelDirective(Encoding); - O << *TLOF.getSymbolForDwarfReference(Sym, Asm->MMI, Encoding);; + const MCExpr *Exp = TLOF.getSymbolForDwarfReference(Sym, Asm->MMI, Encoding); + Asm->OutStreamer.EmitValue(Exp, SizeOfEncodedValue(Encoding), /*addrspace*/0); } -void DwarfPrinter::EmitReference(const GlobalValue *GV, unsigned Encoding)const { +void DwarfPrinter::EmitReference(const GlobalValue *GV, unsigned Encoding)const{ const TargetLoweringObjectFile &TLOF = Asm->getObjFileLowering(); - PrintRelDirective(Encoding); - O << *TLOF.getSymbolForDwarfGlobalReference(GV, Asm->Mang, - Asm->MMI, Encoding);; + const MCExpr *Exp = + TLOF.getSymbolForDwarfGlobalReference(GV, Asm->Mang, Asm->MMI, Encoding); + Asm->OutStreamer.EmitValue(Exp, SizeOfEncodedValue(Encoding), /*addrspace*/0); } /// EmitDifference - Emit the difference between two labels. If this assembler /// supports .set, we emit a .set of a temporary and then use it in the .word. -void DwarfPrinter::EmitDifference(const char *TagHi, unsigned NumberHi, - const char *TagLo, unsigned NumberLo, +void DwarfPrinter::EmitDifference(const MCSymbol *TagHi, const MCSymbol *TagLo, bool IsSmall) { - if (MAI->hasSetDirective()) { - // FIXME: switch to OutStreamer.EmitAssignment. - O << "\t.set\t"; - PrintLabelName("set", SetCounter, Flavor); - O << ","; - PrintLabelName(TagHi, NumberHi); - O << "-"; - PrintLabelName(TagLo, NumberLo); - O << "\n"; - - PrintRelDirective(IsSmall); - PrintLabelName("set", SetCounter, Flavor); - ++SetCounter; - } else { - PrintRelDirective(IsSmall); - PrintLabelName(TagHi, NumberHi); - O << "-"; - PrintLabelName(TagLo, NumberLo); - } + unsigned Size = IsSmall ? 4 : TD->getPointerSize(); + Asm->EmitLabelDifference(TagHi, TagLo, Size); } -void DwarfPrinter::EmitSectionOffset(const char* Label, const char* Section, - unsigned LabelNumber, - unsigned SectionNumber, - bool IsSmall, bool isEH, - bool useSet) { - bool printAbsolute = false; +void DwarfPrinter::EmitSectionOffset(const MCSymbol *Label, + const MCSymbol *Section, + bool IsSmall, bool isEH) { + bool isAbsolute; if (isEH) - printAbsolute = MAI->isAbsoluteEHSectionOffsets(); + isAbsolute = MAI->isAbsoluteEHSectionOffsets(); else - printAbsolute = MAI->isAbsoluteDebugSectionOffsets(); - - if (MAI->hasSetDirective() && useSet) { - // FIXME: switch to OutStreamer.EmitAssignment. - O << "\t.set\t"; - PrintLabelName("set", SetCounter, Flavor); - O << ","; - PrintLabelName(Label, LabelNumber); - - if (!printAbsolute) { - O << "-"; - PrintLabelName(Section, SectionNumber); - } + isAbsolute = MAI->isAbsoluteDebugSectionOffsets(); - O << "\n"; - PrintRelDirective(IsSmall); - PrintLabelName("set", SetCounter, Flavor); - ++SetCounter; - } else { - PrintRelDirective(IsSmall, true); - PrintLabelName(Label, LabelNumber); - - if (!printAbsolute) { - O << "-"; - PrintLabelName(Section, SectionNumber); - } + if (!isAbsolute) + return EmitDifference(Label, Section, IsSmall); + + // On COFF targets, we have to emit the weird .secrel32 directive. + if (const char *SecOffDir = MAI->getDwarfSectionOffsetDirective()) + // FIXME: MCize. + Asm->O << SecOffDir << Label->getName(); + else { + unsigned Size = IsSmall ? 4 : TD->getPointerSize(); + Asm->OutStreamer.EmitSymbolValue(Label, Size, 0/*AddrSpace*/); } } @@ -337,12 +246,9 @@ void DwarfPrinter::EmitFrameMoves(const char *BaseLabel, unsigned BaseLabelID, const MachineMove &Move = Moves[i]; unsigned LabelID = Move.getLabelID(); - if (LabelID) { - LabelID = MMI->MappedLabel(LabelID); - - // Throw out move if the label is invalid. - if (!LabelID) continue; - } + // Throw out move if the label is invalid. + if (LabelID && MMI->isLabelDeleted(LabelID)) + continue; const MachineLocation &Dst = Move.getDestination(); const MachineLocation &Src = Move.getSource(); @@ -350,9 +256,8 @@ void DwarfPrinter::EmitFrameMoves(const char *BaseLabel, unsigned BaseLabelID, // Advance row if new location. if (BaseLabel && LabelID && (BaseLabelID != LabelID || !IsLocal)) { EmitCFAByte(dwarf::DW_CFA_advance_loc4); - EmitDifference("label", LabelID, BaseLabel, BaseLabelID, true); - Asm->O << '\n'; - + EmitDifference(getDWLabel("label", LabelID), + getDWLabel(BaseLabel, BaseLabelID), true); BaseLabelID = LabelID; BaseLabel = "label"; IsLocal = true; diff --git a/lib/CodeGen/AsmPrinter/DwarfPrinter.h b/lib/CodeGen/AsmPrinter/DwarfPrinter.h index bd715f2..5e2d806 100644 --- a/lib/CodeGen/AsmPrinter/DwarfPrinter.h +++ b/lib/CodeGen/AsmPrinter/DwarfPrinter.h @@ -14,7 +14,6 @@ #ifndef CODEGEN_ASMPRINTER_DWARFPRINTER_H__ #define CODEGEN_ASMPRINTER_DWARFPRINTER_H__ -#include "DwarfLabel.h" #include "llvm/CodeGen/MachineLocation.h" #include "llvm/Support/Compiler.h" #include "llvm/Support/FormattedStream.h" @@ -67,15 +66,7 @@ protected: /// SubprogramCount - The running count of functions being compiled. unsigned SubprogramCount; - /// Flavor - A unique string indicating what dwarf producer this is, used to - /// unique labels. - const char * const Flavor; - - /// SetCounter - A unique number for each '.set' directive. - unsigned SetCounter; - - DwarfPrinter(raw_ostream &OS, AsmPrinter *A, const MCAsmInfo *T, - const char *flavor); + DwarfPrinter(raw_ostream &OS, AsmPrinter *A, const MCAsmInfo *T); public: //===------------------------------------------------------------------===// @@ -86,17 +77,17 @@ public: const MCAsmInfo *getMCAsmInfo() const { return MAI; } const TargetData *getTargetData() const { return TD; } + /// getDWLabel - Return the MCSymbol corresponding to the assembler temporary + /// label with the specified stem and unique ID. + MCSymbol *getDWLabel(const char *Name, unsigned ID) const; + + /// getTempLabel - Return an assembler temporary label with the specified + /// name. + MCSymbol *getTempLabel(const char *Name) const; + /// SizeOfEncodedValue - Return the size of the encoding in bytes. unsigned SizeOfEncodedValue(unsigned Encoding) const; - void PrintRelDirective(unsigned Encoding) const; - void PrintRelDirective(bool Force32Bit = false, - bool isInSection = false) const; - - /// EOL - Print a newline character to asm stream. If a comment is present - /// then it will be printed first. Comments should not contain '\n'. - void EOL(const Twine &Comment) const; - /// EmitEncodingByte - Emit a .byte 42 directive that corresponds to an /// encoding. If verbose assembly output is enabled, we output comments /// describing the encoding. Desc is a string saying what the encoding is @@ -115,57 +106,20 @@ public: unsigned PadTo = 0) const; - /// PrintLabelName - Print label name in form used by Dwarf writer. - /// - void PrintLabelName(const DWLabel &Label) const { - PrintLabelName(Label.getTag(), Label.getNumber()); - } - void PrintLabelName(const char *Tag, unsigned Number) const; - void PrintLabelName(const char *Tag, unsigned Number, - const char *Suffix) const; - - /// EmitLabel - Emit location label for internal use by Dwarf. - /// - void EmitLabel(const DWLabel &Label) const { - EmitLabel(Label.getTag(), Label.getNumber()); - } - void EmitLabel(const char *Tag, unsigned Number) const; - /// EmitReference - Emit a reference to a label. /// - void EmitReference(const DWLabel &Label, bool IsPCRelative = false, - bool Force32Bit = false) const { - EmitReference(Label.getTag(), Label.getNumber(), - IsPCRelative, Force32Bit); - } - void EmitReference(const char *Tag, unsigned Number, - bool IsPCRelative = false, - bool Force32Bit = false) const; - void EmitReference(const std::string &Name, bool IsPCRelative = false, - bool Force32Bit = false) const; - void EmitReference(const MCSymbol *Sym, bool IsPCRelative = false, - bool Force32Bit = false) const; - - void EmitReference(const char *Tag, unsigned Number, unsigned Encoding) const; void EmitReference(const MCSymbol *Sym, unsigned Encoding) const; void EmitReference(const GlobalValue *GV, unsigned Encoding) const; /// EmitDifference - Emit the difference between two labels. - void EmitDifference(const DWLabel &LabelHi, const DWLabel &LabelLo, - bool IsSmall = false) { - EmitDifference(LabelHi.getTag(), LabelHi.getNumber(), - LabelLo.getTag(), LabelLo.getNumber(), - IsSmall); - } - void EmitDifference(const char *TagHi, unsigned NumberHi, - const char *TagLo, unsigned NumberLo, + void EmitDifference(const MCSymbol *LabelHi, const MCSymbol *LabelLo, bool IsSmall = false); - void EmitSectionOffset(const char* Label, const char* Section, - unsigned LabelNumber, unsigned SectionNumber, - bool IsSmall = false, bool isEH = false, - bool useSet = true); - + /// EmitSectionOffset - Emit Label-Section or use a special purpose directive + /// to emit a section offset if the target has one. + void EmitSectionOffset(const MCSymbol *Label, const MCSymbol *Section, + bool IsSmall = false, bool isEH = false); + /// EmitFrameMoves - Emit frame instructions to describe the layout of the /// frame. void EmitFrameMoves(const char *BaseLabel, unsigned BaseLabelID, diff --git a/lib/CodeGen/AsmPrinter/DwarfWriter.cpp b/lib/CodeGen/AsmPrinter/DwarfWriter.cpp index 08e1bbc..9fd4c44 100644 --- a/lib/CodeGen/AsmPrinter/DwarfWriter.cpp +++ b/lib/CodeGen/AsmPrinter/DwarfWriter.cpp @@ -73,11 +73,11 @@ void DwarfWriter::EndFunction(const MachineFunction *MF) { MMI->EndFunction(); } -/// RecordSourceLine - Records location information and associates it with a -/// label. Returns a unique label ID used to generate a label and provide -/// correspondence to the source line list. -unsigned DwarfWriter::RecordSourceLine(unsigned Line, unsigned Col, - MDNode *Scope) { +/// RecordSourceLine - Register a source line with debug info. Returns the +/// unique label that was emitted and which provides correspondence to +/// the source line list. +MCSymbol *DwarfWriter::RecordSourceLine(unsigned Line, unsigned Col, + MDNode *Scope) { return DD->recordSourceLine(Line, Col, Scope); } @@ -92,7 +92,7 @@ bool DwarfWriter::ShouldEmitDwarfDebug() const { return DD && DD->ShouldEmitDwarfDebug(); } -void DwarfWriter::BeginScope(const MachineInstr *MI, unsigned L) { +void DwarfWriter::BeginScope(const MachineInstr *MI, MCSymbol *L) { DD->beginScope(MI, L); } void DwarfWriter::EndScope(const MachineInstr *MI) { diff --git a/lib/CodeGen/BranchFolding.cpp b/lib/CodeGen/BranchFolding.cpp index d94729a..889763a 100644 --- a/lib/CodeGen/BranchFolding.cpp +++ b/lib/CodeGen/BranchFolding.cpp @@ -310,12 +310,23 @@ static unsigned HashEndOfMBB(const MachineBasicBlock *MBB, return 0; // Empty MBB. --I; + // Skip debug info so it will not affect codegen. + while (I->isDebugValue()) { + if (I==MBB->begin()) + return 0; // MBB empty except for debug info. + --I; + } unsigned Hash = HashMachineInstr(I); if (I == MBB->begin() || minCommonTailLength == 1) return Hash; // Single instr MBB. --I; + while (I->isDebugValue()) { + if (I==MBB->begin()) + return Hash; // MBB with single non-debug instr. + --I; + } // Hash in the second-to-last instruction. Hash ^= HashMachineInstr(I) << 2; return Hash; @@ -334,9 +345,32 @@ static unsigned ComputeCommonTailLength(MachineBasicBlock *MBB1, unsigned TailLen = 0; while (I1 != MBB1->begin() && I2 != MBB2->begin()) { --I1; --I2; - // Don't merge debugging pseudos. - if (I1->isDebugValue() || I2->isDebugValue() || - !I1->isIdenticalTo(I2) || + // Skip debugging pseudos; necessary to avoid changing the code. + while (I1->isDebugValue()) { + if (I1==MBB1->begin()) { + while (I2->isDebugValue()) { + if (I2==MBB2->begin()) + // I1==DBG at begin; I2==DBG at begin + return TailLen; + --I2; + } + ++I2; + // I1==DBG at begin; I2==non-DBG, or first of DBGs not at begin + return TailLen; + } + --I1; + } + // I1==first (untested) non-DBG preceding known match + while (I2->isDebugValue()) { + if (I2==MBB2->begin()) { + ++I1; + // I1==non-DBG, or first of DBGs not at begin; I2==DBG at begin + return TailLen; + } + --I2; + } + // I1, I2==first (untested) non-DBGs preceding known match + if (!I1->isIdenticalTo(I2) || // FIXME: This check is dubious. It's used to get around a problem where // people incorrectly expect inline asm directives to remain in the same // relative order. This is untenable because normal compiler @@ -348,6 +382,29 @@ static unsigned ComputeCommonTailLength(MachineBasicBlock *MBB1, } ++TailLen; } + // Back past possible debugging pseudos at beginning of block. This matters + // when one block differs from the other only by whether debugging pseudos + // are present at the beginning. (This way, the various checks later for + // I1==MBB1->begin() work as expected.) + if (I1 == MBB1->begin() && I2 != MBB2->begin()) { + --I2; + while (I2->isDebugValue()) { + if (I2 == MBB2->begin()) { + return TailLen; + } + --I2; + } + ++I2; + } + if (I2 == MBB2->begin() && I1 != MBB1->begin()) { + --I1; + while (I1->isDebugValue()) { + if (I1 == MBB1->begin()) + return TailLen; + --I1; + } + ++I1; + } return TailLen; } @@ -643,6 +700,8 @@ unsigned BranchFolder::CreateCommonTailOnlyBlock(MachineBasicBlock *&PredBB, SameTails[commonTailIndex].getTailStartPos(); MachineBasicBlock *MBB = SameTails[commonTailIndex].getBlock(); + // If the common tail includes any debug info we will take it pretty + // randomly from one of the inputs. Might be better to remove it? DEBUG(dbgs() << "\nSplitting BB#" << MBB->getNumber() << ", size " << maxCommonTailLength); @@ -912,6 +971,18 @@ bool BranchFolder::OptimizeBranches(MachineFunction &MF) { return MadeChange; } +// Blocks should be considered empty if they contain only debug info; +// else the debug info would affect codegen. +static bool IsEmptyBlock(MachineBasicBlock *MBB) { + if (MBB->empty()) + return true; + for (MachineBasicBlock::iterator MBBI = MBB->begin(), MBBE = MBB->end(); + MBBI!=MBBE; ++MBBI) { + if (!MBBI->isDebugValue()) + return false; + } + return true; +} /// IsBetterFallthrough - Return true if it would be clearly better to /// fall-through to MBB1 than to fall through into MBB2. This has to return @@ -949,7 +1020,7 @@ ReoptimizeBlock: // explicitly. Landing pads should not do this since the landing-pad table // points to this block. Blocks with their addresses taken shouldn't be // optimized away. - if (MBB->empty() && !MBB->isLandingPad() && !MBB->hasAddressTaken()) { + if (IsEmptyBlock(MBB) && !MBB->isLandingPad() && !MBB->hasAddressTaken()) { // Dead block? Leave for cleanup later. if (MBB->pred_empty()) return MadeChange; @@ -1141,7 +1212,23 @@ ReoptimizeBlock: // be 'non-branch terminators' in the block, try removing the branch and // then seeing if the block is empty. TII->RemoveBranch(*MBB); - + // If the only things remaining in the block are debug info, remove these + // as well, so this will behave the same as an empty block in non-debug + // mode. + if (!MBB->empty()) { + bool NonDebugInfoFound = false; + for (MachineBasicBlock::iterator I = MBB->begin(), E = MBB->end(); + I != E; ++I) { + if (!I->isDebugValue()) { + NonDebugInfoFound = true; + break; + } + } + if (!NonDebugInfoFound) + // Make the block empty, losing the debug info (we could probably + // improve this in some cases.) + MBB->erase(MBB->begin(), MBB->end()); + } // If this block is just an unconditional branch to CurTBB, we can // usually completely eliminate the block. The only case we cannot // completely eliminate the block is when the block before this one diff --git a/lib/CodeGen/LLVMTargetMachine.cpp b/lib/CodeGen/LLVMTargetMachine.cpp index 5e88865..9bc0b71 100644 --- a/lib/CodeGen/LLVMTargetMachine.cpp +++ b/lib/CodeGen/LLVMTargetMachine.cpp @@ -67,9 +67,6 @@ static cl::opt<bool> VerifyMachineCode("verify-machineinstrs", cl::Hidden, cl::desc("Verify generated machine code"), cl::init(getenv("LLVM_VERIFY_MACHINEINSTRS")!=NULL)); -static cl::opt<bool> EnableMachineCSE("enable-machine-cse", cl::Hidden, - cl::desc("Enable Machine CSE")); - static cl::opt<cl::boolOrDefault> AsmVerbose("asm-verbose", cl::desc("Add comments to directives."), cl::init(cl::BOU_UNSET)); @@ -328,11 +325,10 @@ bool LLVMTargetMachine::addCommonCodeGenPasses(PassManagerBase &PM, PM.add(createOptimizeExtsPass()); if (!DisableMachineLICM) PM.add(createMachineLICMPass()); - if (EnableMachineCSE) - PM.add(createMachineCSEPass()); + PM.add(createMachineCSEPass()); if (!DisableMachineSink) PM.add(createMachineSinkingPass()); - printAndVerify(PM, "After MachineLICM and MachineSinking", + printAndVerify(PM, "After Machine LICM, CSE and Sinking passes", /* allowDoubleDefs= */ true); } diff --git a/lib/CodeGen/LiveIntervalAnalysis.cpp b/lib/CodeGen/LiveIntervalAnalysis.cpp index ccda66f..f8b1707 100644 --- a/lib/CodeGen/LiveIntervalAnalysis.cpp +++ b/lib/CodeGen/LiveIntervalAnalysis.cpp @@ -593,13 +593,10 @@ void LiveIntervals::handleLiveInRegister(MachineBasicBlock *MBB, MachineBasicBlock::iterator E = MBB->end(); while (mi != E) { - if (mi->isDebugValue()) { + while (mi != E && mi->isDebugValue()) ++mi; - if (mi != E && !mi->isDebugValue()) { - baseIndex = indexes_->getNextNonNullIndex(baseIndex); - } - continue; - } + if (mi == E) + break; if (mi->killsRegister(interval.reg, tri_)) { DEBUG(dbgs() << " killed"); end = baseIndex.getDefIndex(); diff --git a/lib/CodeGen/MachineBasicBlock.cpp b/lib/CodeGen/MachineBasicBlock.cpp index 64134ce..32b1a7d 100644 --- a/lib/CodeGen/MachineBasicBlock.cpp +++ b/lib/CodeGen/MachineBasicBlock.cpp @@ -42,12 +42,11 @@ MachineBasicBlock::~MachineBasicBlock() { /// getSymbol - Return the MCSymbol for this basic block. /// MCSymbol *MachineBasicBlock::getSymbol(MCContext &Ctx) const { - SmallString<60> Name; const MachineFunction *MF = getParent(); - raw_svector_ostream(Name) - << MF->getTarget().getMCAsmInfo()->getPrivateGlobalPrefix() << "BB" - << MF->getFunctionNumber() << '_' << getNumber(); - return Ctx.GetOrCreateSymbol(Name.str()); + const char *Prefix = MF->getTarget().getMCAsmInfo()->getPrivateGlobalPrefix(); + return Ctx.GetOrCreateTemporarySymbol(Twine(Prefix) + "BB" + + Twine(MF->getFunctionNumber()) + "_" + + Twine(getNumber())); } diff --git a/lib/CodeGen/MachineCSE.cpp b/lib/CodeGen/MachineCSE.cpp index b376e3d..ce95d8d 100644 --- a/lib/CodeGen/MachineCSE.cpp +++ b/lib/CodeGen/MachineCSE.cpp @@ -33,9 +33,9 @@ namespace { class MachineCSE : public MachineFunctionPass { const TargetInstrInfo *TII; const TargetRegisterInfo *TRI; - MachineRegisterInfo *MRI; - MachineDominatorTree *DT; AliasAnalysis *AA; + MachineDominatorTree *DT; + MachineRegisterInfo *MRI; public: static char ID; // Pass identification MachineCSE() : MachineFunctionPass(&ID), CurrVN(0) {} @@ -61,6 +61,8 @@ namespace { MachineBasicBlock::const_iterator E); bool hasLivePhysRegDefUse(MachineInstr *MI, MachineBasicBlock *MBB); bool isCSECandidate(MachineInstr *MI); + bool isProfitableToCSE(unsigned CSReg, unsigned Reg, + MachineInstr *CSMI, MachineInstr *MI); bool ProcessBlock(MachineDomTreeNode *Node); }; } // end anonymous namespace @@ -92,7 +94,16 @@ bool MachineCSE::PerformTrivialCoalescing(MachineInstr *MI, if (TII->isMoveInstr(*DefMI, SrcReg, DstReg, SrcSubIdx, DstSubIdx) && TargetRegisterInfo::isVirtualRegister(SrcReg) && !SrcSubIdx && !DstSubIdx) { + const TargetRegisterClass *SRC = MRI->getRegClass(SrcReg); + const TargetRegisterClass *RC = MRI->getRegClass(Reg); + const TargetRegisterClass *NewRC = getCommonSubClass(RC, SRC); + if (!NewRC) + continue; + DEBUG(dbgs() << "Coalescing: " << *DefMI); + DEBUG(dbgs() << "*** to: " << *MI); MO.setReg(SrcReg); + if (NewRC != SRC) + MRI->setRegClass(SrcReg, NewRC); DefMI->eraseFromParent(); ++NumCoalesces; Changed = true; @@ -133,6 +144,8 @@ bool MachineCSE::isPhysDefTriviallyDead(unsigned Reg, return false; } +/// hasLivePhysRegDefUse - Return true if the specified instruction read / write +/// physical registers (except for dead defs of physical registers). bool MachineCSE::hasLivePhysRegDefUse(MachineInstr *MI, MachineBasicBlock *MBB){ unsigned PhysDef = 0; for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { @@ -167,12 +180,19 @@ bool MachineCSE::hasLivePhysRegDefUse(MachineInstr *MI, MachineBasicBlock *MBB){ return false; } -bool MachineCSE::isCSECandidate(MachineInstr *MI) { - // Ignore copies or instructions that read / write physical registers - // (except for dead defs of physical registers). +static bool isCopy(const MachineInstr *MI, const TargetInstrInfo *TII) { unsigned SrcReg, DstReg, SrcSubIdx, DstSubIdx; - if (TII->isMoveInstr(*MI, SrcReg, DstReg, SrcSubIdx, DstSubIdx) || - MI->isExtractSubreg() || MI->isInsertSubreg() || MI->isSubregToReg()) + return TII->isMoveInstr(*MI, SrcReg, DstReg, SrcSubIdx, DstSubIdx) || + MI->isExtractSubreg() || MI->isInsertSubreg() || MI->isSubregToReg(); +} + +bool MachineCSE::isCSECandidate(MachineInstr *MI) { + if (MI->isLabel() || MI->isPHI() || MI->isImplicitDef() || + MI->isKill() || MI->isInlineAsm()) + return false; + + // Ignore copies. + if (isCopy(MI, TII)) return false; // Ignore stuff that we obviously can't move. @@ -194,9 +214,69 @@ bool MachineCSE::isCSECandidate(MachineInstr *MI) { return true; } +/// isProfitableToCSE - Return true if it's profitable to eliminate MI with a +/// common expression that defines Reg. +bool MachineCSE::isProfitableToCSE(unsigned CSReg, unsigned Reg, + MachineInstr *CSMI, MachineInstr *MI) { + // FIXME: Heuristics that works around the lack the live range splitting. + + // Heuristics #1: Don't cse "cheap" computating if the def is not local or in an + // immediate predecessor. We don't want to increase register pressure and end up + // causing other computation to be spilled. + if (MI->getDesc().isAsCheapAsAMove()) { + MachineBasicBlock *CSBB = CSMI->getParent(); + MachineBasicBlock *BB = MI->getParent(); + if (CSBB != BB && + find(CSBB->succ_begin(), CSBB->succ_end(), BB) == CSBB->succ_end()) + return false; + } + + // Heuristics #2: If the expression doesn't not use a vr and the only use + // of the redundant computation are copies, do not cse. + bool HasVRegUse = false; + for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { + const MachineOperand &MO = MI->getOperand(i); + if (MO.isReg() && MO.isUse() && MO.getReg() && + TargetRegisterInfo::isVirtualRegister(MO.getReg())) { + HasVRegUse = true; + break; + } + } + if (!HasVRegUse) { + bool HasNonCopyUse = false; + for (MachineRegisterInfo::use_nodbg_iterator I = MRI->use_nodbg_begin(Reg), + E = MRI->use_nodbg_end(); I != E; ++I) { + MachineInstr *Use = &*I; + // Ignore copies. + if (!isCopy(Use, TII)) { + HasNonCopyUse = true; + break; + } + } + if (!HasNonCopyUse) + return false; + } + + // Heuristics #3: If the common subexpression is used by PHIs, do not reuse + // it unless the defined value is already used in the BB of the new use. + bool HasPHI = false; + SmallPtrSet<MachineBasicBlock*, 4> CSBBs; + for (MachineRegisterInfo::use_nodbg_iterator I = MRI->use_nodbg_begin(CSReg), + E = MRI->use_nodbg_end(); I != E; ++I) { + MachineInstr *Use = &*I; + HasPHI |= Use->isPHI(); + CSBBs.insert(Use->getParent()); + } + + if (!HasPHI) + return true; + return CSBBs.count(MI->getParent()); +} + bool MachineCSE::ProcessBlock(MachineDomTreeNode *Node) { bool Changed = false; + SmallVector<std::pair<unsigned, unsigned>, 8> CSEPairs; ScopedHashTableScope<MachineInstr*, unsigned, MachineInstrExpressionTrait> VNTS(VNT); MachineBasicBlock *MBB = Node->getBlock(); @@ -231,6 +311,9 @@ bool MachineCSE::ProcessBlock(MachineDomTreeNode *Node) { MachineInstr *CSMI = Exps[CSVN]; DEBUG(dbgs() << "Examining: " << *MI); DEBUG(dbgs() << "*** Found a common subexpression: " << *CSMI); + + // Check if it's profitable to perform this CSE. + bool DoCSE = true; unsigned NumDefs = MI->getDesc().getNumDefs(); for (unsigned i = 0, e = MI->getNumOperands(); NumDefs && i != e; ++i) { MachineOperand &MO = MI->getOperand(i); @@ -243,11 +326,26 @@ bool MachineCSE::ProcessBlock(MachineDomTreeNode *Node) { assert(TargetRegisterInfo::isVirtualRegister(OldReg) && TargetRegisterInfo::isVirtualRegister(NewReg) && "Do not CSE physical register defs!"); - MRI->replaceRegWith(OldReg, NewReg); + if (!isProfitableToCSE(NewReg, OldReg, CSMI, MI)) { + DoCSE = false; + break; + } + CSEPairs.push_back(std::make_pair(OldReg, NewReg)); --NumDefs; } - MI->eraseFromParent(); - ++NumCSEs; + + // Actually perform the elimination. + if (DoCSE) { + for (unsigned i = 0, e = CSEPairs.size(); i != e; ++i) + MRI->replaceRegWith(CSEPairs[i].first, CSEPairs[i].second); + MI->eraseFromParent(); + ++NumCSEs; + } else { + DEBUG(dbgs() << "*** Not profitable, avoid CSE!\n"); + VNT.insert(MI, CurrVN++); + Exps.push_back(MI); + } + CSEPairs.clear(); } // Recursively call ProcessBlock with childred. @@ -262,7 +360,7 @@ bool MachineCSE::runOnMachineFunction(MachineFunction &MF) { TII = MF.getTarget().getInstrInfo(); TRI = MF.getTarget().getRegisterInfo(); MRI = &MF.getRegInfo(); - DT = &getAnalysis<MachineDominatorTree>(); AA = &getAnalysis<AliasAnalysis>(); + DT = &getAnalysis<MachineDominatorTree>(); return ProcessBlock(DT->getRootNode()); } diff --git a/lib/CodeGen/MachineFunction.cpp b/lib/CodeGen/MachineFunction.cpp index 4377d5b..1e3cb1e 100644 --- a/lib/CodeGen/MachineFunction.cpp +++ b/lib/CodeGen/MachineFunction.cpp @@ -464,7 +464,9 @@ MCSymbol *MachineFunction::getJTISymbol(unsigned JTI, MCContext &Ctx, SmallString<60> Name; raw_svector_ostream(Name) << Prefix << "JTI" << getFunctionNumber() << '_' << JTI; - return Ctx.GetOrCreateSymbol(Name.str()); + if (isLinkerPrivate) + return Ctx.GetOrCreateSymbol(Name.str()); + return Ctx.GetOrCreateTemporarySymbol(Name.str()); } diff --git a/lib/CodeGen/MachineInstr.cpp b/lib/CodeGen/MachineInstr.cpp index e23670d..4c7cb8f 100644 --- a/lib/CodeGen/MachineInstr.cpp +++ b/lib/CodeGen/MachineInstr.cpp @@ -1219,7 +1219,7 @@ void MachineInstr::print(raw_ostream &OS, const TargetMachine *TM) const { DIScope Scope = DLT.getScope(); OS << " dbg:"; // Omit the directory, since it's usually long and uninteresting. - if (!Scope.isNull()) + if (Scope.Verify()) OS << Scope.getFilename(); else OS << "<unknown>"; diff --git a/lib/CodeGen/MachineModuleInfo.cpp b/lib/CodeGen/MachineModuleInfo.cpp index 5052af7..72fb9fd 100644 --- a/lib/CodeGen/MachineModuleInfo.cpp +++ b/lib/CodeGen/MachineModuleInfo.cpp @@ -185,7 +185,8 @@ void MachineModuleInfo::addCleanup(MachineBasicBlock *LandingPad) { void MachineModuleInfo::TidyLandingPads() { for (unsigned i = 0; i != LandingPads.size(); ) { LandingPadInfo &LandingPad = LandingPads[i]; - LandingPad.LandingPadLabel = MappedLabel(LandingPad.LandingPadLabel); + if (isLabelDeleted(LandingPad.LandingPadLabel)) + LandingPad.LandingPadLabel = 0; // Special case: we *should* emit LPs with null LP MBB. This indicates // "nounwind" case. @@ -195,17 +196,14 @@ void MachineModuleInfo::TidyLandingPads() { } for (unsigned j=0; j != LandingPads[i].BeginLabels.size(); ) { - unsigned BeginLabel = MappedLabel(LandingPad.BeginLabels[j]); - unsigned EndLabel = MappedLabel(LandingPad.EndLabels[j]); - - if (!BeginLabel || !EndLabel) { + unsigned BeginLabel = LandingPad.BeginLabels[j]; + unsigned EndLabel = LandingPad.EndLabels[j]; + if (isLabelDeleted(BeginLabel) || isLabelDeleted(EndLabel)) { LandingPad.BeginLabels.erase(LandingPad.BeginLabels.begin() + j); LandingPad.EndLabels.erase(LandingPad.EndLabels.begin() + j); continue; } - LandingPad.BeginLabels[j] = BeginLabel; - LandingPad.EndLabels[j] = EndLabel; ++j; } diff --git a/lib/CodeGen/PrologEpilogInserter.cpp b/lib/CodeGen/PrologEpilogInserter.cpp index 138e711..2d54cd4 100644 --- a/lib/CodeGen/PrologEpilogInserter.cpp +++ b/lib/CodeGen/PrologEpilogInserter.cpp @@ -57,6 +57,7 @@ bool PEI::runOnMachineFunction(MachineFunction &Fn) { const TargetRegisterInfo *TRI = Fn.getTarget().getRegisterInfo(); RS = TRI->requiresRegisterScavenging(Fn) ? new RegScavenger() : NULL; FrameIndexVirtualScavenging = TRI->requiresFrameIndexScavenging(Fn); + FrameConstantRegMap.clear(); // Get MachineModuleInfo so that we can track the construction of the // frame. @@ -685,7 +686,7 @@ void PEI::replaceFrameIndices(MachineFunction &Fn) { // If this instruction has a FrameIndex operand, we need to // use that target machine register info object to eliminate // it. - int Value; + TargetRegisterInfo::FrameIndexValue Value; unsigned VReg = TRI.eliminateFrameIndex(MI, SPAdj, &Value, FrameIndexVirtualScavenging ? NULL : RS); @@ -764,12 +765,12 @@ void PEI::scavengeFrameVirtualRegs(MachineFunction &Fn) { unsigned CurrentVirtReg = 0; unsigned CurrentScratchReg = 0; bool havePrevValue = false; - int PrevValue = 0; + TargetRegisterInfo::FrameIndexValue PrevValue(0,0); + TargetRegisterInfo::FrameIndexValue Value(0,0); MachineInstr *PrevLastUseMI = NULL; unsigned PrevLastUseOp = 0; bool trackingCurrentValue = false; int SPAdj = 0; - int Value = 0; // The instruction stream may change in the loop, so check BB->end() // directly. @@ -826,8 +827,11 @@ void PEI::scavengeFrameVirtualRegs(MachineFunction &Fn) { if (trackingCurrentValue) { SPAdj = (*Entry).second.second; Value = (*Entry).second.first; - } else - SPAdj = Value = 0; + } else { + SPAdj = 0; + Value.first = 0; + Value.second = 0; + } // If the scratch register from the last allocation is still // available, see if the value matches. If it does, just re-use it. diff --git a/lib/CodeGen/PrologEpilogInserter.h b/lib/CodeGen/PrologEpilogInserter.h index 931f1eb..aa95773 100644 --- a/lib/CodeGen/PrologEpilogInserter.h +++ b/lib/CodeGen/PrologEpilogInserter.h @@ -102,7 +102,8 @@ namespace llvm { // When using the scavenger post-pass to resolve frame reference // materialization registers, maintain a map of the registers to // the constant value and SP adjustment associated with it. - typedef std::pair<int, int> FrameConstantEntry; + typedef std::pair<TargetRegisterInfo::FrameIndexValue, int> + FrameConstantEntry; DenseMap<unsigned, FrameConstantEntry> FrameConstantRegMap; #ifndef NDEBUG diff --git a/lib/CodeGen/SelectionDAG/SDDbgValue.h b/lib/CodeGen/SelectionDAG/SDDbgValue.h index 9e15fc9..d43a044 100644 --- a/lib/CodeGen/SelectionDAG/SDDbgValue.h +++ b/lib/CodeGen/SelectionDAG/SDDbgValue.h @@ -34,14 +34,16 @@ class SDDbgValue { MDNode *mdPtr; uint64_t Offset; DebugLoc DL; + unsigned Order; public: // Constructor for non-constants. - SDDbgValue(MDNode *mdP, SDNode *N, unsigned R, uint64_t off, DebugLoc dl) : - Node(N), ResNo(R), Const(0), mdPtr(mdP), Offset(off), DL(dl) {} + SDDbgValue(MDNode *mdP, SDNode *N, unsigned R, uint64_t off, DebugLoc dl, + unsigned O) : + Node(N), ResNo(R), Const(0), mdPtr(mdP), Offset(off), DL(dl), Order(O) {} // Constructor for constants. - SDDbgValue(MDNode *mdP, Value *C, uint64_t off, DebugLoc dl) : Node(0), - ResNo(0), Const(C), mdPtr(mdP), Offset(off), DL(dl) {} + SDDbgValue(MDNode *mdP, Value *C, uint64_t off, DebugLoc dl, unsigned O) : + Node(0), ResNo(0), Const(C), mdPtr(mdP), Offset(off), DL(dl), Order(O) {} // Returns the MDNode pointer. MDNode *getMDPtr() { return mdPtr; } @@ -60,6 +62,10 @@ public: // Returns the DebugLoc. DebugLoc getDebugLoc() { return DL; } + + // Returns the SDNodeOrder. This is the order of the preceding node in the + // input. + unsigned getOrder() { return Order; } }; } // end llvm namespace diff --git a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp index 023e486..746d4e2 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp @@ -3208,7 +3208,7 @@ bool MeetsMaxMemopRequirement(std::vector<EVT> &MemOps, bool isSrcConst = isa<ConstantSDNode>(Src); EVT VT = TLI.getOptimalMemOpType(Size, Align, isSrcConst, isSrcStr, DAG); bool AllowUnalign = TLI.allowsUnalignedMemoryAccesses(VT); - if (VT != MVT::iAny) { + if (VT != MVT::Other) { const Type *Ty = VT.getTypeForEVT(*DAG.getContext()); unsigned NewAlign = (unsigned) TLI.getTargetData()->getABITypeAlignment(Ty); // If source is a string constant, this will require an unaligned load. @@ -3216,14 +3216,14 @@ bool MeetsMaxMemopRequirement(std::vector<EVT> &MemOps, if (Dst.getOpcode() != ISD::FrameIndex) { // Can't change destination alignment. It requires a unaligned store. if (AllowUnalign) - VT = MVT::iAny; + VT = MVT::Other; } else { int FI = cast<FrameIndexSDNode>(Dst)->getIndex(); MachineFrameInfo *MFI = DAG.getMachineFunction().getFrameInfo(); if (MFI->isFixedObjectIndex(FI)) { // Can't change destination alignment. It requires a unaligned store. if (AllowUnalign) - VT = MVT::iAny; + VT = MVT::Other; } else { // Give the stack frame object a larger alignment if needed. if (MFI->getObjectAlignment(FI) < NewAlign) @@ -3234,7 +3234,7 @@ bool MeetsMaxMemopRequirement(std::vector<EVT> &MemOps, } } - if (VT == MVT::iAny) { + if (VT == MVT::Other) { if (TLI.allowsUnalignedMemoryAccesses(MVT::i64)) { VT = MVT::i64; } else { diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp index 05f9f1f..a82f0f7 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp @@ -2141,6 +2141,9 @@ SelectCodeCommon(SDNode *NodeToMatch, const unsigned char *MatcherTable, while (1) { assert(MatcherIndex < TableSize && "Invalid index"); +#ifndef NDEBUG + unsigned CurrentOpcodeIndex = MatcherIndex; +#endif BuiltinOpcodes Opcode = (BuiltinOpcodes)MatcherTable[MatcherIndex++]; switch (Opcode) { case OPC_Scope: { @@ -2666,6 +2669,7 @@ SelectCodeCommon(SDNode *NodeToMatch, const unsigned char *MatcherTable, // If the code reached this point, then the match failed. See if there is // another child to try in the current 'Scope', otherwise pop it until we // find a case to check. + DEBUG(errs() << " Match failed at index " << CurrentOpcodeIndex << "\n"); while (1) { if (MatchScopes.empty()) { CannotYetSelect(NodeToMatch); @@ -2680,13 +2684,12 @@ SelectCodeCommon(SDNode *NodeToMatch, const unsigned char *MatcherTable, NodeStack.append(LastScope.NodeStack.begin(), LastScope.NodeStack.end()); N = NodeStack.back(); - DEBUG(errs() << " Match failed at index " << MatcherIndex - << " continuing at " << LastScope.FailIndex << "\n"); - if (LastScope.NumMatchedMemRefs != MatchedMemRefs.size()) MatchedMemRefs.resize(LastScope.NumMatchedMemRefs); MatcherIndex = LastScope.FailIndex; + DEBUG(errs() << " Continuing at " << MatcherIndex << "\n"); + InputChain = LastScope.InputChain; InputFlag = LastScope.InputFlag; if (!LastScope.HasChainNodesMatched) diff --git a/lib/CodeGen/SimpleRegisterCoalescing.cpp b/lib/CodeGen/SimpleRegisterCoalescing.cpp index ce72b2f..d25df1d 100644 --- a/lib/CodeGen/SimpleRegisterCoalescing.cpp +++ b/lib/CodeGen/SimpleRegisterCoalescing.cpp @@ -1671,8 +1671,20 @@ bool SimpleRegisterCoalescing::JoinCopy(CopyRec &TheCopy, bool &Again) { // density, do not join them, instead mark the physical register as its // allocation preference. LiveInterval &JoinVInt = SrcIsPhys ? DstInt : SrcInt; + LiveInterval &JoinPInt = SrcIsPhys ? SrcInt : DstInt; unsigned JoinVReg = SrcIsPhys ? DstReg : SrcReg; unsigned JoinPReg = SrcIsPhys ? SrcReg : DstReg; + + // Don't join with physregs that have a ridiculous number of live + // ranges. The data structure performance is really bad when that + // happens. + if (JoinPInt.ranges.size() > 1000) { + mri_->setRegAllocationHint(JoinVInt.reg, 0, JoinPReg); + ++numAborts; + DEBUG(dbgs() << "\tPhysical register too complicated, abort!\n"); + return false; + } + const TargetRegisterClass *RC = mri_->getRegClass(JoinVReg); unsigned Threshold = allocatableRCRegs_[RC].count() * 2; unsigned Length = li_->getApproximateInstructionCount(JoinVInt); diff --git a/lib/CodeGen/TargetLoweringObjectFileImpl.cpp b/lib/CodeGen/TargetLoweringObjectFileImpl.cpp index 3b3be5d..2014b42 100644 --- a/lib/CodeGen/TargetLoweringObjectFileImpl.cpp +++ b/lib/CodeGen/TargetLoweringObjectFileImpl.cpp @@ -403,12 +403,15 @@ getSymbolForDwarfGlobalReference(const GlobalValue *GV, Mangler *Mang, // Add information about the stub reference to ELFMMI so that the stub // gets emitted by the asmprinter. - MCSymbol *Sym = getContext().GetOrCreateSymbol(Name.str()); + MCSymbol *Sym = getContext().GetOrCreateTemporarySymbol(Name.str()); MCSymbol *&StubSym = ELFMMI.getGVStubEntry(Sym); if (StubSym == 0) { Name.clear(); Mang->getNameWithPrefix(Name, GV, false); - StubSym = getContext().GetOrCreateSymbol(Name.str()); + if (GV->hasPrivateLinkage()) + StubSym = getContext().GetOrCreateTemporarySymbol(Name.str()); + else + StubSym = getContext().GetOrCreateSymbol(Name.str()); } return TargetLoweringObjectFile:: @@ -463,6 +466,14 @@ getMachOSection(StringRef Segment, StringRef Section, void TargetLoweringObjectFileMachO::Initialize(MCContext &Ctx, const TargetMachine &TM) { + // _foo.eh symbols are currently always exported so that the linker knows + // about them. This is not necessary on 10.6 and later, but it + // doesn't hurt anything. + // FIXME: I need to get this from Triple. + IsFunctionEHSymbolGlobal = true; + IsFunctionEHFrameSymbolPrivate = false; + SupportsWeakOmittedEHFrame = false; + if (UniquingMap != 0) ((MachOUniqueMapTy*)UniquingMap)->clear(); TargetLoweringObjectFile::Initialize(Ctx, TM); @@ -651,16 +662,16 @@ SelectSectionForGlobal(const GlobalValue *GV, SectionKind Kind, } // FIXME: Alignment check should be handled by section classifier. - if (Kind.isMergeable1ByteCString() || - (Kind.isMergeable2ByteCString() && !GV->hasExternalLinkage())) { - if (TM.getTargetData()->getPreferredAlignment( - cast<GlobalVariable>(GV)) < 32) { - if (Kind.isMergeable1ByteCString()) - return CStringSection; - assert(Kind.isMergeable2ByteCString()); - return UStringSection; - } - } + if (Kind.isMergeable1ByteCString() && + TM.getTargetData()->getPreferredAlignment(cast<GlobalVariable>(GV)) < 32) + return CStringSection; + + // Do not put 16-bit arrays in the UString section if they have an + // externally visible label, this runs into issues with certain linker + // versions. + if (Kind.isMergeable2ByteCString() && !GV->hasExternalLinkage() && + TM.getTargetData()->getPreferredAlignment(cast<GlobalVariable>(GV)) < 32) + return UStringSection; if (Kind.isMergeableConst()) { if (Kind.isMergeableConst4()) @@ -749,12 +760,15 @@ getSymbolForDwarfGlobalReference(const GlobalValue *GV, Mangler *Mang, // Add information about the stub reference to MachOMMI so that the stub // gets emitted by the asmprinter. - MCSymbol *Sym = getContext().GetOrCreateSymbol(Name.str()); + MCSymbol *Sym = getContext().GetOrCreateTemporarySymbol(Name.str()); MCSymbol *&StubSym = MachOMMI.getGVStubEntry(Sym); if (StubSym == 0) { Name.clear(); Mang->getNameWithPrefix(Name, GV, false); - StubSym = getContext().GetOrCreateSymbol(Name.str()); + if (GV->hasPrivateLinkage()) + StubSym = getContext().GetOrCreateTemporarySymbol(Name.str()); + else + StubSym = getContext().GetOrCreateSymbol(Name.str()); } return TargetLoweringObjectFile:: |