diff options
Diffstat (limited to 'lib/CodeGen/AsmPrinter')
-rw-r--r-- | lib/CodeGen/AsmPrinter/AsmPrinter.cpp | 128 | ||||
-rw-r--r-- | lib/CodeGen/AsmPrinter/DIE.h | 7 | ||||
-rw-r--r-- | lib/CodeGen/AsmPrinter/DwarfDebug.cpp | 313 | ||||
-rw-r--r-- | lib/CodeGen/AsmPrinter/DwarfDebug.h | 31 | ||||
-rw-r--r-- | lib/CodeGen/AsmPrinter/DwarfException.cpp | 108 | ||||
-rw-r--r-- | lib/CodeGen/AsmPrinter/DwarfException.h | 20 | ||||
-rw-r--r-- | lib/CodeGen/AsmPrinter/DwarfPrinter.cpp | 45 | ||||
-rw-r--r-- | lib/CodeGen/AsmPrinter/DwarfPrinter.h | 2 | ||||
-rw-r--r-- | lib/CodeGen/AsmPrinter/OcamlGCPrinter.cpp | 6 |
9 files changed, 350 insertions, 310 deletions
diff --git a/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/lib/CodeGen/AsmPrinter/AsmPrinter.cpp index 4978fba44cdc..2636e2c4017f 100644 --- a/lib/CodeGen/AsmPrinter/AsmPrinter.cpp +++ b/lib/CodeGen/AsmPrinter/AsmPrinter.cpp @@ -55,12 +55,13 @@ using namespace llvm; STATISTIC(EmittedInsts, "Number of machine instrs printed"); char AsmPrinter::ID = 0; + AsmPrinter::AsmPrinter(formatted_raw_ostream &o, TargetMachine &tm, - MCContext &Ctx, MCStreamer &Streamer, - const MCAsmInfo *T) + MCStreamer &Streamer) : MachineFunctionPass(&ID), O(o), - TM(tm), MAI(T), TRI(tm.getRegisterInfo()), - OutContext(Ctx), OutStreamer(Streamer), + TM(tm), MAI(tm.getMCAsmInfo()), TRI(tm.getRegisterInfo()), + OutContext(Streamer.getContext()), + OutStreamer(Streamer), LastMI(0), LastFn(0), Counter(~0U), SetCounter(0), PrevDLT(NULL) { DW = 0; MMI = 0; VerboseAsm = Streamer.isVerboseAsm(); @@ -72,7 +73,6 @@ AsmPrinter::~AsmPrinter() { delete I->second; delete &OutStreamer; - delete &OutContext; } /// getFunctionNumber - Return a unique ID for the current function. @@ -94,17 +94,21 @@ const MCSection *AsmPrinter::getCurrentSection() const { void AsmPrinter::getAnalysisUsage(AnalysisUsage &AU) const { AU.setPreservesAll(); MachineFunctionPass::getAnalysisUsage(AU); + AU.addRequired<MachineModuleInfo>(); AU.addRequired<GCModuleInfo>(); if (VerboseAsm) AU.addRequired<MachineLoopInfo>(); } bool AsmPrinter::doInitialization(Module &M) { + MMI = getAnalysisIfAvailable<MachineModuleInfo>(); + MMI->AnalyzeModule(M); + // Initialize TargetLoweringObjectFile. const_cast<TargetLoweringObjectFile&>(getObjFileLowering()) .Initialize(OutContext, TM); - Mang = new Mangler(*MAI); + Mang = new Mangler(OutContext, *TM.getTargetData()); // Allow the target to emit any magic that it wants at the start of the file. EmitStartOfAsmFile(M); @@ -128,9 +132,6 @@ bool AsmPrinter::doInitialization(Module &M) { << '\n' << MAI->getCommentString() << " End of file scope inline assembly\n"; - MMI = getAnalysisIfAvailable<MachineModuleInfo>(); - if (MMI) - MMI->AnalyzeModule(M); DW = getAnalysisIfAvailable<DwarfWriter>(); if (DW) DW->BeginModule(&M, MMI, O, this, MAI); @@ -193,7 +194,7 @@ void AsmPrinter::EmitGlobalVariable(const GlobalVariable *GV) { if (EmitSpecialLLVMGlobal(GV)) return; - MCSymbol *GVSym = GetGlobalValueSymbol(GV); + MCSymbol *GVSym = Mang->getSymbol(GV); EmitVisibility(GVSym, GV->getVisibility()); if (MAI->hasDotTypeDotSizeDirective()) @@ -306,6 +307,16 @@ void AsmPrinter::EmitFunctionHeader() { // do their wild and crazy things as required. EmitFunctionEntryLabel(); + // If the function had address-taken blocks that got deleted, then we have + // references to the dangling symbols. Emit them at the start of the function + // so that we don't get references to undefined symbols. + std::vector<MCSymbol*> DeadBlockSyms; + MMI->takeDeletedSymbolsForFunction(F, DeadBlockSyms); + for (unsigned i = 0, e = DeadBlockSyms.size(); i != e; ++i) { + OutStreamer.AddComment("Address taken block that was later removed"); + OutStreamer.EmitLabel(DeadBlockSyms[i]); + } + // Add some workaround for linkonce linkage on Cygwin\MinGW. if (MAI->getLinkOnceDirective() != 0 && (F->hasLinkOnceLinkage() || F->hasWeakLinkage())) @@ -477,14 +488,12 @@ bool AsmPrinter::doFinalization(Module &M) { for (Module::const_global_iterator I = M.global_begin(), E = M.global_end(); I != E; ++I) { if (!I->hasExternalWeakLinkage()) continue; - OutStreamer.EmitSymbolAttribute(GetGlobalValueSymbol(I), - MCSA_WeakReference); + OutStreamer.EmitSymbolAttribute(Mang->getSymbol(I), MCSA_WeakReference); } for (Module::const_iterator I = M.begin(), E = M.end(); I != E; ++I) { if (!I->hasExternalWeakLinkage()) continue; - OutStreamer.EmitSymbolAttribute(GetGlobalValueSymbol(I), - MCSA_WeakReference); + OutStreamer.EmitSymbolAttribute(Mang->getSymbol(I), MCSA_WeakReference); } } @@ -492,10 +501,10 @@ bool AsmPrinter::doFinalization(Module &M) { OutStreamer.AddBlankLine(); for (Module::const_alias_iterator I = M.alias_begin(), E = M.alias_end(); I != E; ++I) { - MCSymbol *Name = GetGlobalValueSymbol(I); + MCSymbol *Name = Mang->getSymbol(I); const GlobalValue *GV = cast<GlobalValue>(I->getAliasedGlobal()); - MCSymbol *Target = GetGlobalValueSymbol(GV); + MCSymbol *Target = Mang->getSymbol(GV); if (I->hasExternalLinkage() || !MAI->getWeakRefDirective()) OutStreamer.EmitSymbolAttribute(Name, MCSA_Global); @@ -539,7 +548,7 @@ bool AsmPrinter::doFinalization(Module &M) { void AsmPrinter::SetupMachineFunction(MachineFunction &MF) { this->MF = &MF; // Get the function symbol. - CurrentFnSym = GetGlobalValueSymbol(MF.getFunction()); + CurrentFnSym = Mang->getSymbol(MF.getFunction()); if (VerboseAsm) LI = &getAnalysis<MachineLoopInfo>(); @@ -651,6 +660,7 @@ void AsmPrinter::EmitConstantPool() { void AsmPrinter::EmitJumpTableInfo() { const MachineJumpTableInfo *MJTI = MF->getJumpTableInfo(); if (MJTI == 0) return; + if (MJTI->getEntryKind() == MachineJumpTableInfo::EK_Inline) return; const std::vector<MachineJumpTableEntry> &JT = MJTI->getJumpTables(); if (JT.empty()) return; @@ -698,7 +708,7 @@ void AsmPrinter::EmitJumpTableInfo() { // .set LJTSet, LBB32-base const MCExpr *LHS = - MCSymbolRefExpr::Create(MBB->getSymbol(OutContext), OutContext); + MCSymbolRefExpr::Create(MBB->getSymbol(), OutContext); OutStreamer.EmitAssignment(GetJTSetSymbol(JTI, MBB->getNumber()), MCBinaryExpr::CreateSub(LHS, Base, OutContext)); } @@ -727,6 +737,8 @@ void AsmPrinter::EmitJumpTableEntry(const MachineJumpTableInfo *MJTI, unsigned UID) const { const MCExpr *Value = 0; switch (MJTI->getEntryKind()) { + case MachineJumpTableInfo::EK_Inline: + llvm_unreachable("Cannot emit EK_Inline jump table entry"); break; case MachineJumpTableInfo::EK_Custom32: Value = TM.getTargetLowering()->LowerCustomJumpTableEntry(MJTI, MBB, UID, OutContext); @@ -734,13 +746,13 @@ void AsmPrinter::EmitJumpTableEntry(const MachineJumpTableInfo *MJTI, case MachineJumpTableInfo::EK_BlockAddress: // EK_BlockAddress - Each entry is a plain address of block, e.g.: // .word LBB123 - Value = MCSymbolRefExpr::Create(MBB->getSymbol(OutContext), OutContext); + Value = MCSymbolRefExpr::Create(MBB->getSymbol(), OutContext); break; case MachineJumpTableInfo::EK_GPRel32BlockAddress: { // EK_GPRel32BlockAddress - Each entry is an address of block, encoded // with a relocation as gp-relative, e.g.: // .gprel32 LBB123 - MCSymbol *MBBSym = MBB->getSymbol(OutContext); + MCSymbol *MBBSym = MBB->getSymbol(); OutStreamer.EmitGPRel32Value(MCSymbolRefExpr::Create(MBBSym, OutContext)); return; } @@ -764,7 +776,7 @@ void AsmPrinter::EmitJumpTableEntry(const MachineJumpTableInfo *MJTI, break; } // Otherwise, use the difference as the jump table entry. - Value = MCSymbolRefExpr::Create(MBB->getSymbol(OutContext), OutContext); + Value = MCSymbolRefExpr::Create(MBB->getSymbol(), OutContext); const MCExpr *JTI = MCSymbolRefExpr::Create(GetJTISymbol(UID), OutContext); Value = MCBinaryExpr::CreateSub(Value, JTI, OutContext); break; @@ -842,8 +854,7 @@ void AsmPrinter::EmitLLVMUsedList(Constant *List) { const GlobalValue *GV = dyn_cast<GlobalValue>(InitList->getOperand(i)->stripPointerCasts()); if (GV && getObjFileLowering().shouldEmitUsedDirectiveFor(GV, Mang)) - OutStreamer.EmitSymbolAttribute(GetGlobalValueSymbol(GV), - MCSA_NoDeadStrip); + OutStreamer.EmitSymbolAttribute(Mang->getSymbol(GV), MCSA_NoDeadStrip); } } @@ -960,7 +971,7 @@ static const MCExpr *LowerConstant(const Constant *CV, AsmPrinter &AP) { return MCConstantExpr::Create(CI->getZExtValue(), Ctx); if (const GlobalValue *GV = dyn_cast<GlobalValue>(CV)) - return MCSymbolRefExpr::Create(AP.GetGlobalValueSymbol(GV), Ctx); + return MCSymbolRefExpr::Create(AP.Mang->getSymbol(GV), Ctx); if (const BlockAddress *BA = dyn_cast<BlockAddress>(CV)) return MCSymbolRefExpr::Create(AP.GetBlockAddressSymbol(BA), Ctx); @@ -1308,6 +1319,8 @@ void AsmPrinter::processDebugLoc(const MachineInstr *MI, if (!MAI || !DW || !MAI->doesSupportDebugInformation() || !DW->ShouldEmitDwarfDebug()) return; + if (MI->getOpcode() == TargetOpcode::DBG_VALUE) + return; DebugLoc DL = MI->getDebugLoc(); if (DL.isUnknown()) return; @@ -1499,7 +1512,7 @@ void AsmPrinter::printInlineAsm(const MachineInstr *MI) const { ++OpNo; // Skip over the ID number. if (Modifier[0] == 'l') // labels are target independent - O << *MI->getOperand(OpNo).getMBB()->getSymbol(OutContext); + O << *MI->getOperand(OpNo).getMBB()->getSymbol(); else { AsmPrinter *AP = const_cast<AsmPrinter*>(this); if ((OpFlags & 7) == 4) { @@ -1552,17 +1565,7 @@ 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 { - MCSymbol *Sym = - OutContext.GetOrCreateTemporarySymbol(Twine(MAI->getPrivateGlobalPrefix()) + - "label" + Twine(MI->getOperand(0).getImm())); - OutStreamer.EmitLabel(Sym); -} - -void AsmPrinter::printLabel(unsigned Id) const { - MCSymbol *Sym = - OutContext.GetOrCreateTemporarySymbol(Twine(MAI->getPrivateGlobalPrefix()) + - "label" + Twine(Id)); - OutStreamer.EmitLabel(Sym); + OutStreamer.EmitLabel(MI->getOperand(0).getMCSymbol()); } /// PrintAsmOperand - Print the specified operand of MI, an INLINEASM @@ -1582,28 +1585,11 @@ bool AsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo, } MCSymbol *AsmPrinter::GetBlockAddressSymbol(const BlockAddress *BA) const { - return GetBlockAddressSymbol(BA->getFunction(), BA->getBasicBlock()); + return MMI->getAddrLabelSymbol(BA->getBasicBlock()); } -MCSymbol *AsmPrinter::GetBlockAddressSymbol(const Function *F, - const BasicBlock *BB) const { - assert(BB->hasName() && - "Address of anonymous basic block not supported yet!"); - - // This code must use the function name itself, and not the function number, - // since it must be possible to generate the label name from within other - // functions. - SmallString<60> FnName; - Mang->getNameWithPrefix(FnName, F, false); - - // FIXME: THIS IS BROKEN IF THE LLVM BASIC BLOCK DOESN'T HAVE A NAME! - SmallString<60> NameResult; - Mang->getNameWithPrefix(NameResult, - StringRef("BA") + Twine((unsigned)FnName.size()) + - "_" + FnName.str() + "_" + BB->getName(), - Mangler::Private); - - return OutContext.GetOrCreateTemporarySymbol(NameResult.str()); +MCSymbol *AsmPrinter::GetBlockAddressSymbol(const BasicBlock *BB) const { + return MMI->getAddrLabelSymbol(BB); } /// GetCPISymbol - Return the symbol for the specified constant pool entry. @@ -1626,17 +1612,6 @@ MCSymbol *AsmPrinter::GetJTSetSymbol(unsigned UID, unsigned MBBID) const { Twine(UID) + "_set_" + Twine(MBBID)); } -/// GetGlobalValueSymbol - Return the MCSymbol for the specified global -/// value. -MCSymbol *AsmPrinter::GetGlobalValueSymbol(const GlobalValue *GV) const { - SmallString<60> NameStr; - Mang->getNameWithPrefix(NameStr, GV, false); - - if (!GV->hasPrivateLinkage()) - return OutContext.GetOrCreateSymbol(NameStr.str()); - return OutContext.GetOrCreateTemporarySymbol(NameStr.str()); -} - /// GetSymbolWithGlobalValueBase - Return the MCSymbol for a symbol with /// global value name as its base, with the specified suffix, and where the /// symbol is forced to have private linkage if ForcePrivate is true. @@ -1734,16 +1709,19 @@ void AsmPrinter::EmitBasicBlockStart(const MachineBasicBlock *MBB) const { if (unsigned Align = MBB->getAlignment()) EmitAlignment(Log2_32(Align)); - // If the block has its address taken, emit a special label to satisfy - // references to the block. This is done so that we don't need to - // remember the number of this label, and so that we can make - // forward references to labels without knowing what their numbers - // will be. + // If the block has its address taken, emit any labels that were used to + // reference the block. It is possible that there is more than one label + // here, because multiple LLVM BB's may have been RAUW'd to this block after + // the references were generated. if (MBB->hasAddressTaken()) { const BasicBlock *BB = MBB->getBasicBlock(); if (VerboseAsm) - OutStreamer.AddComment("Address Taken"); - OutStreamer.EmitLabel(GetBlockAddressSymbol(BB->getParent(), BB)); + OutStreamer.AddComment("Block address taken"); + + std::vector<MCSymbol*> Syms = MMI->getAddrLabelSymbolToEmit(BB); + + for (unsigned i = 0, e = Syms.size(); i != e; ++i) + OutStreamer.EmitLabel(Syms[i]); } // Print the main label for the block. @@ -1766,7 +1744,7 @@ void AsmPrinter::EmitBasicBlockStart(const MachineBasicBlock *MBB) const { PrintBasicBlockLoopComments(*MBB, LI, *this); } - OutStreamer.EmitLabel(MBB->getSymbol(OutContext)); + OutStreamer.EmitLabel(MBB->getSymbol()); } } diff --git a/lib/CodeGen/AsmPrinter/DIE.h b/lib/CodeGen/AsmPrinter/DIE.h index e08d748dc108..c5909faab7e1 100644 --- a/lib/CodeGen/AsmPrinter/DIE.h +++ b/lib/CodeGen/AsmPrinter/DIE.h @@ -112,7 +112,6 @@ namespace llvm { //===--------------------------------------------------------------------===// /// DIE - A structured debug information entry. Has an abbreviation which /// describes it's organization. - class CompileUnit; class DIEValue; class DIE { @@ -159,7 +158,6 @@ namespace llvm { void setTag(unsigned Tag) { Abbrev.setTag(Tag); } void setOffset(unsigned O) { Offset = O; } void setSize(unsigned S) { Size = S; } - void setParent(DIE *P) { Parent = P; } /// addValue - Add a value and attributes to a DIE. /// @@ -185,7 +183,7 @@ namespace llvm { } Abbrev.setChildrenFlag(dwarf::DW_CHILDREN_yes); Children.push_back(Child); - Child->setParent(this); + Child->Parent = this; } #ifndef NDEBUG @@ -393,12 +391,11 @@ namespace llvm { /// this class can also be used as a proxy for a debug information entry not /// yet defined (ie. types.) class DIEEntry : public DIEValue { - DIE *Entry; + DIE *const Entry; public: explicit DIEEntry(DIE *E) : DIEValue(isEntry), Entry(E) {} DIE *getEntry() const { return Entry; } - void setEntry(DIE *E) { Entry = E; } /// EmitValue - Emit debug information entry offset. /// diff --git a/lib/CodeGen/AsmPrinter/DwarfDebug.cpp b/lib/CodeGen/AsmPrinter/DwarfDebug.cpp index 36be5b99b946..866f457139ae 100644 --- a/lib/CodeGen/AsmPrinter/DwarfDebug.cpp +++ b/lib/CodeGen/AsmPrinter/DwarfDebug.cpp @@ -25,6 +25,7 @@ #include "llvm/Target/TargetFrameInfo.h" #include "llvm/Target/TargetLoweringObjectFile.h" #include "llvm/Target/TargetRegisterInfo.h" +#include "llvm/ADT/STLExtras.h" #include "llvm/ADT/StringExtras.h" #include "llvm/Support/Debug.h" #include "llvm/Support/ErrorHandling.h" @@ -52,9 +53,9 @@ class CompileUnit { /// Die - Compile unit debug information entry. /// - DIE *CUDie; + const OwningPtr<DIE> CUDie; - /// IndexTyDie - An anonymous type for index type. + /// IndexTyDie - An anonymous type for index type. Owned by CUDie. DIE *IndexTyDie; /// GVToDieMap - Tracks the mapping of unit level debug informaton @@ -78,11 +79,10 @@ class CompileUnit { public: CompileUnit(unsigned I, DIE *D) : ID(I), CUDie(D), IndexTyDie(0) {} - ~CompileUnit() { delete CUDie; delete IndexTyDie; } // Accessors. unsigned getID() const { return ID; } - DIE* getCUDie() const { return CUDie; } + DIE* getCUDie() const { return CUDie.get(); } const StringMap<DIE*> &getGlobals() const { return Globals; } const StringMap<DIE*> &getGlobalTypes() const { return GlobalTypes; } @@ -148,16 +148,21 @@ public: class DbgVariable { DIVariable Var; // Variable Descriptor. unsigned FrameIndex; // Variable frame index. - DbgVariable *AbstractVar; // Abstract variable for this variable. + const MachineInstr *DbgValueMInsn; // DBG_VALUE + DbgVariable *const AbstractVar; // Abstract variable for this variable. DIE *TheDIE; public: - DbgVariable(DIVariable V, unsigned I) - : Var(V), FrameIndex(I), AbstractVar(0), TheDIE(0) {} + // AbsVar may be NULL. + DbgVariable(DIVariable V, unsigned I, DbgVariable *AbsVar) + : Var(V), FrameIndex(I), DbgValueMInsn(0), AbstractVar(AbsVar), TheDIE(0) {} + DbgVariable(DIVariable V, const MachineInstr *MI, DbgVariable *AbsVar) + : Var(V), FrameIndex(0), DbgValueMInsn(MI), AbstractVar(AbsVar), TheDIE(0) + {} // Accessors. DIVariable getVariable() const { return Var; } unsigned getFrameIndex() const { return FrameIndex; } - void setAbstractVariable(DbgVariable *V) { AbstractVar = V; } + const MachineInstr *getDbgValue() const { return DbgValueMInsn; } DbgVariable *getAbstractVariable() const { return AbstractVar; } void setDIE(DIE *D) { TheDIE = D; } DIE *getDIE() const { return TheDIE; } @@ -176,8 +181,10 @@ class DbgScope { 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. - SmallVector<DbgVariable *, 8> Variables;// Variables declared in scope. + // Scopes defined in scope. Contents not owned. + SmallVector<DbgScope *, 4> Scopes; + // Variables declared in scope. Contents owned. + SmallVector<DbgVariable *, 8> Variables; // Private state for dump() mutable unsigned IndentLevel; @@ -192,14 +199,12 @@ public: DbgScope *getParent() const { return Parent; } void setParent(DbgScope *P) { Parent = P; } DIDescriptor getDesc() const { return Desc; } - MDNode *getInlinedAt() const { - return InlinedAtLocation; - } + MDNode *getInlinedAt() const { return InlinedAtLocation; } MDNode *getScopeNode() const { return Desc.getNode(); } MCSymbol *getStartLabel() const { return StartLabel; } MCSymbol *getEndLabel() const { return EndLabel; } - SmallVector<DbgScope *, 4> &getScopes() { return Scopes; } - SmallVector<DbgVariable *, 8> &getVariables() { return Variables; } + const SmallVector<DbgScope *, 4> &getScopes() { return Scopes; } + const SmallVector<DbgVariable *, 8> &getVariables() { return Variables; } void setStartLabel(MCSymbol *S) { StartLabel = S; } void setEndLabel(MCSymbol *E) { EndLabel = E; } void setLastInsn(const MachineInstr *MI) { LastInsn = MI; } @@ -222,14 +227,14 @@ public: assert (getFirstInsn() && "First instruction is missing!"); // Use the end of last child scope as end of this scope. - SmallVector<DbgScope *, 4> &Scopes = getScopes(); + const SmallVector<DbgScope *, 4> &Scopes = getScopes(); const MachineInstr *LastInsn = getFirstInsn(); unsigned LIndex = 0; if (Scopes.empty()) { assert (getLastInsn() && "Inner most scope does not have last insn!"); return; } - for (SmallVector<DbgScope *, 4>::iterator SI = Scopes.begin(), + for (SmallVector<DbgScope *, 4>::const_iterator SI = Scopes.begin(), SE = Scopes.end(); SI != SE; ++SI) { DbgScope *DS = *SI; DS->fixInstructionMarkers(MIIndexMap); @@ -281,8 +286,6 @@ void DbgScope::dump() const { #endif DbgScope::~DbgScope() { - for (unsigned i = 0, N = Scopes.size(); i < N; ++i) - delete Scopes[i]; for (unsigned j = 0, M = Variables.size(); j < M; ++j) delete Variables[j]; } @@ -292,9 +295,9 @@ DbgScope::~DbgScope() { DwarfDebug::DwarfDebug(raw_ostream &OS, AsmPrinter *A, const MCAsmInfo *T) : DwarfPrinter(OS, A, T), ModuleCU(0), AbbreviationsSet(InitAbbreviationsSetSize), Abbreviations(), - DIEValues(), StringPool(), - SectionSourceLines(), didInitial(false), shouldEmit(false), + DIEValues(), SectionSourceLines(), didInitial(false), shouldEmit(false), CurrentFnDbgScope(0), DebugTimer(0) { + NextStringPoolNumber = 0; if (TimePassesIsEnabled) DebugTimer = new Timer("Dwarf Debug Writer"); } @@ -305,6 +308,15 @@ DwarfDebug::~DwarfDebug() { delete DebugTimer; } +MCSymbol *DwarfDebug::getStringPoolEntry(StringRef Str) { + std::pair<MCSymbol*, unsigned> &Entry = StringPool[Str]; + if (Entry.first) return Entry.first; + + Entry.second = NextStringPoolNumber++; + return Entry.first = getDWLabel("string", Entry.second); +} + + /// assignAbbrevNumber - Define a unique number for the abbreviation. /// void DwarfDebug::assignAbbrevNumber(DIEAbbrev &Abbrev) { @@ -820,14 +832,13 @@ void DwarfDebug::addType(DIE *Entity, DIType Ty) { return; } - // Set up proxy. - Entry = createDIEEntry(); - ModuleCU->insertDIEEntry(Ty.getNode(), Entry); - // Construct type. DIE *Buffer = getOrCreateTypeDIE(Ty); - Entry->setEntry(Buffer); + // Set up proxy. + Entry = createDIEEntry(Buffer); + ModuleCU->insertDIEEntry(Ty.getNode(), Entry); + Entity->addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, Entry); } @@ -1315,24 +1326,25 @@ DbgScope *DwarfDebug::getOrCreateAbstractScope(MDNode *N) { /// If there are global variables in this scope then create and insert /// DIEs for these variables. DIE *DwarfDebug::updateSubprogramScopeDIE(MDNode *SPNode) { - DIE *SPDie = ModuleCU->getDIE(SPNode); - assert (SPDie && "Unable to find subprogram DIE!"); + assert(SPDie && "Unable to find subprogram DIE!"); DISubprogram SP(SPNode); + // There is not any need to generate specification DIE for a function // defined at compile unit level. If a function is defined inside another // function then gdb prefers the definition at top level and but does not // expect specification DIE in parent function. So avoid creating // specification DIE for a function defined inside a function. - if (SP.isDefinition() && !SP.getContext().isCompileUnit() - && !SP.getContext().isSubprogram()) { + if (SP.isDefinition() && !SP.getContext().isCompileUnit() && + !SP.getContext().isFile() && !SP.getContext().isSubprogram()) { addUInt(SPDie, dwarf::DW_AT_declaration, dwarf::DW_FORM_flag, 1); - // Add arguments. + + // Add arguments. DICompositeType SPTy = SP.getType(); DIArray Args = SPTy.getTypeArray(); unsigned SPTag = SPTy.getTag(); if (SPTag == dwarf::DW_TAG_subroutine_type) - for (unsigned i = 1, N = Args.getNumElements(); i < N; ++i) { + for (unsigned i = 1, N = Args.getNumElements(); i < N; ++i) { DIE *Arg = new DIE(dwarf::DW_TAG_formal_parameter); DIType ATy = DIType(DIType(Args.getElement(i).getNode())); addType(Arg, ATy); @@ -1421,9 +1433,6 @@ DIE *DwarfDebug::constructInlinedScopeDIE(DbgScope *Scope) { } else I->second.push_back(std::make_pair(StartLabel, ScopeDIE)); - StringPool.insert(InlinedSP.getName()); - StringPool.insert(getRealLinkageName(InlinedSP.getLinkageName())); - DILocation DL(Scope->getInlinedAt()); addUInt(ScopeDIE, dwarf::DW_AT_call_file, 0, ModuleCU->getID()); addUInt(ScopeDIE, dwarf::DW_AT_call_line, 0, DL.getLineNumber()); @@ -1489,17 +1498,41 @@ DIE *DwarfDebug::constructVariableDIE(DbgVariable *DV, DbgScope *Scope) { // Add variable address. if (!Scope->isAbstractScope()) { - MachineLocation Location; - unsigned FrameReg; - int Offset = RI->getFrameIndexReference(*MF, DV->getFrameIndex(), FrameReg); - Location.set(FrameReg, Offset); - - if (VD.hasComplexAddress()) - addComplexAddress(DV, VariableDie, dwarf::DW_AT_location, Location); - else if (VD.isBlockByrefVariable()) - addBlockByrefAddress(DV, VariableDie, dwarf::DW_AT_location, Location); - else - addAddress(VariableDie, dwarf::DW_AT_location, Location); + // Check if variable is described by DBG_VALUE instruction. + if (const MachineInstr *DbgValueInsn = DV->getDbgValue()) { + if (DbgValueInsn->getNumOperands() == 3) { + // FIXME : Handle getNumOperands != 3 + if (DbgValueInsn->getOperand(0).getType() + == MachineOperand::MO_Register + && DbgValueInsn->getOperand(0).getReg()) { + MachineLocation Location; + Location.set(DbgValueInsn->getOperand(0).getReg()); + addAddress(VariableDie, dwarf::DW_AT_location, Location); + } else if (DbgValueInsn->getOperand(0).getType() == + MachineOperand::MO_Immediate) { + DIEBlock *Block = new DIEBlock(); + unsigned Imm = DbgValueInsn->getOperand(0).getImm(); + addUInt(Block, 0, dwarf::DW_FORM_udata, Imm); + addBlock(VariableDie, dwarf::DW_AT_const_value, 0, Block); + } else { + //FIXME : Handle other operand types. + delete VariableDie; + return NULL; + } + } + } else { + MachineLocation Location; + unsigned FrameReg; + int Offset = RI->getFrameIndexReference(*MF, DV->getFrameIndex(), FrameReg); + Location.set(FrameReg, Offset); + + if (VD.hasComplexAddress()) + addComplexAddress(DV, VariableDie, dwarf::DW_AT_location, Location); + else if (VD.isBlockByrefVariable()) + addBlockByrefAddress(DV, VariableDie, dwarf::DW_AT_location, Location); + else + addAddress(VariableDie, dwarf::DW_AT_location, Location); + } } if (Tag == dwarf::DW_TAG_formal_parameter && VD.getType().isArtificial()) @@ -1549,7 +1582,7 @@ DIE *DwarfDebug::constructScopeDIE(DbgScope *Scope) { } // Add variables to scope. - SmallVector<DbgVariable *, 8> &Variables = Scope->getVariables(); + const SmallVector<DbgVariable *, 8> &Variables = Scope->getVariables(); for (unsigned i = 0, N = Variables.size(); i < N; ++i) { DIE *VariableDIE = constructVariableDIE(Variables[i], Scope); if (VariableDIE) @@ -1557,7 +1590,7 @@ DIE *DwarfDebug::constructScopeDIE(DbgScope *Scope) { } // Add nested scopes. - SmallVector<DbgScope *, 4> &Scopes = Scope->getScopes(); + const SmallVector<DbgScope *, 4> &Scopes = Scope->getScopes(); for (unsigned j = 0, M = Scopes.size(); j < M; ++j) { // Define the Scope debug information entry. DIE *NestedDIE = constructScopeDIE(Scopes[j]); @@ -1622,8 +1655,12 @@ DIE *DwarfDebug::getOrCreateNameSpace(DINameSpace NS) { return NDie; } -CompileUnit *DwarfDebug::constructCompileUnit(MDNode *N) { +void DwarfDebug::constructCompileUnit(MDNode *N) { DICompileUnit DIUnit(N); + // Use first compile unit marked as isMain as the compile unit for this + // module. + if (ModuleCU || !DIUnit.isMain()) + return; StringRef FN = DIUnit.getFilename(); StringRef Dir = DIUnit.getDirectory(); unsigned ID = GetOrCreateSourceID(Dir, FN); @@ -1653,14 +1690,9 @@ CompileUnit *DwarfDebug::constructCompileUnit(MDNode *N) { addUInt(Die, dwarf::DW_AT_APPLE_major_runtime_vers, dwarf::DW_FORM_data1, RVer); - CompileUnit *Unit = new CompileUnit(ID, Die); - if (!ModuleCU && DIUnit.isMain()) { - // Use first compile unit marked as isMain as the compile unit - // for this module. - ModuleCU = Unit; - } - - return Unit; + assert(!ModuleCU && + "ModuleCU assigned since the top of constructCompileUnit"); + ModuleCU = new CompileUnit(ID, Die); } void DwarfDebug::constructGlobalVariableDIE(MDNode *N) { @@ -1686,7 +1718,7 @@ void DwarfDebug::constructGlobalVariableDIE(MDNode *N) { // Do not create specification DIE if context is either compile unit // or a subprogram. if (DI_GV.isDefinition() && !GVContext.isCompileUnit() - && !GVContext.isSubprogram()) { + && !GVContext.isFile() && !GVContext.isSubprogram()) { // Create specification DIE. DIE *VariableSpecDIE = new DIE(dwarf::DW_TAG_variable); addDIEEntry(VariableSpecDIE, dwarf::DW_AT_specification, @@ -1694,7 +1726,7 @@ void DwarfDebug::constructGlobalVariableDIE(MDNode *N) { DIEBlock *Block = new DIEBlock(); addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_addr); addLabel(Block, 0, dwarf::DW_FORM_udata, - Asm->GetGlobalValueSymbol(DI_GV.getGlobal())); + Asm->Mang->getSymbol(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); @@ -1702,7 +1734,7 @@ void DwarfDebug::constructGlobalVariableDIE(MDNode *N) { DIEBlock *Block = new DIEBlock(); addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_addr); addLabel(Block, 0, dwarf::DW_FORM_udata, - Asm->GetGlobalValueSymbol(DI_GV.getGlobal())); + Asm->Mang->getSymbol(DI_GV.getGlobal())); addBlock(VariableDie, dwarf::DW_AT_location, 0, Block); } addToContextOwner(VariableDie, GVContext); @@ -1880,9 +1912,6 @@ void DwarfDebug::endModule() { // Emit info into a debug pubtypes section. emitDebugPubTypes(); - // Emit info into a debug str section. - emitDebugStr(); - // Emit info into a debug loc section. emitDebugLoc(); @@ -1898,6 +1927,12 @@ void DwarfDebug::endModule() { // Emit inline info. emitDebugInlineInfo(); + // Emit info into a debug str section. + emitDebugStr(); + + delete ModuleCU; + ModuleCU = NULL; // Reset for the next Module, if any. + if (TimePassesIsEnabled) DebugTimer->stopTimer(); } @@ -1915,7 +1950,29 @@ DbgVariable *DwarfDebug::findAbstractVariable(DIVariable &Var, if (!Scope) return NULL; - AbsDbgVariable = new DbgVariable(Var, FrameIdx); + AbsDbgVariable = new DbgVariable(Var, FrameIdx, + NULL /* No more-abstract variable*/); + Scope->addVariable(AbsDbgVariable); + AbstractVariables[Var.getNode()] = AbsDbgVariable; + return AbsDbgVariable; +} + +/// findAbstractVariable - Find abstract variable, if any, associated with Var. +/// FIXME : Refactor findAbstractVariable. +DbgVariable *DwarfDebug::findAbstractVariable(DIVariable &Var, + const MachineInstr *MI, + DILocation &ScopeLoc) { + + DbgVariable *AbsDbgVariable = AbstractVariables.lookup(Var.getNode()); + if (AbsDbgVariable) + return AbsDbgVariable; + + DbgScope *Scope = AbstractScopes.lookup(ScopeLoc.getScope().getNode()); + if (!Scope) + return NULL; + + AbsDbgVariable = new DbgVariable(Var, MI, + NULL /* No more-abstract variable*/); Scope->addVariable(AbsDbgVariable); AbstractVariables[Var.getNode()] = AbsDbgVariable; return AbsDbgVariable; @@ -1942,11 +1999,46 @@ void DwarfDebug::collectVariableInfo() { if (!Scope) continue; - DbgVariable *RegVar = new DbgVariable(DV, VP.first); + DbgVariable *AbsDbgVariable = findAbstractVariable(DV, VP.first, ScopeLoc); + DbgVariable *RegVar = new DbgVariable(DV, VP.first, AbsDbgVariable); Scope->addVariable(RegVar); - if (DbgVariable *AbsDbgVariable = findAbstractVariable(DV, VP.first, - ScopeLoc)) - RegVar->setAbstractVariable(AbsDbgVariable); + } + + // Collect variable information from DBG_VALUE machine instructions; + for (MachineFunction::const_iterator I = MF->begin(), E = MF->end(); + I != E; ++I) { + for (MachineBasicBlock::const_iterator II = I->begin(), IE = I->end(); + II != IE; ++II) { + const MachineInstr *MInsn = II; + if (MInsn->getOpcode() != TargetOpcode::DBG_VALUE) + continue; + // FIXME : Lift this restriction. + if (MInsn->getNumOperands() != 3) + continue; + DIVariable DV((MDNode*)(MInsn->getOperand(MInsn->getNumOperands() - 1).getMetadata())); + if (DV.getTag() == dwarf::DW_TAG_arg_variable) { + // FIXME Handle inlined subroutine arguments. + DbgVariable *ArgVar = new DbgVariable(DV, MInsn, NULL); + CurrentFnDbgScope->addVariable(ArgVar); + continue; + } + + DebugLoc DL = MInsn->getDebugLoc(); + if (DL.isUnknown()) continue; + DILocation ScopeLoc = MF->getDILocation(DL); + DbgScope *Scope = + ConcreteScopes.lookup(ScopeLoc.getOrigLocation().getNode()); + if (!Scope) + Scope = DbgScopeMap.lookup(ScopeLoc.getScope().getNode()); + // If variable scope is not found then skip this variable. + if (!Scope) + continue; + + DbgVariable *AbsDbgVariable = findAbstractVariable(DV, MInsn, + ScopeLoc); + DbgVariable *RegVar = new DbgVariable(DV, MInsn, AbsDbgVariable); + Scope->addVariable(RegVar); + } } } @@ -1967,7 +2059,7 @@ void DwarfDebug::endScope(const MachineInstr *MI) { if (I == DbgScopeEndMap.end()) return; - MCSymbol *Label = getDWLabel("label", MMI->NextLabelID()); + MCSymbol *Label = MMI->getContext().CreateTempSymbol(); Asm->OutStreamer.EmitLabel(Label); SmallVector<DbgScope*, 2> &SD = I->second; @@ -2017,6 +2109,8 @@ bool DwarfDebug::extractScopeInformation() { for (MachineBasicBlock::const_iterator II = I->begin(), IE = I->end(); II != IE; ++II) { const MachineInstr *MInsn = II; + // FIXME : Remove DBG_VALUE check. + if (MInsn->getOpcode() == TargetOpcode::DBG_VALUE) continue; MIIndexMap[MInsn] = MIIndex++; DebugLoc DL = MInsn->getDebugLoc(); if (DL.isUnknown()) continue; @@ -2037,6 +2131,8 @@ bool DwarfDebug::extractScopeInformation() { for (MachineBasicBlock::const_iterator II = I->begin(), IE = I->end(); II != IE; ++II) { const MachineInstr *MInsn = II; + // FIXME : Remove DBG_VALUE check. + if (MInsn->getOpcode() == TargetOpcode::DBG_VALUE) continue; DebugLoc DL = MInsn->getDebugLoc(); if (DL.isUnknown()) continue; DILocation DLT = MF->getDILocation(DL); @@ -2065,9 +2161,9 @@ bool DwarfDebug::extractScopeInformation() { while (!WorkList.empty()) { DbgScope *S = WorkList.back(); WorkList.pop_back(); - SmallVector<DbgScope *, 4> &Children = S->getScopes(); + const SmallVector<DbgScope *, 4> &Children = S->getScopes(); if (!Children.empty()) - for (SmallVector<DbgScope *, 4>::iterator SI = Children.begin(), + for (SmallVector<DbgScope *, 4>::const_iterator SI = Children.begin(), SE = Children.end(); SI != SE; ++SI) WorkList.push_back(*SI); @@ -2172,11 +2268,13 @@ void DwarfDebug::endFunction(const MachineFunction *MF) { // Clear debug info CurrentFnDbgScope = NULL; - DbgScopeMap.clear(); + DeleteContainerSeconds(DbgScopeMap); DbgScopeBeginMap.clear(); DbgScopeEndMap.clear(); ConcreteScopes.clear(); + DeleteContainerSeconds(AbstractScopes); AbstractScopesList.clear(); + AbstractVariables.clear(); Lines.clear(); if (TimePassesIsEnabled) @@ -2210,16 +2308,15 @@ MCSymbol *DwarfDebug::recordSourceLine(unsigned Line, unsigned Col, MDNode *S) { Dir = DB.getDirectory(); Fn = DB.getFilename(); } else - assert (0 && "Unexpected scope info"); + assert(0 && "Unexpected scope info"); unsigned Src = GetOrCreateSourceID(Dir, Fn); - unsigned ID = MMI->NextLabelID(); - Lines.push_back(SrcLineInfo(Line, Col, Src, ID)); + MCSymbol *Label = MMI->getContext().CreateTempSymbol(); + Lines.push_back(SrcLineInfo(Line, Col, Src, Label)); if (TimePassesIsEnabled) DebugTimer->stopTimer(); - MCSymbol *Label = getDWLabel("label", ID); Asm->OutStreamer.EmitLabel(Label); return Label; } @@ -2607,8 +2704,8 @@ 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 = LineInfo.getLabelID(); - if (MMI->isLabelDeleted(LabelID)) continue; + MCSymbol *Label = LineInfo.getLabel(); + if (!Label->isDefined()) continue; // Not emitted, in dead code. if (LineInfo.getLine() == 0) continue; @@ -2631,8 +2728,8 @@ void DwarfDebug::emitDebugLines() { Asm->EmitInt8(dwarf::DW_LNE_set_address); Asm->OutStreamer.AddComment("Location label"); - Asm->OutStreamer.EmitSymbolValue(getDWLabel("label", LabelID), - TD->getPointerSize(), 0/*AddrSpace*/); + Asm->OutStreamer.EmitSymbolValue(Label, TD->getPointerSize(), + 0/*AddrSpace*/); // If change of source, then switch to the new source. if (Source != LineInfo.getSourceID()) { @@ -2718,7 +2815,7 @@ void DwarfDebug::emitCommonDebugFrame() { std::vector<MachineMove> Moves; RI->getInitialFrameState(Moves); - EmitFrameMoves(NULL, 0, Moves, false); + EmitFrameMoves(0, Moves, false); Asm->EmitAlignment(2, 0, 0, false); Asm->OutStreamer.EmitLabel(getTempLabel("debug_frame_common_end")); @@ -2726,8 +2823,8 @@ void DwarfDebug::emitCommonDebugFrame() { /// emitFunctionDebugFrame - Emit per function frame info into a debug frame /// section. -void -DwarfDebug::emitFunctionDebugFrame(const FunctionDebugFrameInfo&DebugFrameInfo){ +void DwarfDebug:: +emitFunctionDebugFrame(const FunctionDebugFrameInfo &DebugFrameInfo) { if (!MAI->doesDwarfRequireFrameSection()) return; @@ -2736,33 +2833,31 @@ DwarfDebug::emitFunctionDebugFrame(const FunctionDebugFrameInfo&DebugFrameInfo){ Asm->getObjFileLowering().getDwarfFrameSection()); Asm->OutStreamer.AddComment("Length of Frame Information Entry"); - EmitDifference(getDWLabel("debug_frame_end", DebugFrameInfo.Number), - getDWLabel("debug_frame_begin", DebugFrameInfo.Number), true); + MCSymbol *DebugFrameBegin = + getDWLabel("debug_frame_begin", DebugFrameInfo.Number); + MCSymbol *DebugFrameEnd = + getDWLabel("debug_frame_end", DebugFrameInfo.Number); + EmitDifference(DebugFrameEnd, DebugFrameBegin, true); - Asm->OutStreamer.EmitLabel(getDWLabel("debug_frame_begin", - DebugFrameInfo.Number)); + Asm->OutStreamer.EmitLabel(DebugFrameBegin); Asm->OutStreamer.AddComment("FDE CIE offset"); EmitSectionOffset(getTempLabel("debug_frame_common"), getTempLabel("section_debug_frame"), true, false); Asm->OutStreamer.AddComment("FDE initial location"); - Asm->OutStreamer.EmitSymbolValue(getDWLabel("func_begin", - DebugFrameInfo.Number), + MCSymbol *FuncBeginSym = getDWLabel("func_begin", DebugFrameInfo.Number); + Asm->OutStreamer.EmitSymbolValue(FuncBeginSym, TD->getPointerSize(), 0/*AddrSpace*/); - Asm->OutStreamer.AddComment("FDE address range"); - EmitDifference(getDWLabel("func_end", DebugFrameInfo.Number), - getDWLabel("func_begin", DebugFrameInfo.Number)); + EmitDifference(getDWLabel("func_end", DebugFrameInfo.Number), FuncBeginSym); - EmitFrameMoves("func_begin", DebugFrameInfo.Number, DebugFrameInfo.Moves, - false); + EmitFrameMoves(FuncBeginSym, DebugFrameInfo.Moves, false); Asm->EmitAlignment(2, 0, 0, false); - Asm->OutStreamer.EmitLabel(getDWLabel("debug_frame_end", - DebugFrameInfo.Number)); + Asm->OutStreamer.EmitLabel(DebugFrameEnd); } /// emitDebugPubNames - Emit visible names into a debug pubnames section. @@ -2860,14 +2955,23 @@ void DwarfDebug::emitDebugStr() { Asm->OutStreamer.SwitchSection( Asm->getObjFileLowering().getDwarfStrSection()); - // For each of strings in the string pool. - for (unsigned StringID = 1, N = StringPool.size(); StringID <= N; ++StringID){ + // Get all of the string pool entries and put them in an array by their ID so + // we can sort them. + SmallVector<std::pair<unsigned, + StringMapEntry<std::pair<MCSymbol*, unsigned> >*>, 64> Entries; + + for (StringMap<std::pair<MCSymbol*, unsigned> >::iterator + I = StringPool.begin(), E = StringPool.end(); I != E; ++I) + Entries.push_back(std::make_pair(I->second.second, &*I)); + + array_pod_sort(Entries.begin(), Entries.end()); + + for (unsigned i = 0, e = Entries.size(); i != e; ++i) { // Emit a label for reference from debug information entries. - Asm->OutStreamer.EmitLabel(getDWLabel("string", StringID)); + Asm->OutStreamer.EmitLabel(Entries[i].second->getValue().first); // Emit the string itself. - const std::string &String = StringPool[StringID]; - Asm->OutStreamer.EmitBytes(StringRef(String.c_str(), String.size()+1), 0); + Asm->OutStreamer.EmitBytes(Entries[i].second->getKey(), 0/*addrspace*/); } } @@ -2960,13 +3064,12 @@ void DwarfDebug::emitDebugInlineInfo() { Asm->OutStreamer.EmitBytes(Name, 0); Asm->OutStreamer.EmitIntValue(0, 1, 0); // nul terminator. } else - EmitSectionOffset(getDWLabel("string", - StringPool.idFor(getRealLinkageName(LName))), + EmitSectionOffset(getStringPoolEntry(getRealLinkageName(LName)), getTempLabel("section_str"), true); Asm->OutStreamer.AddComment("Function name"); - EmitSectionOffset(getDWLabel("string", StringPool.idFor(Name)), - getTempLabel("section_str"), false, true); + EmitSectionOffset(getStringPoolEntry(Name), getTempLabel("section_str"), + false, true); EmitULEB128(Labels.size(), "Inline count"); for (SmallVector<InlineInfoLabels, 4>::iterator LI = Labels.begin(), diff --git a/lib/CodeGen/AsmPrinter/DwarfDebug.h b/lib/CodeGen/AsmPrinter/DwarfDebug.h index 40d1d646761a..d6634e1f5d10 100644 --- a/lib/CodeGen/AsmPrinter/DwarfDebug.h +++ b/lib/CodeGen/AsmPrinter/DwarfDebug.h @@ -45,16 +45,16 @@ class SrcLineInfo { unsigned Line; // Source line number. unsigned Column; // Source column. unsigned SourceID; // Source ID number. - unsigned LabelID; // Label in code ID number. + MCSymbol *Label; // Label in code ID number. public: - SrcLineInfo(unsigned L, unsigned C, unsigned S, unsigned I) - : Line(L), Column(C), SourceID(S), LabelID(I) {} + SrcLineInfo(unsigned L, unsigned C, unsigned S, MCSymbol *label) + : Line(L), Column(C), SourceID(S), Label(label) {} // Accessors unsigned getLine() const { return Line; } unsigned getColumn() const { return Column; } unsigned getSourceID() const { return SourceID; } - unsigned getLabelID() const { return LabelID; } + MCSymbol *getLabel() const { return Label; } }; class DwarfDebug : public DwarfPrinter { @@ -102,9 +102,12 @@ class DwarfDebug : public DwarfPrinter { /// std::vector<DIEValue *> DIEValues; - /// StringPool - A UniqueVector of strings used by indirect references. - /// - UniqueVector<std::string> StringPool; + /// StringPool - A String->Symbol mapping of strings used by indirect + /// references. + StringMap<std::pair<MCSymbol*, unsigned> > StringPool; + unsigned NextStringPoolNumber; + + MCSymbol *getStringPoolEntry(StringRef Str); /// SectionMap - Provides a unique id per text section. /// @@ -126,7 +129,8 @@ class DwarfDebug : public DwarfPrinter { // DbgScope *CurrentFnDbgScope; - /// DbgScopeMap - Tracks the scopes in the current function. + /// DbgScopeMap - Tracks the scopes in the current function. Owns the + /// contained DbgScope*s. /// DenseMap<MDNode *, DbgScope *> DbgScopeMap; @@ -135,11 +139,12 @@ class DwarfDebug : public DwarfPrinter { DenseMap<MDNode *, DbgScope *> ConcreteScopes; /// AbstractScopes - Tracks the abstract scopes a module. These scopes are - /// not included DbgScopeMap. + /// not included DbgScopeMap. AbstractScopes owns its DbgScope*s. DenseMap<MDNode *, DbgScope *> AbstractScopes; SmallVector<DbgScope *, 4>AbstractScopesList; - /// AbstractVariables - Collection on abstract variables. + /// AbstractVariables - Collection on abstract variables. Owned by the + /// DbgScopes in AbstractScopes. DenseMap<MDNode *, DbgVariable *> AbstractVariables; /// InliendSubprogramDIEs - Collection of subprgram DIEs that are marked @@ -225,7 +230,7 @@ class DwarfDebug : public DwarfPrinter { /// createDIEEntry - Creates a new DIEEntry to be a proxy for a debug /// information entry. - DIEEntry *createDIEEntry(DIE *Entry = NULL); + DIEEntry *createDIEEntry(DIE *Entry); /// addUInt - Add an unsigned integer attribute data and value. /// @@ -356,6 +361,8 @@ class DwarfDebug : public DwarfPrinter { /// findAbstractVariable - Find abstract variable associated with Var. DbgVariable *findAbstractVariable(DIVariable &Var, unsigned FrameIdx, DILocation &Loc); + DbgVariable *findAbstractVariable(DIVariable &Var, const MachineInstr *MI, + DILocation &Loc); /// updateSubprogramScopeDIE - Find DIE for the given subprogram and /// attach appropriate DW_AT_low_pc and DW_AT_high_pc attributes. @@ -473,7 +480,7 @@ class DwarfDebug : public DwarfPrinter { /// as well. unsigned GetOrCreateSourceID(StringRef DirName, StringRef FileName); - CompileUnit *constructCompileUnit(MDNode *N); + void constructCompileUnit(MDNode *N); void constructGlobalVariableDIE(MDNode *N); diff --git a/lib/CodeGen/AsmPrinter/DwarfException.cpp b/lib/CodeGen/AsmPrinter/DwarfException.cpp index 11a01fe51ea6..4946b4c3c25e 100644 --- a/lib/CodeGen/AsmPrinter/DwarfException.cpp +++ b/lib/CodeGen/AsmPrinter/DwarfException.cpp @@ -50,25 +50,6 @@ DwarfException::~DwarfException() { delete ExceptionTimer; } -/// CreateLabelDiff - Emit a label and subtract it from the expression we -/// already have. This is equivalent to emitting "foo - .", but we have to emit -/// the label for "." directly. -const MCExpr *DwarfException::CreateLabelDiff(const MCExpr *ExprRef, - const char *LabelName, - unsigned Index) { - SmallString<64> Name; - raw_svector_ostream(Name) << MAI->getPrivateGlobalPrefix() - << LabelName << Asm->getFunctionNumber() - << "_" << Index; - MCSymbol *DotSym = Asm->OutContext.GetOrCreateTemporarySymbol(Name.str()); - Asm->OutStreamer.EmitLabel(DotSym); - - return MCBinaryExpr::CreateSub(ExprRef, - MCSymbolRefExpr::Create(DotSym, - Asm->OutContext), - Asm->OutContext); -} - /// EmitCIE - Emit a Common Information Entry (CIE). This holds information that /// is shared among many Frame Description Entries. There is at least one CIE /// in every non-empty .debug_frame section. @@ -169,7 +150,7 @@ void DwarfException::EmitCIE(const Function *PersonalityFn, unsigned Index) { // Indicate locations of general callee saved registers in frame. std::vector<MachineMove> Moves; RI->getInitialFrameState(Moves); - EmitFrameMoves(NULL, 0, Moves, true); + EmitFrameMoves(0, Moves, true); // On Darwin the linker honors the alignment of eh_frame, which means it must // be 8-byte on 64-bit targets to match what gcc does. Otherwise you get @@ -240,12 +221,13 @@ void DwarfException::EmitFDE(const FunctionEHFrameInfo &EHFrameInfo) { EHFrameInfo.PersonalityIndex), true, true); + MCSymbol *EHFuncBeginSym = getDWLabel("eh_func_begin", EHFrameInfo.Number); Asm->OutStreamer.AddComment("FDE initial location"); - EmitReference(getDWLabel("eh_func_begin", EHFrameInfo.Number), FDEEncoding); + EmitReference(EHFuncBeginSym, FDEEncoding); + Asm->OutStreamer.AddComment("FDE address range"); - EmitDifference(getDWLabel("eh_func_end", EHFrameInfo.Number), - getDWLabel("eh_func_begin", EHFrameInfo.Number), + EmitDifference(getDWLabel("eh_func_end", EHFrameInfo.Number),EHFuncBeginSym, SizeOfEncodedValue(FDEEncoding) == 4); // If there is a personality and landing pads then point to the language @@ -265,8 +247,7 @@ void DwarfException::EmitFDE(const FunctionEHFrameInfo &EHFrameInfo) { } // Indicate locations of function specific callee saved registers in frame. - EmitFrameMoves("eh_func_begin", EHFrameInfo.Number, EHFrameInfo.Moves, - true); + EmitFrameMoves(EHFuncBeginSym, EHFrameInfo.Moves, true); // On Darwin the linker honors the alignment of eh_frame, which means it // must be 8-byte on 64-bit targets to match what gcc does. Otherwise you @@ -473,7 +454,7 @@ ComputeCallSiteTable(SmallVectorImpl<CallSiteEntry> &CallSites, const SmallVectorImpl<const LandingPadInfo *> &LandingPads, const SmallVectorImpl<unsigned> &FirstActions) { // The end label of the previous invoke or nounwind try-range. - unsigned LastLabel = 0; + MCSymbol *LastLabel = 0; // Whether there is a potentially throwing instruction (currently this means // an ordinary call) between the end of the previous try-range and now. @@ -490,14 +471,11 @@ ComputeCallSiteTable(SmallVectorImpl<CallSiteEntry> &CallSites, if (!MI->isLabel()) { if (MI->getDesc().isCall()) SawPotentiallyThrowing |= !CallToNoUnwindFunction(MI); - continue; } - unsigned BeginLabel = MI->getOperand(0).getImm(); - assert(BeginLabel && "Invalid label!"); - // End of the previous try-range? + MCSymbol *BeginLabel = MI->getOperand(0).getMCSymbol(); if (BeginLabel == LastLabel) SawPotentiallyThrowing = false; @@ -599,7 +577,6 @@ void DwarfException::EmitExceptionTable() { const std::vector<GlobalVariable *> &TypeInfos = MMI->getTypeInfos(); const std::vector<unsigned> &FilterIds = MMI->getFilterIds(); const std::vector<LandingPadInfo> &PadInfos = MMI->getLandingPads(); - if (PadInfos.empty()) return; // Sort the landing pads in order of their type ids. This is used to fold // duplicate actions. @@ -624,7 +601,7 @@ void DwarfException::EmitExceptionTable() { for (unsigned i = 0, N = LandingPads.size(); i != N; ++i) { const LandingPadInfo *LandingPad = LandingPads[i]; for (unsigned j = 0, E = LandingPad->BeginLabels.size(); j != E; ++j) { - unsigned BeginLabel = LandingPad->BeginLabels[j]; + MCSymbol *BeginLabel = LandingPad->BeginLabels[j]; assert(!PadMap.count(BeginLabel) && "Duplicate landing pad labels!"); PadRange P = { i, j }; PadMap[BeginLabel] = P; @@ -809,45 +786,33 @@ void DwarfException::EmitExceptionTable() { for (SmallVectorImpl<CallSiteEntry>::const_iterator I = CallSites.begin(), E = CallSites.end(); I != E; ++I) { const CallSiteEntry &S = *I; - const char *BeginTag; - unsigned BeginNumber; - - if (!S.BeginLabel) { - BeginTag = "eh_func_begin"; - BeginNumber = SubprogramCount; - } else { - BeginTag = "label"; - BeginNumber = S.BeginLabel; - } - + + MCSymbol *EHFuncBeginSym = getDWLabel("eh_func_begin", SubprogramCount); + + MCSymbol *BeginLabel = S.BeginLabel; + if (BeginLabel == 0) + BeginLabel = EHFuncBeginSym; + MCSymbol *EndLabel = S.EndLabel; + if (EndLabel == 0) + EndLabel = getDWLabel("eh_func_end", SubprogramCount); + // 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. Asm->OutStreamer.AddComment("Region start"); - EmitSectionOffset(getDWLabel(BeginTag, BeginNumber), - getDWLabel("eh_func_begin", SubprogramCount), - true, true); - + EmitSectionOffset(BeginLabel, EHFuncBeginSym, true, true); + Asm->OutStreamer.AddComment("Region length"); - if (!S.EndLabel) - EmitDifference(getDWLabel("eh_func_end", SubprogramCount), - getDWLabel(BeginTag, BeginNumber), - true); - else - EmitDifference(getDWLabel("label", S.EndLabel), - getDWLabel(BeginTag, BeginNumber), true); + EmitDifference(EndLabel, BeginLabel, true); // Offset of the landing pad, counted in 16-byte bundles relative to the // @LPStart address. Asm->OutStreamer.AddComment("Landing pad"); - if (!S.PadLabel) { + if (!S.PadLabel) Asm->OutStreamer.EmitIntValue(0, 4/*size*/, 0/*addrspace*/); - } else { - EmitSectionOffset(getDWLabel("label", S.PadLabel), - getDWLabel("eh_func_begin", SubprogramCount), - true, true); - } + else + EmitSectionOffset(S.PadLabel, EHFuncBeginSym, true, true); // Offset of the first associated action record, relative to the start of // the action table. This value is biased by 1 (1 indicates the start of @@ -947,16 +912,11 @@ void DwarfException::BeginFunction(const MachineFunction *MF) { this->MF = MF; shouldEmitTable = shouldEmitMoves = false; - // Map all labels and get rid of any dead landing pads. - MMI->TidyLandingPads(); - // If any landing pads survive, we need an EH table. - if (!MMI->getLandingPads().empty()) - shouldEmitTable = true; + shouldEmitTable = !MMI->getLandingPads().empty(); // See if we need frame move info. - if (!MF->getFunction()->doesNotThrow() || UnwindTablesMandatory) - shouldEmitMoves = true; + shouldEmitMoves = !MF->getFunction()->doesNotThrow() || UnwindTablesMandatory; if (shouldEmitMoves || shouldEmitTable) // Assumes in correct section after the entry point. @@ -978,7 +938,16 @@ void DwarfException::EndFunction() { ExceptionTimer->startTimer(); Asm->OutStreamer.EmitLabel(getDWLabel("eh_func_end", SubprogramCount)); - EmitExceptionTable(); + + // Record if this personality index uses a landing pad. + bool HasLandingPad = !MMI->getLandingPads().empty(); + UsesLSDA[MMI->getPersonalityIndex()] |= HasLandingPad; + + // Map all labels and get rid of any dead landing pads. + MMI->TidyLandingPads(); + + if (HasLandingPad) + EmitExceptionTable(); const TargetLoweringObjectFile &TLOF = Asm->getObjFileLowering(); MCSymbol *FunctionEHSym = @@ -993,9 +962,6 @@ void DwarfException::EndFunction() { MMI->getFrameMoves(), MF->getFunction())); - // Record if this personality index uses a landing pad. - UsesLSDA[MMI->getPersonalityIndex()] |= !MMI->getLandingPads().empty(); - if (TimePassesIsEnabled) ExceptionTimer->stopTimer(); } diff --git a/lib/CodeGen/AsmPrinter/DwarfException.h b/lib/CodeGen/AsmPrinter/DwarfException.h index 3db1a00802d6..4bc4a458c04e 100644 --- a/lib/CodeGen/AsmPrinter/DwarfException.h +++ b/lib/CodeGen/AsmPrinter/DwarfException.h @@ -111,13 +111,6 @@ class DwarfException : public DwarfPrinter { /// PadLT - Order landing pads lexicographically by type id. static bool PadLT(const LandingPadInfo *L, const LandingPadInfo *R); - struct KeyInfo { - static inline unsigned getEmptyKey() { return -1U; } - static inline unsigned getTombstoneKey() { return -2U; } - static unsigned getHashValue(const unsigned &Key) { return Key; } - static bool isEqual(unsigned LHS, unsigned RHS) { return LHS == RHS; } - }; - /// PadRange - Structure holding a try-range and the associated landing pad. struct PadRange { // The index of the landing pad. @@ -126,7 +119,7 @@ class DwarfException : public DwarfPrinter { unsigned RangeIndex; }; - typedef DenseMap<unsigned, PadRange, KeyInfo> RangeMapType; + typedef DenseMap<MCSymbol *, PadRange> RangeMapType; /// ActionEntry - Structure describing an entry in the actions table. struct ActionEntry { @@ -138,11 +131,11 @@ class DwarfException : public DwarfPrinter { /// CallSiteEntry - Structure describing an entry in the call-site table. struct CallSiteEntry { // The 'try-range' is BeginLabel .. EndLabel. - unsigned BeginLabel; // zero indicates the start of the function. - unsigned EndLabel; // zero indicates the end of the function. + MCSymbol *BeginLabel; // zero indicates the start of the function. + MCSymbol *EndLabel; // zero indicates the end of the function. // The landing pad starts at PadLabel. - unsigned PadLabel; // zero indicates that there is no landing pad. + MCSymbol *PadLabel; // zero indicates that there is no landing pad. unsigned Action; }; @@ -169,11 +162,6 @@ class DwarfException : public DwarfPrinter { const SmallVectorImpl<unsigned> &FirstActions); void EmitExceptionTable(); - /// CreateLabelDiff - Emit a label and subtract it from the expression we - /// already have. This is equivalent to emitting "foo - .", but we have to - /// emit the label for "." directly. - const MCExpr *CreateLabelDiff(const MCExpr *ExprRef, const char *LabelName, - unsigned Index); public: //===--------------------------------------------------------------------===// // Main entry points. diff --git a/lib/CodeGen/AsmPrinter/DwarfPrinter.cpp b/lib/CodeGen/AsmPrinter/DwarfPrinter.cpp index 7890e5cc1798..e21269604e24 100644 --- a/lib/CodeGen/AsmPrinter/DwarfPrinter.cpp +++ b/lib/CodeGen/AsmPrinter/DwarfPrinter.cpp @@ -189,7 +189,9 @@ void DwarfPrinter::EmitULEB128(unsigned Value, const char *Desc, void DwarfPrinter::EmitReference(const MCSymbol *Sym, unsigned Encoding) const { const TargetLoweringObjectFile &TLOF = Asm->getObjFileLowering(); - const MCExpr *Exp = TLOF.getSymbolForDwarfReference(Sym, Asm->MMI, Encoding); + const MCExpr *Exp = TLOF.getExprForDwarfReference(Sym, Asm->Mang, + Asm->MMI, Encoding, + Asm->OutStreamer); Asm->OutStreamer.EmitValue(Exp, SizeOfEncodedValue(Encoding), /*addrspace*/0); } @@ -197,7 +199,8 @@ void DwarfPrinter::EmitReference(const GlobalValue *GV, unsigned Encoding)const{ const TargetLoweringObjectFile &TLOF = Asm->getObjFileLowering(); const MCExpr *Exp = - TLOF.getSymbolForDwarfGlobalReference(GV, Asm->Mang, Asm->MMI, Encoding); + TLOF.getExprForDwarfGlobalReference(GV, Asm->Mang, Asm->MMI, Encoding, + Asm->OutStreamer); Asm->OutStreamer.EmitValue(Exp, SizeOfEncodedValue(Encoding), /*addrspace*/0); } @@ -222,10 +225,11 @@ void DwarfPrinter::EmitSectionOffset(const MCSymbol *Label, return EmitDifference(Label, Section, IsSmall); // On COFF targets, we have to emit the weird .secrel32 directive. - if (const char *SecOffDir = MAI->getDwarfSectionOffsetDirective()) + if (const char *SecOffDir = MAI->getDwarfSectionOffsetDirective()) { // FIXME: MCize. Asm->O << SecOffDir << Label->getName(); - else { + Asm->OutStreamer.AddBlankLine(); + } else { unsigned Size = IsSmall ? 4 : TD->getPointerSize(); Asm->OutStreamer.EmitSymbolValue(Label, Size, 0/*AddrSpace*/); } @@ -233,34 +237,31 @@ void DwarfPrinter::EmitSectionOffset(const MCSymbol *Label, /// EmitFrameMoves - Emit frame instructions to describe the layout of the /// frame. -void DwarfPrinter::EmitFrameMoves(const char *BaseLabel, unsigned BaseLabelID, +void DwarfPrinter::EmitFrameMoves(MCSymbol *BaseLabel, const std::vector<MachineMove> &Moves, bool isEH) { - int stackGrowth = - Asm->TM.getFrameInfo()->getStackGrowthDirection() == - TargetFrameInfo::StackGrowsUp ? - TD->getPointerSize() : -TD->getPointerSize(); - bool IsLocal = BaseLabel && strcmp(BaseLabel, "label") == 0; - + int stackGrowth = TD->getPointerSize(); + if (Asm->TM.getFrameInfo()->getStackGrowthDirection() != + TargetFrameInfo::StackGrowsUp) + stackGrowth *= -1; + for (unsigned i = 0, N = Moves.size(); i < N; ++i) { const MachineMove &Move = Moves[i]; - unsigned LabelID = Move.getLabelID(); - + MCSymbol *Label = Move.getLabel(); // Throw out move if the label is invalid. - if (LabelID && MMI->isLabelDeleted(LabelID)) - continue; + if (Label && !Label->isDefined()) continue; // Not emitted, in dead code. const MachineLocation &Dst = Move.getDestination(); const MachineLocation &Src = Move.getSource(); // Advance row if new location. - if (BaseLabel && LabelID && (BaseLabelID != LabelID || !IsLocal)) { - EmitCFAByte(dwarf::DW_CFA_advance_loc4); - EmitDifference(getDWLabel("label", LabelID), - getDWLabel(BaseLabel, BaseLabelID), true); - BaseLabelID = LabelID; - BaseLabel = "label"; - IsLocal = true; + if (BaseLabel && Label) { + MCSymbol *ThisSym = Label; + if (ThisSym != BaseLabel) { + EmitCFAByte(dwarf::DW_CFA_advance_loc4); + EmitDifference(ThisSym, BaseLabel, true); + BaseLabel = ThisSym; + } } // If advancing cfa. diff --git a/lib/CodeGen/AsmPrinter/DwarfPrinter.h b/lib/CodeGen/AsmPrinter/DwarfPrinter.h index 5e2d806a66a5..0b94645a8c7b 100644 --- a/lib/CodeGen/AsmPrinter/DwarfPrinter.h +++ b/lib/CodeGen/AsmPrinter/DwarfPrinter.h @@ -122,7 +122,7 @@ public: /// EmitFrameMoves - Emit frame instructions to describe the layout of the /// frame. - void EmitFrameMoves(const char *BaseLabel, unsigned BaseLabelID, + void EmitFrameMoves(MCSymbol *BaseLabel, const std::vector<MachineMove> &Moves, bool isEH); }; diff --git a/lib/CodeGen/AsmPrinter/OcamlGCPrinter.cpp b/lib/CodeGen/AsmPrinter/OcamlGCPrinter.cpp index 3531ed603933..fa840e133a5e 100644 --- a/lib/CodeGen/AsmPrinter/OcamlGCPrinter.cpp +++ b/lib/CodeGen/AsmPrinter/OcamlGCPrinter.cpp @@ -15,8 +15,9 @@ #include "llvm/CodeGen/AsmPrinter.h" #include "llvm/CodeGen/GCMetadataPrinter.h" #include "llvm/Module.h" -#include "llvm/MC/MCStreamer.h" #include "llvm/MC/MCAsmInfo.h" +#include "llvm/MC/MCSymbol.h" +#include "llvm/MC/MCStreamer.h" #include "llvm/Target/TargetData.h" #include "llvm/Target/TargetLoweringObjectFile.h" #include "llvm/Target/TargetMachine.h" @@ -138,8 +139,7 @@ void OcamlGCMetadataPrinter::finishAssembly(raw_ostream &OS, AsmPrinter &AP, llvm_report_error(Msg.str()); // Very rude! } - OS << AddressDirective - << MAI.getPrivateGlobalPrefix() << "label" << J->Num << '\n'; + OS << AddressDirective << J->Label->getName() << '\n'; AP.EmitInt16(FrameSize); |