diff options
Diffstat (limited to 'lib/CodeGen/AsmPrinter')
-rw-r--r-- | lib/CodeGen/AsmPrinter/AsmPrinter.cpp | 1452 | ||||
-rw-r--r-- | lib/CodeGen/AsmPrinter/DIE.cpp | 70 | ||||
-rw-r--r-- | lib/CodeGen/AsmPrinter/DIE.h | 29 | ||||
-rw-r--r-- | lib/CodeGen/AsmPrinter/DwarfDebug.cpp | 387 | ||||
-rw-r--r-- | lib/CodeGen/AsmPrinter/DwarfDebug.h | 18 | ||||
-rw-r--r-- | lib/CodeGen/AsmPrinter/DwarfException.cpp | 191 | ||||
-rw-r--r-- | lib/CodeGen/AsmPrinter/DwarfException.h | 10 | ||||
-rw-r--r-- | lib/CodeGen/AsmPrinter/DwarfPrinter.cpp | 214 | ||||
-rw-r--r-- | lib/CodeGen/AsmPrinter/DwarfPrinter.h | 266 | ||||
-rw-r--r-- | lib/CodeGen/AsmPrinter/Makefile | 5 | ||||
-rw-r--r-- | lib/CodeGen/AsmPrinter/OcamlGCPrinter.cpp | 13 |
11 files changed, 1225 insertions, 1430 deletions
diff --git a/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/lib/CodeGen/AsmPrinter/AsmPrinter.cpp index 876f628..f4d8864 100644 --- a/lib/CodeGen/AsmPrinter/AsmPrinter.cpp +++ b/lib/CodeGen/AsmPrinter/AsmPrinter.cpp @@ -16,6 +16,7 @@ #include "llvm/DerivedTypes.h" #include "llvm/Constants.h" #include "llvm/Module.h" +#include "llvm/CodeGen/DwarfWriter.h" #include "llvm/CodeGen/GCMetadataPrinter.h" #include "llvm/CodeGen/MachineConstantPool.h" #include "llvm/CodeGen/MachineFrameInfo.h" @@ -23,18 +24,19 @@ #include "llvm/CodeGen/MachineJumpTableInfo.h" #include "llvm/CodeGen/MachineLoopInfo.h" #include "llvm/CodeGen/MachineModuleInfo.h" -#include "llvm/CodeGen/DwarfWriter.h" #include "llvm/Analysis/DebugInfo.h" #include "llvm/MC/MCContext.h" +#include "llvm/MC/MCExpr.h" #include "llvm/MC/MCInst.h" #include "llvm/MC/MCSection.h" #include "llvm/MC/MCStreamer.h" #include "llvm/MC/MCSymbol.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/Format.h" #include "llvm/Support/FormattedStream.h" -#include "llvm/Support/Mangler.h" #include "llvm/MC/MCAsmInfo.h" +#include "llvm/Target/Mangler.h" #include "llvm/Target/TargetData.h" #include "llvm/Target/TargetInstrInfo.h" #include "llvm/Target/TargetLowering.h" @@ -43,7 +45,6 @@ #include "llvm/Target/TargetRegisterInfo.h" #include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/SmallString.h" -#include "llvm/ADT/StringExtras.h" #include <cerrno> using namespace llvm; @@ -51,6 +52,15 @@ static cl::opt<cl::boolOrDefault> AsmVerbose("asm-verbose", cl::desc("Add comments to directives."), cl::init(cl::BOU_UNSET)); +static bool getVerboseAsm(bool VDef) { + switch (AsmVerbose) { + default: + case cl::BOU_UNSET: return VDef; + case cl::BOU_TRUE: return true; + case cl::BOU_FALSE: return false; + } +} + char AsmPrinter::ID = 0; AsmPrinter::AsmPrinter(formatted_raw_ostream &o, TargetMachine &tm, const MCAsmInfo *T, bool VDef) @@ -59,16 +69,13 @@ AsmPrinter::AsmPrinter(formatted_raw_ostream &o, TargetMachine &tm, OutContext(*new MCContext()), // FIXME: Pass instprinter to streamer. - OutStreamer(*createAsmStreamer(OutContext, O, *T, 0)), + OutStreamer(*createAsmStreamer(OutContext, O, *T, + TM.getTargetData()->isLittleEndian(), + getVerboseAsm(VDef), 0)), - LastMI(0), LastFn(0), Counter(~0U), - PrevDLT(0, 0, ~0U, ~0U) { + LastMI(0), LastFn(0), Counter(~0U), PrevDLT(NULL) { DW = 0; MMI = 0; - switch (AsmVerbose) { - case cl::BOU_UNSET: VerboseAsm = VDef; break; - case cl::BOU_TRUE: VerboseAsm = true; break; - case cl::BOU_FALSE: VerboseAsm = false; break; - } + VerboseAsm = getVerboseAsm(VDef); } AsmPrinter::~AsmPrinter() { @@ -103,22 +110,15 @@ bool AsmPrinter::doInitialization(Module &M) { const_cast<TargetLoweringObjectFile&>(getObjFileLowering()) .Initialize(OutContext, TM); - Mang = new Mangler(M, MAI->getGlobalPrefix(), MAI->getPrivateGlobalPrefix(), - MAI->getLinkerPrivateGlobalPrefix()); - - if (MAI->doesAllowQuotesInName()) - Mang->setUseQuotes(true); - - if (MAI->doesAllowNameToStartWithDigit()) - Mang->setSymbolsCanStartWithDigit(true); + Mang = new Mangler(*MAI); // Allow the target to emit any magic that it wants at the start of the file. EmitStartOfAsmFile(M); if (MAI->hasSingleParameterDotFile()) { - /* Very minimal debug info. It is ignored if we emit actual - debug info. If we don't, this at least helps the user find where - a function came from. */ + // Very minimal debug info. It is ignored if we emit actual + // debug info. If we don't, this at least helps the user find where + // a function came from. O << "\t.file\t\"" << M.getModuleIdentifier() << "\"\n"; } @@ -144,11 +144,148 @@ bool AsmPrinter::doInitialization(Module &M) { return false; } +/// EmitGlobalVariable - Emit the specified global variable to the .s file. +void AsmPrinter::EmitGlobalVariable(const GlobalVariable *GV) { + if (!GV->hasInitializer()) // External globals require no code. + return; + + // Check to see if this is a special global used by LLVM, if so, emit it. + if (EmitSpecialLLVMGlobal(GV)) + return; + + MCSymbol *GVSym = GetGlobalValueSymbol(GV); + printVisibility(GVSym, GV->getVisibility()); + + if (MAI->hasDotTypeDotSizeDirective()) { + O << "\t.type\t" << *GVSym; + if (MAI->getCommentString()[0] != '@') + O << ",@object\n"; + else + O << ",%object\n"; + } + + SectionKind GVKind = TargetLoweringObjectFile::getKindForGlobal(GV, TM); + + const TargetData *TD = TM.getTargetData(); + unsigned Size = TD->getTypeAllocSize(GV->getType()->getElementType()); + unsigned AlignLog = TD->getPreferredAlignmentLog(GV); + + // Handle common and BSS local symbols (.lcomm). + if (GVKind.isCommon() || GVKind.isBSSLocal()) { + if (Size == 0) Size = 1; // .comm Foo, 0 is undefined, avoid it. + + if (VerboseAsm) { + WriteAsOperand(OutStreamer.GetCommentOS(), GV, + /*PrintType=*/false, GV->getParent()); + OutStreamer.GetCommentOS() << '\n'; + } + + // Handle common symbols. + if (GVKind.isCommon()) { + // .comm _foo, 42, 4 + OutStreamer.EmitCommonSymbol(GVSym, Size, 1 << AlignLog); + return; + } + + // Handle local BSS symbols. + if (MAI->hasMachoZeroFillDirective()) { + const MCSection *TheSection = + getObjFileLowering().SectionForGlobal(GV, GVKind, Mang, TM); + // .zerofill __DATA, __bss, _foo, 400, 5 + OutStreamer.EmitZerofill(TheSection, GVSym, Size, 1 << AlignLog); + return; + } + + if (MAI->hasLCOMMDirective()) { + // .lcomm _foo, 42 + OutStreamer.EmitLocalCommonSymbol(GVSym, Size); + return; + } + + // .local _foo + OutStreamer.EmitSymbolAttribute(GVSym, MCSA_Local); + // .comm _foo, 42, 4 + OutStreamer.EmitCommonSymbol(GVSym, Size, 1 << AlignLog); + return; + } + + const MCSection *TheSection = + getObjFileLowering().SectionForGlobal(GV, GVKind, Mang, TM); + + // Handle the zerofill directive on darwin, which is a special form of BSS + // emission. + if (GVKind.isBSSExtern() && MAI->hasMachoZeroFillDirective()) { + // .globl _foo + OutStreamer.EmitSymbolAttribute(GVSym, MCSA_Global); + // .zerofill __DATA, __common, _foo, 400, 5 + OutStreamer.EmitZerofill(TheSection, GVSym, Size, 1 << AlignLog); + return; + } + + OutStreamer.SwitchSection(TheSection); + + // TODO: Factor into an 'emit linkage' thing that is shared with function + // bodies. + switch (GV->getLinkage()) { + case GlobalValue::CommonLinkage: + case GlobalValue::LinkOnceAnyLinkage: + case GlobalValue::LinkOnceODRLinkage: + case GlobalValue::WeakAnyLinkage: + case GlobalValue::WeakODRLinkage: + case GlobalValue::LinkerPrivateLinkage: + if (MAI->getWeakDefDirective() != 0) { + // .globl _foo + OutStreamer.EmitSymbolAttribute(GVSym, MCSA_Global); + // .weak_definition _foo + OutStreamer.EmitSymbolAttribute(GVSym, MCSA_WeakDefinition); + } else if (const char *LinkOnce = MAI->getLinkOnceDirective()) { + // .globl _foo + OutStreamer.EmitSymbolAttribute(GVSym, MCSA_Global); + // .linkonce same_size + O << LinkOnce; + } else { + // .weak _foo + OutStreamer.EmitSymbolAttribute(GVSym, MCSA_Weak); + } + break; + case GlobalValue::DLLExportLinkage: + case GlobalValue::AppendingLinkage: + // FIXME: appending linkage variables should go into a section of + // their name or something. For now, just emit them as external. + case GlobalValue::ExternalLinkage: + // If external or appending, declare as a global symbol. + // .globl _foo + OutStreamer.EmitSymbolAttribute(GVSym, MCSA_Global); + break; + case GlobalValue::PrivateLinkage: + case GlobalValue::InternalLinkage: + break; + default: + llvm_unreachable("Unknown linkage type!"); + } + + EmitAlignment(AlignLog, GV); + if (VerboseAsm) { + WriteAsOperand(OutStreamer.GetCommentOS(), GV, + /*PrintType=*/false, GV->getParent()); + OutStreamer.GetCommentOS() << '\n'; + } + OutStreamer.EmitLabel(GVSym); + + EmitGlobalConstant(GV->getInitializer()); + + if (MAI->hasDotTypeDotSizeDirective()) + O << "\t.size\t" << *GVSym << ", " << Size << '\n'; + + OutStreamer.AddBlankLine(); +} + + bool AsmPrinter::doFinalization(Module &M) { // Emit global variables. for (Module::const_global_iterator I = M.global_begin(), E = M.global_end(); I != E; ++I) - PrintGlobalVariable(I); + EmitGlobalVariable(I); // Emit final debug information. if (MAI->doesSupportDebugInformation() || MAI->doesSupportExceptionHandling()) @@ -164,35 +301,37 @@ bool AsmPrinter::doFinalization(Module &M) { // Print out module-level global variables here. for (Module::const_global_iterator I = M.global_begin(), E = M.global_end(); I != E; ++I) { - if (I->hasExternalWeakLinkage()) - O << MAI->getWeakRefDirective() << Mang->getMangledName(I) << '\n'; + if (!I->hasExternalWeakLinkage()) continue; + OutStreamer.EmitSymbolAttribute(GetGlobalValueSymbol(I), + MCSA_WeakReference); } for (Module::const_iterator I = M.begin(), E = M.end(); I != E; ++I) { - if (I->hasExternalWeakLinkage()) - O << MAI->getWeakRefDirective() << Mang->getMangledName(I) << '\n'; + if (!I->hasExternalWeakLinkage()) continue; + OutStreamer.EmitSymbolAttribute(GetGlobalValueSymbol(I), + MCSA_WeakReference); } } if (MAI->getSetDirective()) { - O << '\n'; + OutStreamer.AddBlankLine(); for (Module::const_alias_iterator I = M.alias_begin(), E = M.alias_end(); I != E; ++I) { - std::string Name = Mang->getMangledName(I); + MCSymbol *Name = GetGlobalValueSymbol(I); const GlobalValue *GV = cast<GlobalValue>(I->getAliasedGlobal()); - std::string Target = Mang->getMangledName(GV); + MCSymbol *Target = GetGlobalValueSymbol(GV); if (I->hasExternalLinkage() || !MAI->getWeakRefDirective()) - O << "\t.globl\t" << Name << '\n'; + OutStreamer.EmitSymbolAttribute(Name, MCSA_Global); else if (I->hasWeakLinkage()) - O << MAI->getWeakRefDirective() << Name << '\n'; - else if (!I->hasLocalLinkage()) - llvm_unreachable("Invalid alias linkage"); + OutStreamer.EmitSymbolAttribute(Name, MCSA_WeakReference); + else + assert(I->hasLocalLinkage() && "Invalid alias linkage"); printVisibility(Name, I->getVisibility()); - O << MAI->getSetDirective() << ' ' << Name << ", " << Target << '\n'; + O << MAI->getSetDirective() << ' ' << *Name << ", " << *Target << '\n'; } } @@ -206,9 +345,8 @@ bool AsmPrinter::doFinalization(Module &M) { // to be executable. Some targets have a directive to declare this. Function *InitTrampolineIntrinsic = M.getFunction("llvm.init.trampoline"); if (!InitTrampolineIntrinsic || InitTrampolineIntrinsic->use_empty()) - if (MAI->getNonexecutableStackDirective()) - O << MAI->getNonexecutableStackDirective() << '\n'; - + if (MCSection *S = MAI->getNonexecutableStackSection(OutContext)) + OutStreamer.SwitchSection(S); // Allow the target to emit any magic that it wants at the end of the file, // after everything else has gone out. @@ -222,8 +360,8 @@ bool AsmPrinter::doFinalization(Module &M) { } void AsmPrinter::SetupMachineFunction(MachineFunction &MF) { - // What's my mangled name? - CurrentFnName = Mang->getMangledName(MF.getFunction()); + // Get the function symbol. + CurrentFnSym = GetGlobalValueSymbol(MF.getFunction()); IncrementFunctionNumber(); if (VerboseAsm) @@ -307,19 +445,20 @@ void AsmPrinter::EmitConstantPool(MachineConstantPool *MCP) { // Emit inter-object padding for alignment. unsigned AlignMask = CPE.getAlignment() - 1; unsigned NewOffset = (Offset + AlignMask) & ~AlignMask; - EmitZeros(NewOffset - Offset); + OutStreamer.EmitFill(NewOffset - Offset, 0/*fillval*/, 0/*addrspace*/); const Type *Ty = CPE.getType(); Offset = NewOffset + TM.getTargetData()->getTypeAllocSize(Ty); - O << MAI->getPrivateGlobalPrefix() << "CPI" << getFunctionNumber() << '_' - << CPI << ':'; + // Emit the label with a comment on it. if (VerboseAsm) { - O.PadToColumn(MAI->getCommentColumn()); - O << MAI->getCommentString() << " constant "; - WriteTypeSymbolic(O, CPE.getType(), MF->getFunction()->getParent()); + OutStreamer.GetCommentOS() << "constant pool "; + WriteTypeSymbolic(OutStreamer.GetCommentOS(), CPE.getType(), + MF->getFunction()->getParent()); + OutStreamer.GetCommentOS() << '\n'; } - O << '\n'; + OutStreamer.EmitLabel(GetCPISymbol(CPI)); + if (CPE.isMachineConstantPoolEntry()) EmitMachineConstantPoolValue(CPE.Val.MachineCPVal); else @@ -381,14 +520,11 @@ void AsmPrinter::EmitJumpTableInfo(MachineJumpTableInfo *MJTI, // before each jump table. The first label is never referenced, but tells // the assembler and linker the extents of the jump table object. The // second label is actually referenced by the code. - if (JTInDiffSection && MAI->getLinkerPrivateGlobalPrefix()[0]) { - O << MAI->getLinkerPrivateGlobalPrefix() - << "JTI" << getFunctionNumber() << '_' << i << ":\n"; - } - - O << MAI->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber() - << '_' << i << ":\n"; - + if (JTInDiffSection && MAI->getLinkerPrivateGlobalPrefix()[0]) + OutStreamer.EmitLabel(GetJTISymbol(i, true)); + + OutStreamer.EmitLabel(GetJTISymbol(i)); + for (unsigned ii = 0, ee = JTBBs.size(); ii != ee; ++ii) { printPICJumpTableEntry(MJTI, JTBBs[ii], i); O << '\n'; @@ -418,17 +554,16 @@ void AsmPrinter::printPICJumpTableEntry(const MachineJumpTableInfo *MJTI, // If we're emitting non-PIC code, then emit the entries as direct // references to the target basic blocks. if (!isPIC) { - GetMBBSymbol(MBB->getNumber())->print(O, MAI); + O << *GetMBBSymbol(MBB->getNumber()); } else if (MAI->getSetDirective()) { O << MAI->getPrivateGlobalPrefix() << getFunctionNumber() << '_' << uid << "_set_" << MBB->getNumber(); } else { - GetMBBSymbol(MBB->getNumber())->print(O, MAI); + O << *GetMBBSymbol(MBB->getNumber()); // If the arch uses custom Jump Table directives, don't calc relative to - // JT + // JT. if (!HadJTEntryDirective) - O << '-' << MAI->getPrivateGlobalPrefix() << "JTI" - << getFunctionNumber() << '_' << uid; + O << '-' << *GetJTISymbol(uid); } } @@ -438,7 +573,7 @@ void AsmPrinter::printPICJumpTableEntry(const MachineJumpTableInfo *MJTI, /// do nothing and return false. bool AsmPrinter::EmitSpecialLLVMGlobal(const GlobalVariable *GV) { if (GV->getName() == "llvm.used") { - if (MAI->getUsedDirective() != 0) // No need to emit this at all. + if (MAI->hasNoDeadStrip()) // No need to emit this at all. EmitLLVMUsedList(GV->getInitializer()); return true; } @@ -458,6 +593,13 @@ bool AsmPrinter::EmitSpecialLLVMGlobal(const GlobalVariable *GV) { OutStreamer.SwitchSection(getObjFileLowering().getStaticCtorSection()); EmitAlignment(Align, 0); EmitXXStructorList(GV->getInitializer()); + + if (TM.getRelocationModel() == Reloc::Static && + MAI->hasStaticCtorDtorReferenceInStaticMode()) { + StringRef Sym(".constructors_used"); + OutStreamer.EmitSymbolAttribute(OutContext.GetOrCreateSymbol(Sym), + MCSA_Reference); + } return true; } @@ -465,6 +607,13 @@ bool AsmPrinter::EmitSpecialLLVMGlobal(const GlobalVariable *GV) { OutStreamer.SwitchSection(getObjFileLowering().getStaticDtorSection()); EmitAlignment(Align, 0); EmitXXStructorList(GV->getInitializer()); + + if (TM.getRelocationModel() == Reloc::Static && + MAI->hasStaticCtorDtorReferenceInStaticMode()) { + StringRef Sym(".destructors_used"); + OutStreamer.EmitSymbolAttribute(OutContext.GetOrCreateSymbol(Sym), + MCSA_Reference); + } return true; } @@ -475,8 +624,6 @@ bool AsmPrinter::EmitSpecialLLVMGlobal(const GlobalVariable *GV) { /// global in the specified llvm.used list for which emitUsedDirectiveFor /// is true, as being used with this directive. void AsmPrinter::EmitLLVMUsedList(Constant *List) { - const char *Directive = MAI->getUsedDirective(); - // Should be an array of 'i8*'. ConstantArray *InitList = dyn_cast<ConstantArray>(List); if (InitList == 0) return; @@ -484,11 +631,9 @@ void AsmPrinter::EmitLLVMUsedList(Constant *List) { for (unsigned i = 0, e = InitList->getNumOperands(); i != e; ++i) { const GlobalValue *GV = dyn_cast<GlobalValue>(InitList->getOperand(i)->stripPointerCasts()); - if (GV && getObjFileLowering().shouldEmitUsedDirectiveFor(GV, Mang)) { - O << Directive; - EmitConstantValueOnly(InitList->getOperand(i)); - O << '\n'; - } + if (GV && getObjFileLowering().shouldEmitUsedDirectiveFor(GV, Mang)) + OutStreamer.EmitSymbolAttribute(GetGlobalValueSymbol(GV), + MCSA_NoDeadStrip); } } @@ -510,189 +655,35 @@ void AsmPrinter::EmitXXStructorList(Constant *List) { } } - -//===----------------------------------------------------------------------===// -/// LEB 128 number encoding. - -/// PrintULEB128 - Print a series of hexadecimal values (separated by commas) -/// representing an unsigned leb128 value. -void AsmPrinter::PrintULEB128(unsigned Value) const { - char Buffer[20]; - do { - unsigned char Byte = static_cast<unsigned char>(Value & 0x7f); - Value >>= 7; - if (Value) Byte |= 0x80; - O << "0x" << utohex_buffer(Byte, Buffer+20); - if (Value) O << ", "; - } while (Value); -} - -/// PrintSLEB128 - Print a series of hexadecimal values (separated by commas) -/// representing a signed leb128 value. -void AsmPrinter::PrintSLEB128(int Value) const { - int Sign = Value >> (8 * sizeof(Value) - 1); - bool IsMore; - char Buffer[20]; - - do { - unsigned char Byte = static_cast<unsigned char>(Value & 0x7f); - Value >>= 7; - IsMore = Value != Sign || ((Byte ^ Sign) & 0x40) != 0; - if (IsMore) Byte |= 0x80; - O << "0x" << utohex_buffer(Byte, Buffer+20); - if (IsMore) O << ", "; - } while (IsMore); -} - //===--------------------------------------------------------------------===// // Emission and print routines // -/// PrintHex - Print a value as a hexadecimal value. -/// -void AsmPrinter::PrintHex(int Value) const { - char Buffer[20]; - O << "0x" << utohex_buffer(static_cast<unsigned>(Value), Buffer+20); -} - -/// 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 AsmPrinter::EOL() const { - O << '\n'; -} - -void AsmPrinter::EOL(const std::string &Comment) const { - if (VerboseAsm && !Comment.empty()) { - O.PadToColumn(MAI->getCommentColumn()); - O << MAI->getCommentString() - << ' ' - << Comment; - } - O << '\n'; -} - -void AsmPrinter::EOL(const char* Comment) const { - if (VerboseAsm && *Comment) { - O.PadToColumn(MAI->getCommentColumn()); - O << MAI->getCommentString() - << ' ' - << Comment; - } - O << '\n'; -} - -static const char *DecodeDWARFEncoding(unsigned Encoding) { - switch (Encoding) { - case dwarf::DW_EH_PE_absptr: - return "absptr"; - case dwarf::DW_EH_PE_omit: - return "omit"; - case dwarf::DW_EH_PE_pcrel: - return "pcrel"; - case dwarf::DW_EH_PE_udata4: - return "udata4"; - case dwarf::DW_EH_PE_udata8: - return "udata8"; - case dwarf::DW_EH_PE_sdata4: - return "sdata4"; - case dwarf::DW_EH_PE_sdata8: - return "sdata8"; - case dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_udata4: - return "pcrel udata4"; - case dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4: - return "pcrel sdata4"; - case dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_udata8: - return "pcrel udata8"; - case dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata8: - return "pcrel sdata8"; - case dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel |dwarf::DW_EH_PE_udata4: - return "indirect pcrel udata4"; - case dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel |dwarf::DW_EH_PE_sdata4: - return "indirect pcrel sdata4"; - case dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel |dwarf::DW_EH_PE_udata8: - return "indirect pcrel udata8"; - case dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel |dwarf::DW_EH_PE_sdata8: - return "indirect pcrel sdata8"; - } - - return 0; -} - -void AsmPrinter::EOL(const char *Comment, unsigned Encoding) const { - if (VerboseAsm && *Comment) { - O.PadToColumn(MAI->getCommentColumn()); - O << MAI->getCommentString() - << ' ' - << Comment; - - if (const char *EncStr = DecodeDWARFEncoding(Encoding)) - O << " (" << EncStr << ')'; - } - O << '\n'; -} - -/// EmitULEB128Bytes - Emit an assembler byte data directive to compose an -/// unsigned leb128 value. -void AsmPrinter::EmitULEB128Bytes(unsigned Value) const { - if (MAI->hasLEB128()) { - O << "\t.uleb128\t" - << Value; - } else { - O << MAI->getData8bitsDirective(); - PrintULEB128(Value); - } -} - -/// EmitSLEB128Bytes - print an assembler byte data directive to compose a -/// signed leb128 value. -void AsmPrinter::EmitSLEB128Bytes(int Value) const { - if (MAI->hasLEB128()) { - O << "\t.sleb128\t" - << Value; - } else { - O << MAI->getData8bitsDirective(); - PrintSLEB128(Value); - } -} - /// EmitInt8 - Emit a byte directive and value. /// void AsmPrinter::EmitInt8(int Value) const { - O << MAI->getData8bitsDirective(); - PrintHex(Value & 0xFF); + OutStreamer.EmitIntValue(Value, 1, 0/*addrspace*/); } /// EmitInt16 - Emit a short directive and value. /// void AsmPrinter::EmitInt16(int Value) const { - O << MAI->getData16bitsDirective(); - PrintHex(Value & 0xFFFF); + OutStreamer.EmitIntValue(Value, 2, 0/*addrspace*/); } /// EmitInt32 - Emit a long directive and value. /// void AsmPrinter::EmitInt32(int Value) const { - O << MAI->getData32bitsDirective(); - PrintHex(Value); + OutStreamer.EmitIntValue(Value, 4, 0/*addrspace*/); } /// EmitInt64 - Emit a long long directive and value. /// void AsmPrinter::EmitInt64(uint64_t Value) const { - if (MAI->getData64bitsDirective()) { - O << MAI->getData64bitsDirective(); - PrintHex(Value); - } else { - if (TM.getTargetData()->isBigEndian()) { - EmitInt32(unsigned(Value >> 32)); O << '\n'; - EmitInt32(unsigned(Value)); - } else { - EmitInt32(unsigned(Value)); O << '\n'; - EmitInt32(unsigned(Value >> 32)); - } - } + OutStreamer.EmitIntValue(Value, 8, 0/*addrspace*/); } + /// toOctal - Convert the low order bits of X into an octal digit. /// static inline char toOctal(int X) { @@ -725,31 +716,8 @@ static void printStringChar(formatted_raw_ostream &O, unsigned char C) { } } -/// EmitString - Emit a string with quotes and a null terminator. -/// Special characters are emitted properly. -/// \literal (Eg. '\t') \endliteral -void AsmPrinter::EmitString(const StringRef String) const { - EmitString(String.data(), String.size()); -} - -void AsmPrinter::EmitString(const char *String, unsigned Size) const { - const char* AscizDirective = MAI->getAscizDirective(); - if (AscizDirective) - O << AscizDirective; - else - O << MAI->getAsciiDirective(); - O << '\"'; - for (unsigned i = 0; i < Size; ++i) - printStringChar(O, String[i]); - if (AscizDirective) - O << '\"'; - else - O << "\\0\""; -} - - /// EmitFile - Emit a .file directive. -void AsmPrinter::EmitFile(unsigned Number, const std::string &Name) const { +void AsmPrinter::EmitFile(unsigned Number, StringRef Name) const { O << "\t.file\t" << Number << " \""; for (unsigned i = 0, N = Name.size(); i < N; ++i) printStringChar(O, Name[i]); @@ -788,52 +756,26 @@ void AsmPrinter::EmitAlignment(unsigned NumBits, const GlobalValue *GV, OutStreamer.EmitValueToAlignment(1 << NumBits, FillValue, 1, 0); } -/// EmitZeros - Emit a block of zeros. +/// LowerConstant - Lower the specified LLVM Constant to an MCExpr. /// -void AsmPrinter::EmitZeros(uint64_t NumZeros, unsigned AddrSpace) const { - if (NumZeros) { - if (MAI->getZeroDirective()) { - O << MAI->getZeroDirective() << NumZeros; - if (MAI->getZeroDirectiveSuffix()) - O << MAI->getZeroDirectiveSuffix(); - O << '\n'; - } else { - for (; NumZeros; --NumZeros) - O << MAI->getData8bitsDirective(AddrSpace) << "0\n"; - } - } -} - -// Print out the specified constant, without a storage class. Only the -// constants valid in constant expressions can occur here. -void AsmPrinter::EmitConstantValueOnly(const Constant *CV) { - if (CV->isNullValue() || isa<UndefValue>(CV)) { - O << '0'; - return; - } - - if (const ConstantInt *CI = dyn_cast<ConstantInt>(CV)) { - O << CI->getZExtValue(); - return; - } +static const MCExpr *LowerConstant(const Constant *CV, AsmPrinter &AP) { + MCContext &Ctx = AP.OutContext; - if (const GlobalValue *GV = dyn_cast<GlobalValue>(CV)) { - // This is a constant address for a global variable or function. Use the - // name of the variable or function as the address value. - O << Mang->getMangledName(GV); - return; - } + if (CV->isNullValue() || isa<UndefValue>(CV)) + return MCConstantExpr::Create(0, Ctx); + + if (const ConstantInt *CI = dyn_cast<ConstantInt>(CV)) + return MCConstantExpr::Create(CI->getZExtValue(), Ctx); - if (const BlockAddress *BA = dyn_cast<BlockAddress>(CV)) { - GetBlockAddressSymbol(BA)->print(O, MAI); - return; - } + if (const GlobalValue *GV = dyn_cast<GlobalValue>(CV)) + return MCSymbolRefExpr::Create(AP.GetGlobalValueSymbol(GV), Ctx); + if (const BlockAddress *BA = dyn_cast<BlockAddress>(CV)) + return MCSymbolRefExpr::Create(AP.GetBlockAddressSymbol(BA), Ctx); const ConstantExpr *CE = dyn_cast<ConstantExpr>(CV); if (CE == 0) { - llvm_unreachable("Unknown constant value!"); - O << '0'; - return; + llvm_unreachable("Unknown constant value to lower!"); + return MCConstantExpr::Create(0, Ctx); } switch (CE->getOpcode()) { @@ -845,406 +787,214 @@ void AsmPrinter::EmitConstantValueOnly(const Constant *CV) { case Instruction::SIToFP: case Instruction::FPToUI: case Instruction::FPToSI: - default: - llvm_unreachable("FIXME: Don't support this constant cast expr"); + default: llvm_unreachable("FIXME: Don't support this constant cast expr"); case Instruction::GetElementPtr: { - // generate a symbolic expression for the byte address - const TargetData *TD = TM.getTargetData(); - const Constant *ptrVal = CE->getOperand(0); - SmallVector<Value*, 8> idxVec(CE->op_begin()+1, CE->op_end()); - int64_t Offset = TD->getIndexedOffset(ptrVal->getType(), &idxVec[0], - idxVec.size()); + const TargetData &TD = *AP.TM.getTargetData(); + // Generate a symbolic expression for the byte address + const Constant *PtrVal = CE->getOperand(0); + SmallVector<Value*, 8> IdxVec(CE->op_begin()+1, CE->op_end()); + int64_t Offset = TD.getIndexedOffset(PtrVal->getType(), &IdxVec[0], + IdxVec.size()); + + const MCExpr *Base = LowerConstant(CE->getOperand(0), AP); if (Offset == 0) - return EmitConstantValueOnly(ptrVal); + return Base; // Truncate/sext the offset to the pointer size. - if (TD->getPointerSizeInBits() != 64) { - int SExtAmount = 64-TD->getPointerSizeInBits(); + if (TD.getPointerSizeInBits() != 64) { + int SExtAmount = 64-TD.getPointerSizeInBits(); Offset = (Offset << SExtAmount) >> SExtAmount; } - if (Offset) - O << '('; - EmitConstantValueOnly(ptrVal); - if (Offset > 0) - O << ") + " << Offset; - else - O << ") - " << -Offset; - return; + return MCBinaryExpr::CreateAdd(Base, MCConstantExpr::Create(Offset, Ctx), + Ctx); } + + case Instruction::Trunc: + // We emit the value and depend on the assembler to truncate the generated + // expression properly. This is important for differences between + // blockaddress labels. Since the two labels are in the same function, it + // is reasonable to treat their delta as a 32-bit value. + // FALL THROUGH. case Instruction::BitCast: - return EmitConstantValueOnly(CE->getOperand(0)); + return LowerConstant(CE->getOperand(0), AP); case Instruction::IntToPtr: { + const TargetData &TD = *AP.TM.getTargetData(); // Handle casts to pointers by changing them into casts to the appropriate // integer type. This promotes constant folding and simplifies this code. - const TargetData *TD = TM.getTargetData(); Constant *Op = CE->getOperand(0); - Op = ConstantExpr::getIntegerCast(Op, TD->getIntPtrType(CV->getContext()), + Op = ConstantExpr::getIntegerCast(Op, TD.getIntPtrType(CV->getContext()), false/*ZExt*/); - return EmitConstantValueOnly(Op); + return LowerConstant(Op, AP); } case Instruction::PtrToInt: { + const TargetData &TD = *AP.TM.getTargetData(); // Support only foldable casts to/from pointers that can be eliminated by // changing the pointer to the appropriately sized integer type. Constant *Op = CE->getOperand(0); const Type *Ty = CE->getType(); - const TargetData *TD = TM.getTargetData(); + + const MCExpr *OpExpr = LowerConstant(Op, AP); // We can emit the pointer value into this slot if the slot is an - // integer slot greater or equal to the size of the pointer. - if (TD->getTypeAllocSize(Ty) == TD->getTypeAllocSize(Op->getType())) - return EmitConstantValueOnly(Op); - - O << "(("; - EmitConstantValueOnly(Op); - APInt ptrMask = - APInt::getAllOnesValue(TD->getTypeAllocSizeInBits(Op->getType())); - - SmallString<40> S; - ptrMask.toStringUnsigned(S); - O << ") & " << S.str() << ')'; - return; + // integer slot equal to the size of the pointer. + if (TD.getTypeAllocSize(Ty) == TD.getTypeAllocSize(Op->getType())) + return OpExpr; + + // Otherwise the pointer is smaller than the resultant integer, mask off + // the high bits so we are sure to get a proper truncation if the input is + // a constant expr. + unsigned InBits = TD.getTypeAllocSizeInBits(Op->getType()); + const MCExpr *MaskExpr = MCConstantExpr::Create(~0ULL >> (64-InBits), Ctx); + return MCBinaryExpr::CreateAnd(OpExpr, MaskExpr, Ctx); } - case Instruction::Trunc: - // We emit the value and depend on the assembler to truncate the generated - // expression properly. This is important for differences between - // blockaddress labels. Since the two labels are in the same function, it - // is reasonable to treat their delta as a 32-bit value. - return EmitConstantValueOnly(CE->getOperand(0)); - case Instruction::Add: case Instruction::Sub: case Instruction::And: case Instruction::Or: - case Instruction::Xor: - O << '('; - EmitConstantValueOnly(CE->getOperand(0)); - O << ')'; + case Instruction::Xor: { + const MCExpr *LHS = LowerConstant(CE->getOperand(0), AP); + const MCExpr *RHS = LowerConstant(CE->getOperand(1), AP); switch (CE->getOpcode()) { - case Instruction::Add: - O << " + "; - break; - case Instruction::Sub: - O << " - "; - break; - case Instruction::And: - O << " & "; - break; - case Instruction::Or: - O << " | "; - break; - case Instruction::Xor: - O << " ^ "; - break; - default: - break; + default: llvm_unreachable("Unknown binary operator constant cast expr"); + case Instruction::Add: return MCBinaryExpr::CreateAdd(LHS, RHS, Ctx); + case Instruction::Sub: return MCBinaryExpr::CreateSub(LHS, RHS, Ctx); + case Instruction::And: return MCBinaryExpr::CreateAnd(LHS, RHS, Ctx); + case Instruction::Or: return MCBinaryExpr::CreateOr (LHS, RHS, Ctx); + case Instruction::Xor: return MCBinaryExpr::CreateXor(LHS, RHS, Ctx); } - O << '('; - EmitConstantValueOnly(CE->getOperand(1)); - O << ')'; - break; } -} - -/// printAsCString - Print the specified array as a C compatible string, only if -/// the predicate isString is true. -/// -static void printAsCString(formatted_raw_ostream &O, const ConstantArray *CVA, - unsigned LastElt) { - assert(CVA->isString() && "Array is not string compatible!"); - - O << '\"'; - for (unsigned i = 0; i != LastElt; ++i) { - unsigned char C = - (unsigned char)cast<ConstantInt>(CVA->getOperand(i))->getZExtValue(); - printStringChar(O, C); } - O << '\"'; } -/// EmitString - Emit a zero-byte-terminated string constant. -/// -void AsmPrinter::EmitString(const ConstantArray *CVA) const { - unsigned NumElts = CVA->getNumOperands(); - if (MAI->getAscizDirective() && NumElts && - cast<ConstantInt>(CVA->getOperand(NumElts-1))->getZExtValue() == 0) { - O << MAI->getAscizDirective(); - printAsCString(O, CVA, NumElts-1); - } else { - O << MAI->getAsciiDirective(); - printAsCString(O, CVA, NumElts); +static void EmitGlobalConstantArray(const ConstantArray *CA, unsigned AddrSpace, + AsmPrinter &AP) { + if (AddrSpace != 0 || !CA->isString()) { + // Not a string. Print the values in successive locations + for (unsigned i = 0, e = CA->getNumOperands(); i != e; ++i) + AP.EmitGlobalConstant(CA->getOperand(i), AddrSpace); + return; } - O << '\n'; -} + + // Otherwise, it can be emitted as .ascii. + SmallVector<char, 128> TmpVec; + TmpVec.reserve(CA->getNumOperands()); + for (unsigned i = 0, e = CA->getNumOperands(); i != e; ++i) + TmpVec.push_back(cast<ConstantInt>(CA->getOperand(i))->getZExtValue()); -void AsmPrinter::EmitGlobalConstantArray(const ConstantArray *CVA, - unsigned AddrSpace) { - if (CVA->isString()) { - EmitString(CVA); - } else { // Not a string. Print the values in successive locations - for (unsigned i = 0, e = CVA->getNumOperands(); i != e; ++i) - EmitGlobalConstant(CVA->getOperand(i), AddrSpace); - } + AP.OutStreamer.EmitBytes(StringRef(TmpVec.data(), TmpVec.size()), AddrSpace); } -void AsmPrinter::EmitGlobalConstantVector(const ConstantVector *CP) { - const VectorType *PTy = CP->getType(); - - for (unsigned I = 0, E = PTy->getNumElements(); I < E; ++I) - EmitGlobalConstant(CP->getOperand(I)); +static void EmitGlobalConstantVector(const ConstantVector *CV, + unsigned AddrSpace, AsmPrinter &AP) { + for (unsigned i = 0, e = CV->getType()->getNumElements(); i != e; ++i) + AP.EmitGlobalConstant(CV->getOperand(i), AddrSpace); } -void AsmPrinter::EmitGlobalConstantStruct(const ConstantStruct *CVS, - unsigned AddrSpace) { +static void EmitGlobalConstantStruct(const ConstantStruct *CS, + unsigned AddrSpace, AsmPrinter &AP) { // Print the fields in successive locations. Pad to align if needed! - const TargetData *TD = TM.getTargetData(); - unsigned Size = TD->getTypeAllocSize(CVS->getType()); - const StructLayout *cvsLayout = TD->getStructLayout(CVS->getType()); - uint64_t sizeSoFar = 0; - for (unsigned i = 0, e = CVS->getNumOperands(); i != e; ++i) { - const Constant* field = CVS->getOperand(i); + const TargetData *TD = AP.TM.getTargetData(); + unsigned Size = TD->getTypeAllocSize(CS->getType()); + const StructLayout *Layout = TD->getStructLayout(CS->getType()); + uint64_t SizeSoFar = 0; + for (unsigned i = 0, e = CS->getNumOperands(); i != e; ++i) { + const Constant *Field = CS->getOperand(i); // Check if padding is needed and insert one or more 0s. - uint64_t fieldSize = TD->getTypeAllocSize(field->getType()); - uint64_t padSize = ((i == e-1 ? Size : cvsLayout->getElementOffset(i+1)) - - cvsLayout->getElementOffset(i)) - fieldSize; - sizeSoFar += fieldSize + padSize; + uint64_t FieldSize = TD->getTypeAllocSize(Field->getType()); + uint64_t PadSize = ((i == e-1 ? Size : Layout->getElementOffset(i+1)) + - Layout->getElementOffset(i)) - FieldSize; + SizeSoFar += FieldSize + PadSize; // Now print the actual field value. - EmitGlobalConstant(field, AddrSpace); + AP.EmitGlobalConstant(Field, AddrSpace); // Insert padding - this may include padding to increase the size of the // current field up to the ABI size (if the struct is not packed) as well // as padding to ensure that the next field starts at the right offset. - EmitZeros(padSize, AddrSpace); + AP.OutStreamer.EmitZeros(PadSize, AddrSpace); } - assert(sizeSoFar == cvsLayout->getSizeInBytes() && + assert(SizeSoFar == Layout->getSizeInBytes() && "Layout of constant struct may be incorrect!"); } -void AsmPrinter::EmitGlobalConstantFP(const ConstantFP *CFP, - unsigned AddrSpace) { +static void EmitGlobalConstantFP(const ConstantFP *CFP, unsigned AddrSpace, + AsmPrinter &AP) { // FP Constants are printed as integer constants to avoid losing - // precision... - LLVMContext &Context = CFP->getContext(); - const TargetData *TD = TM.getTargetData(); + // precision. if (CFP->getType()->isDoubleTy()) { - double Val = CFP->getValueAPF().convertToDouble(); // for comment only - uint64_t i = CFP->getValueAPF().bitcastToAPInt().getZExtValue(); - if (MAI->getData64bitsDirective(AddrSpace)) { - O << MAI->getData64bitsDirective(AddrSpace) << i; - if (VerboseAsm) { - O.PadToColumn(MAI->getCommentColumn()); - O << MAI->getCommentString() << " double " << Val; - } - O << '\n'; - } else if (TD->isBigEndian()) { - O << MAI->getData32bitsDirective(AddrSpace) << unsigned(i >> 32); - if (VerboseAsm) { - O.PadToColumn(MAI->getCommentColumn()); - O << MAI->getCommentString() - << " most significant word of double " << Val; - } - O << '\n'; - O << MAI->getData32bitsDirective(AddrSpace) << unsigned(i); - if (VerboseAsm) { - O.PadToColumn(MAI->getCommentColumn()); - O << MAI->getCommentString() - << " least significant word of double " << Val; - } - O << '\n'; - } else { - O << MAI->getData32bitsDirective(AddrSpace) << unsigned(i); - if (VerboseAsm) { - O.PadToColumn(MAI->getCommentColumn()); - O << MAI->getCommentString() - << " least significant word of double " << Val; - } - O << '\n'; - O << MAI->getData32bitsDirective(AddrSpace) << unsigned(i >> 32); - if (VerboseAsm) { - O.PadToColumn(MAI->getCommentColumn()); - O << MAI->getCommentString() - << " most significant word of double " << Val; - } - O << '\n'; + if (AP.VerboseAsm) { + double Val = CFP->getValueAPF().convertToDouble(); + AP.OutStreamer.GetCommentOS() << "double " << Val << '\n'; } + + uint64_t Val = CFP->getValueAPF().bitcastToAPInt().getZExtValue(); + AP.OutStreamer.EmitIntValue(Val, 8, AddrSpace); return; } if (CFP->getType()->isFloatTy()) { - float Val = CFP->getValueAPF().convertToFloat(); // for comment only - O << MAI->getData32bitsDirective(AddrSpace) - << CFP->getValueAPF().bitcastToAPInt().getZExtValue(); - if (VerboseAsm) { - O.PadToColumn(MAI->getCommentColumn()); - O << MAI->getCommentString() << " float " << Val; + if (AP.VerboseAsm) { + float Val = CFP->getValueAPF().convertToFloat(); + AP.OutStreamer.GetCommentOS() << "float " << Val << '\n'; } - O << '\n'; + uint64_t Val = CFP->getValueAPF().bitcastToAPInt().getZExtValue(); + AP.OutStreamer.EmitIntValue(Val, 4, AddrSpace); return; } if (CFP->getType()->isX86_FP80Ty()) { // all long double variants are printed as hex // api needed to prevent premature destruction - APInt api = CFP->getValueAPF().bitcastToAPInt(); - const uint64_t *p = api.getRawData(); - // Convert to double so we can print the approximate val as a comment. - APFloat DoubleVal = CFP->getValueAPF(); - bool ignored; - DoubleVal.convert(APFloat::IEEEdouble, APFloat::rmNearestTiesToEven, - &ignored); - if (TD->isBigEndian()) { - O << MAI->getData16bitsDirective(AddrSpace) << uint16_t(p[1]); - if (VerboseAsm) { - O.PadToColumn(MAI->getCommentColumn()); - O << MAI->getCommentString() - << " most significant halfword of x86_fp80 ~" - << DoubleVal.convertToDouble(); - } - O << '\n'; - O << MAI->getData16bitsDirective(AddrSpace) << uint16_t(p[0] >> 48); - if (VerboseAsm) { - O.PadToColumn(MAI->getCommentColumn()); - O << MAI->getCommentString() << " next halfword"; - } - O << '\n'; - O << MAI->getData16bitsDirective(AddrSpace) << uint16_t(p[0] >> 32); - if (VerboseAsm) { - O.PadToColumn(MAI->getCommentColumn()); - O << MAI->getCommentString() << " next halfword"; - } - O << '\n'; - O << MAI->getData16bitsDirective(AddrSpace) << uint16_t(p[0] >> 16); - if (VerboseAsm) { - O.PadToColumn(MAI->getCommentColumn()); - O << MAI->getCommentString() << " next halfword"; - } - O << '\n'; - O << MAI->getData16bitsDirective(AddrSpace) << uint16_t(p[0]); - if (VerboseAsm) { - O.PadToColumn(MAI->getCommentColumn()); - O << MAI->getCommentString() - << " least significant halfword"; - } - O << '\n'; - } else { - O << MAI->getData16bitsDirective(AddrSpace) << uint16_t(p[0]); - if (VerboseAsm) { - O.PadToColumn(MAI->getCommentColumn()); - O << MAI->getCommentString() - << " least significant halfword of x86_fp80 ~" - << DoubleVal.convertToDouble(); - } - O << '\n'; - O << MAI->getData16bitsDirective(AddrSpace) << uint16_t(p[0] >> 16); - if (VerboseAsm) { - O.PadToColumn(MAI->getCommentColumn()); - O << MAI->getCommentString() - << " next halfword"; - } - O << '\n'; - O << MAI->getData16bitsDirective(AddrSpace) << uint16_t(p[0] >> 32); - if (VerboseAsm) { - O.PadToColumn(MAI->getCommentColumn()); - O << MAI->getCommentString() - << " next halfword"; - } - O << '\n'; - O << MAI->getData16bitsDirective(AddrSpace) << uint16_t(p[0] >> 48); - if (VerboseAsm) { - O.PadToColumn(MAI->getCommentColumn()); - O << MAI->getCommentString() - << " next halfword"; - } - O << '\n'; - O << MAI->getData16bitsDirective(AddrSpace) << uint16_t(p[1]); - if (VerboseAsm) { - O.PadToColumn(MAI->getCommentColumn()); - O << MAI->getCommentString() - << " most significant halfword"; - } - O << '\n'; + APInt API = CFP->getValueAPF().bitcastToAPInt(); + const uint64_t *p = API.getRawData(); + if (AP.VerboseAsm) { + // Convert to double so we can print the approximate val as a comment. + APFloat DoubleVal = CFP->getValueAPF(); + bool ignored; + DoubleVal.convert(APFloat::IEEEdouble, APFloat::rmNearestTiesToEven, + &ignored); + AP.OutStreamer.GetCommentOS() << "x86_fp80 ~= " + << DoubleVal.convertToDouble() << '\n'; } - EmitZeros(TD->getTypeAllocSize(Type::getX86_FP80Ty(Context)) - - TD->getTypeStoreSize(Type::getX86_FP80Ty(Context)), AddrSpace); + + if (AP.TM.getTargetData()->isBigEndian()) { + AP.OutStreamer.EmitIntValue(p[1], 2, AddrSpace); + AP.OutStreamer.EmitIntValue(p[0], 8, AddrSpace); + } else { + AP.OutStreamer.EmitIntValue(p[0], 8, AddrSpace); + AP.OutStreamer.EmitIntValue(p[1], 2, AddrSpace); + } + + // Emit the tail padding for the long double. + const TargetData &TD = *AP.TM.getTargetData(); + AP.OutStreamer.EmitZeros(TD.getTypeAllocSize(CFP->getType()) - + TD.getTypeStoreSize(CFP->getType()), AddrSpace); return; } - if (CFP->getType()->isPPC_FP128Ty()) { - // all long double variants are printed as hex - // api needed to prevent premature destruction - APInt api = CFP->getValueAPF().bitcastToAPInt(); - const uint64_t *p = api.getRawData(); - if (TD->isBigEndian()) { - O << MAI->getData32bitsDirective(AddrSpace) << uint32_t(p[0] >> 32); - if (VerboseAsm) { - O.PadToColumn(MAI->getCommentColumn()); - O << MAI->getCommentString() - << " most significant word of ppc_fp128"; - } - O << '\n'; - O << MAI->getData32bitsDirective(AddrSpace) << uint32_t(p[0]); - if (VerboseAsm) { - O.PadToColumn(MAI->getCommentColumn()); - O << MAI->getCommentString() - << " next word"; - } - O << '\n'; - O << MAI->getData32bitsDirective(AddrSpace) << uint32_t(p[1] >> 32); - if (VerboseAsm) { - O.PadToColumn(MAI->getCommentColumn()); - O << MAI->getCommentString() - << " next word"; - } - O << '\n'; - O << MAI->getData32bitsDirective(AddrSpace) << uint32_t(p[1]); - if (VerboseAsm) { - O.PadToColumn(MAI->getCommentColumn()); - O << MAI->getCommentString() - << " least significant word"; - } - O << '\n'; - } else { - O << MAI->getData32bitsDirective(AddrSpace) << uint32_t(p[1]); - if (VerboseAsm) { - O.PadToColumn(MAI->getCommentColumn()); - O << MAI->getCommentString() - << " least significant word of ppc_fp128"; - } - O << '\n'; - O << MAI->getData32bitsDirective(AddrSpace) << uint32_t(p[1] >> 32); - if (VerboseAsm) { - O.PadToColumn(MAI->getCommentColumn()); - O << MAI->getCommentString() - << " next word"; - } - O << '\n'; - O << MAI->getData32bitsDirective(AddrSpace) << uint32_t(p[0]); - if (VerboseAsm) { - O.PadToColumn(MAI->getCommentColumn()); - O << MAI->getCommentString() - << " next word"; - } - O << '\n'; - O << MAI->getData32bitsDirective(AddrSpace) << uint32_t(p[0] >> 32); - if (VerboseAsm) { - O.PadToColumn(MAI->getCommentColumn()); - O << MAI->getCommentString() - << " most significant word"; - } - O << '\n'; - } - return; - } else llvm_unreachable("Floating point constant type not handled"); + assert(CFP->getType()->isPPC_FP128Ty() && + "Floating point constant type not handled"); + // All long double variants are printed as hex api needed to prevent + // premature destruction. + APInt API = CFP->getValueAPF().bitcastToAPInt(); + const uint64_t *p = API.getRawData(); + if (AP.TM.getTargetData()->isBigEndian()) { + AP.OutStreamer.EmitIntValue(p[0], 8, AddrSpace); + AP.OutStreamer.EmitIntValue(p[1], 8, AddrSpace); + } else { + AP.OutStreamer.EmitIntValue(p[1], 8, AddrSpace); + AP.OutStreamer.EmitIntValue(p[0], 8, AddrSpace); + } } -void AsmPrinter::EmitGlobalConstantLargeInt(const ConstantInt *CI, - unsigned AddrSpace) { - const TargetData *TD = TM.getTargetData(); +static void EmitGlobalConstantLargeInt(const ConstantInt *CI, + unsigned AddrSpace, AsmPrinter &AP) { + const TargetData *TD = AP.TM.getTargetData(); unsigned BitWidth = CI->getBitWidth(); assert((BitWidth & 63) == 0 && "only support multiples of 64-bits"); @@ -1253,100 +1003,58 @@ void AsmPrinter::EmitGlobalConstantLargeInt(const ConstantInt *CI, // quantities at a time. const uint64_t *RawData = CI->getValue().getRawData(); for (unsigned i = 0, e = BitWidth / 64; i != e; ++i) { - uint64_t Val; - if (TD->isBigEndian()) - Val = RawData[e - i - 1]; - else - Val = RawData[i]; - - if (MAI->getData64bitsDirective(AddrSpace)) { - O << MAI->getData64bitsDirective(AddrSpace) << Val << '\n'; - continue; - } - - // Emit two 32-bit chunks, order depends on endianness. - unsigned FirstChunk = unsigned(Val), SecondChunk = unsigned(Val >> 32); - const char *FirstName = " least", *SecondName = " most"; - if (TD->isBigEndian()) { - std::swap(FirstChunk, SecondChunk); - std::swap(FirstName, SecondName); - } - - O << MAI->getData32bitsDirective(AddrSpace) << FirstChunk; - if (VerboseAsm) { - O.PadToColumn(MAI->getCommentColumn()); - O << MAI->getCommentString() - << FirstName << " significant half of i64 " << Val; - } - O << '\n'; - - O << MAI->getData32bitsDirective(AddrSpace) << SecondChunk; - if (VerboseAsm) { - O.PadToColumn(MAI->getCommentColumn()); - O << MAI->getCommentString() - << SecondName << " significant half of i64 " << Val; - } - O << '\n'; + uint64_t Val = TD->isBigEndian() ? RawData[e - i - 1] : RawData[i]; + AP.OutStreamer.EmitIntValue(Val, 8, AddrSpace); } } /// EmitGlobalConstant - Print a general LLVM constant to the .s file. void AsmPrinter::EmitGlobalConstant(const Constant *CV, unsigned AddrSpace) { - const TargetData *TD = TM.getTargetData(); - const Type *type = CV->getType(); - unsigned Size = TD->getTypeAllocSize(type); - - if (CV->isNullValue() || isa<UndefValue>(CV)) { - EmitZeros(Size, AddrSpace); - return; - } - - if (const ConstantArray *CVA = dyn_cast<ConstantArray>(CV)) { - EmitGlobalConstantArray(CVA , AddrSpace); - return; - } - - if (const ConstantStruct *CVS = dyn_cast<ConstantStruct>(CV)) { - EmitGlobalConstantStruct(CVS, AddrSpace); - return; + if (isa<ConstantAggregateZero>(CV) || isa<UndefValue>(CV)) { + uint64_t Size = TM.getTargetData()->getTypeAllocSize(CV->getType()); + return OutStreamer.EmitZeros(Size, AddrSpace); } - if (const ConstantFP *CFP = dyn_cast<ConstantFP>(CV)) { - EmitGlobalConstantFP(CFP, AddrSpace); - return; - } - if (const ConstantInt *CI = dyn_cast<ConstantInt>(CV)) { - // If we can directly emit an 8-byte constant, do it. - if (Size == 8) - if (const char *Data64Dir = MAI->getData64bitsDirective(AddrSpace)) { - O << Data64Dir << CI->getZExtValue() << '\n'; - return; - } - - // Small integers are handled below; large integers are handled here. - if (Size > 4) { - EmitGlobalConstantLargeInt(CI, AddrSpace); + unsigned Size = TM.getTargetData()->getTypeAllocSize(CV->getType()); + switch (Size) { + case 1: + case 2: + case 4: + case 8: + if (VerboseAsm) + OutStreamer.GetCommentOS() << format("0x%llx\n", CI->getZExtValue()); + OutStreamer.EmitIntValue(CI->getZExtValue(), Size, AddrSpace); + return; + default: + EmitGlobalConstantLargeInt(CI, AddrSpace, *this); return; } } - if (const ConstantVector *CP = dyn_cast<ConstantVector>(CV)) { - EmitGlobalConstantVector(CP); - return; - } + if (const ConstantArray *CVA = dyn_cast<ConstantArray>(CV)) + return EmitGlobalConstantArray(CVA, AddrSpace, *this); + + if (const ConstantStruct *CVS = dyn_cast<ConstantStruct>(CV)) + return EmitGlobalConstantStruct(CVS, AddrSpace, *this); - printDataDirective(type, AddrSpace); - EmitConstantValueOnly(CV); - if (VerboseAsm) { - if (const ConstantInt *CI = dyn_cast<ConstantInt>(CV)) { - SmallString<40> S; - CI->getValue().toStringUnsigned(S, 16); - O.PadToColumn(MAI->getCommentColumn()); - O << MAI->getCommentString() << " 0x" << S.str(); - } + if (const ConstantFP *CFP = dyn_cast<ConstantFP>(CV)) + return EmitGlobalConstantFP(CFP, AddrSpace, *this); + + if (const ConstantVector *V = dyn_cast<ConstantVector>(CV)) + return EmitGlobalConstantVector(V, AddrSpace, *this); + + if (isa<ConstantPointerNull>(CV)) { + unsigned Size = TM.getTargetData()->getTypeAllocSize(CV->getType()); + OutStreamer.EmitIntValue(0, Size, AddrSpace); + return; } - O << '\n'; + + // Otherwise, it must be a ConstantExpr. Lower it to an MCExpr, then emit it + // thread the streamer with EmitValue. + OutStreamer.EmitValue(LowerConstant(CV, *this), + TM.getTargetData()->getTypeAllocSize(CV->getType()), + AddrSpace); } void AsmPrinter::EmitMachineConstantPoolValue(MachineConstantPoolValue *MCPV) { @@ -1397,22 +1105,21 @@ void AsmPrinter::processDebugLoc(const MachineInstr *MI, DebugLoc DL = MI->getDebugLoc(); if (DL.isUnknown()) return; - DebugLocTuple CurDLT = MF->getDebugLocTuple(DL); - if (CurDLT.Scope == 0) + DILocation CurDLT = MF->getDILocation(DL); + if (CurDLT.getScope().isNull()) return; - if (BeforePrintingInsn) { - if (CurDLT != PrevDLT) { - unsigned L = DW->RecordSourceLine(CurDLT.Line, CurDLT.Col, - CurDLT.Scope); - printLabel(L); - O << '\n'; - DW->BeginScope(MI, L); - PrevDLT = CurDLT; - } - } else { + 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'; + DW->BeginScope(MI, L); + PrevDLT = CurDLT.getNode(); } } @@ -1587,9 +1294,8 @@ void AsmPrinter::printInlineAsm(const MachineInstr *MI) const { unsigned OpFlags = MI->getOperand(OpNo).getImm(); ++OpNo; // Skip over the ID number. - if (Modifier[0]=='l') // labels are target independent - GetMBBSymbol(MI->getOperand(OpNo).getMBB() - ->getNumber())->print(O, MAI); + if (Modifier[0] == 'l') // labels are target independent + O << *GetMBBSymbol(MI->getOperand(OpNo).getMBB()->getNumber()); else { AsmPrinter *AP = const_cast<AsmPrinter*>(this); if ((OpFlags & 7) == 4) { @@ -1604,8 +1310,7 @@ void AsmPrinter::printInlineAsm(const MachineInstr *MI) const { if (Error) { std::string msg; raw_string_ostream Msg(msg); - Msg << "Invalid operand found in inline asm: '" - << AsmStr << "'\n"; + Msg << "Invalid operand found in inline asm: '" << AsmStr << "'\n"; MI->print(Msg); llvm_report_error(Msg.str()); } @@ -1694,10 +1399,121 @@ MCSymbol *AsmPrinter::GetMBBSymbol(unsigned MBBID) const { SmallString<60> Name; raw_svector_ostream(Name) << MAI->getPrivateGlobalPrefix() << "BB" << getFunctionNumber() << '_' << MBBID; - return OutContext.GetOrCreateSymbol(Name.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()); +} + +/// GetJTISymbol - Return the symbol for the specified jump table entry. +MCSymbol *AsmPrinter::GetJTISymbol(unsigned JTID, bool isLinkerPrivate) const { + const char *Prefix = isLinkerPrivate ? MAI->getLinkerPrivateGlobalPrefix() : + MAI->getPrivateGlobalPrefix(); + SmallString<60> Name; + raw_svector_ostream(Name) << Prefix << "JTI" << getFunctionNumber() << '_' + << JTID; + return OutContext.GetOrCreateSymbol(Name.str()); +} + +/// GetGlobalValueSymbol - Return the MCSymbol for the specified global +/// value. +MCSymbol *AsmPrinter::GetGlobalValueSymbol(const GlobalValue *GV) const { + SmallString<60> NameStr; + Mang->getNameWithPrefix(NameStr, GV, false); + return OutContext.GetOrCreateSymbol(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. +MCSymbol *AsmPrinter::GetSymbolWithGlobalValueBase(const GlobalValue *GV, + StringRef Suffix, + bool ForcePrivate) const { + SmallString<60> NameStr; + Mang->getNameWithPrefix(NameStr, GV, ForcePrivate); + NameStr.append(Suffix.begin(), Suffix.end()); + return OutContext.GetOrCreateSymbol(NameStr.str()); +} + +/// GetExternalSymbolSymbol - Return the MCSymbol for the specified +/// ExternalSymbol. +MCSymbol *AsmPrinter::GetExternalSymbolSymbol(StringRef Sym) const { + SmallString<60> NameStr; + Mang->getNameWithPrefix(NameStr, Sym); + return OutContext.GetOrCreateSymbol(NameStr.str()); +} + + + +/// PrintParentLoopComment - Print comments about parent loops of this one. +static void PrintParentLoopComment(raw_ostream &OS, const MachineLoop *Loop, + unsigned FunctionNumber) { + if (Loop == 0) return; + PrintParentLoopComment(OS, Loop->getParentLoop(), FunctionNumber); + OS.indent(Loop->getLoopDepth()*2) + << "Parent Loop BB" << FunctionNumber << "_" + << Loop->getHeader()->getNumber() + << " Depth=" << Loop->getLoopDepth() << '\n'; +} + + +/// PrintChildLoopComment - Print comments about child loops within +/// the loop for this basic block, with nesting. +static void PrintChildLoopComment(raw_ostream &OS, const MachineLoop *Loop, + unsigned FunctionNumber) { + // Add child loop information + for (MachineLoop::iterator CL = Loop->begin(), E = Loop->end();CL != E; ++CL){ + OS.indent((*CL)->getLoopDepth()*2) + << "Child Loop BB" << FunctionNumber << "_" + << (*CL)->getHeader()->getNumber() << " Depth " << (*CL)->getLoopDepth() + << '\n'; + PrintChildLoopComment(OS, *CL, FunctionNumber); + } +} + +/// EmitComments - Pretty-print comments for basic blocks. +static void PrintBasicBlockLoopComments(const MachineBasicBlock &MBB, + const MachineLoopInfo *LI, + const AsmPrinter &AP) { + // Add loop depth information + const MachineLoop *Loop = LI->getLoopFor(&MBB); + if (Loop == 0) return; + + MachineBasicBlock *Header = Loop->getHeader(); + assert(Header && "No header for loop"); + + // If this block is not a loop header, just print out what is the loop header + // and return. + if (Header != &MBB) { + AP.OutStreamer.AddComment(" in Loop: Header=BB" + + Twine(AP.getFunctionNumber())+"_" + + Twine(Loop->getHeader()->getNumber())+ + " Depth="+Twine(Loop->getLoopDepth())); + return; + } + + // Otherwise, it is a loop header. Print out information about child and + // parent loops. + raw_ostream &OS = AP.OutStreamer.GetCommentOS(); + + PrintParentLoopComment(OS, Loop->getParentLoop(), AP.getFunctionNumber()); + + OS << "=>"; + OS.indent(Loop->getLoopDepth()*2-2); + + OS << "This "; + if (Loop->empty()) + OS << "Inner "; + OS << "Loop Header: Depth=" + Twine(Loop->getLoopDepth()) << '\n'; + + PrintChildLoopComment(OS, Loop, AP.getFunctionNumber()); +} + /// EmitBasicBlockStart - This method prints the label for the specified /// MachineBasicBlock, an alignment (if present) and a comment describing @@ -1713,38 +1529,33 @@ void AsmPrinter::EmitBasicBlockStart(const MachineBasicBlock *MBB) const { // forward references to labels without knowing what their numbers // will be. if (MBB->hasAddressTaken()) { - GetBlockAddressSymbol(MBB->getBasicBlock()->getParent(), - MBB->getBasicBlock())->print(O, MAI); - O << ':'; - if (VerboseAsm) { - O.PadToColumn(MAI->getCommentColumn()); - O << MAI->getCommentString() << " Address Taken"; - } - O << '\n'; + const BasicBlock *BB = MBB->getBasicBlock(); + if (VerboseAsm) + OutStreamer.AddComment("Address Taken"); + OutStreamer.EmitLabel(GetBlockAddressSymbol(BB->getParent(), BB)); } // Print the main label for the block. if (MBB->pred_empty() || MBB->isOnlyReachableByFallthrough()) { - if (VerboseAsm) + if (VerboseAsm) { + // NOTE: Want this comment at start of line. O << MAI->getCommentString() << " BB#" << MBB->getNumber() << ':'; + if (const BasicBlock *BB = MBB->getBasicBlock()) + if (BB->hasName()) + OutStreamer.AddComment("%" + BB->getName()); + + PrintBasicBlockLoopComments(*MBB, LI, *this); + OutStreamer.AddBlankLine(); + } } else { - GetMBBSymbol(MBB->getNumber())->print(O, MAI); - O << ':'; - if (!VerboseAsm) - O << '\n'; - } - - // Print some comments to accompany the label. - if (VerboseAsm) { - if (const BasicBlock *BB = MBB->getBasicBlock()) - if (BB->hasName()) { - O.PadToColumn(MAI->getCommentColumn()); - O << MAI->getCommentString() << ' '; - WriteAsOperand(O, BB, /*PrintType=*/false); - } + if (VerboseAsm) { + if (const BasicBlock *BB = MBB->getBasicBlock()) + if (BB->hasName()) + OutStreamer.AddComment("%" + BB->getName()); + PrintBasicBlockLoopComments(*MBB, LI, *this); + } - EmitComments(*MBB); - O << '\n'; + OutStreamer.EmitLabel(GetMBBSymbol(MBB->getNumber())); } } @@ -1756,10 +1567,9 @@ void AsmPrinter::printPICJumpTableSetLabel(unsigned uid, return; O << MAI->getSetDirective() << ' ' << MAI->getPrivateGlobalPrefix() - << getFunctionNumber() << '_' << uid << "_set_" << MBB->getNumber() << ','; - GetMBBSymbol(MBB->getNumber())->print(O, MAI); - O << '-' << MAI->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber() - << '_' << uid << '\n'; + << getFunctionNumber() << '_' << uid << "_set_" << MBB->getNumber() << ',' + << *GetMBBSymbol(MBB->getNumber()) + << '-' << *GetJTISymbol(uid) << '\n'; } void AsmPrinter::printPICJumpTableSetLabel(unsigned uid, unsigned uid2, @@ -1769,64 +1579,27 @@ void AsmPrinter::printPICJumpTableSetLabel(unsigned uid, unsigned uid2, O << MAI->getSetDirective() << ' ' << MAI->getPrivateGlobalPrefix() << getFunctionNumber() << '_' << uid << '_' << uid2 - << "_set_" << MBB->getNumber() << ','; - GetMBBSymbol(MBB->getNumber())->print(O, MAI); - O << '-' << MAI->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber() + << "_set_" << MBB->getNumber() << ',' + << *GetMBBSymbol(MBB->getNumber()) + << '-' << MAI->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber() << '_' << uid << '_' << uid2 << '\n'; } -/// printDataDirective - This method prints the asm directive for the -/// specified type. -void AsmPrinter::printDataDirective(const Type *type, unsigned AddrSpace) { - const TargetData *TD = TM.getTargetData(); - switch (type->getTypeID()) { - case Type::FloatTyID: case Type::DoubleTyID: - case Type::X86_FP80TyID: case Type::FP128TyID: case Type::PPC_FP128TyID: - assert(0 && "Should have already output floating point constant."); - default: - assert(0 && "Can't handle printing this type of thing"); - case Type::IntegerTyID: { - unsigned BitWidth = cast<IntegerType>(type)->getBitWidth(); - if (BitWidth <= 8) - O << MAI->getData8bitsDirective(AddrSpace); - else if (BitWidth <= 16) - O << MAI->getData16bitsDirective(AddrSpace); - else if (BitWidth <= 32) - O << MAI->getData32bitsDirective(AddrSpace); - else if (BitWidth <= 64) { - assert(MAI->getData64bitsDirective(AddrSpace) && - "Target cannot handle 64-bit constant exprs!"); - O << MAI->getData64bitsDirective(AddrSpace); - } else { - llvm_unreachable("Target cannot handle given data directive width!"); - } +void AsmPrinter::printVisibility(MCSymbol *Sym, unsigned Visibility) const { + MCSymbolAttr Attr = MCSA_Invalid; + + switch (Visibility) { + default: break; + case GlobalValue::HiddenVisibility: + Attr = MAI->getHiddenVisibilityAttr(); break; - } - case Type::PointerTyID: - if (TD->getPointerSize() == 8) { - assert(MAI->getData64bitsDirective(AddrSpace) && - "Target cannot handle 64-bit pointer exprs!"); - O << MAI->getData64bitsDirective(AddrSpace); - } else if (TD->getPointerSize() == 2) { - O << MAI->getData16bitsDirective(AddrSpace); - } else if (TD->getPointerSize() == 1) { - O << MAI->getData8bitsDirective(AddrSpace); - } else { - O << MAI->getData32bitsDirective(AddrSpace); - } + case GlobalValue::ProtectedVisibility: + Attr = MAI->getProtectedVisibilityAttr(); break; } -} -void AsmPrinter::printVisibility(const std::string& Name, - unsigned Visibility) const { - if (Visibility == GlobalValue::HiddenVisibility) { - if (const char *Directive = MAI->getHiddenDirective()) - O << Directive << Name << '\n'; - } else if (Visibility == GlobalValue::ProtectedVisibility) { - if (const char *Directive = MAI->getProtectedDirective()) - O << Directive << Name << '\n'; - } + if (Attr != MCSA_Invalid) + OutStreamer.EmitSymbolAttribute(Sym, Attr); } void AsmPrinter::printOffset(int64_t Offset) const { @@ -1856,8 +1629,8 @@ GCMetadataPrinter *AsmPrinter::GetOrCreateGCPrinter(GCStrategy *S) { return GMP; } - errs() << "no GCMetadataPrinter registered for GC: " << Name << "\n"; - llvm_unreachable(0); + llvm_report_error("no GCMetadataPrinter registered for GC: " + Twine(Name)); + return 0; } /// EmitComments - Pretty-print comments for instructions @@ -1868,20 +1641,20 @@ void AsmPrinter::EmitComments(const MachineInstr &MI) const { bool Newline = false; if (!MI.getDebugLoc().isUnknown()) { - DebugLocTuple DLT = MF->getDebugLocTuple(MI.getDebugLoc()); + DILocation DLT = MF->getDILocation(MI.getDebugLoc()); // Print source line info. O.PadToColumn(MAI->getCommentColumn()); O << MAI->getCommentString() << ' '; - DIScope Scope(DLT.Scope); + DIScope Scope = DLT.getScope(); // Omit the directory, because it's likely to be long and uninteresting. if (!Scope.isNull()) O << Scope.getFilename(); else O << "<unknown>"; - O << ':' << DLT.Line; - if (DLT.Col != 0) - O << ':' << DLT.Col; + O << ':' << DLT.getLineNumber(); + if (DLT.getColumnNumber() != 0) + O << ':' << DLT.getColumnNumber(); Newline = true; } @@ -1943,80 +1716,3 @@ void AsmPrinter::EmitComments(const MachineInstr &MI) const { } } -/// PrintChildLoopComment - Print comments about child loops within -/// the loop for this basic block, with nesting. -/// -static void PrintChildLoopComment(formatted_raw_ostream &O, - const MachineLoop *loop, - const MCAsmInfo *MAI, - int FunctionNumber) { - // Add child loop information - for(MachineLoop::iterator cl = loop->begin(), - clend = loop->end(); - cl != clend; - ++cl) { - MachineBasicBlock *Header = (*cl)->getHeader(); - assert(Header && "No header for loop"); - - O << '\n'; - O.PadToColumn(MAI->getCommentColumn()); - - O << MAI->getCommentString(); - O.indent(((*cl)->getLoopDepth()-1)*2) - << " Child Loop BB" << FunctionNumber << "_" - << Header->getNumber() << " Depth " << (*cl)->getLoopDepth(); - - PrintChildLoopComment(O, *cl, MAI, FunctionNumber); - } -} - -/// EmitComments - Pretty-print comments for basic blocks -void AsmPrinter::EmitComments(const MachineBasicBlock &MBB) const { - if (VerboseAsm) { - // Add loop depth information - const MachineLoop *loop = LI->getLoopFor(&MBB); - - if (loop) { - // Print a newline after bb# annotation. - O << "\n"; - O.PadToColumn(MAI->getCommentColumn()); - O << MAI->getCommentString() << " Loop Depth " << loop->getLoopDepth() - << '\n'; - - O.PadToColumn(MAI->getCommentColumn()); - - MachineBasicBlock *Header = loop->getHeader(); - assert(Header && "No header for loop"); - - if (Header == &MBB) { - O << MAI->getCommentString() << " Loop Header"; - PrintChildLoopComment(O, loop, MAI, getFunctionNumber()); - } - else { - O << MAI->getCommentString() << " Loop Header is BB" - << getFunctionNumber() << "_" << loop->getHeader()->getNumber(); - } - - if (loop->empty()) { - O << '\n'; - O.PadToColumn(MAI->getCommentColumn()); - O << MAI->getCommentString() << " Inner Loop"; - } - - // Add parent loop information - for (const MachineLoop *CurLoop = loop->getParentLoop(); - CurLoop; - CurLoop = CurLoop->getParentLoop()) { - MachineBasicBlock *Header = CurLoop->getHeader(); - assert(Header && "No header for loop"); - - O << '\n'; - O.PadToColumn(MAI->getCommentColumn()); - O << MAI->getCommentString(); - O.indent((CurLoop->getLoopDepth()-1)*2) - << " Inside Loop BB" << getFunctionNumber() << "_" - << Header->getNumber() << " Depth " << CurLoop->getLoopDepth(); - } - } - } -} diff --git a/lib/CodeGen/AsmPrinter/DIE.cpp b/lib/CodeGen/AsmPrinter/DIE.cpp index b85e11a..349e0ac 100644 --- a/lib/CodeGen/AsmPrinter/DIE.cpp +++ b/lib/CodeGen/AsmPrinter/DIE.cpp @@ -13,12 +13,16 @@ #include "DIE.h" #include "DwarfPrinter.h" +#include "llvm/ADT/Twine.h" #include "llvm/CodeGen/AsmPrinter.h" #include "llvm/MC/MCAsmInfo.h" +#include "llvm/MC/MCStreamer.h" +#include "llvm/MC/MCSymbol.h" #include "llvm/Target/TargetData.h" #include "llvm/Support/Debug.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/Format.h" +#include "llvm/Support/FormattedStream.h" using namespace llvm; //===----------------------------------------------------------------------===// @@ -49,31 +53,33 @@ void DIEAbbrev::Profile(FoldingSetNodeID &ID) const { /// Emit - Print the abbreviation using the specified asm printer. /// -void DIEAbbrev::Emit(const AsmPrinter *Asm) const { +void DIEAbbrev::Emit(const DwarfPrinter *DP) const { // Emit its Dwarf tag type. - Asm->EmitULEB128Bytes(Tag); - Asm->EOL(dwarf::TagString(Tag)); + // FIXME: Doing work even in non-asm-verbose runs. + DP->EmitULEB128(Tag, dwarf::TagString(Tag)); // Emit whether it has children DIEs. - Asm->EmitULEB128Bytes(ChildrenFlag); - Asm->EOL(dwarf::ChildrenString(ChildrenFlag)); + // FIXME: Doing work even in non-asm-verbose runs. + DP->EmitULEB128(ChildrenFlag, dwarf::ChildrenString(ChildrenFlag)); // For each attribute description. for (unsigned i = 0, N = Data.size(); i < N; ++i) { const DIEAbbrevData &AttrData = Data[i]; // Emit attribute type. - Asm->EmitULEB128Bytes(AttrData.getAttribute()); - Asm->EOL(dwarf::AttributeString(AttrData.getAttribute())); + // FIXME: Doing work even in non-asm-verbose runs. + DP->EmitULEB128(AttrData.getAttribute(), + dwarf::AttributeString(AttrData.getAttribute())); // Emit form type. - Asm->EmitULEB128Bytes(AttrData.getForm()); - Asm->EOL(dwarf::FormEncodingString(AttrData.getForm())); + // FIXME: Doing work even in non-asm-verbose runs. + DP->EmitULEB128(AttrData.getForm(), + dwarf::FormEncodingString(AttrData.getForm())); } // Mark end of abbreviation. - Asm->EmitULEB128Bytes(0); Asm->EOL("EOM(1)"); - Asm->EmitULEB128Bytes(0); Asm->EOL("EOM(2)"); + DP->EmitULEB128(0, "EOM(1)"); + DP->EmitULEB128(0, "EOM(2)"); } #ifndef NDEBUG @@ -182,22 +188,24 @@ void DIEValue::dump() { /// EmitValue - Emit integer of appropriate size. /// -void DIEInteger::EmitValue(Dwarf *D, unsigned Form) const { +void DIEInteger::EmitValue(DwarfPrinter *D, unsigned Form) const { const AsmPrinter *Asm = D->getAsm(); + unsigned Size = ~0U; switch (Form) { case dwarf::DW_FORM_flag: // Fall thru case dwarf::DW_FORM_ref1: // Fall thru - case dwarf::DW_FORM_data1: Asm->EmitInt8(Integer); break; + case dwarf::DW_FORM_data1: Size = 1; break; case dwarf::DW_FORM_ref2: // Fall thru - case dwarf::DW_FORM_data2: Asm->EmitInt16(Integer); break; + case dwarf::DW_FORM_data2: Size = 2; break; case dwarf::DW_FORM_ref4: // Fall thru - case dwarf::DW_FORM_data4: Asm->EmitInt32(Integer); break; + case dwarf::DW_FORM_data4: Size = 4; break; case dwarf::DW_FORM_ref8: // Fall thru - case dwarf::DW_FORM_data8: Asm->EmitInt64(Integer); break; - case dwarf::DW_FORM_udata: Asm->EmitULEB128Bytes(Integer); break; - case dwarf::DW_FORM_sdata: Asm->EmitSLEB128Bytes(Integer); break; + case dwarf::DW_FORM_data8: Size = 8; break; + case dwarf::DW_FORM_udata: D->EmitULEB128(Integer); return; + case dwarf::DW_FORM_sdata: D->EmitSLEB128(Integer, ""); return; default: llvm_unreachable("DIE Value form not supported yet"); } + Asm->OutStreamer.EmitIntValue(Integer, Size, 0/*addrspace*/); } /// SizeOf - Determine size of integer value in bytes. @@ -233,8 +241,10 @@ void DIEInteger::print(raw_ostream &O) { /// EmitValue - Emit string value. /// -void DIEString::EmitValue(Dwarf *D, unsigned Form) const { - D->getAsm()->EmitString(Str); +void DIEString::EmitValue(DwarfPrinter *D, unsigned Form) const { + D->getAsm()->OutStreamer.EmitBytes(Str, /*addrspace*/0); + // Emit nul terminator. + D->getAsm()->OutStreamer.EmitIntValue(0, 1, /*addrspace*/0); } #ifndef NDEBUG @@ -249,7 +259,7 @@ void DIEString::print(raw_ostream &O) { /// EmitValue - Emit label value. /// -void DIEDwarfLabel::EmitValue(Dwarf *D, unsigned Form) const { +void DIEDwarfLabel::EmitValue(DwarfPrinter *D, unsigned Form) const { bool IsSmall = Form == dwarf::DW_FORM_data4; D->EmitReference(Label, false, IsSmall); } @@ -274,9 +284,9 @@ void DIEDwarfLabel::print(raw_ostream &O) { /// EmitValue - Emit label value. /// -void DIEObjectLabel::EmitValue(Dwarf *D, unsigned Form) const { +void DIEObjectLabel::EmitValue(DwarfPrinter *D, unsigned Form) const { bool IsSmall = Form == dwarf::DW_FORM_data4; - D->EmitReference(Label, false, IsSmall); + D->EmitReference(Sym, false, IsSmall); } /// SizeOf - Determine size of label value in bytes. @@ -288,7 +298,7 @@ unsigned DIEObjectLabel::SizeOf(const TargetData *TD, unsigned Form) const { #ifndef NDEBUG void DIEObjectLabel::print(raw_ostream &O) { - O << "Obj: " << Label; + O << "Obj: " << Sym->getName(); } #endif @@ -298,7 +308,7 @@ void DIEObjectLabel::print(raw_ostream &O) { /// EmitValue - Emit delta value. /// -void DIESectionOffset::EmitValue(Dwarf *D, unsigned Form) const { +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(), @@ -328,7 +338,7 @@ void DIESectionOffset::print(raw_ostream &O) { /// EmitValue - Emit delta value. /// -void DIEDelta::EmitValue(Dwarf *D, unsigned Form) const { +void DIEDelta::EmitValue(DwarfPrinter *D, unsigned Form) const { bool IsSmall = Form == dwarf::DW_FORM_data4; D->EmitDifference(LabelHi, LabelLo, IsSmall); } @@ -355,7 +365,7 @@ void DIEDelta::print(raw_ostream &O) { /// EmitValue - Emit debug information entry offset. /// -void DIEEntry::EmitValue(Dwarf *D, unsigned Form) const { +void DIEEntry::EmitValue(DwarfPrinter *D, unsigned Form) const { D->getAsm()->EmitInt32(Entry->getOffset()); } @@ -383,19 +393,19 @@ unsigned DIEBlock::ComputeSize(const TargetData *TD) { /// EmitValue - Emit block data. /// -void DIEBlock::EmitValue(Dwarf *D, unsigned Form) const { +void DIEBlock::EmitValue(DwarfPrinter *D, unsigned Form) const { const AsmPrinter *Asm = D->getAsm(); switch (Form) { 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: Asm->EmitULEB128Bytes(Size); 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->EOL(); + Asm->O << '\n'; Values[i]->EmitValue(D, AbbrevData[i].getForm()); } } diff --git a/lib/CodeGen/AsmPrinter/DIE.h b/lib/CodeGen/AsmPrinter/DIE.h index a6dc9b6..af90289 100644 --- a/lib/CodeGen/AsmPrinter/DIE.h +++ b/lib/CodeGen/AsmPrinter/DIE.h @@ -23,8 +23,9 @@ namespace llvm { class AsmPrinter; - class Dwarf; + class DwarfPrinter; class TargetData; + class MCSymbol; //===--------------------------------------------------------------------===// /// DIEAbbrevData - Dwarf abbreviation data, describes the one attribute of a @@ -100,7 +101,7 @@ namespace llvm { /// Emit - Print the abbreviation using the specified asm printer. /// - void Emit(const AsmPrinter *Asm) const; + void Emit(const DwarfPrinter *DP) const; #ifndef NDEBUG void print(raw_ostream &O); @@ -221,7 +222,7 @@ namespace llvm { /// EmitValue - Emit value via the Dwarf writer. /// - virtual void EmitValue(Dwarf *D, unsigned Form) const = 0; + virtual void EmitValue(DwarfPrinter *D, unsigned Form) const = 0; /// SizeOf - Return the size of a value in bytes. /// @@ -261,7 +262,7 @@ namespace llvm { /// EmitValue - Emit integer of appropriate size. /// - virtual void EmitValue(Dwarf *D, unsigned Form) const; + virtual void EmitValue(DwarfPrinter *D, unsigned Form) const; /// SizeOf - Determine size of integer value in bytes. /// @@ -287,7 +288,7 @@ namespace llvm { /// EmitValue - Emit string value. /// - virtual void EmitValue(Dwarf *D, unsigned Form) const; + virtual void EmitValue(DwarfPrinter *D, unsigned Form) const; /// SizeOf - Determine size of string value in bytes. /// @@ -314,7 +315,7 @@ namespace llvm { /// EmitValue - Emit label value. /// - virtual void EmitValue(Dwarf *D, unsigned Form) const; + virtual void EmitValue(DwarfPrinter *D, unsigned Form) const; /// SizeOf - Determine size of label value in bytes. /// @@ -333,14 +334,14 @@ namespace llvm { /// DIEObjectLabel - A label to an object in code or data. // class DIEObjectLabel : public DIEValue { - const std::string Label; + const MCSymbol *Sym; public: - explicit DIEObjectLabel(const std::string &L) - : DIEValue(isAsIsLabel), Label(L) {} + explicit DIEObjectLabel(const MCSymbol *S) + : DIEValue(isAsIsLabel), Sym(S) {} /// EmitValue - Emit label value. /// - virtual void EmitValue(Dwarf *D, unsigned Form) const; + virtual void EmitValue(DwarfPrinter *D, unsigned Form) const; /// SizeOf - Determine size of label value in bytes. /// @@ -373,7 +374,7 @@ namespace llvm { /// EmitValue - Emit section offset. /// - virtual void EmitValue(Dwarf *D, unsigned Form) const; + virtual void EmitValue(DwarfPrinter *D, unsigned Form) const; /// SizeOf - Determine size of section offset value in bytes. /// @@ -402,7 +403,7 @@ namespace llvm { /// EmitValue - Emit delta value. /// - virtual void EmitValue(Dwarf *D, unsigned Form) const; + virtual void EmitValue(DwarfPrinter *D, unsigned Form) const; /// SizeOf - Determine size of delta value in bytes. /// @@ -431,7 +432,7 @@ namespace llvm { /// EmitValue - Emit debug information entry offset. /// - virtual void EmitValue(Dwarf *D, unsigned Form) const; + virtual void EmitValue(DwarfPrinter *D, unsigned Form) const; /// SizeOf - Determine size of debug information entry in bytes. /// @@ -473,7 +474,7 @@ namespace llvm { /// EmitValue - Emit block data. /// - virtual void EmitValue(Dwarf *D, unsigned Form) const; + virtual void EmitValue(DwarfPrinter *D, unsigned Form) const; /// SizeOf - Determine size of block data in bytes. /// diff --git a/lib/CodeGen/AsmPrinter/DwarfDebug.cpp b/lib/CodeGen/AsmPrinter/DwarfDebug.cpp index 15f37ae..513987f 100644 --- a/lib/CodeGen/AsmPrinter/DwarfDebug.cpp +++ b/lib/CodeGen/AsmPrinter/DwarfDebug.cpp @@ -18,6 +18,7 @@ #include "llvm/MC/MCSection.h" #include "llvm/MC/MCStreamer.h" #include "llvm/MC/MCAsmInfo.h" +#include "llvm/Target/Mangler.h" #include "llvm/Target/TargetData.h" #include "llvm/Target/TargetFrameInfo.h" #include "llvm/Target/TargetLoweringObjectFile.h" @@ -25,7 +26,7 @@ #include "llvm/ADT/StringExtras.h" #include "llvm/Support/Debug.h" #include "llvm/Support/ErrorHandling.h" -#include "llvm/Support/Mangler.h" +#include "llvm/Support/FormattedStream.h" #include "llvm/Support/Timer.h" #include "llvm/System/Path.h" using namespace llvm; @@ -56,12 +57,12 @@ class CompileUnit { /// GVToDieMap - Tracks the mapping of unit level debug informaton /// variables to debug information entries. /// FIXME : Rename GVToDieMap -> NodeToDieMap - ValueMap<MDNode *, DIE *> GVToDieMap; + DenseMap<MDNode *, DIE *> GVToDieMap; /// GVToDIEEntryMap - Tracks the mapping of unit level debug informaton /// descriptors to debug information entries using a DIEEntry proxy. /// FIXME : Rename - ValueMap<MDNode *, DIEEntry *> GVToDIEEntryMap; + DenseMap<MDNode *, DIEEntry *> GVToDIEEntryMap; /// Globals - A map of globally visible named entities for this unit. /// @@ -108,7 +109,7 @@ public: /// getDIEEntry - Returns the debug information entry for the speciefied /// debug variable. DIEEntry *getDIEEntry(MDNode *N) { - ValueMap<MDNode *, DIEEntry *>::iterator I = GVToDIEEntryMap.find(N); + DenseMap<MDNode *, DIEEntry *>::iterator I = GVToDIEEntryMap.find(N); if (I == GVToDIEEntryMap.end()) return NULL; return I->second; @@ -165,7 +166,7 @@ public: class DbgScope { DbgScope *Parent; // Parent to this scope. DIDescriptor Desc; // Debug info descriptor for scope. - WeakVH InlinedAtLocation; // Location at which scope is inlined. + MDNode * InlinedAtLocation; // Location at which scope is inlined. bool AbstractScope; // Abstract Scope unsigned StartLabelID; // Label ID of the beginning of scope. unsigned EndLabelID; // Label ID of the end of scope. @@ -274,7 +275,7 @@ DbgScope::~DbgScope() { } // end llvm namespace DwarfDebug::DwarfDebug(raw_ostream &OS, AsmPrinter *A, const MCAsmInfo *T) - : Dwarf(OS, A, T, "dbg"), ModuleCU(0), + : DwarfPrinter(OS, A, T, "dbg"), ModuleCU(0), AbbreviationsSet(InitAbbreviationsSetSize), Abbreviations(), DIEValues(), StringPool(), SectionSourceLines(), didInitial(false), shouldEmit(false), @@ -343,7 +344,7 @@ void DwarfDebug::addSInt(DIE *Die, unsigned Attribute, /// addString - Add a string attribute data and value. DIEString only /// keeps string reference. void DwarfDebug::addString(DIE *Die, unsigned Attribute, unsigned Form, - const StringRef String) { + StringRef String) { DIEValue *Value = new DIEString(String); DIEValues.push_back(Value); Die->addValue(Attribute, Form, Value); @@ -361,8 +362,8 @@ void DwarfDebug::addLabel(DIE *Die, unsigned Attribute, unsigned Form, /// addObjectLabel - Add an non-Dwarf label attribute data and value. /// void DwarfDebug::addObjectLabel(DIE *Die, unsigned Attribute, unsigned Form, - const std::string &Label) { - DIEValue *Value = new DIEObjectLabel(Label); + const MCSymbol *Sym) { + DIEValue *Value = new DIEObjectLabel(Sym); DIEValues.push_back(Value); Die->addValue(Attribute, Form, Value); } @@ -1162,7 +1163,8 @@ DIE *DwarfDebug::createSubprogramDIE(const DISubprogram &SP, bool MakeDecl) { addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_constu); addUInt(Block, 0, dwarf::DW_FORM_data1, SP.getVirtualIndex()); addBlock(SPDie, dwarf::DW_AT_vtable_elem_location, 0, Block); - ContainingTypeMap.insert(std::make_pair(SPDie, WeakVH(SP.getContainingType().getNode()))); + ContainingTypeMap.insert(std::make_pair(SPDie, + SP.getContainingType().getNode())); } if (MakeDecl || !SP.isDefinition()) { @@ -1379,7 +1381,7 @@ DIE *DwarfDebug::constructInlinedScopeDIE(DbgScope *Scope) { InlinedSubprogramDIEs.insert(OriginDIE); // Track the start label for this inlined function. - ValueMap<MDNode *, SmallVector<InlineInfoLabels, 4> >::iterator + DenseMap<MDNode *, SmallVector<InlineInfoLabels, 4> >::iterator I = InlineInfo.find(InlinedSP.getNode()); if (I == InlineInfo.end()) { @@ -1665,14 +1667,14 @@ void DwarfDebug::constructGlobalVariableDIE(MDNode *N) { DIEBlock *Block = new DIEBlock(); addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_addr); addObjectLabel(Block, 0, dwarf::DW_FORM_udata, - Asm->Mang->getMangledName(DI_GV.getGlobal())); + Asm->GetGlobalValueSymbol(DI_GV.getGlobal())); addBlock(VariableSpecDIE, dwarf::DW_AT_location, 0, Block); 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->Mang->getMangledName(DI_GV.getGlobal())); + Asm->GetGlobalValueSymbol(DI_GV.getGlobal())); addBlock(VariableDie, dwarf::DW_AT_location, 0, Block); } addToContextOwner(VariableDie, GVContext); @@ -1770,13 +1772,15 @@ void DwarfDebug::beginModule(Module *M, MachineModuleInfo *mmi) { for (unsigned i = 1, e = getNumSourceIds()+1; i != e; ++i) { // Remember source id starts at 1. std::pair<unsigned, unsigned> Id = getSourceDirectoryAndFileIds(i); + // FIXME: don't use sys::path for this! This should not depend on the + // host. sys::Path FullPath(getSourceDirectoryName(Id.first)); bool AppendOk = FullPath.appendComponent(getSourceFileName(Id.second)); assert(AppendOk && "Could not append filename to directory!"); AppendOk = false; Asm->EmitFile(i, FullPath.str()); - Asm->EOL(); + Asm->O << '\n'; } } @@ -1808,7 +1812,7 @@ void DwarfDebug::endModule() { TE = TopLevelDIEsVector.end(); TI != TE; ++TI) ModuleCU->getCUDie()->addChild(*TI); - for (DenseMap<DIE *, WeakVH>::iterator CI = ContainingTypeMap.begin(), + for (DenseMap<DIE *, MDNode *>::iterator CI = ContainingTypeMap.begin(), CE = ContainingTypeMap.end(); CI != CE; ++CI) { DIE *SPDie = CI->first; MDNode *N = dyn_cast_or_null<MDNode>(CI->second); @@ -1906,8 +1910,7 @@ void DwarfDebug::collectVariableInfo() { MachineModuleInfo::VariableDbgInfoMapTy &VMap = MMI->getVariableDbgInfo(); for (MachineModuleInfo::VariableDbgInfoMapTy::iterator VI = VMap.begin(), VE = VMap.end(); VI != VE; ++VI) { - MetadataBase *MB = VI->first; - MDNode *Var = dyn_cast_or_null<MDNode>(MB); + MDNode *Var = VI->first; if (!Var) continue; DIVariable DV (Var); std::pair< unsigned, MDNode *> VP = VI->second; @@ -2000,13 +2003,14 @@ bool DwarfDebug::extractScopeInformation(MachineFunction *MF) { MIIndexMap[MInsn] = MIIndex++; DebugLoc DL = MInsn->getDebugLoc(); if (DL.isUnknown()) continue; - DebugLocTuple DLT = MF->getDebugLocTuple(DL); - if (!DLT.Scope) 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. - if (DIDescriptor(DLT.Scope).isCompileUnit()) continue; - createDbgScope(DLT.Scope, DLT.InlinedAtLoc); + if (DLTScope.isCompileUnit()) continue; + createDbgScope(DLTScope.getNode(), DLT.getOrigLocation().getNode()); } } @@ -2019,13 +2023,15 @@ bool DwarfDebug::extractScopeInformation(MachineFunction *MF) { const MachineInstr *MInsn = II; DebugLoc DL = MInsn->getDebugLoc(); if (DL.isUnknown()) continue; - DebugLocTuple DLT = MF->getDebugLocTuple(DL); - if (!DLT.Scope) 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. - if (DIDescriptor(DLT.Scope).isCompileUnit()) continue; - DbgScope *Scope = getUpdatedDbgScope(DLT.Scope, MInsn, DLT.InlinedAtLoc); + if (DLTScope.isCompileUnit()) continue; + DbgScope *Scope = getUpdatedDbgScope(DLTScope.getNode(), MInsn, + DLT.getOrigLocation().getNode()); Scope->setLastInsn(MInsn); } } @@ -2038,10 +2044,18 @@ bool DwarfDebug::extractScopeInformation(MachineFunction *MF) { // Each scope has first instruction and last instruction to mark beginning // and end of a scope respectively. Create an inverse map that list scopes // starts (and ends) with an instruction. One instruction may start (or end) - // multiple scopes. - for (ValueMap<MDNode *, DbgScope *>::iterator DI = DbgScopeMap.begin(), - DE = DbgScopeMap.end(); DI != DE; ++DI) { - DbgScope *S = DI->second; + // multiple scopes. Ignore scopes that are not reachable. + SmallVector<DbgScope *, 4> WorkList; + WorkList.push_back(CurrentFnDbgScope); + while (!WorkList.empty()) { + DbgScope *S = WorkList.back(); WorkList.pop_back(); + + SmallVector<DbgScope *, 4> &Children = S->getScopes(); + if (!Children.empty()) + for (SmallVector<DbgScope *, 4>::iterator SI = Children.begin(), + SE = Children.end(); SI != SE; ++SI) + WorkList.push_back(*SI); + if (S->isAbstractScope()) continue; const MachineInstr *MI = S->getFirstInsn(); @@ -2090,13 +2104,16 @@ void DwarfDebug::beginFunction(MachineFunction *MF) { // function. DebugLoc FDL = MF->getDefaultDebugLoc(); if (!FDL.isUnknown()) { - DebugLocTuple DLT = MF->getDebugLocTuple(FDL); + DILocation DLT = MF->getDILocation(FDL); unsigned LabelID = 0; - DISubprogram SP = getDISubprogram(DLT.Scope); + DISubprogram SP = getDISubprogram(DLT.getScope().getNode()); if (!SP.isNull()) - LabelID = recordSourceLine(SP.getLineNumber(), 0, DLT.Scope); + LabelID = recordSourceLine(SP.getLineNumber(), 0, + DLT.getScope().getNode()); else - LabelID = recordSourceLine(DLT.Line, DLT.Col, DLT.Scope); + LabelID = recordSourceLine(DLT.getLineNumber(), + DLT.getColumnNumber(), + DLT.getScope().getNode()); Asm->printLabel(LabelID); O << '\n'; } @@ -2142,14 +2159,12 @@ void DwarfDebug::endFunction(MachineFunction *MF) { } // Clear debug info - if (CurrentFnDbgScope) { - CurrentFnDbgScope = NULL; - DbgScopeMap.clear(); - DbgScopeBeginMap.clear(); - DbgScopeEndMap.clear(); - ConcreteScopes.clear(); - AbstractScopesList.clear(); - } + CurrentFnDbgScope = NULL; + DbgScopeMap.clear(); + DbgScopeBeginMap.clear(); + DbgScopeEndMap.clear(); + ConcreteScopes.clear(); + AbstractScopesList.clear(); Lines.clear(); if (TimePassesIsEnabled) @@ -2332,19 +2347,15 @@ void DwarfDebug::emitDIE(DIE *Die) { unsigned AbbrevNumber = Die->getAbbrevNumber(); const DIEAbbrev *Abbrev = Abbreviations[AbbrevNumber - 1]; - Asm->EOL(); + Asm->O << '\n'; // Emit the code (index) for the abbreviation. - Asm->EmitULEB128Bytes(AbbrevNumber); - - if (Asm->isVerbose()) - Asm->EOL(std::string("Abbrev [" + - utostr(AbbrevNumber) + - "] 0x" + utohexstr(Die->getOffset()) + - ":0x" + utohexstr(Die->getSize()) + " " + - dwarf::TagString(Abbrev->getTag()))); - else - Asm->EOL(); + if (Asm->VerboseAsm) + Asm->OutStreamer.AddComment("Abbrev [" + Twine(AbbrevNumber) + "] 0x" + + Twine::utohexstr(Die->getOffset()) + ":0x" + + Twine::utohexstr(Die->getSize()) + " " + + dwarf::TagString(Abbrev->getTag())); + EmitULEB128(AbbrevNumber); SmallVector<DIEValue*, 32> &Values = Die->getValues(); const SmallVector<DIEAbbrevData, 8> &AbbrevData = Abbrev->getData(); @@ -2372,7 +2383,7 @@ void DwarfDebug::emitDIE(DIE *Die) { break; } - Asm->EOL(dwarf::AttributeString(Attr)); + EOL(dwarf::AttributeString(Attr)); } // Emit the DIE children if any. @@ -2382,7 +2393,7 @@ void DwarfDebug::emitDIE(DIE *Die) { for (unsigned j = 0, M = Children.size(); j < M; ++j) emitDIE(Children[j]); - Asm->EmitInt8(0); Asm->EOL("End Of Children Mark"); + Asm->EmitInt8(0); EOL("End Of Children Mark"); } } @@ -2404,21 +2415,20 @@ void DwarfDebug::emitDebugInfo() { sizeof(int8_t) + // Pointer Size (in bytes) sizeof(int32_t); // FIXME - extra pad for gdb bug. - Asm->EmitInt32(ContentSize); Asm->EOL("Length of Compilation Unit Info"); - Asm->EmitInt16(dwarf::DWARF_VERSION); Asm->EOL("DWARF version number"); + 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); - Asm->EOL("Offset Into Abbrev. Section"); - Asm->EmitInt8(TD->getPointerSize()); Asm->EOL("Address Size (in bytes)"); + EOL("Offset Into Abbrev. Section"); + Asm->EmitInt8(TD->getPointerSize()); EOL("Address Size (in bytes)"); emitDIE(Die); // FIXME - extra padding for gdb bug. - Asm->EmitInt8(0); Asm->EOL("Extra Pad For GDB"); - Asm->EmitInt8(0); Asm->EOL("Extra Pad For GDB"); - Asm->EmitInt8(0); Asm->EOL("Extra Pad For GDB"); - Asm->EmitInt8(0); Asm->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"); + Asm->EmitInt8(0); EOL("Extra Pad For GDB"); EmitLabel("info_end", ModuleCU->getID()); - - Asm->EOL(); + Asm->O << '\n'; } /// emitAbbreviations - Emit the abbreviation section. @@ -2438,20 +2448,18 @@ void DwarfDebug::emitAbbreviations() const { const DIEAbbrev *Abbrev = Abbreviations[i]; // Emit the abbrevations code (base 1 index.) - Asm->EmitULEB128Bytes(Abbrev->getNumber()); - Asm->EOL("Abbreviation Code"); + EmitULEB128(Abbrev->getNumber(), "Abbreviation Code"); // Emit the abbreviations data. - Abbrev->Emit(Asm); - - Asm->EOL(); + Abbrev->Emit(this); + Asm->O << '\n'; } // Mark end of abbreviations. - Asm->EmitULEB128Bytes(0); Asm->EOL("EOM(3)"); + EmitULEB128(0, "EOM(3)"); EmitLabel("abbrev_end", 0); - Asm->EOL(); + Asm->O << '\n'; } } @@ -2460,15 +2468,15 @@ void DwarfDebug::emitAbbreviations() const { /// void DwarfDebug::emitEndOfLineMatrix(unsigned SectionEnd) { // Define last address of section. - Asm->EmitInt8(0); Asm->EOL("Extended Op"); - Asm->EmitInt8(TD->getPointerSize() + 1); Asm->EOL("Op size"); - Asm->EmitInt8(dwarf::DW_LNE_set_address); Asm->EOL("DW_LNE_set_address"); - EmitReference("section_end", SectionEnd); Asm->EOL("Section end label"); + 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"); // Mark end of matrix. - Asm->EmitInt8(0); Asm->EOL("DW_LNE_end_sequence"); - Asm->EmitULEB128Bytes(1); Asm->EOL(); - Asm->EmitInt8(1); Asm->EOL(); + Asm->EmitInt8(0); EOL("DW_LNE_end_sequence"); + Asm->EmitInt8(1); + Asm->EmitInt8(1); } /// emitDebugLines - Emit source line information. @@ -2490,59 +2498,55 @@ void DwarfDebug::emitDebugLines() { // Construct the section header. EmitDifference("line_end", 0, "line_begin", 0, true); - Asm->EOL("Length of Source Line Info"); + EOL("Length of Source Line Info"); EmitLabel("line_begin", 0); - Asm->EmitInt16(dwarf::DWARF_VERSION); Asm->EOL("DWARF version number"); + Asm->EmitInt16(dwarf::DWARF_VERSION); EOL("DWARF version number"); EmitDifference("line_prolog_end", 0, "line_prolog_begin", 0, true); - Asm->EOL("Prolog Length"); + EOL("Prolog Length"); EmitLabel("line_prolog_begin", 0); - Asm->EmitInt8(1); Asm->EOL("Minimum Instruction Length"); - - Asm->EmitInt8(1); Asm->EOL("Default is_stmt_start flag"); - - Asm->EmitInt8(MinLineDelta); Asm->EOL("Line Base Value (Special Opcodes)"); - - Asm->EmitInt8(MaxLineDelta); Asm->EOL("Line Range Value (Special Opcodes)"); - - Asm->EmitInt8(-MinLineDelta); Asm->EOL("Special Opcode Base"); + 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"); // Line number standard opcode encodings argument count - Asm->EmitInt8(0); Asm->EOL("DW_LNS_copy arg count"); - Asm->EmitInt8(1); Asm->EOL("DW_LNS_advance_pc arg count"); - Asm->EmitInt8(1); Asm->EOL("DW_LNS_advance_line arg count"); - Asm->EmitInt8(1); Asm->EOL("DW_LNS_set_file arg count"); - Asm->EmitInt8(1); Asm->EOL("DW_LNS_set_column arg count"); - Asm->EmitInt8(0); Asm->EOL("DW_LNS_negate_stmt arg count"); - Asm->EmitInt8(0); Asm->EOL("DW_LNS_set_basic_block arg count"); - Asm->EmitInt8(0); Asm->EOL("DW_LNS_const_add_pc arg count"); - Asm->EmitInt8(1); Asm->EOL("DW_LNS_fixed_advance_pc arg 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"); // Emit directories. for (unsigned DI = 1, DE = getNumSourceDirectories()+1; DI != DE; ++DI) { - Asm->EmitString(getSourceDirectoryName(DI)); - Asm->EOL("Directory"); + const std::string &Dir = getSourceDirectoryName(DI); + if (Asm->VerboseAsm) Asm->OutStreamer.AddComment("Directory"); + Asm->OutStreamer.EmitBytes(StringRef(Dir.c_str(), Dir.size()+1), 0); } - Asm->EmitInt8(0); Asm->EOL("End of directories"); + Asm->EmitInt8(0); EOL("End of directories"); // Emit files. for (unsigned SI = 1, SE = getNumSourceIds()+1; SI != SE; ++SI) { // Remember source id starts at 1. std::pair<unsigned, unsigned> Id = getSourceDirectoryAndFileIds(SI); - Asm->EmitString(getSourceFileName(Id.second)); - Asm->EOL("Source"); - Asm->EmitULEB128Bytes(Id.first); - Asm->EOL("Directory #"); - Asm->EmitULEB128Bytes(0); - Asm->EOL("Mod date"); - Asm->EmitULEB128Bytes(0); - Asm->EOL("File size"); + const std::string &FN = getSourceFileName(Id.second); + if (Asm->VerboseAsm) Asm->OutStreamer.AddComment("Source"); + Asm->OutStreamer.EmitBytes(StringRef(FN.c_str(), FN.size()+1), 0); + + EmitULEB128(Id.first, "Directory #"); + EmitULEB128(0, "Mod date"); + EmitULEB128(0, "File size"); } - Asm->EmitInt8(0); Asm->EOL("End of files"); + Asm->EmitInt8(0); EOL("End of files"); EmitLabel("line_prolog_end", 0); @@ -2558,7 +2562,7 @@ void DwarfDebug::emitDebugLines() { O << '\t' << MAI->getCommentString() << " Section" << S->getName() << '\n'; }*/ - Asm->EOL(); + Asm->O << '\n'; // Dwarf assumes we start with first line of first source file. unsigned Source = 1; @@ -2573,7 +2577,7 @@ void DwarfDebug::emitDebugLines() { if (LineInfo.getLine() == 0) continue; if (!Asm->isVerbose()) - Asm->EOL(); + Asm->O << '\n'; else { std::pair<unsigned, unsigned> SourceID = getSourceDirectoryAndFileIds(LineInfo.getSourceID()); @@ -2584,16 +2588,16 @@ void DwarfDebug::emitDebugLines() { } // Define the line address. - Asm->EmitInt8(0); Asm->EOL("Extended Op"); - Asm->EmitInt8(TD->getPointerSize() + 1); Asm->EOL("Op size"); - Asm->EmitInt8(dwarf::DW_LNE_set_address); Asm->EOL("DW_LNE_set_address"); - EmitReference("label", LabelID); Asm->EOL("Location label"); + 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"); // If change of source, then switch to the new source. if (Source != LineInfo.getSourceID()) { Source = LineInfo.getSourceID(); - Asm->EmitInt8(dwarf::DW_LNS_set_file); Asm->EOL("DW_LNS_set_file"); - Asm->EmitULEB128Bytes(Source); Asm->EOL("New Source"); + Asm->EmitInt8(dwarf::DW_LNS_set_file); EOL("DW_LNS_set_file"); + EmitULEB128(Source, "New Source"); } // If change of line. @@ -2608,17 +2612,17 @@ 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); Asm->EOL("Line Delta"); + Asm->EmitInt8(Delta - MinLineDelta); EOL("Line Delta"); } else { // ... otherwise use long hand. Asm->EmitInt8(dwarf::DW_LNS_advance_line); - Asm->EOL("DW_LNS_advance_line"); - Asm->EmitSLEB128Bytes(Offset); Asm->EOL("Line Offset"); - Asm->EmitInt8(dwarf::DW_LNS_copy); Asm->EOL("DW_LNS_copy"); + EOL("DW_LNS_advance_line"); + EmitSLEB128(Offset, "Line Offset"); + Asm->EmitInt8(dwarf::DW_LNS_copy); EOL("DW_LNS_copy"); } } else { // Copy the previous row (different address or source) - Asm->EmitInt8(dwarf::DW_LNS_copy); Asm->EOL("DW_LNS_copy"); + Asm->EmitInt8(dwarf::DW_LNS_copy); EOL("DW_LNS_copy"); } } @@ -2632,7 +2636,7 @@ void DwarfDebug::emitDebugLines() { emitEndOfLineMatrix(1); EmitLabel("line_end", 0); - Asm->EOL(); + Asm->O << '\n'; } /// emitCommonDebugFrame - Emit common frame info into a debug frame section. @@ -2653,21 +2657,19 @@ void DwarfDebug::emitCommonDebugFrame() { EmitLabel("debug_frame_common", 0); EmitDifference("debug_frame_common_end", 0, "debug_frame_common_begin", 0, true); - Asm->EOL("Length of Common Information Entry"); + EOL("Length of Common Information Entry"); EmitLabel("debug_frame_common_begin", 0); Asm->EmitInt32((int)dwarf::DW_CIE_ID); - Asm->EOL("CIE Identifier Tag"); + EOL("CIE Identifier Tag"); Asm->EmitInt8(dwarf::DW_CIE_VERSION); - Asm->EOL("CIE Version"); - Asm->EmitString(""); - Asm->EOL("CIE Augmentation"); - Asm->EmitULEB128Bytes(1); - Asm->EOL("CIE Code Alignment Factor"); - Asm->EmitSLEB128Bytes(stackGrowth); - Asm->EOL("CIE Data Alignment Factor"); + EOL("CIE Version"); + 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->EmitInt8(RI->getDwarfRegNum(RI->getRARegister(), false)); - Asm->EOL("CIE RA Column"); + EOL("CIE RA Column"); std::vector<MachineMove> Moves; RI->getInitialFrameState(Moves); @@ -2676,8 +2678,7 @@ void DwarfDebug::emitCommonDebugFrame() { Asm->EmitAlignment(2, 0, 0, false); EmitLabel("debug_frame_common_end", 0); - - Asm->EOL(); + Asm->O << '\n'; } /// emitFunctionDebugFrame - Emit per function frame info into a debug frame @@ -2693,27 +2694,26 @@ DwarfDebug::emitFunctionDebugFrame(const FunctionDebugFrameInfo&DebugFrameInfo){ EmitDifference("debug_frame_end", DebugFrameInfo.Number, "debug_frame_begin", DebugFrameInfo.Number, true); - Asm->EOL("Length of Frame Information Entry"); + EOL("Length of Frame Information Entry"); EmitLabel("debug_frame_begin", DebugFrameInfo.Number); EmitSectionOffset("debug_frame_common", "section_debug_frame", 0, 0, true, false); - Asm->EOL("FDE CIE offset"); + EOL("FDE CIE offset"); EmitReference("func_begin", DebugFrameInfo.Number); - Asm->EOL("FDE initial location"); + EOL("FDE initial location"); EmitDifference("func_end", DebugFrameInfo.Number, "func_begin", DebugFrameInfo.Number); - Asm->EOL("FDE address range"); + EOL("FDE address range"); EmitFrameMoves("func_begin", DebugFrameInfo.Number, DebugFrameInfo.Moves, false); Asm->EmitAlignment(2, 0, 0, false); EmitLabel("debug_frame_end", DebugFrameInfo.Number); - - Asm->EOL(); + Asm->O << '\n'; } /// emitDebugPubNames - Emit visible names into a debug pubnames section. @@ -2725,19 +2725,19 @@ void DwarfDebug::emitDebugPubNames() { EmitDifference("pubnames_end", ModuleCU->getID(), "pubnames_begin", ModuleCU->getID(), true); - Asm->EOL("Length of Public Names Info"); + EOL("Length of Public Names Info"); EmitLabel("pubnames_begin", ModuleCU->getID()); - Asm->EmitInt16(dwarf::DWARF_VERSION); Asm->EOL("DWARF Version"); + Asm->EmitInt16(dwarf::DWARF_VERSION); EOL("DWARF Version"); EmitSectionOffset("info_begin", "section_info", ModuleCU->getID(), 0, true, false); - Asm->EOL("Offset of Compilation Unit Info"); + EOL("Offset of Compilation Unit Info"); EmitDifference("info_end", ModuleCU->getID(), "info_begin", ModuleCU->getID(), true); - Asm->EOL("Compilation Unit Length"); + EOL("Compilation Unit Length"); const StringMap<DIE*> &Globals = ModuleCU->getGlobals(); for (StringMap<DIE*>::const_iterator @@ -2745,14 +2745,16 @@ void DwarfDebug::emitDebugPubNames() { const char *Name = GI->getKeyData(); DIE * Entity = GI->second; - Asm->EmitInt32(Entity->getOffset()); Asm->EOL("DIE offset"); - Asm->EmitString(Name, strlen(Name)); Asm->EOL("External Name"); + Asm->EmitInt32(Entity->getOffset()); EOL("DIE offset"); + + if (Asm->VerboseAsm) + Asm->OutStreamer.AddComment("External Name"); + Asm->OutStreamer.EmitBytes(StringRef(Name, strlen(Name)+1), 0); } - Asm->EmitInt32(0); Asm->EOL("End Mark"); + Asm->EmitInt32(0); EOL("End Mark"); EmitLabel("pubnames_end", ModuleCU->getID()); - - Asm->EOL(); + Asm->O << '\n'; } void DwarfDebug::emitDebugPubTypes() { @@ -2761,19 +2763,19 @@ void DwarfDebug::emitDebugPubTypes() { Asm->getObjFileLowering().getDwarfPubTypesSection()); EmitDifference("pubtypes_end", ModuleCU->getID(), "pubtypes_begin", ModuleCU->getID(), true); - Asm->EOL("Length of Public Types Info"); + EOL("Length of Public Types Info"); EmitLabel("pubtypes_begin", ModuleCU->getID()); - Asm->EmitInt16(dwarf::DWARF_VERSION); Asm->EOL("DWARF Version"); + Asm->EmitInt16(dwarf::DWARF_VERSION); EOL("DWARF Version"); EmitSectionOffset("info_begin", "section_info", ModuleCU->getID(), 0, true, false); - Asm->EOL("Offset of Compilation ModuleCU Info"); + EOL("Offset of Compilation ModuleCU Info"); EmitDifference("info_end", ModuleCU->getID(), "info_begin", ModuleCU->getID(), true); - Asm->EOL("Compilation ModuleCU Length"); + EOL("Compilation ModuleCU Length"); const StringMap<DIE*> &Globals = ModuleCU->getGlobalTypes(); for (StringMap<DIE*>::const_iterator @@ -2781,14 +2783,15 @@ void DwarfDebug::emitDebugPubTypes() { const char *Name = GI->getKeyData(); DIE * Entity = GI->second; - Asm->EmitInt32(Entity->getOffset()); Asm->EOL("DIE offset"); - Asm->EmitString(Name, strlen(Name)); Asm->EOL("External Name"); + Asm->EmitInt32(Entity->getOffset()); EOL("DIE offset"); + + if (Asm->VerboseAsm) Asm->OutStreamer.AddComment("External Name"); + Asm->OutStreamer.EmitBytes(StringRef(Name, strlen(Name)), 0); } - Asm->EmitInt32(0); Asm->EOL("End Mark"); + Asm->EmitInt32(0); EOL("End Mark"); EmitLabel("pubtypes_end", ModuleCU->getID()); - - Asm->EOL(); + Asm->O << '\n'; } /// emitDebugStr - Emit visible names into a debug str section. @@ -2808,10 +2811,10 @@ void DwarfDebug::emitDebugStr() { // Emit the string itself. const std::string &String = StringPool[StringID]; - Asm->EmitString(String); Asm->EOL(); + Asm->OutStreamer.EmitBytes(StringRef(String.c_str(), String.size()+1), 0); } - Asm->EOL(); + Asm->O << '\n'; } } @@ -2821,7 +2824,6 @@ void DwarfDebug::emitDebugLoc() { // Start the dwarf loc section. Asm->OutStreamer.SwitchSection( Asm->getObjFileLowering().getDwarfLocSection()); - Asm->EOL(); } /// EmitDebugARanges - Emit visible names into a debug aranges section. @@ -2836,29 +2838,27 @@ void DwarfDebug::EmitDebugARanges() { CompileUnit *Unit = GetBaseCompileUnit(); // Don't include size of length - Asm->EmitInt32(0x1c); Asm->EOL("Length of Address Ranges Info"); + Asm->EmitInt32(0x1c); EOL("Length of Address Ranges Info"); - Asm->EmitInt16(dwarf::DWARF_VERSION); Asm->EOL("Dwarf Version"); + Asm->EmitInt16(dwarf::DWARF_VERSION); EOL("Dwarf Version"); EmitReference("info_begin", Unit->getID()); - Asm->EOL("Offset of Compilation Unit Info"); + EOL("Offset of Compilation Unit Info"); - Asm->EmitInt8(TD->getPointerSize()); Asm->EOL("Size of Address"); + Asm->EmitInt8(TD->getPointerSize()); EOL("Size of Address"); - Asm->EmitInt8(0); Asm->EOL("Size of Segment Descriptor"); + Asm->EmitInt8(0); EOL("Size of Segment Descriptor"); - Asm->EmitInt16(0); Asm->EOL("Pad (1)"); - Asm->EmitInt16(0); Asm->EOL("Pad (2)"); + Asm->EmitInt16(0); EOL("Pad (1)"); + Asm->EmitInt16(0); EOL("Pad (2)"); // Range 1 - EmitReference("text_begin", 0); Asm->EOL("Address"); - EmitDifference("text_end", 0, "text_begin", 0, true); Asm->EOL("Length"); + EmitReference("text_begin", 0); EOL("Address"); + EmitDifference("text_end", 0, "text_begin", 0, true); EOL("Length"); - Asm->EmitInt32(0); Asm->EOL("EOM (1)"); - Asm->EmitInt32(0); Asm->EOL("EOM (2)"); + Asm->EmitInt32(0); EOL("EOM (1)"); + Asm->EmitInt32(0); EOL("EOM (2)"); #endif - - Asm->EOL(); } /// emitDebugRanges - Emit visible names into a debug ranges section. @@ -2867,7 +2867,6 @@ void DwarfDebug::emitDebugRanges() { // Start the dwarf ranges section. Asm->OutStreamer.SwitchSection( Asm->getObjFileLowering().getDwarfRangesSection()); - Asm->EOL(); } /// emitDebugMacInfo - Emit visible names into a debug macinfo section. @@ -2877,7 +2876,6 @@ void DwarfDebug::emitDebugMacInfo() { Asm->getObjFileLowering().getDwarfMacroInfoSection()) { // Start the dwarf macinfo section. Asm->OutStreamer.SwitchSection(LineInfo); - Asm->EOL(); } } @@ -2908,53 +2906,54 @@ void DwarfDebug::emitDebugInlineInfo() { Asm->OutStreamer.SwitchSection( Asm->getObjFileLowering().getDwarfDebugInlineSection()); - Asm->EOL(); + EmitDifference("debug_inlined_end", 1, "debug_inlined_begin", 1, true); - Asm->EOL("Length of Debug Inlined Information Entry"); + EOL("Length of Debug Inlined Information Entry"); EmitLabel("debug_inlined_begin", 1); - Asm->EmitInt16(dwarf::DWARF_VERSION); Asm->EOL("Dwarf Version"); - Asm->EmitInt8(TD->getPointerSize()); Asm->EOL("Address Size (in bytes)"); + Asm->EmitInt16(dwarf::DWARF_VERSION); EOL("Dwarf Version"); + Asm->EmitInt8(TD->getPointerSize()); EOL("Address Size (in bytes)"); for (SmallVector<MDNode *, 4>::iterator I = InlinedSPNodes.begin(), E = InlinedSPNodes.end(); I != E; ++I) { MDNode *Node = *I; - ValueMap<MDNode *, SmallVector<InlineInfoLabels, 4> >::iterator II + DenseMap<MDNode *, SmallVector<InlineInfoLabels, 4> >::iterator II = InlineInfo.find(Node); SmallVector<InlineInfoLabels, 4> &Labels = II->second; DISubprogram SP(Node); StringRef LName = SP.getLinkageName(); StringRef Name = SP.getName(); - if (LName.empty()) - Asm->EmitString(Name); - else + 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); + StringPool.idFor(getRealLinkageName(LName)), false, true); - Asm->EOL("MIPS linkage name"); + EOL("MIPS linkage name"); EmitSectionOffset("string", "section_str", StringPool.idFor(Name), false, true); - Asm->EOL("Function name"); - Asm->EmitULEB128Bytes(Labels.size()); Asm->EOL("Inline count"); + EOL("Function name"); + 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()); Asm->EOL("DIE offset"); + Asm->EmitInt32(SP->getOffset()); EOL("DIE offset"); if (TD->getPointerSize() == sizeof(int32_t)) O << MAI->getData32bitsDirective(); else O << MAI->getData64bitsDirective(); - PrintLabelName("label", LI->first); Asm->EOL("low_pc"); + PrintLabelName("label", LI->first); EOL("low_pc"); } } EmitLabel("debug_inlined_end", 1); - Asm->EOL(); + Asm->O << '\n'; } diff --git a/lib/CodeGen/AsmPrinter/DwarfDebug.h b/lib/CodeGen/AsmPrinter/DwarfDebug.h index 2b8164e..e723621 100644 --- a/lib/CodeGen/AsmPrinter/DwarfDebug.h +++ b/lib/CodeGen/AsmPrinter/DwarfDebug.h @@ -20,7 +20,7 @@ #include "llvm/CodeGen/MachineLocation.h" #include "llvm/Analysis/DebugInfo.h" #include "llvm/Support/raw_ostream.h" -#include "llvm/ADT/ValueMap.h" +#include "llvm/ADT/DenseMap.h" #include "llvm/ADT/FoldingSet.h" #include "llvm/ADT/SmallSet.h" #include "llvm/ADT/StringMap.h" @@ -57,7 +57,7 @@ public: unsigned getLabelID() const { return LabelID; } }; -class DwarfDebug : public Dwarf { +class DwarfDebug : public DwarfPrinter { //===--------------------------------------------------------------------===// // Attributes used to construct specific Dwarf sections. // @@ -136,25 +136,25 @@ class DwarfDebug : public Dwarf { /// DbgScopeMap - Tracks the scopes in the current function. /// - ValueMap<MDNode *, DbgScope *> DbgScopeMap; + DenseMap<MDNode *, DbgScope *> DbgScopeMap; /// ConcreteScopes - Tracks the concrete scopees in the current function. /// These scopes are also included in DbgScopeMap. - ValueMap<MDNode *, DbgScope *> ConcreteScopes; + DenseMap<MDNode *, DbgScope *> ConcreteScopes; /// AbstractScopes - Tracks the abstract scopes a module. These scopes are /// not included DbgScopeMap. - ValueMap<MDNode *, DbgScope *> AbstractScopes; + DenseMap<MDNode *, DbgScope *> AbstractScopes; SmallVector<DbgScope *, 4>AbstractScopesList; /// AbstractVariables - Collection on abstract variables. - ValueMap<MDNode *, DbgVariable *> AbstractVariables; + DenseMap<MDNode *, DbgVariable *> AbstractVariables; /// InliendSubprogramDIEs - Collection of subprgram DIEs that are marked /// (at the end of the module) as DW_AT_inline. SmallPtrSet<DIE *, 4> InlinedSubprogramDIEs; - DenseMap<DIE *, WeakVH> ContainingTypeMap; + DenseMap<DIE *, MDNode *> ContainingTypeMap; /// AbstractSubprogramDIEs - Collection of abstruct subprogram DIEs. SmallPtrSet<DIE *, 4> AbstractSubprogramDIEs; @@ -176,7 +176,7 @@ class DwarfDebug : public Dwarf { /// InlineInfo - Keep track of inlined functions and their location. This /// information is used to populate debug_inlined section. typedef std::pair<unsigned, DIE *> InlineInfoLabels; - ValueMap<MDNode *, SmallVector<InlineInfoLabels, 4> > InlineInfo; + DenseMap<MDNode *, SmallVector<InlineInfoLabels, 4> > InlineInfo; SmallVector<MDNode *, 4> InlinedSPNodes; /// CompileUnitOffsets - A vector of the offsets of the compile units. This is @@ -256,7 +256,7 @@ class DwarfDebug : public Dwarf { /// addObjectLabel - Add an non-Dwarf label attribute data and value. /// void addObjectLabel(DIE *Die, unsigned Attribute, unsigned Form, - const std::string &Label); + const MCSymbol *Sym); /// addSectionOffset - Add a section offset label attribute data and value. /// diff --git a/lib/CodeGen/AsmPrinter/DwarfException.cpp b/lib/CodeGen/AsmPrinter/DwarfException.cpp index d01f300..2ae16c0 100644 --- a/lib/CodeGen/AsmPrinter/DwarfException.cpp +++ b/lib/CodeGen/AsmPrinter/DwarfException.cpp @@ -22,22 +22,23 @@ #include "llvm/MC/MCExpr.h" #include "llvm/MC/MCSection.h" #include "llvm/MC/MCStreamer.h" +#include "llvm/MC/MCSymbol.h" +#include "llvm/Target/Mangler.h" #include "llvm/Target/TargetData.h" #include "llvm/Target/TargetFrameInfo.h" #include "llvm/Target/TargetLoweringObjectFile.h" #include "llvm/Target/TargetOptions.h" #include "llvm/Target/TargetRegisterInfo.h" #include "llvm/Support/Dwarf.h" -#include "llvm/Support/Mangler.h" +#include "llvm/Support/FormattedStream.h" #include "llvm/Support/Timer.h" -#include "llvm/Support/raw_ostream.h" #include "llvm/ADT/SmallString.h" #include "llvm/ADT/StringExtras.h" using namespace llvm; DwarfException::DwarfException(raw_ostream &OS, AsmPrinter *A, const MCAsmInfo *T) - : Dwarf(OS, A, T, "eh"), shouldEmitTable(false), shouldEmitMoves(false), + : DwarfPrinter(OS, A, T, "eh"), shouldEmitTable(false),shouldEmitMoves(false), shouldEmitTableModule(false), shouldEmitMovesModule(false), ExceptionTimer(0) { if (TimePassesIsEnabled) @@ -114,14 +115,14 @@ void DwarfException::EmitCIE(const Function *PersonalityFn, unsigned Index) { // Define the eh frame length. EmitDifference("eh_frame_common_end", Index, "eh_frame_common_begin", Index, true); - Asm->EOL("Length of Common Information Entry"); + EOL("Length of Common Information Entry"); // EH frame header. EmitLabel("eh_frame_common_begin", Index); - Asm->EmitInt32((int)0); - Asm->EOL("CIE Identifier Tag"); - Asm->EmitInt8(dwarf::DW_CIE_VERSION); - Asm->EOL("CIE Version"); + if (Asm->VerboseAsm) 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.EmitIntValue(dwarf::DW_CIE_VERSION, 1/*size*/, 0/*addr*/); // The personality presence indicates that language specific information will // show up in the eh frame. Find out how we are supposed to lower the @@ -145,7 +146,7 @@ void DwarfException::EmitCIE(const Function *PersonalityFn, unsigned Index) { unsigned LSDAEncoding = dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4; unsigned FDEEncoding = dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4; - char Augmentation[5] = { 0 }; + char Augmentation[6] = { 0 }; unsigned AugmentationSize = 0; char *APtr = Augmentation + 1; @@ -170,22 +171,17 @@ void DwarfException::EmitCIE(const Function *PersonalityFn, unsigned Index) { if (APtr != Augmentation + 1) Augmentation[0] = 'z'; - Asm->EmitString(Augmentation); - Asm->EOL("CIE Augmentation"); + Asm->OutStreamer.EmitBytes(StringRef(Augmentation, strlen(Augmentation)+1),0); + EOL("CIE Augmentation"); // Round out reader. - Asm->EmitULEB128Bytes(1); - Asm->EOL("CIE Code Alignment Factor"); - Asm->EmitSLEB128Bytes(stackGrowth); - Asm->EOL("CIE Data Alignment Factor"); + EmitULEB128(1, "CIE Code Alignment Factor"); + EmitSLEB128(stackGrowth, "CIE Data Alignment Factor"); Asm->EmitInt8(RI->getDwarfRegNum(RI->getRARegister(), true)); - Asm->EOL("CIE Return Address Column"); + EOL("CIE Return Address Column"); - Asm->EmitULEB128Bytes(AugmentationSize); - Asm->EOL("Augmentation Size"); - - Asm->EmitInt8(PerEncoding); - Asm->EOL("Personality", PerEncoding); + EmitULEB128(AugmentationSize, "Augmentation Size"); + EmitEncodingByte(PerEncoding, "Personality"); // If there is a personality, we need to indicate the function's location. if (PersonalityRef) { @@ -193,15 +189,11 @@ void DwarfException::EmitCIE(const Function *PersonalityFn, unsigned Index) { PersonalityRef = CreateLabelDiff(PersonalityRef, "personalityref_addr", Index); - O << MAI->getData32bitsDirective(); - PersonalityRef->print(O, MAI); - Asm->EOL("Personality"); - - Asm->EmitInt8(LSDAEncoding); - Asm->EOL("LSDA Encoding", LSDAEncoding); + O << MAI->getData32bitsDirective() << *PersonalityRef; + EOL("Personality"); - Asm->EmitInt8(FDEEncoding); - Asm->EOL("FDE Encoding", FDEEncoding); + EmitEncodingByte(LSDAEncoding, "LSDA"); + EmitEncodingByte(FDEEncoding, "FDE"); } // Indicate locations of general callee saved registers in frame. @@ -214,8 +206,7 @@ void DwarfException::EmitCIE(const Function *PersonalityFn, unsigned Index) { // holes which confuse readers of eh_frame. Asm->EmitAlignment(TD->getPointerSize() == 4 ? 2 : 3, 0, 0, false); EmitLabel("eh_frame_common_end", Index); - - Asm->EOL(); + Asm->O << '\n'; } /// EmitFDE - Emit the Frame Description Entry (FDE) for the function. @@ -231,16 +222,17 @@ void DwarfException::EmitFDE(const FunctionEHFrameInfo &EHFrameInfo) { // corresponding function is static, this should not be externally visible. if (!TheFunc->hasLocalLinkage()) if (const char *GlobalEHDirective = MAI->getGlobalEHDirective()) - O << GlobalEHDirective << EHFrameInfo.FnName << '\n'; + O << GlobalEHDirective << *EHFrameInfo.FunctionEHSym << '\n'; // If corresponding function is weak definition, this should be too. if (TheFunc->isWeakForLinker() && MAI->getWeakDefDirective()) - O << MAI->getWeakDefDirective() << EHFrameInfo.FnName << '\n'; + O << MAI->getWeakDefDirective() << *EHFrameInfo.FunctionEHSym << '\n'; // If corresponding function is hidden, this should be too. if (TheFunc->hasHiddenVisibility()) - if (const char *HiddenDirective = MAI->getHiddenDirective()) - O << HiddenDirective << EHFrameInfo.FnName << '\n' ; + if (MCSymbolAttr HiddenAttr = MAI->getHiddenVisibilityAttr()) + Asm->OutStreamer.EmitSymbolAttribute(EHFrameInfo.FunctionEHSym, + HiddenAttr); // If there are no calls then you can't unwind. This may mean we can omit the // EH Frame, but some environments do not handle weak absolute symbols. If @@ -250,19 +242,20 @@ void DwarfException::EmitFDE(const FunctionEHFrameInfo &EHFrameInfo) { (!TheFunc->isWeakForLinker() || !MAI->getWeakDefDirective() || MAI->getSupportsWeakOmittedEHFrame())) { - O << EHFrameInfo.FnName << " = 0\n"; + O << *EHFrameInfo.FunctionEHSym << " = 0\n"; // This name has no connection to the function, so it might get // dead-stripped when the function is not, erroneously. Prohibit // dead-stripping unconditionally. - if (const char *UsedDirective = MAI->getUsedDirective()) - O << UsedDirective << EHFrameInfo.FnName << "\n\n"; + if (MAI->hasNoDeadStrip()) + Asm->OutStreamer.EmitSymbolAttribute(EHFrameInfo.FunctionEHSym, + MCSA_NoDeadStrip); } else { - O << EHFrameInfo.FnName << ":\n"; + O << *EHFrameInfo.FunctionEHSym << ":\n"; // EH frame header. EmitDifference("eh_frame_end", EHFrameInfo.Number, "eh_frame_begin", EHFrameInfo.Number, true); - Asm->EOL("Length of Frame Information Entry"); + EOL("Length of Frame Information Entry"); EmitLabel("eh_frame_begin", EHFrameInfo.Number); @@ -270,34 +263,39 @@ void DwarfException::EmitFDE(const FunctionEHFrameInfo &EHFrameInfo) { EHFrameInfo.Number, EHFrameInfo.PersonalityIndex, true, true, false); - Asm->EOL("FDE CIE offset"); + EOL("FDE CIE offset"); EmitReference("eh_func_begin", EHFrameInfo.Number, true, true); - Asm->EOL("FDE initial location"); + EOL("FDE initial location"); EmitDifference("eh_func_end", EHFrameInfo.Number, "eh_func_begin", EHFrameInfo.Number, true); - Asm->EOL("FDE address range"); + EOL("FDE address range"); // If there is a personality and landing pads then point to the language // specific data area in the exception table. if (MMI->getPersonalities()[0] != NULL) { - bool is4Byte = TD->getPointerSize() == sizeof(int32_t); - Asm->EmitULEB128Bytes(is4Byte ? 4 : 8); - Asm->EOL("Augmentation size"); + if (Asm->TM.getLSDAEncoding() != DwarfLSDAEncoding::EightByte) { + EmitULEB128(4, "Augmentation size"); - if (EHFrameInfo.hasLandingPads) - EmitReference("exception", EHFrameInfo.Number, true, false); - else { - if (is4Byte) - Asm->EmitInt32((int)0); + if (EHFrameInfo.hasLandingPads) + EmitReference("exception", EHFrameInfo.Number, true, true); else - Asm->EmitInt64((int)0); + Asm->OutStreamer.EmitIntValue(0, 4/*size*/, 0/*addrspace*/); + } else { + EmitULEB128(TD->getPointerSize(), "Augmentation size"); + + if (EHFrameInfo.hasLandingPads) { + EmitReference("exception", EHFrameInfo.Number, true, false); + } else { + Asm->OutStreamer.EmitIntValue(0, TD->getPointerSize(), + 0/*addrspace*/); + } } - Asm->EOL("Language Specific Data Area"); + + EOL("Language Specific Data Area"); } else { - Asm->EmitULEB128Bytes(0); - Asm->EOL("Augmentation size"); + EmitULEB128(0, "Augmentation size"); } // Indicate locations of function specific callee saved registers in frame. @@ -317,11 +315,11 @@ void DwarfException::EmitFDE(const FunctionEHFrameInfo &EHFrameInfo) { // on unused functions (calling undefined externals) being dead-stripped to // link correctly. Yes, there really is. if (MMI->isUsedFunction(EHFrameInfo.function)) - if (const char *UsedDirective = MAI->getUsedDirective()) - O << UsedDirective << EHFrameInfo.FnName << "\n\n"; + if (MAI->hasNoDeadStrip()) + Asm->OutStreamer.EmitSymbolAttribute(EHFrameInfo.FunctionEHSym, + MCSA_NoDeadStrip); } - - Asm->EOL(); + Asm->O << '\n'; } /// SharedTypeIds - How many leading type ids two landing pads have in common. @@ -765,7 +763,7 @@ void DwarfException::EmitExceptionTable() { for (unsigned i = 0; i != SizeAlign; ++i) { Asm->EmitInt8(0); - Asm->EOL("Padding"); + EOL("Padding"); } EmitLabel("exception", SubprogramCount); @@ -778,23 +776,16 @@ void DwarfException::EmitExceptionTable() { } // Emit the header. - Asm->EmitInt8(dwarf::DW_EH_PE_omit); - Asm->EOL("@LPStart format", dwarf::DW_EH_PE_omit); + EmitEncodingByte(dwarf::DW_EH_PE_omit, "@LPStart"); + EmitEncodingByte(TTypeFormat, "@TType"); - Asm->EmitInt8(TTypeFormat); - Asm->EOL("@TType format", TTypeFormat); - - if (HaveTTData) { - Asm->EmitULEB128Bytes(TyOffset); - Asm->EOL("@TType base offset"); - } + if (HaveTTData) + EmitULEB128(TyOffset, "@TType base offset"); // SjLj Exception handling if (IsSJLJ) { - Asm->EmitInt8(dwarf::DW_EH_PE_udata4); - Asm->EOL("Call site format", dwarf::DW_EH_PE_udata4); - Asm->EmitULEB128Bytes(SizeSites); - Asm->EOL("Call site table length"); + EmitEncodingByte(dwarf::DW_EH_PE_udata4, "Call site"); + EmitULEB128(SizeSites, "Call site table length"); // Emit the landing pad site information. unsigned idx = 0; @@ -804,14 +795,12 @@ void DwarfException::EmitExceptionTable() { // Offset of the landing pad, counted in 16-byte bundles relative to the // @LPStart address. - Asm->EmitULEB128Bytes(idx); - Asm->EOL("Landing pad"); + EmitULEB128(idx, "Landing pad"); // 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 // the action table), and 0 indicates that there are no actions. - Asm->EmitULEB128Bytes(S.Action); - Asm->EOL("Action"); + EmitULEB128(S.Action, "Action"); } } else { // DWARF Exception handling @@ -836,10 +825,8 @@ void DwarfException::EmitExceptionTable() { // supposed to throw. // Emit the landing pad call site table. - Asm->EmitInt8(dwarf::DW_EH_PE_udata4); - Asm->EOL("Call site format", dwarf::DW_EH_PE_udata4); - Asm->EmitULEB128Bytes(SizeSites); - Asm->EOL("Call site table size"); + EmitEncodingByte(dwarf::DW_EH_PE_udata4, "Call site"); + EmitULEB128(SizeSites, "Call site table size"); for (SmallVectorImpl<CallSiteEntry>::const_iterator I = CallSites.begin(), E = CallSites.end(); I != E; ++I) { @@ -860,7 +847,7 @@ void DwarfException::EmitExceptionTable() { // the start of the procedure fragment. EmitSectionOffset(BeginTag, "eh_func_begin", BeginNumber, SubprogramCount, true, true); - Asm->EOL("Region start"); + EOL("Region start"); if (!S.EndLabel) EmitDifference("eh_func_end", SubprogramCount, BeginTag, BeginNumber, @@ -868,23 +855,22 @@ void DwarfException::EmitExceptionTable() { else EmitDifference("label", S.EndLabel, BeginTag, BeginNumber, true); - Asm->EOL("Region length"); + EOL("Region length"); // Offset of the landing pad, counted in 16-byte bundles relative to the // @LPStart address. if (!S.PadLabel) - Asm->EmitInt32(0); + Asm->OutStreamer.EmitIntValue(0, 4/*size*/, 0/*addrspace*/); else EmitSectionOffset("label", "eh_func_begin", S.PadLabel, SubprogramCount, true, true); - Asm->EOL("Landing pad"); + EOL("Landing pad"); // 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 // the action table), and 0 indicates that there are no actions. - Asm->EmitULEB128Bytes(S.Action); - Asm->EOL("Action"); + EmitULEB128(S.Action, "Action"); } } @@ -897,17 +883,13 @@ void DwarfException::EmitExceptionTable() { // // Used by the runtime to match the type of the thrown exception to the // type of the catch clauses or the types in the exception specification. - - Asm->EmitSLEB128Bytes(Action.ValueForTypeID); - Asm->EOL("TypeInfo index"); + EmitSLEB128(Action.ValueForTypeID, "TypeInfo index"); // Action Record // // Self-relative signed displacement in bytes of the next action record, // or 0 if there is no next action record. - - Asm->EmitSLEB128Bytes(Action.NextAction); - Asm->EOL("Next action"); + EmitSLEB128(Action.NextAction, "Next action"); } // Emit the Catch TypeInfos. @@ -916,24 +898,19 @@ void DwarfException::EmitExceptionTable() { const GlobalVariable *GV = *I; PrintRelDirective(); - if (GV) { - O << Asm->Mang->getMangledName(GV); - } else { + if (GV) + O << *Asm->GetGlobalValueSymbol(GV); + else O << "0x0"; - } - Asm->EOL("TypeInfo"); + EOL("TypeInfo"); } // Emit the Exception Specifications. for (std::vector<unsigned>::const_iterator I = FilterIds.begin(), E = FilterIds.end(); I < E; ++I) { unsigned TypeID = *I; - Asm->EmitULEB128Bytes(TypeID); - if (TypeID != 0) - Asm->EOL("Exception specification"); - else - Asm->EOL(); + EmitULEB128(TypeID, TypeID != 0 ? "Exception specification" : 0); } Asm->EmitAlignment(2, 0, 0, false); @@ -1008,12 +985,12 @@ void DwarfException::EndFunction() { EmitLabel("eh_func_end", SubprogramCount); EmitExceptionTable(); - std::string FunctionEHName = - Asm->Mang->getMangledName(MF->getFunction(), ".eh", - Asm->MAI->is_EHSymbolPrivate()); + MCSymbol *FunctionEHSym = + Asm->GetSymbolWithGlobalValueBase(MF->getFunction(), ".eh", + Asm->MAI->is_EHSymbolPrivate()); // Save EH frame information - EHFrames.push_back(FunctionEHFrameInfo(FunctionEHName, SubprogramCount, + EHFrames.push_back(FunctionEHFrameInfo(FunctionEHSym, SubprogramCount, MMI->getPersonalityIndex(), MF->getFrameInfo()->hasCalls(), !MMI->getLandingPads().empty(), diff --git a/lib/CodeGen/AsmPrinter/DwarfException.h b/lib/CodeGen/AsmPrinter/DwarfException.h index aa01c5b..3921e91 100644 --- a/lib/CodeGen/AsmPrinter/DwarfException.h +++ b/lib/CodeGen/AsmPrinter/DwarfException.h @@ -32,21 +32,21 @@ class raw_ostream; //===----------------------------------------------------------------------===// /// DwarfException - Emits Dwarf exception handling directives. /// -class DwarfException : public Dwarf { +class DwarfException : public DwarfPrinter { struct FunctionEHFrameInfo { - std::string FnName; + MCSymbol *FunctionEHSym; // L_foo.eh unsigned Number; unsigned PersonalityIndex; bool hasCalls; bool hasLandingPads; std::vector<MachineMove> Moves; - const Function * function; + const Function *function; - FunctionEHFrameInfo(const std::string &FN, unsigned Num, unsigned P, + FunctionEHFrameInfo(MCSymbol *EHSym, unsigned Num, unsigned P, bool hC, bool hL, const std::vector<MachineMove> &M, const Function *f): - FnName(FN), Number(Num), PersonalityIndex(P), + FunctionEHSym(EHSym), Number(Num), PersonalityIndex(P), hasCalls(hC), hasLandingPads(hL), Moves(M), function (f) { } }; diff --git a/lib/CodeGen/AsmPrinter/DwarfPrinter.cpp b/lib/CodeGen/AsmPrinter/DwarfPrinter.cpp index 20b959b..d204bba 100644 --- a/lib/CodeGen/AsmPrinter/DwarfPrinter.cpp +++ b/lib/CodeGen/AsmPrinter/DwarfPrinter.cpp @@ -18,21 +18,22 @@ #include "llvm/CodeGen/MachineFunction.h" #include "llvm/CodeGen/MachineModuleInfo.h" #include "llvm/MC/MCAsmInfo.h" +#include "llvm/MC/MCStreamer.h" +#include "llvm/MC/MCSymbol.h" #include "llvm/Target/TargetData.h" #include "llvm/Target/TargetFrameInfo.h" #include "llvm/Target/TargetRegisterInfo.h" #include "llvm/Support/Dwarf.h" #include "llvm/Support/ErrorHandling.h" -#include "llvm/ADT/StringExtras.h" using namespace llvm; -Dwarf::Dwarf(raw_ostream &OS, AsmPrinter *A, const MCAsmInfo *T, - const char *flavor) +DwarfPrinter::DwarfPrinter(raw_ostream &OS, AsmPrinter *A, const MCAsmInfo *T, + const char *flavor) : 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) {} -void Dwarf::PrintRelDirective(bool Force32Bit, bool isInSection) const { +void DwarfPrinter::PrintRelDirective(bool Force32Bit, bool isInSection) const { if (isInSection && MAI->getDwarfSectionOffsetDirective()) O << MAI->getDwarfSectionOffsetDirective(); else if (Force32Bit || TD->getPointerSize() == sizeof(int32_t)) @@ -41,14 +42,125 @@ void Dwarf::PrintRelDirective(bool Force32Bit, bool isInSection) const { O << 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"; + case dwarf::DW_EH_PE_omit: return "omit"; + case dwarf::DW_EH_PE_pcrel: return "pcrel"; + case dwarf::DW_EH_PE_udata4: return "udata4"; + case dwarf::DW_EH_PE_udata8: return "udata8"; + case dwarf::DW_EH_PE_sdata4: return "sdata4"; + case dwarf::DW_EH_PE_sdata8: return "sdata8"; + case dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_udata4: return "pcrel udata4"; + case dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4: return "pcrel sdata4"; + case dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_udata8: return "pcrel udata8"; + case dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata8: return "pcrel sdata8"; + case dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel |dwarf::DW_EH_PE_udata4: + return "indirect pcrel udata4"; + case dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel |dwarf::DW_EH_PE_sdata4: + return "indirect pcrel sdata4"; + case dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel |dwarf::DW_EH_PE_udata8: + return "indirect pcrel udata8"; + case dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel |dwarf::DW_EH_PE_sdata8: + return "indirect pcrel sdata8"; + } + + return "<unknown encoding>"; +} + +/// 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 an optional string saying what the +/// encoding is specifying (e.g. "LSDA"). +void DwarfPrinter::EmitEncodingByte(unsigned Val, const char *Desc) { + if (Asm->VerboseAsm) { + if (Desc != 0) + Asm->OutStreamer.AddComment(Twine(Desc)+" Encoding = " + + Twine(DecodeDWARFEncoding(Val))); + else + Asm->OutStreamer.AddComment(Twine("Encoding = ") + + DecodeDWARFEncoding(Val)); + } + + Asm->OutStreamer.EmitIntValue(Val, 1, 0/*addrspace*/); +} + +/// EmitCFAByte - Emit a .byte 42 directive for a DW_CFA_xxx value. +void DwarfPrinter::EmitCFAByte(unsigned Val) { + if (Asm->VerboseAsm) { + if (Val >= dwarf::DW_CFA_offset && Val < dwarf::DW_CFA_offset+64) + Asm->OutStreamer.AddComment("DW_CFA_offset + Reg (" + + Twine(Val-dwarf::DW_CFA_offset) + ")"); + else + Asm->OutStreamer.AddComment(dwarf::CallFrameString(Val)); + } + Asm->OutStreamer.EmitIntValue(Val, 1, 0/*addrspace*/); +} + +/// EmitSLEB128 - emit the specified signed leb128 value. +void DwarfPrinter::EmitSLEB128(int Value, const char *Desc) const { + if (Asm->VerboseAsm && Desc) + Asm->OutStreamer.AddComment(Desc); + + if (MAI->hasLEB128()) { + O << "\t.sleb128\t" << Value; + Asm->OutStreamer.AddBlankLine(); + return; + } + + // If we don't have .sleb128, emit as .bytes. + int Sign = Value >> (8 * sizeof(Value) - 1); + bool IsMore; + + do { + unsigned char Byte = static_cast<unsigned char>(Value & 0x7f); + Value >>= 7; + IsMore = Value != Sign || ((Byte ^ Sign) & 0x40) != 0; + if (IsMore) Byte |= 0x80; + + Asm->OutStreamer.EmitIntValue(Byte, 1, /*addrspace*/0); + } while (IsMore); +} + +/// EmitULEB128 - emit the specified signed leb128 value. +void DwarfPrinter::EmitULEB128(unsigned Value, const char *Desc) const { + if (Asm->VerboseAsm && Desc) + Asm->OutStreamer.AddComment(Desc); + + if (MAI->hasLEB128()) { + O << "\t.uleb128\t" << Value; + Asm->OutStreamer.AddBlankLine(); + return; + } + + // If we don't have .uleb128, emit as .bytes. + do { + unsigned char Byte = static_cast<unsigned char>(Value & 0x7f); + Value >>= 7; + if (Value) Byte |= 0x80; + Asm->OutStreamer.EmitIntValue(Byte, 1, /*addrspace*/0); + } while (Value); +} + + /// PrintLabelName - Print label name in form used by Dwarf writer. /// -void Dwarf::PrintLabelName(const char *Tag, unsigned Number) const { +void DwarfPrinter::PrintLabelName(const char *Tag, unsigned Number) const { O << MAI->getPrivateGlobalPrefix() << Tag; if (Number) O << Number; } -void Dwarf::PrintLabelName(const char *Tag, unsigned Number, - const char *Suffix) const { +void DwarfPrinter::PrintLabelName(const char *Tag, unsigned Number, + const char *Suffix) const { O << MAI->getPrivateGlobalPrefix() << Tag; if (Number) O << Number; O << Suffix; @@ -56,32 +168,39 @@ void Dwarf::PrintLabelName(const char *Tag, unsigned Number, /// EmitLabel - Emit location label for internal use by Dwarf. /// -void Dwarf::EmitLabel(const char *Tag, unsigned Number) const { +void DwarfPrinter::EmitLabel(const char *Tag, unsigned Number) const { PrintLabelName(Tag, Number); O << ":\n"; } /// EmitReference - Emit a reference to a label. /// -void Dwarf::EmitReference(const char *Tag, unsigned Number, - bool IsPCRelative, bool Force32Bit) const { +void DwarfPrinter::EmitReference(const char *Tag, unsigned Number, + bool IsPCRelative, bool Force32Bit) const { PrintRelDirective(Force32Bit); PrintLabelName(Tag, Number); if (IsPCRelative) O << "-" << MAI->getPCSymbol(); } -void Dwarf::EmitReference(const std::string &Name, bool IsPCRelative, - bool Force32Bit) const { +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(); +} + /// EmitDifference - Emit the difference between two labels. Some assemblers do /// not behave with absolute expressions with data directives, so there is an /// option (needsSet) to use an intermediary set expression. -void Dwarf::EmitDifference(const char *TagHi, unsigned NumberHi, - const char *TagLo, unsigned NumberLo, - bool IsSmall) { +void DwarfPrinter::EmitDifference(const char *TagHi, unsigned NumberHi, + const char *TagLo, unsigned NumberLo, + bool IsSmall) { if (MAI->needsSet()) { O << "\t.set\t"; PrintLabelName("set", SetCounter, Flavor); @@ -102,10 +221,11 @@ void Dwarf::EmitDifference(const char *TagHi, unsigned NumberHi, } } -void Dwarf::EmitSectionOffset(const char* Label, const char* Section, - unsigned LabelNumber, unsigned SectionNumber, - bool IsSmall, bool isEH, - bool useSet) { +void DwarfPrinter::EmitSectionOffset(const char* Label, const char* Section, + unsigned LabelNumber, + unsigned SectionNumber, + bool IsSmall, bool isEH, + bool useSet) { bool printAbsolute = false; if (isEH) printAbsolute = MAI->isAbsoluteEHSectionOffsets(); @@ -140,8 +260,9 @@ void Dwarf::EmitSectionOffset(const char* Label, const char* Section, /// EmitFrameMoves - Emit frame instructions to describe the layout of the /// frame. -void Dwarf::EmitFrameMoves(const char *BaseLabel, unsigned BaseLabelID, - const std::vector<MachineMove> &Moves, bool isEH) { +void DwarfPrinter::EmitFrameMoves(const char *BaseLabel, unsigned BaseLabelID, + const std::vector<MachineMove> &Moves, + bool isEH) { int stackGrowth = Asm->TM.getFrameInfo()->getStackGrowthDirection() == TargetFrameInfo::StackGrowsUp ? @@ -164,10 +285,9 @@ void Dwarf::EmitFrameMoves(const char *BaseLabel, unsigned BaseLabelID, // Advance row if new location. if (BaseLabel && LabelID && (BaseLabelID != LabelID || !IsLocal)) { - Asm->EmitInt8(dwarf::DW_CFA_advance_loc4); - Asm->EOL("DW_CFA_advance_loc4"); + EmitCFAByte(dwarf::DW_CFA_advance_loc4); EmitDifference("label", LabelID, BaseLabel, BaseLabelID, true); - Asm->EOL(); + Asm->O << '\n'; BaseLabelID = LabelID; BaseLabel = "label"; @@ -178,29 +298,22 @@ void Dwarf::EmitFrameMoves(const char *BaseLabel, unsigned BaseLabelID, if (Dst.isReg() && Dst.getReg() == MachineLocation::VirtualFP) { if (!Src.isReg()) { if (Src.getReg() == MachineLocation::VirtualFP) { - Asm->EmitInt8(dwarf::DW_CFA_def_cfa_offset); - Asm->EOL("DW_CFA_def_cfa_offset"); + EmitCFAByte(dwarf::DW_CFA_def_cfa_offset); } else { - Asm->EmitInt8(dwarf::DW_CFA_def_cfa); - Asm->EOL("DW_CFA_def_cfa"); - Asm->EmitULEB128Bytes(RI->getDwarfRegNum(Src.getReg(), isEH)); - Asm->EOL("Register"); + EmitCFAByte(dwarf::DW_CFA_def_cfa); + EmitULEB128(RI->getDwarfRegNum(Src.getReg(), isEH), "Register"); } int Offset = -Src.getOffset(); - - Asm->EmitULEB128Bytes(Offset); - Asm->EOL("Offset"); + EmitULEB128(Offset, "Offset"); } else { llvm_unreachable("Machine move not supported yet."); } } else if (Src.isReg() && Src.getReg() == MachineLocation::VirtualFP) { if (Dst.isReg()) { - Asm->EmitInt8(dwarf::DW_CFA_def_cfa_register); - Asm->EOL("DW_CFA_def_cfa_register"); - Asm->EmitULEB128Bytes(RI->getDwarfRegNum(Dst.getReg(), isEH)); - Asm->EOL("Register"); + EmitCFAByte(dwarf::DW_CFA_def_cfa_register); + EmitULEB128(RI->getDwarfRegNum(Dst.getReg(), isEH), "Register"); } else { llvm_unreachable("Machine move not supported yet."); } @@ -209,27 +322,16 @@ void Dwarf::EmitFrameMoves(const char *BaseLabel, unsigned BaseLabelID, int Offset = Dst.getOffset() / stackGrowth; if (Offset < 0) { - Asm->EmitInt8(dwarf::DW_CFA_offset_extended_sf); - Asm->EOL("DW_CFA_offset_extended_sf"); - Asm->EmitULEB128Bytes(Reg); - Asm->EOL("Reg"); - Asm->EmitSLEB128Bytes(Offset); - Asm->EOL("Offset"); + EmitCFAByte(dwarf::DW_CFA_offset_extended_sf); + EmitULEB128(Reg, "Reg"); + EmitSLEB128(Offset, "Offset"); } else if (Reg < 64) { - Asm->EmitInt8(dwarf::DW_CFA_offset + Reg); - if (Asm->isVerbose()) - Asm->EOL("DW_CFA_offset + Reg (" + utostr(Reg) + ")"); - else - Asm->EOL(); - Asm->EmitULEB128Bytes(Offset); - Asm->EOL("Offset"); + EmitCFAByte(dwarf::DW_CFA_offset + Reg); + EmitULEB128(Offset, "Offset"); } else { - Asm->EmitInt8(dwarf::DW_CFA_offset_extended); - Asm->EOL("DW_CFA_offset_extended"); - Asm->EmitULEB128Bytes(Reg); - Asm->EOL("Reg"); - Asm->EmitULEB128Bytes(Offset); - Asm->EOL("Offset"); + EmitCFAByte(dwarf::DW_CFA_offset_extended); + EmitULEB128(Reg, "Reg"); + EmitULEB128(Offset, "Offset"); } } } diff --git a/lib/CodeGen/AsmPrinter/DwarfPrinter.h b/lib/CodeGen/AsmPrinter/DwarfPrinter.h index dedd695..86fe2ab 100644 --- a/lib/CodeGen/AsmPrinter/DwarfPrinter.h +++ b/lib/CodeGen/AsmPrinter/DwarfPrinter.h @@ -17,135 +17,149 @@ #include "DwarfLabel.h" #include "llvm/CodeGen/MachineLocation.h" #include "llvm/Support/Compiler.h" -#include "llvm/Support/raw_ostream.h" +#include "llvm/Support/FormattedStream.h" #include <vector> namespace llvm { - class AsmPrinter; - class MachineFunction; - class MachineModuleInfo; - class Module; - class MCAsmInfo; - class TargetData; - class TargetRegisterInfo; - - class Dwarf { - protected: - //===-------------------------------------------------------------==---===// - // Core attributes used by the DWARF printer. - // - - /// O - Stream to .s file. - /// - raw_ostream &O; - - /// Asm - Target of Dwarf emission. - /// - AsmPrinter *Asm; - - /// MAI - Target asm information. - /// - const MCAsmInfo *MAI; - - /// TD - Target data. - /// - const TargetData *TD; - - /// RI - Register Information. - /// - const TargetRegisterInfo *RI; - - /// M - Current module. - /// - Module *M; - - /// MF - Current machine function. - /// - MachineFunction *MF; - - /// MMI - Collected machine module information. - /// - MachineModuleInfo *MMI; - - /// 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; - - Dwarf(raw_ostream &OS, AsmPrinter *A, const MCAsmInfo *T, - const char *flavor); - public: - //===------------------------------------------------------------------===// - // Accessors. - // - const AsmPrinter *getAsm() const { return Asm; } - MachineModuleInfo *getMMI() const { return MMI; } - const MCAsmInfo *getMCAsmInfo() const { return MAI; } - const TargetData *getTargetData() const { return TD; } - - void PrintRelDirective(bool Force32Bit = false, - bool isInSection = false) 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; - - /// EmitDifference - Emit the difference between two labels. Some - /// assemblers do not behave with absolute expressions with data directives, - /// so there is an option (needsSet) to use an intermediary set expression. - 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, - bool IsSmall = false); - - void EmitSectionOffset(const char* Label, const char* Section, - unsigned LabelNumber, unsigned SectionNumber, - bool IsSmall = false, bool isEH = false, - bool useSet = true); - - /// EmitFrameMoves - Emit frame instructions to describe the layout of the - /// frame. - void EmitFrameMoves(const char *BaseLabel, unsigned BaseLabelID, - const std::vector<MachineMove> &Moves, bool isEH); +class AsmPrinter; +class MachineFunction; +class MachineModuleInfo; +class Module; +class MCAsmInfo; +class TargetData; +class TargetRegisterInfo; +class MCSymbol; +class Twine; + +class DwarfPrinter { +protected: + //===-------------------------------------------------------------==---===// + // Core attributes used by the DWARF printer. + // + + /// O - Stream to .s file. + raw_ostream &O; + + /// Asm - Target of Dwarf emission. + AsmPrinter *Asm; + + /// MAI - Target asm information. + const MCAsmInfo *MAI; + + /// TD - Target data. + const TargetData *TD; + + /// RI - Register Information. + const TargetRegisterInfo *RI; + + /// M - Current module. + Module *M; + + /// MF - Current machine function. + MachineFunction *MF; + + /// MMI - Collected machine module information. + MachineModuleInfo *MMI; + + /// 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); +public: + + //===------------------------------------------------------------------===// + // Accessors. + // + const AsmPrinter *getAsm() const { return Asm; } + MachineModuleInfo *getMMI() const { return MMI; } + const MCAsmInfo *getMCAsmInfo() const { return MAI; } + const TargetData *getTargetData() const { return TD; } + + 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 + /// specifying (e.g. "LSDA"). + void EmitEncodingByte(unsigned Val, const char *Desc); + + /// EmitCFAByte - Emit a .byte 42 directive for a DW_CFA_xxx value. + void EmitCFAByte(unsigned Val); + + + /// EmitSLEB128 - emit the specified signed leb128 value. + void EmitSLEB128(int Value, const char *Desc) const; + + /// EmitULEB128 - emit the specified unsigned leb128 value. + void EmitULEB128(unsigned Value, const char *Desc = 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; + + /// EmitDifference - Emit the difference between two labels. Some + /// assemblers do not behave with absolute expressions with data directives, + /// so there is an option (needsSet) to use an intermediary set expression. + 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, + bool IsSmall = false); + + void EmitSectionOffset(const char* Label, const char* Section, + unsigned LabelNumber, unsigned SectionNumber, + bool IsSmall = false, bool isEH = false, + bool useSet = true); + + /// EmitFrameMoves - Emit frame instructions to describe the layout of the + /// frame. + void EmitFrameMoves(const char *BaseLabel, unsigned BaseLabelID, + const std::vector<MachineMove> &Moves, bool isEH); }; } // end llvm namespace diff --git a/lib/CodeGen/AsmPrinter/Makefile b/lib/CodeGen/AsmPrinter/Makefile index 8f65d8d..b0071d0 100644 --- a/lib/CodeGen/AsmPrinter/Makefile +++ b/lib/CodeGen/AsmPrinter/Makefile @@ -1,4 +1,4 @@ -##===- lib/CodeGen/SelectionDAG/Makefile -------------------*- Makefile -*-===## +##===- lib/CodeGen/AsmPrinter/Makefile ---------------------*- Makefile -*-===## # # The LLVM Compiler Infrastructure # @@ -6,8 +6,9 @@ # License. See LICENSE.TXT for details. # ##===----------------------------------------------------------------------===## + LEVEL = ../../.. LIBRARYNAME = LLVMAsmPrinter -PARALLEL_DIRS = +CXXFLAGS = -fno-rtti include $(LEVEL)/Makefile.common diff --git a/lib/CodeGen/AsmPrinter/OcamlGCPrinter.cpp b/lib/CodeGen/AsmPrinter/OcamlGCPrinter.cpp index 9286ad5..3531ed6 100644 --- a/lib/CodeGen/AsmPrinter/OcamlGCPrinter.cpp +++ b/lib/CodeGen/AsmPrinter/OcamlGCPrinter.cpp @@ -21,7 +21,7 @@ #include "llvm/Target/TargetLoweringObjectFile.h" #include "llvm/Target/TargetMachine.h" #include "llvm/Support/ErrorHandling.h" -#include "llvm/Support/raw_ostream.h" +#include "llvm/Support/FormattedStream.h" using namespace llvm; namespace { @@ -105,8 +105,7 @@ void OcamlGCMetadataPrinter::finishAssembly(raw_ostream &OS, AsmPrinter &AP, AP.OutStreamer.SwitchSection(AP.getObjFileLowering().getDataSection()); EmitCamlGlobal(getModule(), OS, AP, MAI, "data_end"); - OS << AddressDirective << 0; // FIXME: Why does ocaml emit this?? - AP.EOL(); + OS << AddressDirective << 0 << '\n'; // FIXME: Why does ocaml emit this?? AP.OutStreamer.SwitchSection(AP.getObjFileLowering().getDataSection()); EmitCamlGlobal(getModule(), OS, AP, MAI, "frametable"); @@ -140,14 +139,11 @@ void OcamlGCMetadataPrinter::finishAssembly(raw_ostream &OS, AsmPrinter &AP, } OS << AddressDirective - << MAI.getPrivateGlobalPrefix() << "label" << J->Num; - AP.EOL("call return address"); + << MAI.getPrivateGlobalPrefix() << "label" << J->Num << '\n'; AP.EmitInt16(FrameSize); - AP.EOL("stack frame size"); AP.EmitInt16(LiveCount); - AP.EOL("live root count"); for (GCFunctionInfo::live_iterator K = FI.live_begin(J), KE = FI.live_end(J); K != KE; ++K) { @@ -155,8 +151,7 @@ void OcamlGCMetadataPrinter::finishAssembly(raw_ostream &OS, AsmPrinter &AP, "GC root stack offset is outside of fixed stack frame and out " "of range for ocaml GC!"); - OS << "\t.word\t" << K->StackOffset; - AP.EOL("stack offset"); + AP.EmitInt32(K->StackOffset); } AP.EmitAlignment(AddressAlignLog); |