summaryrefslogtreecommitdiff
path: root/lib/CodeGen
diff options
context:
space:
mode:
authorRoman Divacky <rdivacky@FreeBSD.org>2010-04-06 15:52:58 +0000
committerRoman Divacky <rdivacky@FreeBSD.org>2010-04-06 15:52:58 +0000
commit9f4a1da9a0a56a0b0a7f8249f34b3cdea6179c41 (patch)
tree0dd020f28a4846707f8d60717d9b2921ea187bd8 /lib/CodeGen
parentb5efedaf2ab20d844d5a21cdef76b55acbf4f01c (diff)
downloadsrc-test2-9f4a1da9a0a56a0b0a7f8249f34b3cdea6179c41.tar.gz
src-test2-9f4a1da9a0a56a0b0a7f8249f34b3cdea6179c41.zip
Notes
Diffstat (limited to 'lib/CodeGen')
-rw-r--r--lib/CodeGen/AsmPrinter/AsmPrinter.cpp547
-rw-r--r--lib/CodeGen/AsmPrinter/AsmPrinterDwarf.cpp279
-rw-r--r--lib/CodeGen/AsmPrinter/AsmPrinterInlineAsm.cpp357
-rw-r--r--lib/CodeGen/AsmPrinter/CMakeLists.txt4
-rw-r--r--lib/CodeGen/AsmPrinter/DIE.cpp78
-rw-r--r--lib/CodeGen/AsmPrinter/DIE.h34
-rw-r--r--lib/CodeGen/AsmPrinter/DwarfDebug.cpp532
-rw-r--r--lib/CodeGen/AsmPrinter/DwarfDebug.h127
-rw-r--r--lib/CodeGen/AsmPrinter/DwarfException.cpp218
-rw-r--r--lib/CodeGen/AsmPrinter/DwarfException.h32
-rw-r--r--lib/CodeGen/AsmPrinter/DwarfPrinter.cpp308
-rw-r--r--lib/CodeGen/AsmPrinter/DwarfPrinter.h131
-rw-r--r--lib/CodeGen/AsmPrinter/DwarfWriter.cpp87
-rw-r--r--lib/CodeGen/AsmPrinter/OcamlGCPrinter.cpp82
-rw-r--r--lib/CodeGen/GCMetadataPrinter.cpp6
-rw-r--r--lib/CodeGen/LLVMTargetMachine.cpp19
-rw-r--r--lib/CodeGen/MachineFunction.cpp5
-rw-r--r--lib/CodeGen/MachineFunctionAnalysis.cpp20
-rw-r--r--lib/CodeGen/MachineModuleInfo.cpp1
-rw-r--r--lib/CodeGen/MachineSink.cpp5
-rw-r--r--lib/CodeGen/PrologEpilogInserter.cpp6
-rw-r--r--lib/CodeGen/SelectionDAG/FastISel.cpp74
-rw-r--r--lib/CodeGen/SelectionDAG/LegalizeDAG.cpp1
-rw-r--r--lib/CodeGen/SelectionDAG/SelectionDAG.cpp73
-rw-r--r--lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp117
-rw-r--r--lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h1
-rw-r--r--lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp21
27 files changed, 1557 insertions, 1608 deletions
diff --git a/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
index 625a2b95f205..c86e2411d303 100644
--- a/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
+++ b/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
@@ -13,11 +13,9 @@
#define DEBUG_TYPE "asm-printer"
#include "llvm/CodeGen/AsmPrinter.h"
-#include "llvm/Assembly/Writer.h"
-#include "llvm/DerivedTypes.h"
-#include "llvm/Constants.h"
+#include "DwarfDebug.h"
+#include "DwarfException.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"
@@ -27,50 +25,59 @@
#include "llvm/CodeGen/MachineModuleInfo.h"
#include "llvm/Analysis/ConstantFolding.h"
#include "llvm/Analysis/DebugInfo.h"
+#include "llvm/MC/MCAsmInfo.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/MC/MCAsmInfo.h"
#include "llvm/Target/Mangler.h"
#include "llvm/Target/TargetData.h"
#include "llvm/Target/TargetInstrInfo.h"
#include "llvm/Target/TargetLowering.h"
#include "llvm/Target/TargetLoweringObjectFile.h"
-#include "llvm/Target/TargetOptions.h"
#include "llvm/Target/TargetRegisterInfo.h"
-#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/Statistic.h"
-#include "llvm/Support/CommandLine.h"
-#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/Format.h"
-#include "llvm/Support/FormattedStream.h"
-#include <cerrno>
using namespace llvm;
STATISTIC(EmittedInsts, "Number of machine instrs printed");
char AsmPrinter::ID = 0;
-AsmPrinter::AsmPrinter(formatted_raw_ostream &o, TargetMachine &tm,
- MCStreamer &Streamer)
- : MachineFunctionPass(&ID), O(o),
- TM(tm), MAI(tm.getMCAsmInfo()), TRI(tm.getRegisterInfo()),
+typedef DenseMap<GCStrategy*,GCMetadataPrinter*> gcp_map_type;
+static gcp_map_type &getGCMap(void *&P) {
+ if (P == 0)
+ P = new gcp_map_type();
+ return *(gcp_map_type*)P;
+}
+
+
+AsmPrinter::AsmPrinter(TargetMachine &tm, MCStreamer &Streamer)
+ : MachineFunctionPass(&ID),
+ TM(tm), MAI(tm.getMCAsmInfo()),
OutContext(Streamer.getContext()),
OutStreamer(Streamer),
LastMI(0), LastFn(0), Counter(~0U), SetCounter(0) {
- DW = 0; MMI = 0;
+ DD = 0; DE = 0; MMI = 0; LI = 0;
+ GCMetadataPrinters = 0;
VerboseAsm = Streamer.isVerboseAsm();
}
AsmPrinter::~AsmPrinter() {
- for (gcp_iterator I = GCMetadataPrinters.begin(),
- E = GCMetadataPrinters.end(); I != E; ++I)
- delete I->second;
+ assert(DD == 0 && DE == 0 && "Debug/EH info didn't get finalized");
+
+ if (GCMetadataPrinters != 0) {
+ gcp_map_type &GCMap = getGCMap(GCMetadataPrinters);
+
+ for (gcp_map_type::iterator I = GCMap.begin(), E = GCMap.end(); I != E; ++I)
+ delete I->second;
+ delete &GCMap;
+ GCMetadataPrinters = 0;
+ }
delete &OutStreamer;
}
@@ -85,18 +92,25 @@ TargetLoweringObjectFile &AsmPrinter::getObjFileLowering() const {
return TM.getTargetLowering()->getObjFileLowering();
}
+
+/// getTargetData - Return information about data layout.
+const TargetData &AsmPrinter::getTargetData() const {
+ return *TM.getTargetData();
+}
+
/// getCurrentSection() - Return the current section we are emitting to.
const MCSection *AsmPrinter::getCurrentSection() const {
return OutStreamer.getCurrentSection();
}
+
void AsmPrinter::getAnalysisUsage(AnalysisUsage &AU) const {
AU.setPreservesAll();
MachineFunctionPass::getAnalysisUsage(AU);
AU.addRequired<MachineModuleInfo>();
AU.addRequired<GCModuleInfo>();
- if (VerboseAsm)
+ if (isVerbose())
AU.addRequired<MachineLoopInfo>();
}
@@ -124,17 +138,22 @@ bool AsmPrinter::doInitialization(Module &M) {
assert(MI && "AsmPrinter didn't require GCModuleInfo?");
for (GCModuleInfo::iterator I = MI->begin(), E = MI->end(); I != E; ++I)
if (GCMetadataPrinter *MP = GetOrCreateGCPrinter(*I))
- MP->beginAssembly(O, *this, *MAI);
-
- if (!M.getModuleInlineAsm().empty())
- O << MAI->getCommentString() << " Start of file scope inline assembly\n"
- << M.getModuleInlineAsm()
- << '\n' << MAI->getCommentString()
- << " End of file scope inline assembly\n";
+ MP->beginAssembly(*this);
- DW = getAnalysisIfAvailable<DwarfWriter>();
- if (DW)
- DW->BeginModule(&M, MMI, O, this, MAI);
+ // Emit module-level inline asm if it exists.
+ if (!M.getModuleInlineAsm().empty()) {
+ OutStreamer.AddComment("Start of file scope inline assembly");
+ OutStreamer.AddBlankLine();
+ EmitInlineAsm(M.getModuleInlineAsm(), 0/*no loc cookie*/);
+ OutStreamer.AddComment("End of file scope inline assembly");
+ OutStreamer.AddBlankLine();
+ }
+
+ if (MAI->doesSupportDebugInformation())
+ DD = new DwarfDebug(this, &M);
+
+ if (MAI->doesSupportExceptionHandling())
+ DE = new DwarfException(this);
return false;
}
@@ -161,7 +180,7 @@ void AsmPrinter::EmitLinkage(unsigned Linkage, MCSymbol *GVSym) const {
// .linkonce discard
// FIXME: It would be nice to use .linkonce samesize for non-common
// globals.
- O << LinkOnce;
+ OutStreamer.EmitRawText(StringRef(LinkOnce));
} else {
// .weak _foo
OutStreamer.EmitSymbolAttribute(GVSym, MCSA_Weak);
@@ -210,7 +229,7 @@ void AsmPrinter::EmitGlobalVariable(const GlobalVariable *GV) {
if (GVKind.isCommon() || GVKind.isBSSLocal()) {
if (Size == 0) Size = 1; // .comm Foo, 0 is undefined, avoid it.
- if (VerboseAsm) {
+ if (isVerbose()) {
WriteAsOperand(OutStreamer.GetCommentOS(), GV,
/*PrintType=*/false, GV->getParent());
OutStreamer.GetCommentOS() << '\n';
@@ -263,7 +282,7 @@ void AsmPrinter::EmitGlobalVariable(const GlobalVariable *GV) {
EmitLinkage(GV->getLinkage(), GVSym);
EmitAlignment(AlignLog, GV);
- if (VerboseAsm) {
+ if (isVerbose()) {
WriteAsOperand(OutStreamer.GetCommentOS(), GV,
/*PrintType=*/false, GV->getParent());
OutStreamer.GetCommentOS() << '\n';
@@ -297,7 +316,7 @@ void AsmPrinter::EmitFunctionHeader() {
if (MAI->hasDotTypeDotSizeDirective())
OutStreamer.EmitSymbolAttribute(CurrentFnSym, MCSA_ELF_TypeFunction);
- if (VerboseAsm) {
+ if (isVerbose()) {
WriteAsOperand(OutStreamer.GetCommentOS(), F,
/*PrintType=*/false, F->getParent());
OutStreamer.GetCommentOS() << '\n';
@@ -319,13 +338,17 @@ void AsmPrinter::EmitFunctionHeader() {
// Add some workaround for linkonce linkage on Cygwin\MinGW.
if (MAI->getLinkOnceDirective() != 0 &&
- (F->hasLinkOnceLinkage() || F->hasWeakLinkage()))
+ (F->hasLinkOnceLinkage() || F->hasWeakLinkage())) {
// FIXME: What is this?
- O << "Lllvm$workaround$fake$stub$" << *CurrentFnSym << ":\n";
+ MCSymbol *FakeStub =
+ OutContext.GetOrCreateSymbol(Twine("Lllvm$workaround$fake$stub$")+
+ CurrentFnSym->getName());
+ OutStreamer.EmitLabel(FakeStub);
+ }
// Emit pre-function debug and/or EH information.
- if (MAI->doesSupportDebugInformation() || MAI->doesSupportExceptionHandling())
- DW->BeginFunction(MF);
+ if (DE) DE->BeginFunction(MF);
+ if (DD) DD->beginFunction(MF);
}
/// EmitFunctionEntryLabel - Emit the label that is the entrypoint for the
@@ -389,6 +412,28 @@ static void EmitComments(const MachineInstr &MI, raw_ostream &CommentOS) {
}
}
+/// EmitImplicitDef - This method emits the specified machine instruction
+/// that is an implicit def.
+static void EmitImplicitDef(const MachineInstr *MI, AsmPrinter &AP) {
+ unsigned RegNo = MI->getOperand(0).getReg();
+ AP.OutStreamer.AddComment(Twine("implicit-def: ") +
+ AP.TM.getRegisterInfo()->getName(RegNo));
+ AP.OutStreamer.AddBlankLine();
+}
+
+static void EmitKill(const MachineInstr *MI, AsmPrinter &AP) {
+ std::string Str = "kill:";
+ for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
+ const MachineOperand &Op = MI->getOperand(i);
+ assert(Op.isReg() && "KILL instruction must have only register operands");
+ Str += ' ';
+ Str += AP.TM.getRegisterInfo()->getName(Op.getReg());
+ Str += (Op.isDef() ? "<def>" : "<kill>");
+ }
+ AP.OutStreamer.AddComment(Str);
+ AP.OutStreamer.AddBlankLine();
+}
+
/// EmitFunctionBody - This method emits the body and trailer for a
@@ -397,6 +442,8 @@ void AsmPrinter::EmitFunctionBody() {
// Emit target-specific gunk before the function body.
EmitFunctionBodyStart();
+ bool ShouldPrintDebugScopes = DD && MMI->hasDebugInfo();
+
// Print out code for the function.
bool HasAnyRealCode = false;
for (MachineFunction::const_iterator I = MF->begin(), E = MF->end();
@@ -411,34 +458,34 @@ void AsmPrinter::EmitFunctionBody() {
++EmittedInsts;
- // FIXME: Clean up processDebugLoc.
- processDebugLoc(II, true);
+ if (ShouldPrintDebugScopes)
+ DD->beginScope(II);
- if (VerboseAsm)
+ if (isVerbose())
EmitComments(*II, OutStreamer.GetCommentOS());
switch (II->getOpcode()) {
case TargetOpcode::DBG_LABEL:
case TargetOpcode::EH_LABEL:
case TargetOpcode::GC_LABEL:
- printLabelInst(II);
+ OutStreamer.EmitLabel(II->getOperand(0).getMCSymbol());
break;
case TargetOpcode::INLINEASM:
- printInlineAsm(II);
+ EmitInlineAsm(II);
break;
case TargetOpcode::IMPLICIT_DEF:
- printImplicitDef(II);
+ if (isVerbose()) EmitImplicitDef(II, *this);
break;
case TargetOpcode::KILL:
- printKill(II);
+ if (isVerbose()) EmitKill(II, *this);
break;
default:
EmitInstruction(II);
break;
}
- // FIXME: Clean up processDebugLoc.
- processDebugLoc(II, false);
+ if (ShouldPrintDebugScopes)
+ DD->endScope(II);
}
}
@@ -451,12 +498,25 @@ void AsmPrinter::EmitFunctionBody() {
// Emit target-specific gunk after the function body.
EmitFunctionBodyEnd();
- if (MAI->hasDotTypeDotSizeDirective())
- O << "\t.size\t" << *CurrentFnSym << ", .-" << *CurrentFnSym << '\n';
+ // If the target wants a .size directive for the size of the function, emit
+ // it.
+ if (MAI->hasDotTypeDotSizeDirective()) {
+ // Create a symbol for the end of function, so we can get the size as
+ // difference between the function label and the temp label.
+ MCSymbol *FnEndLabel = OutContext.CreateTempSymbol();
+ OutStreamer.EmitLabel(FnEndLabel);
+
+ const MCExpr *SizeExp =
+ MCBinaryExpr::CreateSub(MCSymbolRefExpr::Create(FnEndLabel, OutContext),
+ MCSymbolRefExpr::Create(CurrentFnSym, OutContext),
+ OutContext);
+ OutStreamer.EmitELFSize(CurrentFnSym, SizeExp);
+ }
// Emit post-function debug information.
- if (MAI->doesSupportDebugInformation() || MAI->doesSupportExceptionHandling())
- DW->EndFunction(MF);
+ if (DD) DD->endFunction(MF);
+ if (DE) DE->EndFunction();
+ MMI->EndFunction();
// Print out jump tables referenced by the function.
EmitJumpTableInfo();
@@ -471,9 +531,15 @@ bool AsmPrinter::doFinalization(Module &M) {
I != E; ++I)
EmitGlobalVariable(I);
- // Emit final debug information.
- if (MAI->doesSupportDebugInformation() || MAI->doesSupportExceptionHandling())
- DW->EndModule();
+ // Finalize debug and EH information.
+ if (DE) {
+ DE->EndModule();
+ delete DE; DE = 0;
+ }
+ if (DD) {
+ DD->endModule();
+ delete DD; DD = 0;
+ }
// If the target wants to know about weak references, print them all.
if (MAI->getWeakRefDirective()) {
@@ -523,7 +589,7 @@ bool AsmPrinter::doFinalization(Module &M) {
assert(MI && "AsmPrinter didn't require GCModuleInfo?");
for (GCModuleInfo::iterator I = MI->end(), E = MI->begin(); I != E; )
if (GCMetadataPrinter *MP = GetOrCreateGCPrinter(*--I))
- MP->finishAssembly(O, *this, *MAI);
+ MP->finishAssembly(*this);
// If we don't have any trampolines, then we don't require stack memory
// to be executable. Some targets have a directive to declare this.
@@ -537,7 +603,7 @@ bool AsmPrinter::doFinalization(Module &M) {
EmitEndOfAsmFile(M);
delete Mang; Mang = 0;
- DW = 0; MMI = 0;
+ MMI = 0;
OutStreamer.Finish();
return false;
@@ -548,7 +614,7 @@ void AsmPrinter::SetupMachineFunction(MachineFunction &MF) {
// Get the function symbol.
CurrentFnSym = Mang->getSymbol(MF.getFunction());
- if (VerboseAsm)
+ if (isVerbose())
LI = &getAnalysis<MachineLoopInfo>();
}
@@ -636,7 +702,7 @@ void AsmPrinter::EmitConstantPool() {
Offset = NewOffset + TM.getTargetData()->getTypeAllocSize(Ty);
// Emit the label with a comment on it.
- if (VerboseAsm) {
+ if (isVerbose()) {
OutStreamer.GetCommentOS() << "constant pool ";
WriteTypeSymbolic(OutStreamer.GetCommentOS(), CPE.getType(),
MF->getFunction()->getParent());
@@ -896,12 +962,6 @@ void AsmPrinter::EmitInt32(int Value) const {
OutStreamer.EmitIntValue(Value, 4, 0/*addrspace*/);
}
-/// EmitInt64 - Emit a long long directive and value.
-///
-void AsmPrinter::EmitInt64(uint64_t Value) const {
- OutStreamer.EmitIntValue(Value, 8, 0/*addrspace*/);
-}
-
/// EmitLabelDifference - Emit something like ".long Hi-Lo" where the size
/// in bytes of the directive is specified by Size and Hi/Lo specify the
/// labels. This implicitly uses .set if it is available.
@@ -919,9 +979,7 @@ void AsmPrinter::EmitLabelDifference(const MCSymbol *Hi, const MCSymbol *Lo,
}
// Otherwise, emit with .set (aka assignment).
- MCSymbol *SetLabel =
- OutContext.GetOrCreateSymbol(Twine(MAI->getPrivateGlobalPrefix()) +
- "set" + Twine(SetCounter++));
+ MCSymbol *SetLabel = GetTempSymbol("set", SetCounter++);
OutStreamer.EmitAssignment(SetLabel, Diff);
OutStreamer.EmitSymbolValue(SetLabel, Size, 0/*AddrSpace*/);
}
@@ -1156,7 +1214,7 @@ static void EmitGlobalConstantFP(const ConstantFP *CFP, unsigned AddrSpace,
// FP Constants are printed as integer constants to avoid losing
// precision.
if (CFP->getType()->isDoubleTy()) {
- if (AP.VerboseAsm) {
+ if (AP.isVerbose()) {
double Val = CFP->getValueAPF().convertToDouble();
AP.OutStreamer.GetCommentOS() << "double " << Val << '\n';
}
@@ -1167,7 +1225,7 @@ static void EmitGlobalConstantFP(const ConstantFP *CFP, unsigned AddrSpace,
}
if (CFP->getType()->isFloatTy()) {
- if (AP.VerboseAsm) {
+ if (AP.isVerbose()) {
float Val = CFP->getValueAPF().convertToFloat();
AP.OutStreamer.GetCommentOS() << "float " << Val << '\n';
}
@@ -1181,7 +1239,7 @@ static void EmitGlobalConstantFP(const ConstantFP *CFP, unsigned AddrSpace,
// api needed to prevent premature destruction
APInt API = CFP->getValueAPF().bitcastToAPInt();
const uint64_t *p = API.getRawData();
- if (AP.VerboseAsm) {
+ if (AP.isVerbose()) {
// Convert to double so we can print the approximate val as a comment.
APFloat DoubleVal = CFP->getValueAPF();
bool ignored;
@@ -1252,7 +1310,7 @@ void AsmPrinter::EmitGlobalConstant(const Constant *CV, unsigned AddrSpace) {
case 2:
case 4:
case 8:
- if (VerboseAsm)
+ if (isVerbose())
OutStreamer.GetCommentOS() << format("0x%llx\n", CI->getZExtValue());
OutStreamer.EmitIntValue(CI->getZExtValue(), Size, AddrSpace);
return;
@@ -1295,297 +1353,31 @@ void AsmPrinter::EmitMachineConstantPoolValue(MachineConstantPoolValue *MCPV) {
llvm_unreachable("Target does not support EmitMachineConstantPoolValue");
}
-/// PrintSpecial - Print information related to the specified machine instr
-/// that is independent of the operand, and may be independent of the instr
-/// itself. This can be useful for portably encoding the comment character
-/// or other bits of target-specific knowledge into the asmstrings. The
-/// syntax used is ${:comment}. Targets can override this to add support
-/// for their own strange codes.
-void AsmPrinter::PrintSpecial(const MachineInstr *MI, const char *Code) const {
- if (!strcmp(Code, "private")) {
- O << MAI->getPrivateGlobalPrefix();
- } else if (!strcmp(Code, "comment")) {
- if (VerboseAsm)
- O << MAI->getCommentString();
- } else if (!strcmp(Code, "uid")) {
- // Comparing the address of MI isn't sufficient, because machineinstrs may
- // be allocated to the same address across functions.
- const Function *ThisF = MI->getParent()->getParent()->getFunction();
-
- // If this is a new LastFn instruction, bump the counter.
- if (LastMI != MI || LastFn != ThisF) {
- ++Counter;
- LastMI = MI;
- LastFn = ThisF;
- }
- O << Counter;
- } else {
- std::string msg;
- raw_string_ostream Msg(msg);
- Msg << "Unknown special formatter '" << Code
- << "' for machine instr: " << *MI;
- llvm_report_error(Msg.str());
- }
-}
-
-/// processDebugLoc - Processes the debug information of each machine
-/// instruction's DebugLoc.
-void AsmPrinter::processDebugLoc(const MachineInstr *MI,
- bool BeforePrintingInsn) {
- if (!MAI || !DW || !MAI->doesSupportDebugInformation()
- || !DW->ShouldEmitDwarfDebug())
- return;
-
- if (!BeforePrintingInsn)
- // After printing instruction
- DW->EndScope(MI);
- else
- DW->BeginScope(MI);
-}
-
-
-/// printInlineAsm - This method formats and prints the specified machine
-/// instruction that is an inline asm.
-void AsmPrinter::printInlineAsm(const MachineInstr *MI) const {
- unsigned NumOperands = MI->getNumOperands();
-
- // Count the number of register definitions.
- unsigned NumDefs = 0;
- for (; MI->getOperand(NumDefs).isReg() && MI->getOperand(NumDefs).isDef();
- ++NumDefs)
- assert(NumDefs != NumOperands-1 && "No asm string?");
-
- assert(MI->getOperand(NumDefs).isSymbol() && "No asm string?");
-
- // Disassemble the AsmStr, printing out the literal pieces, the operands, etc.
- const char *AsmStr = MI->getOperand(NumDefs).getSymbolName();
-
- O << '\t';
-
- // If this asmstr is empty, just print the #APP/#NOAPP markers.
- // These are useful to see where empty asm's wound up.
- if (AsmStr[0] == 0) {
- O << MAI->getCommentString() << MAI->getInlineAsmStart() << "\n\t";
- O << MAI->getCommentString() << MAI->getInlineAsmEnd() << '\n';
- return;
- }
-
- O << MAI->getCommentString() << MAI->getInlineAsmStart() << "\n\t";
-
- // The variant of the current asmprinter.
- int AsmPrinterVariant = MAI->getAssemblerDialect();
-
- int CurVariant = -1; // The number of the {.|.|.} region we are in.
- const char *LastEmitted = AsmStr; // One past the last character emitted.
-
- while (*LastEmitted) {
- switch (*LastEmitted) {
- default: {
- // Not a special case, emit the string section literally.
- const char *LiteralEnd = LastEmitted+1;
- while (*LiteralEnd && *LiteralEnd != '{' && *LiteralEnd != '|' &&
- *LiteralEnd != '}' && *LiteralEnd != '$' && *LiteralEnd != '\n')
- ++LiteralEnd;
- if (CurVariant == -1 || CurVariant == AsmPrinterVariant)
- O.write(LastEmitted, LiteralEnd-LastEmitted);
- LastEmitted = LiteralEnd;
- break;
- }
- case '\n':
- ++LastEmitted; // Consume newline character.
- O << '\n'; // Indent code with newline.
- break;
- case '$': {
- ++LastEmitted; // Consume '$' character.
- bool Done = true;
-
- // Handle escapes.
- switch (*LastEmitted) {
- default: Done = false; break;
- case '$': // $$ -> $
- if (CurVariant == -1 || CurVariant == AsmPrinterVariant)
- O << '$';
- ++LastEmitted; // Consume second '$' character.
- break;
- case '(': // $( -> same as GCC's { character.
- ++LastEmitted; // Consume '(' character.
- if (CurVariant != -1) {
- llvm_report_error("Nested variants found in inline asm string: '"
- + std::string(AsmStr) + "'");
- }
- CurVariant = 0; // We're in the first variant now.
- break;
- case '|':
- ++LastEmitted; // consume '|' character.
- if (CurVariant == -1)
- O << '|'; // this is gcc's behavior for | outside a variant
- else
- ++CurVariant; // We're in the next variant.
- break;
- case ')': // $) -> same as GCC's } char.
- ++LastEmitted; // consume ')' character.
- if (CurVariant == -1)
- O << '}'; // this is gcc's behavior for } outside a variant
- else
- CurVariant = -1;
- break;
- }
- if (Done) break;
-
- bool HasCurlyBraces = false;
- if (*LastEmitted == '{') { // ${variable}
- ++LastEmitted; // Consume '{' character.
- HasCurlyBraces = true;
- }
-
- // If we have ${:foo}, then this is not a real operand reference, it is a
- // "magic" string reference, just like in .td files. Arrange to call
- // PrintSpecial.
- if (HasCurlyBraces && *LastEmitted == ':') {
- ++LastEmitted;
- const char *StrStart = LastEmitted;
- const char *StrEnd = strchr(StrStart, '}');
- if (StrEnd == 0) {
- llvm_report_error("Unterminated ${:foo} operand in inline asm string: '"
- + std::string(AsmStr) + "'");
- }
-
- std::string Val(StrStart, StrEnd);
- PrintSpecial(MI, Val.c_str());
- LastEmitted = StrEnd+1;
- break;
- }
-
- const char *IDStart = LastEmitted;
- char *IDEnd;
- errno = 0;
- long Val = strtol(IDStart, &IDEnd, 10); // We only accept numbers for IDs.
- if (!isdigit(*IDStart) || (Val == 0 && errno == EINVAL)) {
- llvm_report_error("Bad $ operand number in inline asm string: '"
- + std::string(AsmStr) + "'");
- }
- LastEmitted = IDEnd;
-
- char Modifier[2] = { 0, 0 };
-
- if (HasCurlyBraces) {
- // If we have curly braces, check for a modifier character. This
- // supports syntax like ${0:u}, which correspond to "%u0" in GCC asm.
- if (*LastEmitted == ':') {
- ++LastEmitted; // Consume ':' character.
- if (*LastEmitted == 0) {
- llvm_report_error("Bad ${:} expression in inline asm string: '"
- + std::string(AsmStr) + "'");
- }
-
- Modifier[0] = *LastEmitted;
- ++LastEmitted; // Consume modifier character.
- }
-
- if (*LastEmitted != '}') {
- llvm_report_error("Bad ${} expression in inline asm string: '"
- + std::string(AsmStr) + "'");
- }
- ++LastEmitted; // Consume '}' character.
- }
-
- if ((unsigned)Val >= NumOperands-1) {
- llvm_report_error("Invalid $ operand number in inline asm string: '"
- + std::string(AsmStr) + "'");
- }
-
- // Okay, we finally have a value number. Ask the target to print this
- // operand!
- if (CurVariant == -1 || CurVariant == AsmPrinterVariant) {
- unsigned OpNo = 1;
-
- bool Error = false;
-
- // Scan to find the machine operand number for the operand.
- for (; Val; --Val) {
- if (OpNo >= MI->getNumOperands()) break;
- unsigned OpFlags = MI->getOperand(OpNo).getImm();
- OpNo += InlineAsm::getNumOperandRegisters(OpFlags) + 1;
- }
-
- if (OpNo >= MI->getNumOperands()) {
- Error = true;
- } else {
- unsigned OpFlags = MI->getOperand(OpNo).getImm();
- ++OpNo; // Skip over the ID number.
-
- if (Modifier[0] == 'l') // labels are target independent
- O << *MI->getOperand(OpNo).getMBB()->getSymbol();
- else {
- AsmPrinter *AP = const_cast<AsmPrinter*>(this);
- if ((OpFlags & 7) == 4) {
- Error = AP->PrintAsmMemoryOperand(MI, OpNo, AsmPrinterVariant,
- Modifier[0] ? Modifier : 0);
- } else {
- Error = AP->PrintAsmOperand(MI, OpNo, AsmPrinterVariant,
- Modifier[0] ? Modifier : 0);
- }
- }
- }
- if (Error) {
- std::string msg;
- raw_string_ostream Msg(msg);
- Msg << "Invalid operand found in inline asm: '" << AsmStr << "'\n";
- MI->print(Msg);
- llvm_report_error(Msg.str());
- }
- }
- break;
- }
- }
- }
- O << "\n\t" << MAI->getCommentString() << MAI->getInlineAsmEnd();
- OutStreamer.AddBlankLine();
-}
-
-/// printImplicitDef - This method prints the specified machine instruction
-/// that is an implicit def.
-void AsmPrinter::printImplicitDef(const MachineInstr *MI) const {
- if (!VerboseAsm) return;
- O.PadToColumn(MAI->getCommentColumn());
- O << MAI->getCommentString() << " implicit-def: "
- << TRI->getName(MI->getOperand(0).getReg());
- OutStreamer.AddBlankLine();
+void AsmPrinter::printOffset(int64_t Offset, raw_ostream &OS) const {
+ if (Offset > 0)
+ OS << '+' << Offset;
+ else if (Offset < 0)
+ OS << Offset;
}
-void AsmPrinter::printKill(const MachineInstr *MI) const {
- if (!VerboseAsm) return;
- O.PadToColumn(MAI->getCommentColumn());
- O << MAI->getCommentString() << " kill:";
- for (unsigned n = 0, e = MI->getNumOperands(); n != e; ++n) {
- const MachineOperand &op = MI->getOperand(n);
- assert(op.isReg() && "KILL instruction must have only register operands");
- O << ' ' << TRI->getName(op.getReg()) << (op.isDef() ? "<def>" : "<kill>");
- }
- OutStreamer.AddBlankLine();
-}
+//===----------------------------------------------------------------------===//
+// Symbol Lowering Routines.
+//===----------------------------------------------------------------------===//
-/// printLabel - This method prints a local label used by debug and
-/// exception handling tables.
-void AsmPrinter::printLabelInst(const MachineInstr *MI) const {
- OutStreamer.EmitLabel(MI->getOperand(0).getMCSymbol());
+/// GetTempSymbol - Return the MCSymbol corresponding to the assembler
+/// temporary label with the specified stem and unique ID.
+MCSymbol *AsmPrinter::GetTempSymbol(StringRef Name, unsigned ID) const {
+ return OutContext.GetOrCreateSymbol(Twine(MAI->getPrivateGlobalPrefix()) +
+ Name + Twine(ID));
}
-/// PrintAsmOperand - Print the specified operand of MI, an INLINEASM
-/// instruction, using the specified assembler variant. Targets should
-/// override this to format as appropriate.
-bool AsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
- unsigned AsmVariant, const char *ExtraCode) {
- // Target doesn't support this yet!
- return true;
+/// GetTempSymbol - Return an assembler temporary label with the specified
+/// stem.
+MCSymbol *AsmPrinter::GetTempSymbol(StringRef Name) const {
+ return OutContext.GetOrCreateSymbol(Twine(MAI->getPrivateGlobalPrefix())+
+ Name);
}
-bool AsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo,
- unsigned AsmVariant,
- const char *ExtraCode) {
- // Target doesn't support this yet!
- return true;
-}
MCSymbol *AsmPrinter::GetBlockAddressSymbol(const BlockAddress *BA) const {
return MMI->getAddrLabelSymbol(BA->getBasicBlock());
@@ -1663,10 +1455,10 @@ static void PrintChildLoopComment(raw_ostream &OS, const MachineLoop *Loop,
}
}
-/// PrintBasicBlockLoopComments - Pretty-print comments for basic blocks.
-static void PrintBasicBlockLoopComments(const MachineBasicBlock &MBB,
- const MachineLoopInfo *LI,
- const AsmPrinter &AP) {
+/// EmitBasicBlockLoopComments - Pretty-print comments for basic blocks.
+static void EmitBasicBlockLoopComments(const MachineBasicBlock &MBB,
+ const MachineLoopInfo *LI,
+ const AsmPrinter &AP) {
// Add loop depth information
const MachineLoop *Loop = LI->getLoopFor(&MBB);
if (Loop == 0) return;
@@ -1716,7 +1508,7 @@ void AsmPrinter::EmitBasicBlockStart(const MachineBasicBlock *MBB) const {
// the references were generated.
if (MBB->hasAddressTaken()) {
const BasicBlock *BB = MBB->getBasicBlock();
- if (VerboseAsm)
+ if (isVerbose())
OutStreamer.AddComment("Block address taken");
std::vector<MCSymbol*> Syms = MMI->getAddrLabelSymbolToEmit(BB);
@@ -1727,22 +1519,23 @@ void AsmPrinter::EmitBasicBlockStart(const MachineBasicBlock *MBB) const {
// Print the main label for the block.
if (MBB->pred_empty() || isBlockOnlyReachableByFallthrough(MBB)) {
- if (VerboseAsm) {
- // NOTE: Want this comment at start of line.
- O << MAI->getCommentString() << " BB#" << MBB->getNumber() << ':';
+ if (isVerbose() && OutStreamer.hasRawTextSupport()) {
if (const BasicBlock *BB = MBB->getBasicBlock())
if (BB->hasName())
OutStreamer.AddComment("%" + BB->getName());
- PrintBasicBlockLoopComments(*MBB, LI, *this);
- OutStreamer.AddBlankLine();
+ EmitBasicBlockLoopComments(*MBB, LI, *this);
+
+ // NOTE: Want this comment at start of line, don't emit with AddComment.
+ OutStreamer.EmitRawText(Twine(MAI->getCommentString()) + " BB#" +
+ Twine(MBB->getNumber()) + ":");
}
} else {
- if (VerboseAsm) {
+ if (isVerbose()) {
if (const BasicBlock *BB = MBB->getBasicBlock())
if (BB->hasName())
OutStreamer.AddComment("%" + BB->getName());
- PrintBasicBlockLoopComments(*MBB, LI, *this);
+ EmitBasicBlockLoopComments(*MBB, LI, *this);
}
OutStreamer.EmitLabel(MBB->getSymbol());
@@ -1766,18 +1559,11 @@ void AsmPrinter::EmitVisibility(MCSymbol *Sym, unsigned Visibility) const {
OutStreamer.EmitSymbolAttribute(Sym, Attr);
}
-void AsmPrinter::printOffset(int64_t Offset) const {
- if (Offset > 0)
- O << '+' << Offset;
- else if (Offset < 0)
- O << Offset;
-}
-
/// isBlockOnlyReachableByFallthough - Return true if the basic block has
/// exactly one predecessor and the control transfer mechanism between
/// the predecessor and this block is a fall-through.
-bool AsmPrinter::isBlockOnlyReachableByFallthrough(const MachineBasicBlock *MBB)
- const {
+bool AsmPrinter::
+isBlockOnlyReachableByFallthrough(const MachineBasicBlock *MBB) const {
// If this is a landing pad, it isn't a fall through. If it has no preds,
// then nothing falls through to it.
if (MBB->isLandingPad() || MBB->pred_empty())
@@ -1809,9 +1595,10 @@ bool AsmPrinter::isBlockOnlyReachableByFallthrough(const MachineBasicBlock *MBB)
GCMetadataPrinter *AsmPrinter::GetOrCreateGCPrinter(GCStrategy *S) {
if (!S->usesMetadata())
return 0;
-
- gcp_iterator GCPI = GCMetadataPrinters.find(S);
- if (GCPI != GCMetadataPrinters.end())
+
+ gcp_map_type &GCMap = getGCMap(GCMetadataPrinters);
+ gcp_map_type::iterator GCPI = GCMap.find(S);
+ if (GCPI != GCMap.end())
return GCPI->second;
const char *Name = S->getName().c_str();
@@ -1822,7 +1609,7 @@ GCMetadataPrinter *AsmPrinter::GetOrCreateGCPrinter(GCStrategy *S) {
if (strcmp(Name, I->getName()) == 0) {
GCMetadataPrinter *GMP = I->instantiate();
GMP->S = S;
- GCMetadataPrinters.insert(std::make_pair(S, GMP));
+ GCMap.insert(std::make_pair(S, GMP));
return GMP;
}
diff --git a/lib/CodeGen/AsmPrinter/AsmPrinterDwarf.cpp b/lib/CodeGen/AsmPrinter/AsmPrinterDwarf.cpp
new file mode 100644
index 000000000000..b310578584bc
--- /dev/null
+++ b/lib/CodeGen/AsmPrinter/AsmPrinterDwarf.cpp
@@ -0,0 +1,279 @@
+//===-- AsmPrinterDwarf.cpp - AsmPrinter Dwarf Support --------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the Dwarf emissions parts of AsmPrinter.
+//
+//===----------------------------------------------------------------------===//
+
+#define DEBUG_TYPE "asm-printer"
+#include "llvm/CodeGen/AsmPrinter.h"
+#include "llvm/CodeGen/MachineLocation.h"
+#include "llvm/MC/MCAsmInfo.h"
+#include "llvm/MC/MCSection.h"
+#include "llvm/MC/MCStreamer.h"
+#include "llvm/MC/MCSymbol.h"
+#include "llvm/Target/TargetData.h"
+#include "llvm/Target/TargetFrameInfo.h"
+#include "llvm/Target/TargetLoweringObjectFile.h"
+#include "llvm/Target/TargetMachine.h"
+#include "llvm/Target/TargetRegisterInfo.h"
+#include "llvm/ADT/Twine.h"
+#include "llvm/Support/Dwarf.h"
+using namespace llvm;
+
+//===----------------------------------------------------------------------===//
+// Dwarf Emission Helper Routines
+//===----------------------------------------------------------------------===//
+
+/// EmitSLEB128 - emit the specified signed leb128 value.
+void AsmPrinter::EmitSLEB128(int Value, const char *Desc) const {
+ if (isVerbose() && Desc)
+ OutStreamer.AddComment(Desc);
+
+ if (MAI->hasLEB128()) {
+ // FIXME: MCize.
+ OutStreamer.EmitRawText("\t.sleb128\t" + Twine(Value));
+ 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;
+ OutStreamer.EmitIntValue(Byte, 1, /*addrspace*/0);
+ } while (IsMore);
+}
+
+/// EmitULEB128 - emit the specified signed leb128 value.
+void AsmPrinter::EmitULEB128(unsigned Value, const char *Desc,
+ unsigned PadTo) const {
+ if (isVerbose() && Desc)
+ OutStreamer.AddComment(Desc);
+
+ if (MAI->hasLEB128() && PadTo == 0) {
+ // FIXME: MCize.
+ OutStreamer.EmitRawText("\t.uleb128\t" + Twine(Value));
+ return;
+ }
+
+ // If we don't have .uleb128 or we want to emit padding, emit as .bytes.
+ do {
+ unsigned char Byte = static_cast<unsigned char>(Value & 0x7f);
+ Value >>= 7;
+ if (Value || PadTo != 0) Byte |= 0x80;
+ OutStreamer.EmitIntValue(Byte, 1, /*addrspace*/0);
+ } while (Value);
+
+ if (PadTo) {
+ if (PadTo > 1)
+ OutStreamer.EmitFill(PadTo - 1, 0x80/*fillval*/, 0/*addrspace*/);
+ OutStreamer.EmitFill(1, 0/*fillval*/, 0/*addrspace*/);
+ }
+}
+
+/// EmitCFAByte - Emit a .byte 42 directive for a DW_CFA_xxx value.
+void AsmPrinter::EmitCFAByte(unsigned Val) const {
+ if (isVerbose()) {
+ if (Val >= dwarf::DW_CFA_offset && Val < dwarf::DW_CFA_offset+64)
+ OutStreamer.AddComment("DW_CFA_offset + Reg (" +
+ Twine(Val-dwarf::DW_CFA_offset) + ")");
+ else
+ OutStreamer.AddComment(dwarf::CallFrameString(Val));
+ }
+ OutStreamer.EmitIntValue(Val, 1, 0/*addrspace*/);
+}
+
+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 AsmPrinter::EmitEncodingByte(unsigned Val, const char *Desc) const {
+ if (isVerbose()) {
+ if (Desc != 0)
+ OutStreamer.AddComment(Twine(Desc)+" Encoding = " +
+ Twine(DecodeDWARFEncoding(Val)));
+ else
+ OutStreamer.AddComment(Twine("Encoding = ") +
+ DecodeDWARFEncoding(Val));
+ }
+
+ OutStreamer.EmitIntValue(Val, 1, 0/*addrspace*/);
+}
+
+/// GetSizeOfEncodedValue - Return the size of the encoding in bytes.
+unsigned AsmPrinter::GetSizeOfEncodedValue(unsigned Encoding) const {
+ if (Encoding == dwarf::DW_EH_PE_omit)
+ return 0;
+
+ switch (Encoding & 0x07) {
+ default: assert(0 && "Invalid encoded value.");
+ case dwarf::DW_EH_PE_absptr: return TM.getTargetData()->getPointerSize();
+ case dwarf::DW_EH_PE_udata2: return 2;
+ case dwarf::DW_EH_PE_udata4: return 4;
+ case dwarf::DW_EH_PE_udata8: return 8;
+ }
+}
+
+void AsmPrinter::EmitReference(const MCSymbol *Sym, unsigned Encoding) const {
+ const TargetLoweringObjectFile &TLOF = getObjFileLowering();
+
+ const MCExpr *Exp =
+ TLOF.getExprForDwarfReference(Sym, Mang, MMI, Encoding, OutStreamer);
+ OutStreamer.EmitValue(Exp, GetSizeOfEncodedValue(Encoding), /*addrspace*/0);
+}
+
+void AsmPrinter::EmitReference(const GlobalValue *GV, unsigned Encoding)const{
+ const TargetLoweringObjectFile &TLOF = getObjFileLowering();
+
+ const MCExpr *Exp =
+ TLOF.getExprForDwarfGlobalReference(GV, Mang, MMI, Encoding, OutStreamer);
+ OutStreamer.EmitValue(Exp, GetSizeOfEncodedValue(Encoding), /*addrspace*/0);
+}
+
+/// EmitSectionOffset - Emit the 4-byte offset of Label from the start of its
+/// section. This can be done with a special directive if the target supports
+/// it (e.g. cygwin) or by emitting it as an offset from a label at the start
+/// of the section.
+///
+/// SectionLabel is a temporary label emitted at the start of the section that
+/// Label lives in.
+void AsmPrinter::EmitSectionOffset(const MCSymbol *Label,
+ const MCSymbol *SectionLabel) const {
+ // On COFF targets, we have to emit the special .secrel32 directive.
+ if (const char *SecOffDir = MAI->getDwarfSectionOffsetDirective()) {
+ // FIXME: MCize.
+ OutStreamer.EmitRawText(SecOffDir + Twine(Label->getName()));
+ return;
+ }
+
+ // Get the section that we're referring to, based on SectionLabel.
+ const MCSection &Section = SectionLabel->getSection();
+
+ // If Label has already been emitted, verify that it is in the same section as
+ // section label for sanity.
+ assert((!Label->isInSection() || &Label->getSection() == &Section) &&
+ "Section offset using wrong section base for label");
+
+ // If the section in question will end up with an address of 0 anyway, we can
+ // just emit an absolute reference to save a relocation.
+ if (Section.isBaseAddressKnownZero()) {
+ OutStreamer.EmitSymbolValue(Label, 4, 0/*AddrSpace*/);
+ return;
+ }
+
+ // Otherwise, emit it as a label difference from the start of the section.
+ EmitLabelDifference(Label, SectionLabel, 4);
+}
+
+//===----------------------------------------------------------------------===//
+// Dwarf Lowering Routines
+//===----------------------------------------------------------------------===//
+
+
+/// EmitFrameMoves - Emit frame instructions to describe the layout of the
+/// frame.
+void AsmPrinter::EmitFrameMoves(const std::vector<MachineMove> &Moves,
+ MCSymbol *BaseLabel, bool isEH) const {
+ const TargetRegisterInfo *RI = TM.getRegisterInfo();
+
+ int stackGrowth = TM.getTargetData()->getPointerSize();
+ if (TM.getFrameInfo()->getStackGrowthDirection() !=
+ TargetFrameInfo::StackGrowsUp)
+ stackGrowth *= -1;
+
+ for (unsigned i = 0, N = Moves.size(); i < N; ++i) {
+ const MachineMove &Move = Moves[i];
+ MCSymbol *Label = Move.getLabel();
+ // Throw out move if the label is invalid.
+ if (Label && !Label->isDefined()) continue; // Not emitted, in dead code.
+
+ const MachineLocation &Dst = Move.getDestination();
+ const MachineLocation &Src = Move.getSource();
+
+ // Advance row if new location.
+ if (BaseLabel && Label) {
+ MCSymbol *ThisSym = Label;
+ if (ThisSym != BaseLabel) {
+ EmitCFAByte(dwarf::DW_CFA_advance_loc4);
+ EmitLabelDifference(ThisSym, BaseLabel, 4);
+ BaseLabel = ThisSym;
+ }
+ }
+
+ // If advancing cfa.
+ if (Dst.isReg() && Dst.getReg() == MachineLocation::VirtualFP) {
+ assert(!Src.isReg() && "Machine move not supported yet.");
+
+ if (Src.getReg() == MachineLocation::VirtualFP) {
+ EmitCFAByte(dwarf::DW_CFA_def_cfa_offset);
+ } else {
+ EmitCFAByte(dwarf::DW_CFA_def_cfa);
+ EmitULEB128(RI->getDwarfRegNum(Src.getReg(), isEH), "Register");
+ }
+
+ EmitULEB128(-Src.getOffset(), "Offset");
+ continue;
+ }
+
+ if (Src.isReg() && Src.getReg() == MachineLocation::VirtualFP) {
+ assert(Dst.isReg() && "Machine move not supported yet.");
+ EmitCFAByte(dwarf::DW_CFA_def_cfa_register);
+ EmitULEB128(RI->getDwarfRegNum(Dst.getReg(), isEH), "Register");
+ continue;
+ }
+
+ unsigned Reg = RI->getDwarfRegNum(Src.getReg(), isEH);
+ int Offset = Dst.getOffset() / stackGrowth;
+
+ if (Offset < 0) {
+ EmitCFAByte(dwarf::DW_CFA_offset_extended_sf);
+ EmitULEB128(Reg, "Reg");
+ EmitSLEB128(Offset, "Offset");
+ } else if (Reg < 64) {
+ EmitCFAByte(dwarf::DW_CFA_offset + Reg);
+ EmitULEB128(Offset, "Offset");
+ } else {
+ EmitCFAByte(dwarf::DW_CFA_offset_extended);
+ EmitULEB128(Reg, "Reg");
+ EmitULEB128(Offset, "Offset");
+ }
+ }
+}
diff --git a/lib/CodeGen/AsmPrinter/AsmPrinterInlineAsm.cpp b/lib/CodeGen/AsmPrinter/AsmPrinterInlineAsm.cpp
new file mode 100644
index 000000000000..255bcd413f22
--- /dev/null
+++ b/lib/CodeGen/AsmPrinter/AsmPrinterInlineAsm.cpp
@@ -0,0 +1,357 @@
+//===-- AsmPrinterInlineAsm.cpp - AsmPrinter Inline Asm Handling ----------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the inline assembler pieces of the AsmPrinter class.
+//
+//===----------------------------------------------------------------------===//
+
+#define DEBUG_TYPE "asm-printer"
+#include "llvm/CodeGen/AsmPrinter.h"
+#include "llvm/InlineAsm.h"
+#include "llvm/LLVMContext.h"
+#include "llvm/Module.h"
+#include "llvm/CodeGen/MachineBasicBlock.h"
+#include "llvm/CodeGen/MachineModuleInfo.h"
+#include "llvm/MC/MCAsmInfo.h"
+#include "llvm/MC/MCStreamer.h"
+#include "llvm/MC/MCSymbol.h"
+#include "llvm/MC/MCParser/AsmParser.h"
+#include "llvm/Target/TargetAsmParser.h"
+#include "llvm/Target/TargetMachine.h"
+#include "llvm/Target/TargetRegistry.h"
+#include "llvm/ADT/OwningPtr.h"
+#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/Twine.h"
+#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Support/SourceMgr.h"
+#include "llvm/Support/raw_ostream.h"
+using namespace llvm;
+
+/// EmitInlineAsm - Emit a blob of inline asm to the output streamer.
+void AsmPrinter::EmitInlineAsm(StringRef Str, unsigned LocCookie) const {
+ assert(!Str.empty() && "Can't emit empty inline asm block");
+
+ // Remember if the buffer is nul terminated or not so we can avoid a copy.
+ bool isNullTerminated = Str.back() == 0;
+ if (isNullTerminated)
+ Str = Str.substr(0, Str.size()-1);
+
+ // If the output streamer is actually a .s file, just emit the blob textually.
+ // This is useful in case the asm parser doesn't handle something but the
+ // system assembler does.
+ if (OutStreamer.hasRawTextSupport()) {
+ OutStreamer.EmitRawText(Str);
+ return;
+ }
+
+ SourceMgr SrcMgr;
+
+ // If the current LLVMContext has an inline asm handler, set it in SourceMgr.
+ LLVMContext &LLVMCtx = MMI->getModule()->getContext();
+ bool HasDiagHandler = false;
+ if (void *DiagHandler = LLVMCtx.getInlineAsmDiagnosticHandler()) {
+ SrcMgr.setDiagHandler((SourceMgr::DiagHandlerTy)(intptr_t)DiagHandler,
+ LLVMCtx.getInlineAsmDiagnosticContext(), LocCookie);
+ HasDiagHandler = true;
+ }
+
+ MemoryBuffer *Buffer;
+ if (isNullTerminated)
+ Buffer = MemoryBuffer::getMemBuffer(Str, "<inline asm>");
+ else
+ Buffer = MemoryBuffer::getMemBufferCopy(Str, "<inline asm>");
+
+ // Tell SrcMgr about this buffer, it takes ownership of the buffer.
+ SrcMgr.AddNewSourceBuffer(Buffer, SMLoc());
+
+ AsmParser Parser(SrcMgr, OutContext, OutStreamer, *MAI);
+ OwningPtr<TargetAsmParser> TAP(TM.getTarget().createAsmParser(Parser));
+ if (!TAP)
+ llvm_report_error("Inline asm not supported by this streamer because"
+ " we don't have an asm parser for this target\n");
+ Parser.setTargetParser(*TAP.get());
+
+ // Don't implicitly switch to the text section before the asm.
+ int Res = Parser.Run(/*NoInitialTextSection*/ true,
+ /*NoFinalize*/ true);
+ if (Res && !HasDiagHandler)
+ llvm_report_error("Error parsing inline asm\n");
+}
+
+
+/// EmitInlineAsm - This method formats and emits the specified machine
+/// instruction that is an inline asm.
+void AsmPrinter::EmitInlineAsm(const MachineInstr *MI) const {
+ assert(MI->isInlineAsm() && "printInlineAsm only works on inline asms");
+
+ unsigned NumOperands = MI->getNumOperands();
+
+ // Count the number of register definitions to find the asm string.
+ unsigned NumDefs = 0;
+ for (; MI->getOperand(NumDefs).isReg() && MI->getOperand(NumDefs).isDef();
+ ++NumDefs)
+ assert(NumDefs != NumOperands-1 && "No asm string?");
+
+ assert(MI->getOperand(NumDefs).isSymbol() && "No asm string?");
+
+ // Disassemble the AsmStr, printing out the literal pieces, the operands, etc.
+ const char *AsmStr = MI->getOperand(NumDefs).getSymbolName();
+
+ // If this asmstr is empty, just print the #APP/#NOAPP markers.
+ // These are useful to see where empty asm's wound up.
+ if (AsmStr[0] == 0) {
+ // Don't emit the comments if writing to a .o file.
+ if (!OutStreamer.hasRawTextSupport()) return;
+
+ OutStreamer.EmitRawText(Twine("\t")+MAI->getCommentString()+
+ MAI->getInlineAsmStart());
+ OutStreamer.EmitRawText(Twine("\t")+MAI->getCommentString()+
+ MAI->getInlineAsmEnd());
+ return;
+ }
+
+ // Emit the #APP start marker. This has to happen even if verbose-asm isn't
+ // enabled, so we use EmitRawText.
+ if (OutStreamer.hasRawTextSupport())
+ OutStreamer.EmitRawText(Twine("\t")+MAI->getCommentString()+
+ MAI->getInlineAsmStart());
+
+ // Emit the inline asm to a temporary string so we can emit it through
+ // EmitInlineAsm.
+ SmallString<256> StringData;
+ raw_svector_ostream OS(StringData);
+
+ OS << '\t';
+
+ // The variant of the current asmprinter.
+ int AsmPrinterVariant = MAI->getAssemblerDialect();
+
+ int CurVariant = -1; // The number of the {.|.|.} region we are in.
+ const char *LastEmitted = AsmStr; // One past the last character emitted.
+
+ while (*LastEmitted) {
+ switch (*LastEmitted) {
+ default: {
+ // Not a special case, emit the string section literally.
+ const char *LiteralEnd = LastEmitted+1;
+ while (*LiteralEnd && *LiteralEnd != '{' && *LiteralEnd != '|' &&
+ *LiteralEnd != '}' && *LiteralEnd != '$' && *LiteralEnd != '\n')
+ ++LiteralEnd;
+ if (CurVariant == -1 || CurVariant == AsmPrinterVariant)
+ OS.write(LastEmitted, LiteralEnd-LastEmitted);
+ LastEmitted = LiteralEnd;
+ break;
+ }
+ case '\n':
+ ++LastEmitted; // Consume newline character.
+ OS << '\n'; // Indent code with newline.
+ break;
+ case '$': {
+ ++LastEmitted; // Consume '$' character.
+ bool Done = true;
+
+ // Handle escapes.
+ switch (*LastEmitted) {
+ default: Done = false; break;
+ case '$': // $$ -> $
+ if (CurVariant == -1 || CurVariant == AsmPrinterVariant)
+ OS << '$';
+ ++LastEmitted; // Consume second '$' character.
+ break;
+ case '(': // $( -> same as GCC's { character.
+ ++LastEmitted; // Consume '(' character.
+ if (CurVariant != -1) {
+ llvm_report_error("Nested variants found in inline asm string: '"
+ + std::string(AsmStr) + "'");
+ }
+ CurVariant = 0; // We're in the first variant now.
+ break;
+ case '|':
+ ++LastEmitted; // consume '|' character.
+ if (CurVariant == -1)
+ OS << '|'; // this is gcc's behavior for | outside a variant
+ else
+ ++CurVariant; // We're in the next variant.
+ break;
+ case ')': // $) -> same as GCC's } char.
+ ++LastEmitted; // consume ')' character.
+ if (CurVariant == -1)
+ OS << '}'; // this is gcc's behavior for } outside a variant
+ else
+ CurVariant = -1;
+ break;
+ }
+ if (Done) break;
+
+ bool HasCurlyBraces = false;
+ if (*LastEmitted == '{') { // ${variable}
+ ++LastEmitted; // Consume '{' character.
+ HasCurlyBraces = true;
+ }
+
+ // If we have ${:foo}, then this is not a real operand reference, it is a
+ // "magic" string reference, just like in .td files. Arrange to call
+ // PrintSpecial.
+ if (HasCurlyBraces && *LastEmitted == ':') {
+ ++LastEmitted;
+ const char *StrStart = LastEmitted;
+ const char *StrEnd = strchr(StrStart, '}');
+ if (StrEnd == 0)
+ llvm_report_error(Twine("Unterminated ${:foo} operand in inline asm"
+ " string: '") + Twine(AsmStr) + "'");
+
+ std::string Val(StrStart, StrEnd);
+ PrintSpecial(MI, OS, Val.c_str());
+ LastEmitted = StrEnd+1;
+ break;
+ }
+
+ const char *IDStart = LastEmitted;
+ const char *IDEnd = IDStart;
+ while (*IDEnd >= '0' && *IDEnd <= '9') ++IDEnd;
+
+ unsigned Val;
+ if (StringRef(IDStart, IDEnd-IDStart).getAsInteger(10, Val))
+ llvm_report_error("Bad $ operand number in inline asm string: '"
+ + std::string(AsmStr) + "'");
+ LastEmitted = IDEnd;
+
+ char Modifier[2] = { 0, 0 };
+
+ if (HasCurlyBraces) {
+ // If we have curly braces, check for a modifier character. This
+ // supports syntax like ${0:u}, which correspond to "%u0" in GCC asm.
+ if (*LastEmitted == ':') {
+ ++LastEmitted; // Consume ':' character.
+ if (*LastEmitted == 0)
+ llvm_report_error("Bad ${:} expression in inline asm string: '" +
+ std::string(AsmStr) + "'");
+
+ Modifier[0] = *LastEmitted;
+ ++LastEmitted; // Consume modifier character.
+ }
+
+ if (*LastEmitted != '}')
+ llvm_report_error("Bad ${} expression in inline asm string: '"
+ + std::string(AsmStr) + "'");
+ ++LastEmitted; // Consume '}' character.
+ }
+
+ if (Val >= NumOperands-1)
+ llvm_report_error("Invalid $ operand number in inline asm string: '"
+ + std::string(AsmStr) + "'");
+
+ // Okay, we finally have a value number. Ask the target to print this
+ // operand!
+ if (CurVariant == -1 || CurVariant == AsmPrinterVariant) {
+ unsigned OpNo = 1;
+
+ bool Error = false;
+
+ // Scan to find the machine operand number for the operand.
+ for (; Val; --Val) {
+ if (OpNo >= MI->getNumOperands()) break;
+ unsigned OpFlags = MI->getOperand(OpNo).getImm();
+ OpNo += InlineAsm::getNumOperandRegisters(OpFlags) + 1;
+ }
+
+ if (OpNo >= MI->getNumOperands()) {
+ Error = true;
+ } else {
+ unsigned OpFlags = MI->getOperand(OpNo).getImm();
+ ++OpNo; // Skip over the ID number.
+
+ if (Modifier[0] == 'l') // labels are target independent
+ // FIXME: What if the operand isn't an MBB, report error?
+ OS << *MI->getOperand(OpNo).getMBB()->getSymbol();
+ else {
+ AsmPrinter *AP = const_cast<AsmPrinter*>(this);
+ if ((OpFlags & 7) == 4) {
+ Error = AP->PrintAsmMemoryOperand(MI, OpNo, AsmPrinterVariant,
+ Modifier[0] ? Modifier : 0,
+ OS);
+ } else {
+ Error = AP->PrintAsmOperand(MI, OpNo, AsmPrinterVariant,
+ Modifier[0] ? Modifier : 0, OS);
+ }
+ }
+ }
+ if (Error) {
+ std::string msg;
+ raw_string_ostream Msg(msg);
+ Msg << "Invalid operand found in inline asm: '" << AsmStr << "'\n";
+ MI->print(Msg);
+ llvm_report_error(Msg.str());
+ }
+ }
+ break;
+ }
+ }
+ }
+ OS << '\n' << (char)0; // null terminate string.
+ EmitInlineAsm(OS.str(), 0/*no loc cookie*/);
+
+ // Emit the #NOAPP end marker. This has to happen even if verbose-asm isn't
+ // enabled, so we use EmitRawText.
+ if (OutStreamer.hasRawTextSupport())
+ OutStreamer.EmitRawText(Twine("\t")+MAI->getCommentString()+
+ MAI->getInlineAsmEnd());
+}
+
+
+/// PrintSpecial - Print information related to the specified machine instr
+/// that is independent of the operand, and may be independent of the instr
+/// itself. This can be useful for portably encoding the comment character
+/// or other bits of target-specific knowledge into the asmstrings. The
+/// syntax used is ${:comment}. Targets can override this to add support
+/// for their own strange codes.
+void AsmPrinter::PrintSpecial(const MachineInstr *MI, raw_ostream &OS,
+ const char *Code) const {
+ if (!strcmp(Code, "private")) {
+ OS << MAI->getPrivateGlobalPrefix();
+ } else if (!strcmp(Code, "comment")) {
+ OS << MAI->getCommentString();
+ } else if (!strcmp(Code, "uid")) {
+ // Comparing the address of MI isn't sufficient, because machineinstrs may
+ // be allocated to the same address across functions.
+
+ // If this is a new LastFn instruction, bump the counter.
+ if (LastMI != MI || LastFn != getFunctionNumber()) {
+ ++Counter;
+ LastMI = MI;
+ LastFn = getFunctionNumber();
+ }
+ OS << Counter;
+ } else {
+ std::string msg;
+ raw_string_ostream Msg(msg);
+ Msg << "Unknown special formatter '" << Code
+ << "' for machine instr: " << *MI;
+ llvm_report_error(Msg.str());
+ }
+}
+
+/// PrintAsmOperand - Print the specified operand of MI, an INLINEASM
+/// instruction, using the specified assembler variant. Targets should
+/// override this to format as appropriate.
+bool AsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
+ unsigned AsmVariant, const char *ExtraCode,
+ raw_ostream &O) {
+ // Target doesn't support this yet!
+ return true;
+}
+
+bool AsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo,
+ unsigned AsmVariant,
+ const char *ExtraCode, raw_ostream &O) {
+ // Target doesn't support this yet!
+ return true;
+}
+
diff --git a/lib/CodeGen/AsmPrinter/CMakeLists.txt b/lib/CodeGen/AsmPrinter/CMakeLists.txt
index 7dc1fb596568..afc482dd15bf 100644
--- a/lib/CodeGen/AsmPrinter/CMakeLists.txt
+++ b/lib/CodeGen/AsmPrinter/CMakeLists.txt
@@ -1,9 +1,9 @@
add_llvm_library(LLVMAsmPrinter
AsmPrinter.cpp
+ AsmPrinterDwarf.cpp
+ AsmPrinterInlineAsm.cpp
DIE.cpp
DwarfDebug.cpp
DwarfException.cpp
- DwarfPrinter.cpp
- DwarfWriter.cpp
OcamlGCPrinter.cpp
)
diff --git a/lib/CodeGen/AsmPrinter/DIE.cpp b/lib/CodeGen/AsmPrinter/DIE.cpp
index e0e3ff794672..b2c70d51f5a5 100644
--- a/lib/CodeGen/AsmPrinter/DIE.cpp
+++ b/lib/CodeGen/AsmPrinter/DIE.cpp
@@ -12,7 +12,6 @@
//===----------------------------------------------------------------------===//
#include "DIE.h"
-#include "DwarfPrinter.h"
#include "llvm/ADT/Twine.h"
#include "llvm/CodeGen/AsmPrinter.h"
#include "llvm/MC/MCAsmInfo.h"
@@ -54,14 +53,14 @@ void DIEAbbrev::Profile(FoldingSetNodeID &ID) const {
/// Emit - Print the abbreviation using the specified asm printer.
///
-void DIEAbbrev::Emit(const DwarfPrinter *DP) const {
+void DIEAbbrev::Emit(AsmPrinter *AP) const {
// Emit its Dwarf tag type.
// FIXME: Doing work even in non-asm-verbose runs.
- DP->EmitULEB128(Tag, dwarf::TagString(Tag));
+ AP->EmitULEB128(Tag, dwarf::TagString(Tag));
// Emit whether it has children DIEs.
// FIXME: Doing work even in non-asm-verbose runs.
- DP->EmitULEB128(ChildrenFlag, dwarf::ChildrenString(ChildrenFlag));
+ AP->EmitULEB128(ChildrenFlag, dwarf::ChildrenString(ChildrenFlag));
// For each attribute description.
for (unsigned i = 0, N = Data.size(); i < N; ++i) {
@@ -69,18 +68,18 @@ void DIEAbbrev::Emit(const DwarfPrinter *DP) const {
// Emit attribute type.
// FIXME: Doing work even in non-asm-verbose runs.
- DP->EmitULEB128(AttrData.getAttribute(),
- dwarf::AttributeString(AttrData.getAttribute()));
+ AP->EmitULEB128(AttrData.getAttribute(),
+ dwarf::AttributeString(AttrData.getAttribute()));
// Emit form type.
// FIXME: Doing work even in non-asm-verbose runs.
- DP->EmitULEB128(AttrData.getForm(),
+ AP->EmitULEB128(AttrData.getForm(),
dwarf::FormEncodingString(AttrData.getForm()));
}
// Mark end of abbreviation.
- DP->EmitULEB128(0, "EOM(1)");
- DP->EmitULEB128(0, "EOM(2)");
+ AP->EmitULEB128(0, "EOM(1)");
+ AP->EmitULEB128(0, "EOM(2)");
}
#ifndef NDEBUG
@@ -188,8 +187,7 @@ void DIEValue::dump() {
/// EmitValue - Emit integer of appropriate size.
///
-void DIEInteger::EmitValue(DwarfPrinter *D, unsigned Form) const {
- const AsmPrinter *Asm = D->getAsm();
+void DIEInteger::EmitValue(AsmPrinter *Asm, unsigned Form) const {
unsigned Size = ~0U;
switch (Form) {
case dwarf::DW_FORM_flag: // Fall thru
@@ -201,8 +199,8 @@ void DIEInteger::EmitValue(DwarfPrinter *D, unsigned Form) const {
case dwarf::DW_FORM_data4: Size = 4; break;
case dwarf::DW_FORM_ref8: // Fall thru
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;
+ case dwarf::DW_FORM_udata: Asm->EmitULEB128(Integer); return;
+ case dwarf::DW_FORM_sdata: Asm->EmitSLEB128(Integer); return;
default: llvm_unreachable("DIE Value form not supported yet");
}
Asm->OutStreamer.EmitIntValue(Integer, Size, 0/*addrspace*/);
@@ -210,7 +208,7 @@ void DIEInteger::EmitValue(DwarfPrinter *D, unsigned Form) const {
/// SizeOf - Determine size of integer value in bytes.
///
-unsigned DIEInteger::SizeOf(const TargetData *TD, unsigned Form) const {
+unsigned DIEInteger::SizeOf(AsmPrinter *AP, unsigned Form) const {
switch (Form) {
case dwarf::DW_FORM_flag: // Fall thru
case dwarf::DW_FORM_ref1: // Fall thru
@@ -241,10 +239,10 @@ void DIEInteger::print(raw_ostream &O) {
/// EmitValue - Emit string value.
///
-void DIEString::EmitValue(DwarfPrinter *D, unsigned Form) const {
- D->getAsm()->OutStreamer.EmitBytes(Str, /*addrspace*/0);
+void DIEString::EmitValue(AsmPrinter *AP, unsigned Form) const {
+ AP->OutStreamer.EmitBytes(Str, /*addrspace*/0);
// Emit nul terminator.
- D->getAsm()->OutStreamer.EmitIntValue(0, 1, /*addrspace*/0);
+ AP->OutStreamer.EmitIntValue(0, 1, /*addrspace*/0);
}
#ifndef NDEBUG
@@ -259,17 +257,15 @@ void DIEString::print(raw_ostream &O) {
/// EmitValue - Emit label value.
///
-void DIELabel::EmitValue(DwarfPrinter *D, unsigned Form) const {
- bool IsSmall = Form == dwarf::DW_FORM_data4;
- unsigned Size = IsSmall ? 4 : D->getTargetData()->getPointerSize();
- D->getAsm()->OutStreamer.EmitSymbolValue(Label, Size, 0/*AddrSpace*/);
+void DIELabel::EmitValue(AsmPrinter *AP, unsigned Form) const {
+ AP->OutStreamer.EmitSymbolValue(Label, SizeOf(AP, Form), 0/*AddrSpace*/);
}
/// SizeOf - Determine size of label value in bytes.
///
-unsigned DIELabel::SizeOf(const TargetData *TD, unsigned Form) const {
+unsigned DIELabel::SizeOf(AsmPrinter *AP, unsigned Form) const {
if (Form == dwarf::DW_FORM_data4) return 4;
- return TD->getPointerSize();
+ return AP->getTargetData().getPointerSize();
}
#ifndef NDEBUG
@@ -284,16 +280,15 @@ void DIELabel::print(raw_ostream &O) {
/// EmitValue - Emit delta value.
///
-void DIEDelta::EmitValue(DwarfPrinter *D, unsigned Form) const {
- bool IsSmall = Form == dwarf::DW_FORM_data4;
- D->EmitDifference(LabelHi, LabelLo, IsSmall);
+void DIEDelta::EmitValue(AsmPrinter *AP, unsigned Form) const {
+ AP->EmitLabelDifference(LabelHi, LabelLo, SizeOf(AP, Form));
}
/// SizeOf - Determine size of delta value in bytes.
///
-unsigned DIEDelta::SizeOf(const TargetData *TD, unsigned Form) const {
+unsigned DIEDelta::SizeOf(AsmPrinter *AP, unsigned Form) const {
if (Form == dwarf::DW_FORM_data4) return 4;
- return TD->getPointerSize();
+ return AP->getTargetData().getPointerSize();
}
#ifndef NDEBUG
@@ -308,8 +303,8 @@ void DIEDelta::print(raw_ostream &O) {
/// EmitValue - Emit debug information entry offset.
///
-void DIEEntry::EmitValue(DwarfPrinter *D, unsigned Form) const {
- D->getAsm()->EmitInt32(Entry->getOffset());
+void DIEEntry::EmitValue(AsmPrinter *AP, unsigned Form) const {
+ AP->EmitInt32(Entry->getOffset());
}
#ifndef NDEBUG
@@ -324,11 +319,11 @@ void DIEEntry::print(raw_ostream &O) {
/// ComputeSize - calculate the size of the block.
///
-unsigned DIEBlock::ComputeSize(const TargetData *TD) {
+unsigned DIEBlock::ComputeSize(AsmPrinter *AP) {
if (!Size) {
const SmallVector<DIEAbbrevData, 8> &AbbrevData = Abbrev.getData();
for (unsigned i = 0, N = Values.size(); i < N; ++i)
- Size += Values[i]->SizeOf(TD, AbbrevData[i].getForm());
+ Size += Values[i]->SizeOf(AP, AbbrevData[i].getForm());
}
return Size;
@@ -336,29 +331,28 @@ unsigned DIEBlock::ComputeSize(const TargetData *TD) {
/// EmitValue - Emit block data.
///
-void DIEBlock::EmitValue(DwarfPrinter *D, unsigned Form) const {
- const AsmPrinter *Asm = D->getAsm();
+void DIEBlock::EmitValue(AsmPrinter *Asm, unsigned Form) const {
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: D->EmitULEB128(Size); break;
- default: llvm_unreachable("Improper form for block"); break;
+ default: assert(0 && "Improper form for block"); break;
+ 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->EmitULEB128(Size); break;
}
const SmallVector<DIEAbbrevData, 8> &AbbrevData = Abbrev.getData();
for (unsigned i = 0, N = Values.size(); i < N; ++i)
- Values[i]->EmitValue(D, AbbrevData[i].getForm());
+ Values[i]->EmitValue(Asm, AbbrevData[i].getForm());
}
/// SizeOf - Determine size of block data in bytes.
///
-unsigned DIEBlock::SizeOf(const TargetData *TD, unsigned Form) const {
+unsigned DIEBlock::SizeOf(AsmPrinter *AP, unsigned Form) const {
switch (Form) {
case dwarf::DW_FORM_block1: return Size + sizeof(int8_t);
case dwarf::DW_FORM_block2: return Size + sizeof(int16_t);
case dwarf::DW_FORM_block4: return Size + sizeof(int32_t);
- case dwarf::DW_FORM_block: return Size + MCAsmInfo::getULEB128Size(Size);
+ case dwarf::DW_FORM_block: return Size + MCAsmInfo::getULEB128Size(Size);
default: llvm_unreachable("Improper form for block"); break;
}
return 0;
diff --git a/lib/CodeGen/AsmPrinter/DIE.h b/lib/CodeGen/AsmPrinter/DIE.h
index 8b27ed20cb63..454326db0ea1 100644
--- a/lib/CodeGen/AsmPrinter/DIE.h
+++ b/lib/CodeGen/AsmPrinter/DIE.h
@@ -22,8 +22,6 @@
namespace llvm {
class AsmPrinter;
- class DwarfPrinter;
- class TargetData;
class MCSymbol;
class raw_ostream;
@@ -101,7 +99,7 @@ namespace llvm {
/// Emit - Print the abbreviation using the specified asm printer.
///
- void Emit(const DwarfPrinter *DP) const;
+ void Emit(AsmPrinter *AP) const;
#ifndef NDEBUG
void print(raw_ostream &O);
@@ -221,11 +219,11 @@ namespace llvm {
/// EmitValue - Emit value via the Dwarf writer.
///
- virtual void EmitValue(DwarfPrinter *D, unsigned Form) const = 0;
+ virtual void EmitValue(AsmPrinter *AP, unsigned Form) const = 0;
/// SizeOf - Return the size of a value in bytes.
///
- virtual unsigned SizeOf(const TargetData *TD, unsigned Form) const = 0;
+ virtual unsigned SizeOf(AsmPrinter *AP, unsigned Form) const = 0;
// Implement isa/cast/dyncast.
static bool classof(const DIEValue *) { return true; }
@@ -261,11 +259,11 @@ namespace llvm {
/// EmitValue - Emit integer of appropriate size.
///
- virtual void EmitValue(DwarfPrinter *D, unsigned Form) const;
+ virtual void EmitValue(AsmPrinter *AP, unsigned Form) const;
/// SizeOf - Determine size of integer value in bytes.
///
- virtual unsigned SizeOf(const TargetData *TD, unsigned Form) const;
+ virtual unsigned SizeOf(AsmPrinter *AP, unsigned Form) const;
// Implement isa/cast/dyncast.
@@ -287,11 +285,11 @@ namespace llvm {
/// EmitValue - Emit string value.
///
- virtual void EmitValue(DwarfPrinter *D, unsigned Form) const;
+ virtual void EmitValue(AsmPrinter *AP, unsigned Form) const;
/// SizeOf - Determine size of string value in bytes.
///
- virtual unsigned SizeOf(const TargetData *, unsigned /*Form*/) const {
+ virtual unsigned SizeOf(AsmPrinter *AP, unsigned /*Form*/) const {
return Str.size() + sizeof(char); // sizeof('\0');
}
@@ -314,11 +312,11 @@ namespace llvm {
/// EmitValue - Emit label value.
///
- virtual void EmitValue(DwarfPrinter *D, unsigned Form) const;
+ virtual void EmitValue(AsmPrinter *AP, unsigned Form) const;
/// SizeOf - Determine size of label value in bytes.
///
- virtual unsigned SizeOf(const TargetData *TD, unsigned Form) const;
+ virtual unsigned SizeOf(AsmPrinter *AP, unsigned Form) const;
// Implement isa/cast/dyncast.
static bool classof(const DIELabel *) { return true; }
@@ -341,11 +339,11 @@ namespace llvm {
/// EmitValue - Emit delta value.
///
- virtual void EmitValue(DwarfPrinter *D, unsigned Form) const;
+ virtual void EmitValue(AsmPrinter *AP, unsigned Form) const;
/// SizeOf - Determine size of delta value in bytes.
///
- virtual unsigned SizeOf(const TargetData *TD, unsigned Form) const;
+ virtual unsigned SizeOf(AsmPrinter *AP, unsigned Form) const;
// Implement isa/cast/dyncast.
static bool classof(const DIEDelta *) { return true; }
@@ -369,11 +367,11 @@ namespace llvm {
/// EmitValue - Emit debug information entry offset.
///
- virtual void EmitValue(DwarfPrinter *D, unsigned Form) const;
+ virtual void EmitValue(AsmPrinter *AP, unsigned Form) const;
/// SizeOf - Determine size of debug information entry in bytes.
///
- virtual unsigned SizeOf(const TargetData *TD, unsigned Form) const {
+ virtual unsigned SizeOf(AsmPrinter *AP, unsigned Form) const {
return sizeof(int32_t);
}
@@ -398,7 +396,7 @@ namespace llvm {
/// ComputeSize - calculate the size of the block.
///
- unsigned ComputeSize(const TargetData *TD);
+ unsigned ComputeSize(AsmPrinter *AP);
/// BestForm - Choose the best form for data.
///
@@ -411,11 +409,11 @@ namespace llvm {
/// EmitValue - Emit block data.
///
- virtual void EmitValue(DwarfPrinter *D, unsigned Form) const;
+ virtual void EmitValue(AsmPrinter *AP, unsigned Form) const;
/// SizeOf - Determine size of block data in bytes.
///
- virtual unsigned SizeOf(const TargetData *TD, unsigned Form) const;
+ virtual unsigned SizeOf(AsmPrinter *AP, unsigned Form) const;
// Implement isa/cast/dyncast.
static bool classof(const DIEBlock *) { return true; }
diff --git a/lib/CodeGen/AsmPrinter/DwarfDebug.cpp b/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
index 9084456c8f4d..b472d1e5335c 100644
--- a/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
+++ b/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
@@ -13,6 +13,8 @@
#define DEBUG_TYPE "dwarfdebug"
#include "DwarfDebug.h"
+#include "DIE.h"
+#include "llvm/Constants.h"
#include "llvm/Module.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineModuleInfo.h"
@@ -24,7 +26,9 @@
#include "llvm/Target/TargetData.h"
#include "llvm/Target/TargetFrameInfo.h"
#include "llvm/Target/TargetLoweringObjectFile.h"
+#include "llvm/Target/TargetMachine.h"
#include "llvm/Target/TargetRegisterInfo.h"
+#include "llvm/Analysis/DebugInfo.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/Support/Debug.h"
@@ -269,6 +273,8 @@ public:
void dump() const;
#endif
};
+
+} // end llvm namespace
#ifndef NDEBUG
void DbgScope::dump() const {
@@ -296,16 +302,19 @@ DbgScope::~DbgScope() {
delete Variables[j];
}
-} // end llvm namespace
-
-DwarfDebug::DwarfDebug(raw_ostream &OS, AsmPrinter *A, const MCAsmInfo *T)
- : DwarfPrinter(OS, A, T), ModuleCU(0),
- AbbreviationsSet(InitAbbreviationsSetSize), Abbreviations(),
- DIEBlocks(), SectionSourceLines(), didInitial(false), shouldEmit(false),
+DwarfDebug::DwarfDebug(AsmPrinter *A, Module *M)
+ : Asm(A), MMI(Asm->MMI), ModuleCU(0),
+ AbbreviationsSet(InitAbbreviationsSetSize),
CurrentFnDbgScope(0), DebugTimer(0) {
NextStringPoolNumber = 0;
+
+ DwarfFrameSectionSym = DwarfInfoSectionSym = DwarfAbbrevSectionSym = 0;
+ DwarfStrSectionSym = TextSectionSym = 0;
+
if (TimePassesIsEnabled)
DebugTimer = new Timer("Dwarf Debug Writer");
+
+ beginModule(M);
}
DwarfDebug::~DwarfDebug() {
for (unsigned j = 0, M = DIEBlocks.size(); j < M; ++j)
@@ -319,7 +328,7 @@ MCSymbol *DwarfDebug::getStringPoolEntry(StringRef Str) {
if (Entry.first) return Entry.first;
Entry.second = NextStringPoolNumber++;
- return Entry.first = getDWLabel("string", Entry.second);
+ return Entry.first = Asm->GetTempSymbol("string", Entry.second);
}
@@ -395,11 +404,19 @@ void DwarfDebug::addDelta(DIE *Die, unsigned Attribute, unsigned Form,
Die->addValue(Attribute, Form, Value);
}
+/// addDIEEntry - Add a DIE attribute data and value.
+///
+void DwarfDebug::addDIEEntry(DIE *Die, unsigned Attribute, unsigned Form,
+ DIE *Entry) {
+ Die->addValue(Attribute, Form, createDIEEntry(Entry));
+}
+
+
/// addBlock - Add block data.
///
void DwarfDebug::addBlock(DIE *Die, unsigned Attribute, unsigned Form,
DIEBlock *Block) {
- Block->ComputeSize(TD);
+ Block->ComputeSize(Asm);
DIEBlocks.push_back(Block); // Memoize so we can call the destructor later on.
Die->addValue(Attribute, Block->BestForm(), Block);
}
@@ -553,6 +570,7 @@ void DwarfDebug::addComplexAddress(DbgVariable *&DV, DIE *Die,
// Decode the original location, and use that as the start of the byref
// variable's location.
+ const TargetRegisterInfo *RI = Asm->TM.getRegisterInfo();
unsigned Reg = RI->getDwarfRegNum(Location.getReg(), false);
DIEBlock *Block = new (DIEValueAllocator) DIEBlock();
@@ -693,6 +711,7 @@ void DwarfDebug::addBlockByrefAddress(DbgVariable *&DV, DIE *Die,
// Decode the original location, and use that as the start of the byref
// variable's location.
+ const TargetRegisterInfo *RI = Asm->TM.getRegisterInfo();
unsigned Reg = RI->getDwarfRegNum(Location.getReg(), false);
DIEBlock *Block = new (DIEValueAllocator) DIEBlock();
@@ -748,6 +767,7 @@ void DwarfDebug::addBlockByrefAddress(DbgVariable *&DV, DIE *Die,
/// provided.
void DwarfDebug::addAddress(DIE *Die, unsigned Attribute,
const MachineLocation &Location) {
+ const TargetRegisterInfo *RI = Asm->TM.getRegisterInfo();
unsigned Reg = RI->getDwarfRegNum(Location.getReg(), false);
DIEBlock *Block = new (DIEValueAllocator) DIEBlock();
@@ -1114,7 +1134,8 @@ DIE *DwarfDebug::createMemberDIE(const DIDerivedType &DT) {
Offset -= FieldOffset;
// Maybe we need to work from the other end.
- if (TD->isLittleEndian()) Offset = FieldSize - (Offset + Size);
+ if (Asm->getTargetData().isLittleEndian())
+ Offset = FieldSize - (Offset + Size);
addUInt(MemberDie, dwarf::DW_AT_bit_offset, 0, Offset);
// Here WD_AT_data_member_location points to the anonymous
@@ -1272,7 +1293,7 @@ DbgScope *DwarfDebug::getUpdatedDbgScope(MDNode *N, const MachineInstr *MI,
if (!Parent && !InlinedAt) {
StringRef SPName = DISubprogram(N).getLinkageName();
- if (SPName == MF->getFunction()->getName())
+ if (SPName == Asm->MF->getFunction()->getName())
CurrentFnDbgScope = NScope;
}
@@ -1316,50 +1337,51 @@ DbgScope *DwarfDebug::getOrCreateAbstractScope(MDNode *N) {
/// If there are global variables in this scope then create and insert
/// DIEs for these variables.
DIE *DwarfDebug::updateSubprogramScopeDIE(MDNode *SPNode) {
- DIE *SPDie = ModuleCU->getDIE(SPNode);
- assert(SPDie && "Unable to find subprogram DIE!");
- DISubprogram SP(SPNode);
+ DIE *SPDie = ModuleCU->getDIE(SPNode);
+ assert(SPDie && "Unable to find subprogram DIE!");
+ DISubprogram SP(SPNode);
+
+ // There is not any need to generate specification DIE for a function
+ // defined at compile unit level. If a function is defined inside another
+ // function then gdb prefers the definition at top level and but does not
+ // expect specification DIE in parent function. So avoid creating
+ // specification DIE for a function defined inside a function.
+ if (SP.isDefinition() && !SP.getContext().isCompileUnit() &&
+ !SP.getContext().isFile() && !SP.getContext().isSubprogram()) {
+ addUInt(SPDie, dwarf::DW_AT_declaration, dwarf::DW_FORM_flag, 1);
+
+ // Add arguments.
+ DICompositeType SPTy = SP.getType();
+ DIArray Args = SPTy.getTypeArray();
+ unsigned SPTag = SPTy.getTag();
+ if (SPTag == dwarf::DW_TAG_subroutine_type)
+ for (unsigned i = 1, N = Args.getNumElements(); i < N; ++i) {
+ DIE *Arg = new DIE(dwarf::DW_TAG_formal_parameter);
+ DIType ATy = DIType(DIType(Args.getElement(i).getNode()));
+ addType(Arg, ATy);
+ if (ATy.isArtificial())
+ addUInt(Arg, dwarf::DW_AT_artificial, dwarf::DW_FORM_flag, 1);
+ SPDie->addChild(Arg);
+ }
+ DIE *SPDeclDie = SPDie;
+ SPDie = new DIE(dwarf::DW_TAG_subprogram);
+ addDIEEntry(SPDie, dwarf::DW_AT_specification, dwarf::DW_FORM_ref4,
+ SPDeclDie);
+ ModuleCU->addDie(SPDie);
+ }
+
+ addLabel(SPDie, dwarf::DW_AT_low_pc, dwarf::DW_FORM_addr,
+ Asm->GetTempSymbol("func_begin", Asm->getFunctionNumber()));
+ addLabel(SPDie, dwarf::DW_AT_high_pc, dwarf::DW_FORM_addr,
+ Asm->GetTempSymbol("func_end", Asm->getFunctionNumber()));
+ const TargetRegisterInfo *RI = Asm->TM.getRegisterInfo();
+ MachineLocation Location(RI->getFrameRegister(*Asm->MF));
+ addAddress(SPDie, dwarf::DW_AT_frame_base, Location);
+
+ if (!DISubprogram(SPNode).isLocalToUnit())
+ addUInt(SPDie, dwarf::DW_AT_external, dwarf::DW_FORM_flag, 1);
- // There is not any need to generate specification DIE for a function
- // defined at compile unit level. If a function is defined inside another
- // function then gdb prefers the definition at top level and but does not
- // expect specification DIE in parent function. So avoid creating
- // specification DIE for a function defined inside a function.
- if (SP.isDefinition() && !SP.getContext().isCompileUnit() &&
- !SP.getContext().isFile() && !SP.getContext().isSubprogram()) {
- addUInt(SPDie, dwarf::DW_AT_declaration, dwarf::DW_FORM_flag, 1);
-
- // Add arguments.
- DICompositeType SPTy = SP.getType();
- DIArray Args = SPTy.getTypeArray();
- unsigned SPTag = SPTy.getTag();
- if (SPTag == dwarf::DW_TAG_subroutine_type)
- for (unsigned i = 1, N = Args.getNumElements(); i < N; ++i) {
- DIE *Arg = new DIE(dwarf::DW_TAG_formal_parameter);
- DIType ATy = DIType(DIType(Args.getElement(i).getNode()));
- addType(Arg, ATy);
- if (ATy.isArtificial())
- addUInt(Arg, dwarf::DW_AT_artificial, dwarf::DW_FORM_flag, 1);
- SPDie->addChild(Arg);
- }
- DIE *SPDeclDie = SPDie;
- SPDie = new DIE(dwarf::DW_TAG_subprogram);
- addDIEEntry(SPDie, dwarf::DW_AT_specification, dwarf::DW_FORM_ref4,
- SPDeclDie);
- ModuleCU->addDie(SPDie);
- }
-
- addLabel(SPDie, dwarf::DW_AT_low_pc, dwarf::DW_FORM_addr,
- getDWLabel("func_begin", SubprogramCount));
- addLabel(SPDie, dwarf::DW_AT_high_pc, dwarf::DW_FORM_addr,
- getDWLabel("func_end", SubprogramCount));
- MachineLocation Location(RI->getFrameRegister(*MF));
- addAddress(SPDie, dwarf::DW_AT_frame_base, Location);
-
- if (!DISubprogram(SPNode).isLocalToUnit())
- addUInt(SPDie, dwarf::DW_AT_external, dwarf::DW_FORM_flag, 1);
-
- return SPDie;
+ return SPDie;
}
/// constructLexicalScope - Construct new DW_TAG_lexical_block
@@ -1377,9 +1399,10 @@ DIE *DwarfDebug::constructLexicalScopeDIE(DbgScope *Scope) {
return ScopeDIE;
addLabel(ScopeDIE, dwarf::DW_AT_low_pc, dwarf::DW_FORM_addr,
- Start ? Start : getDWLabel("func_begin", SubprogramCount));
+ Start ? Start : Asm->GetTempSymbol("func_begin",
+ Asm->getFunctionNumber()));
addLabel(ScopeDIE, dwarf::DW_AT_high_pc, dwarf::DW_FORM_addr,
- End ? End : getDWLabel("func_end", SubprogramCount));
+ End ? End : Asm->GetTempSymbol("func_end",Asm->getFunctionNumber()));
return ScopeDIE;
}
@@ -1510,6 +1533,31 @@ DIE *DwarfDebug::constructVariableDIE(DbgVariable *DV, DbgScope *Scope) {
if (MCSymbol *VS = DV->getDbgValueLabel())
addLabel(VariableDie, dwarf::DW_AT_start_scope, dwarf::DW_FORM_addr,
VS);
+ } else if (DbgValueInsn->getOperand(0).getType() ==
+ MachineOperand::MO_FPImmediate) {
+ DIEBlock *Block = new (DIEValueAllocator) DIEBlock();
+ APFloat FPImm = DbgValueInsn->getOperand(0).getFPImm()->getValueAPF();
+
+ // Get the raw data form of the floating point.
+ const APInt FltVal = FPImm.bitcastToAPInt();
+ const char *FltPtr = (const char*)FltVal.getRawData();
+
+ unsigned NumBytes = FltVal.getBitWidth() / 8; // 8 bits per byte.
+ bool LittleEndian = Asm->getTargetData().isLittleEndian();
+ int Incr = (LittleEndian ? 1 : -1);
+ int Start = (LittleEndian ? 0 : NumBytes - 1);
+ int Stop = (LittleEndian ? NumBytes : -1);
+
+ // Output the constant to DWARF one byte at a time.
+ for (; Start != Stop; Start += Incr)
+ addUInt(Block, 0, dwarf::DW_FORM_data1,
+ (unsigned char)0xFF & FltPtr[Start]);
+
+ addBlock(VariableDie, dwarf::DW_AT_const_value, 0, Block);
+
+ if (MCSymbol *VS = DV->getDbgValueLabel())
+ addLabel(VariableDie, dwarf::DW_AT_start_scope, dwarf::DW_FORM_addr,
+ VS);
} else {
//FIXME : Handle other operand types.
delete VariableDie;
@@ -1519,7 +1567,8 @@ DIE *DwarfDebug::constructVariableDIE(DbgVariable *DV, DbgScope *Scope) {
} else {
MachineLocation Location;
unsigned FrameReg;
- int Offset = RI->getFrameIndexReference(*MF, DV->getFrameIndex(),
+ const TargetRegisterInfo *RI = Asm->TM.getRegisterInfo();
+ int Offset = RI->getFrameIndexReference(*Asm->MF, DV->getFrameIndex(),
FrameReg);
Location.set(FrameReg, Offset);
@@ -1667,10 +1716,9 @@ void DwarfDebug::constructCompileUnit(MDNode *N) {
addUInt(Die, dwarf::DW_AT_language, dwarf::DW_FORM_data1,
DIUnit.getLanguage());
addString(Die, dwarf::DW_AT_name, dwarf::DW_FORM_string, FN);
- addLabel(Die, dwarf::DW_AT_low_pc, dwarf::DW_FORM_addr,
- getTempLabel("text_begin"));
+ addLabel(Die, dwarf::DW_AT_low_pc, dwarf::DW_FORM_addr, TextSectionSym);
addLabel(Die, dwarf::DW_AT_high_pc, dwarf::DW_FORM_addr,
- getTempLabel("text_end"));
+ Asm->GetTempSymbol("text_end"));
// DW_AT_stmt_list is a offset of line number information for this
// compile unit in debug_line section. It is always zero when only one
// compile unit is emitted in one object file.
@@ -1780,25 +1828,37 @@ void DwarfDebug::constructSubprogramDIE(MDNode *N) {
/// beginModule - Emit all Dwarf sections that should come prior to the
/// content. Create global DIEs and emit initial debug info sections.
/// This is inovked by the target AsmPrinter.
-void DwarfDebug::beginModule(Module *M, MachineModuleInfo *mmi) {
- this->M = M;
-
- if (!MAI->doesSupportDebugInformation())
- return;
-
+void DwarfDebug::beginModule(Module *M) {
TimeRegion Timer(DebugTimer);
-
+
DebugInfoFinder DbgFinder;
DbgFinder.processModule(*M);
+ bool HasDebugInfo = false;
+
+ // Scan all the compile-units to see if there are any marked as the main unit.
+ // if not, we do not generate debug info.
+ for (DebugInfoFinder::iterator I = DbgFinder.compile_unit_begin(),
+ E = DbgFinder.compile_unit_end(); I != E; ++I) {
+ if (DICompileUnit(*I).isMain()) {
+ HasDebugInfo = true;
+ break;
+ }
+ }
+
+ if (!HasDebugInfo) return;
+
+ // Tell MMI that we have debug info.
+ MMI->setDebugInfoAvailability(true);
+
+ // Emit initial sections.
+ EmitSectionLabels();
+
// Create all the compile unit DIEs.
for (DebugInfoFinder::iterator I = DbgFinder.compile_unit_begin(),
E = DbgFinder.compile_unit_end(); I != E; ++I)
constructCompileUnit(*I);
- if (!ModuleCU)
- return;
-
// Create DIEs for each subprogram.
for (DebugInfoFinder::iterator I = DbgFinder.subprogram_begin(),
E = DbgFinder.subprogram_end(); I != E; ++I)
@@ -1809,16 +1869,12 @@ void DwarfDebug::beginModule(Module *M, MachineModuleInfo *mmi) {
E = DbgFinder.global_variable_end(); I != E; ++I)
constructGlobalVariableDIE(*I);
- MMI = mmi;
- shouldEmit = true;
- MMI->setDebugInfoAvailability(true);
-
// Prime section data.
SectionMap.insert(Asm->getObjFileLowering().getTextSection());
// Print out .file directives to specify files for .loc directives. These are
// printed out early so that they precede any .loc directives.
- if (MAI->hasDotLocAndDotFile()) {
+ if (Asm->MAI->hasDotLocAndDotFile()) {
for (unsigned i = 1, e = getNumSourceIds()+1; i != e; ++i) {
// Remember source id starts at 1.
std::pair<unsigned, unsigned> Id = getSourceDirectoryAndFileIds(i);
@@ -1832,9 +1888,6 @@ void DwarfDebug::beginModule(Module *M, MachineModuleInfo *mmi) {
Asm->OutStreamer.EmitDwarfFileDirective(i, FullPath.str());
}
}
-
- // Emit initial sections
- emitInitial();
}
/// endModule - Emit all Dwarf sections that should come after the content.
@@ -1871,14 +1924,14 @@ void DwarfDebug::endModule() {
// Standard sections final addresses.
Asm->OutStreamer.SwitchSection(Asm->getObjFileLowering().getTextSection());
- Asm->OutStreamer.EmitLabel(getTempLabel("text_end"));
+ Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("text_end"));
Asm->OutStreamer.SwitchSection(Asm->getObjFileLowering().getDataSection());
- Asm->OutStreamer.EmitLabel(getTempLabel("data_end"));
+ Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("data_end"));
// End text sections.
for (unsigned i = 1, N = SectionMap.size(); i <= N; ++i) {
Asm->OutStreamer.SwitchSection(SectionMap[i]);
- Asm->OutStreamer.EmitLabel(getDWLabel("section_end", i));
+ Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("section_end", i));
}
// Emit common frame information.
@@ -1975,9 +2028,7 @@ DbgVariable *DwarfDebug::findAbstractVariable(DIVariable &Var,
/// collectVariableInfo - Populate DbgScope entries with variables' info.
void DwarfDebug::collectVariableInfo() {
- if (!MMI) return;
-
- const LLVMContext &Ctx = MF->getFunction()->getContext();
+ const LLVMContext &Ctx = Asm->MF->getFunction()->getContext();
MachineModuleInfo::VariableDbgInfoMapTy &VMap = MMI->getVariableDbgInfo();
for (MachineModuleInfo::VariableDbgInfoMapTy::iterator VI = VMap.begin(),
@@ -2003,7 +2054,7 @@ void DwarfDebug::collectVariableInfo() {
}
// Collect variable information from DBG_VALUE machine instructions;
- for (MachineFunction::const_iterator I = MF->begin(), E = MF->end();
+ for (MachineFunction::const_iterator I = Asm->MF->begin(), E = Asm->MF->end();
I != E; ++I) {
for (MachineBasicBlock::const_iterator II = I->begin(), IE = I->end();
II != IE; ++II) {
@@ -2055,7 +2106,7 @@ void DwarfDebug::beginScope(const MachineInstr *MI) {
if (DL == PrevInstLoc)
return;
- MDNode *Scope = DL.getScope(MF->getFunction()->getContext());
+ MDNode *Scope = DL.getScope(Asm->MF->getFunction()->getContext());
// FIXME: Should only verify each scope once!
if (!DIScope(Scope).Verify())
@@ -2148,10 +2199,10 @@ bool DwarfDebug::extractScopeInformation() {
DenseMap<const MachineInstr *, unsigned> MIIndexMap;
unsigned MIIndex = 0;
- LLVMContext &Ctx = MF->getFunction()->getContext();
+ LLVMContext &Ctx = Asm->MF->getFunction()->getContext();
// Scan each instruction and create scopes. First build working set of scopes.
- for (MachineFunction::const_iterator I = MF->begin(), E = MF->end();
+ for (MachineFunction::const_iterator I = Asm->MF->begin(), E = Asm->MF->end();
I != E; ++I) {
for (MachineBasicBlock::const_iterator II = I->begin(), IE = I->end();
II != IE; ++II) {
@@ -2175,7 +2226,7 @@ bool DwarfDebug::extractScopeInformation() {
// Build scope hierarchy using working set of scopes.
- for (MachineFunction::const_iterator I = MF->begin(), E = MF->end();
+ for (MachineFunction::const_iterator I = Asm->MF->begin(), E = Asm->MF->end();
I != E; ++I) {
for (MachineBasicBlock::const_iterator II = I->begin(), IE = I->end();
II != IE; ++II) {
@@ -2243,18 +2294,17 @@ bool DwarfDebug::extractScopeInformation() {
/// beginFunction - Gather pre-function debug information. Assumes being
/// emitted immediately after the function entry point.
void DwarfDebug::beginFunction(const MachineFunction *MF) {
- this->MF = MF;
-
- if (!ShouldEmitDwarfDebug()) return;
+ if (!MMI->hasDebugInfo()) return;
+
+ TimeRegion Timer(DebugTimer);
if (!extractScopeInformation())
return;
- TimeRegion Timer(DebugTimer);
-
collectVariableInfo();
// Assumes in correct section after the entry point.
- Asm->OutStreamer.EmitLabel(getDWLabel("func_begin", ++SubprogramCount));
+ Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("func_begin",
+ Asm->getFunctionNumber()));
// Emit label for the implicitly defined dbg.stoppoint at the start of the
// function.
@@ -2279,14 +2329,15 @@ void DwarfDebug::beginFunction(const MachineFunction *MF) {
/// endFunction - Gather and emit post-function debug information.
///
void DwarfDebug::endFunction(const MachineFunction *MF) {
- if (!ShouldEmitDwarfDebug()) return;
- if (DbgScopeMap.empty()) return;
+ if (!MMI->hasDebugInfo() ||
+ DbgScopeMap.empty()) return;
TimeRegion Timer(DebugTimer);
if (CurrentFnDbgScope) {
// Define end label for subprogram.
- Asm->OutStreamer.EmitLabel(getDWLabel("func_end", SubprogramCount));
+ Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("func_end",
+ Asm->getFunctionNumber()));
// Get function line info.
if (!Lines.empty()) {
@@ -2306,7 +2357,7 @@ void DwarfDebug::endFunction(const MachineFunction *MF) {
constructScopeDIE(CurrentFnDbgScope);
- DebugFrames.push_back(FunctionDebugFrameInfo(SubprogramCount,
+ DebugFrames.push_back(FunctionDebugFrameInfo(Asm->getFunctionNumber(),
MMI->getFrameMoves()));
}
@@ -2327,9 +2378,6 @@ void DwarfDebug::endFunction(const MachineFunction *MF) {
/// unique label that was emitted and which provides correspondence to
/// the source line list.
MCSymbol *DwarfDebug::recordSourceLine(unsigned Line, unsigned Col, MDNode *S) {
- if (!MMI)
- return 0;
-
TimeRegion Timer(DebugTimer);
StringRef Dir;
@@ -2404,7 +2452,7 @@ DwarfDebug::computeSizeAndOffset(DIE *Die, unsigned Offset, bool Last) {
// Size the DIE attribute values.
for (unsigned i = 0, N = Values.size(); i < N; ++i)
// Size attribute value.
- Offset += Values[i]->SizeOf(TD, AbbrevData[i].getForm());
+ Offset += Values[i]->SizeOf(Asm, AbbrevData[i].getForm());
// Size the DIE children if any.
if (!Children.empty()) {
@@ -2436,50 +2484,48 @@ void DwarfDebug::computeSizeAndOffsets() {
CompileUnitOffsets[ModuleCU] = 0;
}
-/// emitInitial - Emit initial Dwarf declarations. This is necessary for cc
-/// tools to recognize the object file contains Dwarf information.
-void DwarfDebug::emitInitial() {
- // Check to see if we already emitted intial headers.
- if (didInitial) return;
- didInitial = true;
+/// EmitSectionSym - Switch to the specified MCSection and emit an assembler
+/// temporary label to it if SymbolStem is specified.
+static MCSymbol *EmitSectionSym(AsmPrinter *Asm, const MCSection *Section,
+ const char *SymbolStem = 0) {
+ Asm->OutStreamer.SwitchSection(Section);
+ if (!SymbolStem) return 0;
+
+ MCSymbol *TmpSym = Asm->GetTempSymbol(SymbolStem);
+ Asm->OutStreamer.EmitLabel(TmpSym);
+ return TmpSym;
+}
+/// EmitSectionLabels - Emit initial Dwarf sections with a label at
+/// the start of each one.
+void DwarfDebug::EmitSectionLabels() {
const TargetLoweringObjectFile &TLOF = Asm->getObjFileLowering();
// Dwarf sections base addresses.
- if (MAI->doesDwarfRequireFrameSection()) {
- Asm->OutStreamer.SwitchSection(TLOF.getDwarfFrameSection());
- Asm->OutStreamer.EmitLabel(getTempLabel("section_debug_frame"));
- }
-
- Asm->OutStreamer.SwitchSection(TLOF.getDwarfInfoSection());
- Asm->OutStreamer.EmitLabel(getTempLabel("section_info"));
- Asm->OutStreamer.SwitchSection(TLOF.getDwarfAbbrevSection());
- Asm->OutStreamer.EmitLabel(getTempLabel("section_abbrev"));
- Asm->OutStreamer.SwitchSection(TLOF.getDwarfARangesSection());
- Asm->OutStreamer.EmitLabel(getTempLabel("section_aranges"));
-
- if (const MCSection *LineInfoDirective = TLOF.getDwarfMacroInfoSection()) {
- Asm->OutStreamer.SwitchSection(LineInfoDirective);
- Asm->OutStreamer.EmitLabel(getTempLabel("section_macinfo"));
- }
-
- Asm->OutStreamer.SwitchSection(TLOF.getDwarfLineSection());
- Asm->OutStreamer.EmitLabel(getTempLabel("section_line"));
- Asm->OutStreamer.SwitchSection(TLOF.getDwarfLocSection());
- Asm->OutStreamer.EmitLabel(getTempLabel("section_loc"));
- Asm->OutStreamer.SwitchSection(TLOF.getDwarfPubNamesSection());
- Asm->OutStreamer.EmitLabel(getTempLabel("section_pubnames"));
- Asm->OutStreamer.SwitchSection(TLOF.getDwarfPubTypesSection());
- Asm->OutStreamer.EmitLabel(getTempLabel("section_pubtypes"));
- Asm->OutStreamer.SwitchSection(TLOF.getDwarfStrSection());
- Asm->OutStreamer.EmitLabel(getTempLabel("section_str"));
- Asm->OutStreamer.SwitchSection(TLOF.getDwarfRangesSection());
- Asm->OutStreamer.EmitLabel(getTempLabel("section_ranges"));
-
- Asm->OutStreamer.SwitchSection(TLOF.getTextSection());
- Asm->OutStreamer.EmitLabel(getTempLabel("text_begin"));
- Asm->OutStreamer.SwitchSection(TLOF.getDataSection());
- Asm->OutStreamer.EmitLabel(getTempLabel("data_begin"));
+ if (Asm->MAI->doesDwarfRequireFrameSection()) {
+ DwarfFrameSectionSym =
+ EmitSectionSym(Asm, TLOF.getDwarfFrameSection(), "section_debug_frame");
+ }
+
+ DwarfInfoSectionSym =
+ EmitSectionSym(Asm, TLOF.getDwarfInfoSection(), "section_info");
+ DwarfAbbrevSectionSym =
+ EmitSectionSym(Asm, TLOF.getDwarfAbbrevSection(), "section_abbrev");
+ EmitSectionSym(Asm, TLOF.getDwarfARangesSection());
+
+ if (const MCSection *MacroInfo = TLOF.getDwarfMacroInfoSection())
+ EmitSectionSym(Asm, MacroInfo);
+
+ EmitSectionSym(Asm, TLOF.getDwarfLineSection());
+ EmitSectionSym(Asm, TLOF.getDwarfLocSection());
+ EmitSectionSym(Asm, TLOF.getDwarfPubNamesSection());
+ EmitSectionSym(Asm, TLOF.getDwarfPubTypesSection());
+ DwarfStrSectionSym =
+ EmitSectionSym(Asm, TLOF.getDwarfStrSection(), "section_str");
+ EmitSectionSym(Asm, TLOF.getDwarfRangesSection());
+
+ TextSectionSym = EmitSectionSym(Asm, TLOF.getTextSection(), "text_begin");
+ EmitSectionSym(Asm, TLOF.getDataSection());
}
/// emitDIE - Recusively Emits a debug information entry.
@@ -2490,12 +2536,12 @@ void DwarfDebug::emitDIE(DIE *Die) {
const DIEAbbrev *Abbrev = Abbreviations[AbbrevNumber - 1];
// Emit the code (index) for the abbreviation.
- if (Asm->VerboseAsm)
+ if (Asm->isVerbose())
Asm->OutStreamer.AddComment("Abbrev [" + Twine(AbbrevNumber) + "] 0x" +
Twine::utohexstr(Die->getOffset()) + ":0x" +
Twine::utohexstr(Die->getSize()) + " " +
dwarf::TagString(Abbrev->getTag()));
- EmitULEB128(AbbrevNumber);
+ Asm->EmitULEB128(AbbrevNumber);
const SmallVector<DIEValue*, 32> &Values = Die->getValues();
const SmallVector<DIEAbbrevData, 8> &AbbrevData = Abbrev->getData();
@@ -2506,7 +2552,7 @@ void DwarfDebug::emitDIE(DIE *Die) {
unsigned Form = AbbrevData[i].getForm();
assert(Form && "Too many attributes for DIE (check abbreviation)");
- if (Asm->VerboseAsm)
+ if (Asm->isVerbose())
Asm->OutStreamer.AddComment(dwarf::AttributeString(Attr));
switch (Attr) {
@@ -2522,7 +2568,7 @@ void DwarfDebug::emitDIE(DIE *Die) {
}
default:
// Emit an attribute using the defined form.
- Values[i]->EmitValue(this, Form);
+ Values[i]->EmitValue(Asm, Form);
break;
}
}
@@ -2534,7 +2580,7 @@ void DwarfDebug::emitDIE(DIE *Die) {
for (unsigned j = 0, M = Children.size(); j < M; ++j)
emitDIE(Children[j]);
- if (Asm->VerboseAsm)
+ if (Asm->isVerbose())
Asm->OutStreamer.AddComment("End Of Children Mark");
Asm->EmitInt8(0);
}
@@ -2549,7 +2595,8 @@ void DwarfDebug::emitDebugInfo() {
DIE *Die = ModuleCU->getCUDie();
// Emit the compile units header.
- Asm->OutStreamer.EmitLabel(getDWLabel("info_begin", ModuleCU->getID()));
+ Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("info_begin",
+ ModuleCU->getID()));
// Emit size of content not including length itself
unsigned ContentSize = Die->getSize() +
@@ -2563,10 +2610,10 @@ void DwarfDebug::emitDebugInfo() {
Asm->OutStreamer.AddComment("DWARF version number");
Asm->EmitInt16(dwarf::DWARF_VERSION);
Asm->OutStreamer.AddComment("Offset Into Abbrev. Section");
- EmitSectionOffset(getTempLabel("abbrev_begin"),getTempLabel("section_abbrev"),
- true);
+ Asm->EmitSectionOffset(Asm->GetTempSymbol("abbrev_begin"),
+ DwarfAbbrevSectionSym);
Asm->OutStreamer.AddComment("Address Size (in bytes)");
- Asm->EmitInt8(TD->getPointerSize());
+ Asm->EmitInt8(Asm->getTargetData().getPointerSize());
emitDIE(Die);
// FIXME - extra padding for gdb bug.
@@ -2575,7 +2622,7 @@ void DwarfDebug::emitDebugInfo() {
Asm->EmitInt8(0);
Asm->EmitInt8(0);
Asm->EmitInt8(0);
- Asm->OutStreamer.EmitLabel(getDWLabel("info_end", ModuleCU->getID()));
+ Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("info_end", ModuleCU->getID()));
}
/// emitAbbreviations - Emit the abbreviation section.
@@ -2587,7 +2634,7 @@ void DwarfDebug::emitAbbreviations() const {
Asm->OutStreamer.SwitchSection(
Asm->getObjFileLowering().getDwarfAbbrevSection());
- Asm->OutStreamer.EmitLabel(getTempLabel("abbrev_begin"));
+ Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("abbrev_begin"));
// For each abbrevation.
for (unsigned i = 0, N = Abbreviations.size(); i < N; ++i) {
@@ -2595,16 +2642,16 @@ void DwarfDebug::emitAbbreviations() const {
const DIEAbbrev *Abbrev = Abbreviations[i];
// Emit the abbrevations code (base 1 index.)
- EmitULEB128(Abbrev->getNumber(), "Abbreviation Code");
+ Asm->EmitULEB128(Abbrev->getNumber(), "Abbreviation Code");
// Emit the abbreviations data.
- Abbrev->Emit(this);
+ Abbrev->Emit(Asm);
}
// Mark end of abbreviations.
- EmitULEB128(0, "EOM(3)");
+ Asm->EmitULEB128(0, "EOM(3)");
- Asm->OutStreamer.EmitLabel(getTempLabel("abbrev_end"));
+ Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("abbrev_end"));
}
}
@@ -2617,14 +2664,15 @@ void DwarfDebug::emitEndOfLineMatrix(unsigned SectionEnd) {
Asm->EmitInt8(0);
Asm->OutStreamer.AddComment("Op size");
- Asm->EmitInt8(TD->getPointerSize() + 1);
+ Asm->EmitInt8(Asm->getTargetData().getPointerSize() + 1);
Asm->OutStreamer.AddComment("DW_LNE_set_address");
Asm->EmitInt8(dwarf::DW_LNE_set_address);
Asm->OutStreamer.AddComment("Section end label");
- Asm->OutStreamer.EmitSymbolValue(getDWLabel("section_end", SectionEnd),
- TD->getPointerSize(), 0/*AddrSpace*/);
+ Asm->OutStreamer.EmitSymbolValue(Asm->GetTempSymbol("section_end",SectionEnd),
+ Asm->getTargetData().getPointerSize(),
+ 0/*AddrSpace*/);
// Mark end of matrix.
Asm->OutStreamer.AddComment("DW_LNE_end_sequence");
@@ -2638,7 +2686,7 @@ void DwarfDebug::emitEndOfLineMatrix(unsigned SectionEnd) {
void DwarfDebug::emitDebugLines() {
// If the target is using .loc/.file, the assembler will be emitting the
// .debug_line table automatically.
- if (MAI->hasDotLocAndDotFile())
+ if (Asm->MAI->hasDotLocAndDotFile())
return;
// Minimum line delta, thus ranging from -10..(255-10).
@@ -2652,16 +2700,17 @@ void DwarfDebug::emitDebugLines() {
// Construct the section header.
Asm->OutStreamer.AddComment("Length of Source Line Info");
- EmitDifference(getTempLabel("line_end"), getTempLabel("line_begin"), true);
- Asm->OutStreamer.EmitLabel(getTempLabel("line_begin"));
+ Asm->EmitLabelDifference(Asm->GetTempSymbol("line_end"),
+ Asm->GetTempSymbol("line_begin"), 4);
+ Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("line_begin"));
Asm->OutStreamer.AddComment("DWARF version number");
Asm->EmitInt16(dwarf::DWARF_VERSION);
Asm->OutStreamer.AddComment("Prolog Length");
- EmitDifference(getTempLabel("line_prolog_end"),
- getTempLabel("line_prolog_begin"), true);
- Asm->OutStreamer.EmitLabel(getTempLabel("line_prolog_begin"));
+ Asm->EmitLabelDifference(Asm->GetTempSymbol("line_prolog_end"),
+ Asm->GetTempSymbol("line_prolog_begin"), 4);
+ Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("line_prolog_begin"));
Asm->OutStreamer.AddComment("Minimum Instruction Length");
Asm->EmitInt8(1);
@@ -2697,7 +2746,7 @@ void DwarfDebug::emitDebugLines() {
// Emit directories.
for (unsigned DI = 1, DE = getNumSourceDirectories()+1; DI != DE; ++DI) {
const std::string &Dir = getSourceDirectoryName(DI);
- if (Asm->VerboseAsm) Asm->OutStreamer.AddComment("Directory");
+ if (Asm->isVerbose()) Asm->OutStreamer.AddComment("Directory");
Asm->OutStreamer.EmitBytes(StringRef(Dir.c_str(), Dir.size()+1), 0);
}
@@ -2709,18 +2758,18 @@ void DwarfDebug::emitDebugLines() {
// Remember source id starts at 1.
std::pair<unsigned, unsigned> Id = getSourceDirectoryAndFileIds(SI);
const std::string &FN = getSourceFileName(Id.second);
- if (Asm->VerboseAsm) Asm->OutStreamer.AddComment("Source");
+ if (Asm->isVerbose()) 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->EmitULEB128(Id.first, "Directory #");
+ Asm->EmitULEB128(0, "Mod date");
+ Asm->EmitULEB128(0, "File size");
}
Asm->OutStreamer.AddComment("End of files");
Asm->EmitInt8(0);
- Asm->OutStreamer.EmitLabel(getTempLabel("line_prolog_end"));
+ Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("line_prolog_end"));
// A sequence for each text section.
unsigned SecSrcLinesSize = SectionSourceLines.size();
@@ -2754,13 +2803,14 @@ void DwarfDebug::emitDebugLines() {
Asm->OutStreamer.AddComment("Extended Op");
Asm->EmitInt8(0);
Asm->OutStreamer.AddComment("Op size");
- Asm->EmitInt8(TD->getPointerSize() + 1);
+ Asm->EmitInt8(Asm->getTargetData().getPointerSize() + 1);
Asm->OutStreamer.AddComment("DW_LNE_set_address");
Asm->EmitInt8(dwarf::DW_LNE_set_address);
Asm->OutStreamer.AddComment("Location label");
- Asm->OutStreamer.EmitSymbolValue(Label, TD->getPointerSize(),
+ Asm->OutStreamer.EmitSymbolValue(Label,
+ Asm->getTargetData().getPointerSize(),
0/*AddrSpace*/);
// If change of source, then switch to the new source.
@@ -2768,7 +2818,7 @@ void DwarfDebug::emitDebugLines() {
Source = LineInfo.getSourceID();
Asm->OutStreamer.AddComment("DW_LNS_set_file");
Asm->EmitInt8(dwarf::DW_LNS_set_file);
- EmitULEB128(Source, "New Source");
+ Asm->EmitULEB128(Source, "New Source");
}
// If change of line.
@@ -2789,7 +2839,7 @@ void DwarfDebug::emitDebugLines() {
// ... otherwise use long hand.
Asm->OutStreamer.AddComment("DW_LNS_advance_line");
Asm->EmitInt8(dwarf::DW_LNS_advance_line);
- EmitSLEB128(Offset, "Line Offset");
+ Asm->EmitSLEB128(Offset, "Line Offset");
Asm->OutStreamer.AddComment("DW_LNS_copy");
Asm->EmitInt8(dwarf::DW_LNS_copy);
}
@@ -2809,55 +2859,56 @@ void DwarfDebug::emitDebugLines() {
// put into it, emit an empty table.
emitEndOfLineMatrix(1);
- Asm->OutStreamer.EmitLabel(getTempLabel("line_end"));
+ Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("line_end"));
}
/// emitCommonDebugFrame - Emit common frame info into a debug frame section.
///
void DwarfDebug::emitCommonDebugFrame() {
- if (!MAI->doesDwarfRequireFrameSection())
+ if (!Asm->MAI->doesDwarfRequireFrameSection())
return;
- int stackGrowth =
- Asm->TM.getFrameInfo()->getStackGrowthDirection() ==
- TargetFrameInfo::StackGrowsUp ?
- TD->getPointerSize() : -TD->getPointerSize();
+ int stackGrowth = Asm->getTargetData().getPointerSize();
+ if (Asm->TM.getFrameInfo()->getStackGrowthDirection() ==
+ TargetFrameInfo::StackGrowsDown)
+ stackGrowth *= -1;
// Start the dwarf frame section.
Asm->OutStreamer.SwitchSection(
Asm->getObjFileLowering().getDwarfFrameSection());
- Asm->OutStreamer.EmitLabel(getTempLabel("debug_frame_common"));
+ Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("debug_frame_common"));
Asm->OutStreamer.AddComment("Length of Common Information Entry");
- EmitDifference(getTempLabel("debug_frame_common_end"),
- getTempLabel("debug_frame_common_begin"), true);
+ Asm->EmitLabelDifference(Asm->GetTempSymbol("debug_frame_common_end"),
+ Asm->GetTempSymbol("debug_frame_common_begin"), 4);
- Asm->OutStreamer.EmitLabel(getTempLabel("debug_frame_common_begin"));
+ Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("debug_frame_common_begin"));
Asm->OutStreamer.AddComment("CIE Identifier Tag");
Asm->EmitInt32((int)dwarf::DW_CIE_ID);
Asm->OutStreamer.AddComment("CIE Version");
Asm->EmitInt8(dwarf::DW_CIE_VERSION);
Asm->OutStreamer.AddComment("CIE Augmentation");
Asm->OutStreamer.EmitIntValue(0, 1, /*addrspace*/0); // nul terminator.
- EmitULEB128(1, "CIE Code Alignment Factor");
- EmitSLEB128(stackGrowth, "CIE Data Alignment Factor");
+ Asm->EmitULEB128(1, "CIE Code Alignment Factor");
+ Asm->EmitSLEB128(stackGrowth, "CIE Data Alignment Factor");
Asm->OutStreamer.AddComment("CIE RA Column");
+ const TargetRegisterInfo *RI = Asm->TM.getRegisterInfo();
Asm->EmitInt8(RI->getDwarfRegNum(RI->getRARegister(), false));
std::vector<MachineMove> Moves;
RI->getInitialFrameState(Moves);
- EmitFrameMoves(0, Moves, false);
+ Asm->EmitFrameMoves(Moves, 0, false);
Asm->EmitAlignment(2, 0, 0, false);
- Asm->OutStreamer.EmitLabel(getTempLabel("debug_frame_common_end"));
+ Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("debug_frame_common_end"));
}
/// emitFunctionDebugFrame - Emit per function frame info into a debug frame
/// section.
void DwarfDebug::
emitFunctionDebugFrame(const FunctionDebugFrameInfo &DebugFrameInfo) {
- if (!MAI->doesDwarfRequireFrameSection())
+ if (!Asm->MAI->doesDwarfRequireFrameSection())
return;
// Start the dwarf frame section.
@@ -2866,27 +2917,30 @@ emitFunctionDebugFrame(const FunctionDebugFrameInfo &DebugFrameInfo) {
Asm->OutStreamer.AddComment("Length of Frame Information Entry");
MCSymbol *DebugFrameBegin =
- getDWLabel("debug_frame_begin", DebugFrameInfo.Number);
+ Asm->GetTempSymbol("debug_frame_begin", DebugFrameInfo.Number);
MCSymbol *DebugFrameEnd =
- getDWLabel("debug_frame_end", DebugFrameInfo.Number);
- EmitDifference(DebugFrameEnd, DebugFrameBegin, true);
+ Asm->GetTempSymbol("debug_frame_end", DebugFrameInfo.Number);
+ Asm->EmitLabelDifference(DebugFrameEnd, DebugFrameBegin, 4);
Asm->OutStreamer.EmitLabel(DebugFrameBegin);
Asm->OutStreamer.AddComment("FDE CIE offset");
- EmitSectionOffset(getTempLabel("debug_frame_common"),
- getTempLabel("section_debug_frame"), true);
+ Asm->EmitSectionOffset(Asm->GetTempSymbol("debug_frame_common"),
+ DwarfFrameSectionSym);
Asm->OutStreamer.AddComment("FDE initial location");
- MCSymbol *FuncBeginSym = getDWLabel("func_begin", DebugFrameInfo.Number);
+ MCSymbol *FuncBeginSym =
+ Asm->GetTempSymbol("func_begin", DebugFrameInfo.Number);
Asm->OutStreamer.EmitSymbolValue(FuncBeginSym,
- TD->getPointerSize(), 0/*AddrSpace*/);
+ Asm->getTargetData().getPointerSize(),
+ 0/*AddrSpace*/);
Asm->OutStreamer.AddComment("FDE address range");
- EmitDifference(getDWLabel("func_end", DebugFrameInfo.Number), FuncBeginSym);
+ Asm->EmitLabelDifference(Asm->GetTempSymbol("func_end",DebugFrameInfo.Number),
+ FuncBeginSym, Asm->getTargetData().getPointerSize());
- EmitFrameMoves(FuncBeginSym, DebugFrameInfo.Moves, false);
+ Asm->EmitFrameMoves(DebugFrameInfo.Moves, FuncBeginSym, false);
Asm->EmitAlignment(2, 0, 0, false);
Asm->OutStreamer.EmitLabel(DebugFrameEnd);
@@ -2900,22 +2954,24 @@ void DwarfDebug::emitDebugPubNames() {
Asm->getObjFileLowering().getDwarfPubNamesSection());
Asm->OutStreamer.AddComment("Length of Public Names Info");
- EmitDifference(getDWLabel("pubnames_end", ModuleCU->getID()),
- getDWLabel("pubnames_begin", ModuleCU->getID()), true);
+ Asm->EmitLabelDifference(
+ Asm->GetTempSymbol("pubnames_end", ModuleCU->getID()),
+ Asm->GetTempSymbol("pubnames_begin", ModuleCU->getID()), 4);
- Asm->OutStreamer.EmitLabel(getDWLabel("pubnames_begin", ModuleCU->getID()));
+ Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("pubnames_begin",
+ ModuleCU->getID()));
Asm->OutStreamer.AddComment("DWARF Version");
Asm->EmitInt16(dwarf::DWARF_VERSION);
Asm->OutStreamer.AddComment("Offset of Compilation Unit Info");
- EmitSectionOffset(getDWLabel("info_begin", ModuleCU->getID()),
- getTempLabel("section_info"), true);
+ Asm->EmitSectionOffset(Asm->GetTempSymbol("info_begin", ModuleCU->getID()),
+ DwarfInfoSectionSym);
Asm->OutStreamer.AddComment("Compilation Unit Length");
- EmitDifference(getDWLabel("info_end", ModuleCU->getID()),
- getDWLabel("info_begin", ModuleCU->getID()),
- true);
+ Asm->EmitLabelDifference(Asm->GetTempSymbol("info_end", ModuleCU->getID()),
+ Asm->GetTempSymbol("info_begin", ModuleCU->getID()),
+ 4);
const StringMap<DIE*> &Globals = ModuleCU->getGlobals();
for (StringMap<DIE*>::const_iterator
@@ -2926,14 +2982,15 @@ void DwarfDebug::emitDebugPubNames() {
Asm->OutStreamer.AddComment("DIE offset");
Asm->EmitInt32(Entity->getOffset());
- if (Asm->VerboseAsm)
+ if (Asm->isVerbose())
Asm->OutStreamer.AddComment("External Name");
Asm->OutStreamer.EmitBytes(StringRef(Name, strlen(Name)+1), 0);
}
Asm->OutStreamer.AddComment("End Mark");
Asm->EmitInt32(0);
- Asm->OutStreamer.EmitLabel(getDWLabel("pubnames_end", ModuleCU->getID()));
+ Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("pubnames_end",
+ ModuleCU->getID()));
}
void DwarfDebug::emitDebugPubTypes() {
@@ -2941,22 +2998,24 @@ void DwarfDebug::emitDebugPubTypes() {
Asm->OutStreamer.SwitchSection(
Asm->getObjFileLowering().getDwarfPubTypesSection());
Asm->OutStreamer.AddComment("Length of Public Types Info");
- EmitDifference(getDWLabel("pubtypes_end", ModuleCU->getID()),
- getDWLabel("pubtypes_begin", ModuleCU->getID()), true);
+ Asm->EmitLabelDifference(
+ Asm->GetTempSymbol("pubtypes_end", ModuleCU->getID()),
+ Asm->GetTempSymbol("pubtypes_begin", ModuleCU->getID()), 4);
- Asm->OutStreamer.EmitLabel(getDWLabel("pubtypes_begin", ModuleCU->getID()));
+ Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("pubtypes_begin",
+ ModuleCU->getID()));
- if (Asm->VerboseAsm) Asm->OutStreamer.AddComment("DWARF Version");
+ if (Asm->isVerbose()) Asm->OutStreamer.AddComment("DWARF Version");
Asm->EmitInt16(dwarf::DWARF_VERSION);
Asm->OutStreamer.AddComment("Offset of Compilation ModuleCU Info");
- EmitSectionOffset(getDWLabel("info_begin", ModuleCU->getID()),
- getTempLabel("section_info"), true);
+ Asm->EmitSectionOffset(Asm->GetTempSymbol("info_begin", ModuleCU->getID()),
+ DwarfInfoSectionSym);
Asm->OutStreamer.AddComment("Compilation ModuleCU Length");
- EmitDifference(getDWLabel("info_end", ModuleCU->getID()),
- getDWLabel("info_begin", ModuleCU->getID()),
- true);
+ Asm->EmitLabelDifference(Asm->GetTempSymbol("info_end", ModuleCU->getID()),
+ Asm->GetTempSymbol("info_begin", ModuleCU->getID()),
+ 4);
const StringMap<DIE*> &Globals = ModuleCU->getGlobalTypes();
for (StringMap<DIE*>::const_iterator
@@ -2964,16 +3023,17 @@ void DwarfDebug::emitDebugPubTypes() {
const char *Name = GI->getKeyData();
DIE * Entity = GI->second;
- if (Asm->VerboseAsm) Asm->OutStreamer.AddComment("DIE offset");
+ if (Asm->isVerbose()) Asm->OutStreamer.AddComment("DIE offset");
Asm->EmitInt32(Entity->getOffset());
- if (Asm->VerboseAsm) Asm->OutStreamer.AddComment("External Name");
+ if (Asm->isVerbose()) Asm->OutStreamer.AddComment("External Name");
Asm->OutStreamer.EmitBytes(StringRef(Name, GI->getKeyLength()+1), 0);
}
Asm->OutStreamer.AddComment("End Mark");
Asm->EmitInt32(0);
- Asm->OutStreamer.EmitLabel(getDWLabel("pubtypes_end", ModuleCU->getID()));
+ Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("pubtypes_end",
+ ModuleCU->getID()));
}
/// emitDebugStr - Emit visible names into a debug str section.
@@ -3059,7 +3119,7 @@ void DwarfDebug::emitDebugMacInfo() {
/// __debug_info section, and the low_pc is the starting address for the
/// inlining instance.
void DwarfDebug::emitDebugInlineInfo() {
- if (!MAI->doesDwarfUsesInlineInfoSection())
+ if (!Asm->MAI->doesDwarfUsesInlineInfoSection())
return;
if (!ModuleCU)
@@ -3069,15 +3129,15 @@ void DwarfDebug::emitDebugInlineInfo() {
Asm->getObjFileLowering().getDwarfDebugInlineSection());
Asm->OutStreamer.AddComment("Length of Debug Inlined Information Entry");
- EmitDifference(getDWLabel("debug_inlined_end", 1),
- getDWLabel("debug_inlined_begin", 1), true);
+ Asm->EmitLabelDifference(Asm->GetTempSymbol("debug_inlined_end", 1),
+ Asm->GetTempSymbol("debug_inlined_begin", 1), 4);
- Asm->OutStreamer.EmitLabel(getDWLabel("debug_inlined_begin", 1));
+ Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("debug_inlined_begin", 1));
Asm->OutStreamer.AddComment("Dwarf Version");
Asm->EmitInt16(dwarf::DWARF_VERSION);
Asm->OutStreamer.AddComment("Address Size (in bytes)");
- Asm->EmitInt8(TD->getPointerSize());
+ Asm->EmitInt8(Asm->getTargetData().getPointerSize());
for (SmallVector<MDNode *, 4>::iterator I = InlinedSPNodes.begin(),
E = InlinedSPNodes.end(); I != E; ++I) {
@@ -3095,23 +3155,23 @@ void DwarfDebug::emitDebugInlineInfo() {
Asm->OutStreamer.EmitBytes(Name, 0);
Asm->OutStreamer.EmitIntValue(0, 1, 0); // nul terminator.
} else
- EmitSectionOffset(getStringPoolEntry(getRealLinkageName(LName)),
- getTempLabel("section_str"), true);
+ Asm->EmitSectionOffset(getStringPoolEntry(getRealLinkageName(LName)),
+ DwarfStrSectionSym);
Asm->OutStreamer.AddComment("Function name");
- EmitSectionOffset(getStringPoolEntry(Name), getTempLabel("section_str"),
- true);
- EmitULEB128(Labels.size(), "Inline count");
+ Asm->EmitSectionOffset(getStringPoolEntry(Name), DwarfStrSectionSym);
+ Asm->EmitULEB128(Labels.size(), "Inline count");
for (SmallVector<InlineInfoLabels, 4>::iterator LI = Labels.begin(),
LE = Labels.end(); LI != LE; ++LI) {
- if (Asm->VerboseAsm) Asm->OutStreamer.AddComment("DIE offset");
+ if (Asm->isVerbose()) Asm->OutStreamer.AddComment("DIE offset");
Asm->EmitInt32(LI->second->getOffset());
- if (Asm->VerboseAsm) Asm->OutStreamer.AddComment("low_pc");
- Asm->OutStreamer.EmitSymbolValue(LI->first, TD->getPointerSize(), 0);
+ if (Asm->isVerbose()) Asm->OutStreamer.AddComment("low_pc");
+ Asm->OutStreamer.EmitSymbolValue(LI->first,
+ Asm->getTargetData().getPointerSize(),0);
}
}
- Asm->OutStreamer.EmitLabel(getDWLabel("debug_inlined_end", 1));
+ Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("debug_inlined_end", 1));
}
diff --git a/lib/CodeGen/AsmPrinter/DwarfDebug.h b/lib/CodeGen/AsmPrinter/DwarfDebug.h
index 03d9d9935f2f..c7baf5f5d38d 100644
--- a/lib/CodeGen/AsmPrinter/DwarfDebug.h
+++ b/lib/CodeGen/AsmPrinter/DwarfDebug.h
@@ -14,19 +14,14 @@
#ifndef CODEGEN_ASMPRINTER_DWARFDEBUG_H__
#define CODEGEN_ASMPRINTER_DWARFDEBUG_H__
-#include "DIE.h"
-#include "DwarfPrinter.h"
#include "llvm/CodeGen/AsmPrinter.h"
-#include "llvm/CodeGen/MachineLocation.h"
-#include "llvm/Analysis/DebugInfo.h"
-#include "llvm/Support/Allocator.h"
-#include "llvm/Support/raw_ostream.h"
+#include "DIE.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/FoldingSet.h"
-#include "llvm/ADT/SmallSet.h"
+#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/UniqueVector.h"
-#include <string>
+#include "llvm/Support/Allocator.h"
namespace llvm {
@@ -35,9 +30,27 @@ class DbgConcreteScope;
class DbgScope;
class DbgVariable;
class MachineFrameInfo;
+class MachineLocation;
class MachineModuleInfo;
class MCAsmInfo;
class Timer;
+class DIEAbbrev;
+class DIE;
+class DIEBlock;
+class DIEEntry;
+
+class DIEnumerator;
+class DIDescriptor;
+class DIVariable;
+class DIGlobal;
+class DIGlobalVariable;
+class DISubprogram;
+class DIBasicType;
+class DIDerivedType;
+class DIType;
+class DINameSpace;
+class DISubrange;
+class DICompositeType;
//===----------------------------------------------------------------------===//
/// SrcLineInfo - This class is used to record source line correspondence.
@@ -58,7 +71,13 @@ public:
MCSymbol *getLabel() const { return Label; }
};
-class DwarfDebug : public DwarfPrinter {
+class DwarfDebug {
+ /// Asm - Target of Dwarf emission.
+ AsmPrinter *Asm;
+
+ /// MMI - Collected machine module information.
+ MachineModuleInfo *MMI;
+
//===--------------------------------------------------------------------===//
// Attributes used to construct specific Dwarf sections.
//
@@ -120,14 +139,6 @@ class DwarfDebug : public DwarfPrinter {
///
std::vector<std::vector<SrcLineInfo> > SectionSourceLines;
- /// didInitial - Flag to indicate if initial emission has been done.
- ///
- bool didInitial;
-
- /// shouldEmit - Flag to indicate if debug information should be emitted.
- ///
- bool shouldEmit;
-
// CurrentFnDbgScope - Top level scope for the current function.
//
DbgScope *CurrentFnDbgScope;
@@ -210,6 +221,14 @@ class DwarfDebug : public DwarfPrinter {
std::vector<FunctionDebugFrameInfo> DebugFrames;
+ // Section Symbols: these are assembler temporary labels that are emitted at
+ // the beginning of each supported dwarf section. These are used to form
+ // section offsets and are created by EmitSectionLabels.
+ MCSymbol *DwarfFrameSectionSym, *DwarfInfoSectionSym, *DwarfAbbrevSectionSym;
+ MCSymbol *DwarfStrSectionSym, *TextSectionSym;
+
+private:
+
/// getSourceDirectoryAndFileIds - Return the directory and file ids that
/// maps to the source id. Source id starts at 1.
std::pair<unsigned, unsigned>
@@ -273,10 +292,8 @@ class DwarfDebug : public DwarfPrinter {
/// addDIEEntry - Add a DIE attribute data and value.
///
- void addDIEEntry(DIE *Die, unsigned Attribute, unsigned Form, DIE *Entry) {
- Die->addValue(Attribute, Form, createDIEEntry(Entry));
- }
-
+ void addDIEEntry(DIE *Die, unsigned Attribute, unsigned Form, DIE *Entry);
+
/// addBlock - Add block data.
///
void addBlock(DIE *Die, unsigned Attribute, unsigned Form, DIEBlock *Block);
@@ -396,9 +413,9 @@ class DwarfDebug : public DwarfPrinter {
/// constructScopeDIE - Construct a DIE for this scope.
DIE *constructScopeDIE(DbgScope *Scope);
- /// emitInitial - Emit initial Dwarf declarations. This is necessary for cc
- /// tools to recognize the object file contains Dwarf information.
- void emitInitial();
+ /// EmitSectionLabels - Emit initial Dwarf sections with a label at
+ /// the start of each one.
+ void EmitSectionLabels();
/// emitDIE - Recusively Emits a debug information entry.
///
@@ -487,8 +504,8 @@ class DwarfDebug : public DwarfPrinter {
/// GetOrCreateSourceID - Look up the source id with the given directory and
/// source file names. If none currently exists, create a new id and insert it
- /// in the SourceIds map. This can update DirectoryNames and SourceFileNames maps
- /// as well.
+ /// in the SourceIds map. This can update DirectoryNames and SourceFileNames
+ /// maps as well.
unsigned GetOrCreateSourceID(StringRef DirName, StringRef FileName);
void constructCompileUnit(MDNode *N);
@@ -503,44 +520,17 @@ class DwarfDebug : public DwarfPrinter {
///
DIType getBlockByrefType(DIType Ty, std::string Name);
-public:
- //===--------------------------------------------------------------------===//
- // Main entry points.
- //
- DwarfDebug(raw_ostream &OS, AsmPrinter *A, const MCAsmInfo *T);
- virtual ~DwarfDebug();
-
- /// ShouldEmitDwarfDebug - Returns true if Dwarf debugging declarations should
- /// be emitted.
- bool ShouldEmitDwarfDebug() const { return shouldEmit; }
-
- /// beginModule - Emit all Dwarf sections that should come prior to the
- /// content.
- void beginModule(Module *M, MachineModuleInfo *MMI);
-
- /// endModule - Emit all Dwarf sections that should come after the content.
- ///
- void endModule();
-
- /// beginFunction - Gather pre-function debug information. Assumes being
- /// emitted immediately after the function entry point.
- void beginFunction(const MachineFunction *MF);
-
- /// endFunction - Gather and emit post-function debug information.
- ///
- void endFunction(const MachineFunction *MF);
-
/// recordSourceLine - Register a source line with debug info. Returns the
/// unique label that was emitted and which provides correspondence to
/// the source line list.
MCSymbol *recordSourceLine(unsigned Line, unsigned Col, MDNode *Scope);
-
+
/// getSourceLineCount - Return the number of source lines in the debug
/// info.
unsigned getSourceLineCount() const {
return Lines.size();
}
-
+
/// getOrCreateSourceID - Public version of GetOrCreateSourceID. This can be
/// timed. Look up the source id with the given directory and source file
/// names. If none currently exists, create a new id and insert it in the
@@ -548,13 +538,36 @@ public:
/// well.
unsigned getOrCreateSourceID(const std::string &DirName,
const std::string &FileName);
-
+
/// extractScopeInformation - Scan machine instructions in this function
/// and collect DbgScopes. Return true, if atleast one scope was found.
bool extractScopeInformation();
-
+
/// collectVariableInfo - Populate DbgScope entries with variables' info.
void collectVariableInfo();
+
+public:
+ //===--------------------------------------------------------------------===//
+ // Main entry points.
+ //
+ DwarfDebug(AsmPrinter *A, Module *M);
+ ~DwarfDebug();
+
+ /// beginModule - Emit all Dwarf sections that should come prior to the
+ /// content.
+ void beginModule(Module *M);
+
+ /// endModule - Emit all Dwarf sections that should come after the content.
+ ///
+ void endModule();
+
+ /// beginFunction - Gather pre-function debug information. Assumes being
+ /// emitted immediately after the function entry point.
+ void beginFunction(const MachineFunction *MF);
+
+ /// endFunction - Gather and emit post-function debug information.
+ ///
+ void endFunction(const MachineFunction *MF);
/// beginScope - Process beginning of a scope.
void beginScope(const MachineInstr *MI);
diff --git a/lib/CodeGen/AsmPrinter/DwarfException.cpp b/lib/CodeGen/AsmPrinter/DwarfException.cpp
index 8b616b012614..72c97a43085c 100644
--- a/lib/CodeGen/AsmPrinter/DwarfException.cpp
+++ b/lib/CodeGen/AsmPrinter/DwarfException.cpp
@@ -13,6 +13,7 @@
#include "DwarfException.h"
#include "llvm/Module.h"
+#include "llvm/CodeGen/AsmPrinter.h"
#include "llvm/CodeGen/MachineModuleInfo.h"
#include "llvm/CodeGen/MachineFrameInfo.h"
#include "llvm/CodeGen/MachineFunction.h"
@@ -27,6 +28,7 @@
#include "llvm/Target/TargetData.h"
#include "llvm/Target/TargetFrameInfo.h"
#include "llvm/Target/TargetLoweringObjectFile.h"
+#include "llvm/Target/TargetMachine.h"
#include "llvm/Target/TargetOptions.h"
#include "llvm/Target/TargetRegisterInfo.h"
#include "llvm/Support/Dwarf.h"
@@ -37,9 +39,8 @@
#include "llvm/ADT/Twine.h"
using namespace llvm;
-DwarfException::DwarfException(raw_ostream &OS, AsmPrinter *A,
- const MCAsmInfo *T)
- : DwarfPrinter(OS, A, T), shouldEmitTable(false),shouldEmitMoves(false),
+DwarfException::DwarfException(AsmPrinter *A)
+ : Asm(A), MMI(Asm->MMI), shouldEmitTable(false), shouldEmitMoves(false),
shouldEmitTableModule(false), shouldEmitMovesModule(false),
ExceptionTimer(0) {
if (TimePassesIsEnabled)
@@ -55,10 +56,10 @@ DwarfException::~DwarfException() {
/// in every non-empty .debug_frame section.
void DwarfException::EmitCIE(const Function *PersonalityFn, unsigned Index) {
// Size and sign of stack growth.
- int stackGrowth =
- Asm->TM.getFrameInfo()->getStackGrowthDirection() ==
- TargetFrameInfo::StackGrowsUp ?
- TD->getPointerSize() : -TD->getPointerSize();
+ int stackGrowth = Asm->getTargetData().getPointerSize();
+ if (Asm->TM.getFrameInfo()->getStackGrowthDirection() ==
+ TargetFrameInfo::StackGrowsDown)
+ stackGrowth *= -1;
const TargetLoweringObjectFile &TLOF = Asm->getObjFileLowering();
@@ -67,24 +68,25 @@ void DwarfException::EmitCIE(const Function *PersonalityFn, unsigned Index) {
MCSymbol *EHFrameSym;
if (TLOF.isFunctionEHFrameSymbolPrivate())
- EHFrameSym = getDWLabel("EH_frame", Index);
+ EHFrameSym = Asm->GetTempSymbol("EH_frame", Index);
else
EHFrameSym = Asm->OutContext.GetOrCreateSymbol(Twine("EH_frame") +
Twine(Index));
Asm->OutStreamer.EmitLabel(EHFrameSym);
- Asm->OutStreamer.EmitLabel(getDWLabel("section_eh_frame", Index));
+ Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("section_eh_frame", Index));
// Define base labels.
- Asm->OutStreamer.EmitLabel(getDWLabel("eh_frame_common", Index));
+ Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("eh_frame_common", Index));
// Define the eh frame length.
Asm->OutStreamer.AddComment("Length of Common Information Entry");
- EmitDifference(getDWLabel("eh_frame_common_end", Index),
- getDWLabel("eh_frame_common_begin", Index), true);
+ Asm->EmitLabelDifference(Asm->GetTempSymbol("eh_frame_common_end", Index),
+ Asm->GetTempSymbol("eh_frame_common_begin", Index),
+ 4);
// EH frame header.
- Asm->OutStreamer.EmitLabel(getDWLabel("eh_frame_common_begin", Index));
+ Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("eh_frame_common_begin",Index));
Asm->OutStreamer.AddComment("CIE Identifier Tag");
Asm->OutStreamer.EmitIntValue(0, 4/*size*/, 0/*addrspace*/);
Asm->OutStreamer.AddComment("DW_CIE_VERSION");
@@ -105,7 +107,7 @@ void DwarfException::EmitCIE(const Function *PersonalityFn, unsigned Index) {
if (PersonalityFn) {
// There is a personality function.
*APtr++ = 'P';
- AugmentationSize += 1 + SizeOfEncodedValue(PerEncoding);
+ AugmentationSize += 1 + Asm->GetSizeOfEncodedValue(PerEncoding);
}
if (UsesLSDA[Index]) {
@@ -127,36 +129,39 @@ void DwarfException::EmitCIE(const Function *PersonalityFn, unsigned Index) {
Asm->OutStreamer.EmitBytes(StringRef(Augmentation, strlen(Augmentation)+1),0);
// Round out reader.
- EmitULEB128(1, "CIE Code Alignment Factor");
- EmitSLEB128(stackGrowth, "CIE Data Alignment Factor");
+ Asm->EmitULEB128(1, "CIE Code Alignment Factor");
+ Asm->EmitSLEB128(stackGrowth, "CIE Data Alignment Factor");
Asm->OutStreamer.AddComment("CIE Return Address Column");
+
+ const TargetRegisterInfo *RI = Asm->TM.getRegisterInfo();
Asm->EmitInt8(RI->getDwarfRegNum(RI->getRARegister(), true));
if (Augmentation[0]) {
- EmitULEB128(AugmentationSize, "Augmentation Size");
+ Asm->EmitULEB128(AugmentationSize, "Augmentation Size");
// If there is a personality, we need to indicate the function's location.
if (PersonalityFn) {
- EmitEncodingByte(PerEncoding, "Personality");
+ Asm->EmitEncodingByte(PerEncoding, "Personality");
Asm->OutStreamer.AddComment("Personality");
- EmitReference(PersonalityFn, PerEncoding);
+ Asm->EmitReference(PersonalityFn, PerEncoding);
}
if (UsesLSDA[Index])
- EmitEncodingByte(LSDAEncoding, "LSDA");
+ Asm->EmitEncodingByte(LSDAEncoding, "LSDA");
if (FDEEncoding != dwarf::DW_EH_PE_absptr)
- EmitEncodingByte(FDEEncoding, "FDE");
+ Asm->EmitEncodingByte(FDEEncoding, "FDE");
}
// Indicate locations of general callee saved registers in frame.
std::vector<MachineMove> Moves;
RI->getInitialFrameState(Moves);
- EmitFrameMoves(0, Moves, true);
+ Asm->EmitFrameMoves(Moves, 0, true);
// On Darwin the linker honors the alignment of eh_frame, which means it must
// be 8-byte on 64-bit targets to match what gcc does. Otherwise you get
// holes which confuse readers of eh_frame.
- Asm->EmitAlignment(TD->getPointerSize() == 4 ? 2 : 3, 0, 0, false);
- Asm->OutStreamer.EmitLabel(getDWLabel("eh_frame_common_end", Index));
+ Asm->EmitAlignment(Asm->getTargetData().getPointerSize() == 4 ? 2 : 3,
+ 0, 0, false);
+ Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("eh_frame_common_end", Index));
}
/// EmitFDE - Emit the Frame Description Entry (FDE) for the function.
@@ -178,13 +183,13 @@ void DwarfException::EmitFDE(const FunctionEHFrameInfo &EHFrameInfo) {
Asm->OutStreamer.EmitSymbolAttribute(EHFrameInfo.FunctionEHSym,MCSA_Global);
// If corresponding function is weak definition, this should be too.
- if (TheFunc->isWeakForLinker() && MAI->getWeakDefDirective())
+ if (TheFunc->isWeakForLinker() && Asm->MAI->getWeakDefDirective())
Asm->OutStreamer.EmitSymbolAttribute(EHFrameInfo.FunctionEHSym,
MCSA_WeakDefinition);
// If corresponding function is hidden, this should be too.
if (TheFunc->hasHiddenVisibility())
- if (MCSymbolAttr HiddenAttr = MAI->getHiddenVisibilityAttr())
+ if (MCSymbolAttr HiddenAttr = Asm->MAI->getHiddenVisibilityAttr())
Asm->OutStreamer.EmitSymbolAttribute(EHFrameInfo.FunctionEHSym,
HiddenAttr);
@@ -194,14 +199,14 @@ void DwarfException::EmitFDE(const FunctionEHFrameInfo &EHFrameInfo) {
// info is to be available for non-EH uses.
if (!EHFrameInfo.hasCalls && !UnwindTablesMandatory &&
(!TheFunc->isWeakForLinker() ||
- !MAI->getWeakDefDirective() ||
+ !Asm->MAI->getWeakDefDirective() ||
TLOF.getSupportsWeakOmittedEHFrame())) {
Asm->OutStreamer.EmitAssignment(EHFrameInfo.FunctionEHSym,
MCConstantExpr::Create(0, Asm->OutContext));
// This name has no connection to the function, so it might get
// dead-stripped when the function is not, erroneously. Prohibit
// dead-stripping unconditionally.
- if (MAI->hasNoDeadStrip())
+ if (Asm->MAI->hasNoDeadStrip())
Asm->OutStreamer.EmitSymbolAttribute(EHFrameInfo.FunctionEHSym,
MCSA_NoDeadStrip);
} else {
@@ -209,52 +214,58 @@ void DwarfException::EmitFDE(const FunctionEHFrameInfo &EHFrameInfo) {
// EH frame header.
Asm->OutStreamer.AddComment("Length of Frame Information Entry");
- EmitDifference(getDWLabel("eh_frame_end", EHFrameInfo.Number),
- getDWLabel("eh_frame_begin", EHFrameInfo.Number),
- true);
+ Asm->EmitLabelDifference(
+ Asm->GetTempSymbol("eh_frame_end", EHFrameInfo.Number),
+ Asm->GetTempSymbol("eh_frame_begin", EHFrameInfo.Number), 4);
- Asm->OutStreamer.EmitLabel(getDWLabel("eh_frame_begin",EHFrameInfo.Number));
+ Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("eh_frame_begin",
+ EHFrameInfo.Number));
Asm->OutStreamer.AddComment("FDE CIE offset");
- EmitSectionOffset(getDWLabel("eh_frame_begin", EHFrameInfo.Number),
- getDWLabel("eh_frame_common",
- EHFrameInfo.PersonalityIndex),
- true, true);
+ Asm->EmitLabelDifference(
+ Asm->GetTempSymbol("eh_frame_begin", EHFrameInfo.Number),
+ Asm->GetTempSymbol("eh_frame_common",
+ EHFrameInfo.PersonalityIndex), 4);
- MCSymbol *EHFuncBeginSym = getDWLabel("eh_func_begin", EHFrameInfo.Number);
+ MCSymbol *EHFuncBeginSym =
+ Asm->GetTempSymbol("eh_func_begin", EHFrameInfo.Number);
Asm->OutStreamer.AddComment("FDE initial location");
- EmitReference(EHFuncBeginSym, FDEEncoding);
+ Asm->EmitReference(EHFuncBeginSym, FDEEncoding);
Asm->OutStreamer.AddComment("FDE address range");
- EmitDifference(getDWLabel("eh_func_end", EHFrameInfo.Number),EHFuncBeginSym,
- SizeOfEncodedValue(FDEEncoding) == 4);
+ Asm->EmitLabelDifference(Asm->GetTempSymbol("eh_func_end",
+ EHFrameInfo.Number),
+ EHFuncBeginSym,
+ Asm->GetSizeOfEncodedValue(FDEEncoding));
// 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) {
- unsigned Size = SizeOfEncodedValue(LSDAEncoding);
+ unsigned Size = Asm->GetSizeOfEncodedValue(LSDAEncoding);
- EmitULEB128(Size, "Augmentation size");
+ Asm->EmitULEB128(Size, "Augmentation size");
Asm->OutStreamer.AddComment("Language Specific Data Area");
if (EHFrameInfo.hasLandingPads)
- EmitReference(getDWLabel("exception", EHFrameInfo.Number),LSDAEncoding);
+ Asm->EmitReference(Asm->GetTempSymbol("exception", EHFrameInfo.Number),
+ LSDAEncoding);
else
Asm->OutStreamer.EmitIntValue(0, Size/*size*/, 0/*addrspace*/);
} else {
- EmitULEB128(0, "Augmentation size");
+ Asm->EmitULEB128(0, "Augmentation size");
}
// Indicate locations of function specific callee saved registers in frame.
- EmitFrameMoves(EHFuncBeginSym, EHFrameInfo.Moves, true);
+ Asm->EmitFrameMoves(EHFrameInfo.Moves, EHFuncBeginSym, true);
// On Darwin the linker honors the alignment of eh_frame, which means it
// must be 8-byte on 64-bit targets to match what gcc does. Otherwise you
// get holes which confuse readers of eh_frame.
- Asm->EmitAlignment(TD->getPointerSize() == sizeof(int32_t) ? 2 : 3,
+ Asm->EmitAlignment(Asm->getTargetData().getPointerSize() == 4 ? 2 : 3,
0, 0, false);
- Asm->OutStreamer.EmitLabel(getDWLabel("eh_frame_end", EHFrameInfo.Number));
+ Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("eh_frame_end",
+ EHFrameInfo.Number));
// If the function is marked used, this table should be also. We cannot
// make the mark unconditional in this case, since retaining the table also
@@ -262,7 +273,7 @@ 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 (MAI->hasNoDeadStrip())
+ if (Asm->MAI->hasNoDeadStrip())
Asm->OutStreamer.EmitSymbolAttribute(EHFrameInfo.FunctionEHSym,
MCSA_NoDeadStrip);
}
@@ -348,7 +359,7 @@ ComputeActionsTable(const SmallVectorImpl<const LandingPadInfo*> &LandingPads,
I = LandingPads.begin(), E = LandingPads.end(); I != E; ++I) {
const LandingPadInfo *LPI = *I;
const std::vector<int> &TypeIds = LPI->TypeIds;
- const unsigned NumShared = PrevLPI ? SharedTypeIds(LPI, PrevLPI) : 0;
+ unsigned NumShared = PrevLPI ? SharedTypeIds(LPI, PrevLPI) : 0;
unsigned SizeSiteActions = 0;
if (NumShared < TypeIds.size()) {
@@ -356,7 +367,7 @@ ComputeActionsTable(const SmallVectorImpl<const LandingPadInfo*> &LandingPads,
unsigned PrevAction = (unsigned)-1;
if (NumShared) {
- const unsigned SizePrevIds = PrevLPI->TypeIds.size();
+ unsigned SizePrevIds = PrevLPI->TypeIds.size();
assert(Actions.size());
PrevAction = Actions.size() - 1;
SizeAction =
@@ -465,7 +476,7 @@ ComputeCallSiteTable(SmallVectorImpl<CallSiteEntry> &CallSites,
bool PreviousIsInvoke = false;
// Visit all instructions in order of address.
- for (MachineFunction::const_iterator I = MF->begin(), E = MF->end();
+ for (MachineFunction::const_iterator I = Asm->MF->begin(), E = Asm->MF->end();
I != E; ++I) {
for (MachineBasicBlock::const_iterator MI = I->begin(), E = I->end();
MI != E; ++MI) {
@@ -496,7 +507,7 @@ ComputeCallSiteTable(SmallVectorImpl<CallSiteEntry> &CallSites,
// create a call-site entry with no landing pad for the region between the
// try-ranges.
if (SawPotentiallyThrowing &&
- MAI->getExceptionHandlingType() == ExceptionHandling::Dwarf) {
+ Asm->MAI->getExceptionHandlingType() == ExceptionHandling::Dwarf) {
CallSiteEntry Site = { LastLabel, BeginLabel, 0, 0 };
CallSites.push_back(Site);
PreviousIsInvoke = false;
@@ -519,7 +530,7 @@ ComputeCallSiteTable(SmallVectorImpl<CallSiteEntry> &CallSites,
// Try to merge with the previous call-site. SJLJ doesn't do this
if (PreviousIsInvoke &&
- MAI->getExceptionHandlingType() == ExceptionHandling::Dwarf) {
+ Asm->MAI->getExceptionHandlingType() == ExceptionHandling::Dwarf) {
CallSiteEntry &Prev = CallSites.back();
if (Site.PadLabel == Prev.PadLabel && Site.Action == Prev.Action) {
// Extend the range of the previous entry.
@@ -529,7 +540,7 @@ ComputeCallSiteTable(SmallVectorImpl<CallSiteEntry> &CallSites,
}
// Otherwise, create a new call-site.
- if (MAI->getExceptionHandlingType() == ExceptionHandling::Dwarf)
+ if (Asm->MAI->getExceptionHandlingType() == ExceptionHandling::Dwarf)
CallSites.push_back(Site);
else {
// SjLj EH must maintain the call sites in the order assigned
@@ -548,7 +559,7 @@ ComputeCallSiteTable(SmallVectorImpl<CallSiteEntry> &CallSites,
// function may throw, create a call-site entry with no landing pad for the
// region following the try-range.
if (SawPotentiallyThrowing &&
- MAI->getExceptionHandlingType() == ExceptionHandling::Dwarf) {
+ Asm->MAI->getExceptionHandlingType() == ExceptionHandling::Dwarf) {
CallSiteEntry Site = { LastLabel, 0, 0, 0 };
CallSites.push_back(Site);
}
@@ -616,18 +627,19 @@ void DwarfException::EmitExceptionTable() {
// Final tallies.
// Call sites.
- const unsigned SiteStartSize = SizeOfEncodedValue(dwarf::DW_EH_PE_udata4);
- const unsigned SiteLengthSize = SizeOfEncodedValue(dwarf::DW_EH_PE_udata4);
- const unsigned LandingPadSize = SizeOfEncodedValue(dwarf::DW_EH_PE_udata4);
- bool IsSJLJ = MAI->getExceptionHandlingType() == ExceptionHandling::SjLj;
+ bool IsSJLJ = Asm->MAI->getExceptionHandlingType() == ExceptionHandling::SjLj;
bool HaveTTData = IsSJLJ ? (!TypeInfos.empty() || !FilterIds.empty()) : true;
+
unsigned CallSiteTableLength;
-
if (IsSJLJ)
CallSiteTableLength = 0;
- else
- CallSiteTableLength = CallSites.size() *
- (SiteStartSize + SiteLengthSize + LandingPadSize);
+ else {
+ unsigned SiteStartSize = 4; // dwarf::DW_EH_PE_udata4
+ unsigned SiteLengthSize = 4; // dwarf::DW_EH_PE_udata4
+ unsigned LandingPadSize = 4; // dwarf::DW_EH_PE_udata4
+ CallSiteTableLength =
+ CallSites.size() * (SiteStartSize + SiteLengthSize + LandingPadSize);
+ }
for (unsigned i = 0, e = CallSites.size(); i < e; ++i) {
CallSiteTableLength += MCAsmInfo::getULEB128Size(CallSites[i].Action);
@@ -644,7 +656,8 @@ void DwarfException::EmitExceptionTable() {
// For SjLj exceptions, if there is no TypeInfo, then we just explicitly say
// that we're omitting that bit.
TTypeEncoding = dwarf::DW_EH_PE_omit;
- TypeFormatSize = SizeOfEncodedValue(dwarf::DW_EH_PE_absptr);
+ // dwarf::DW_EH_PE_absptr
+ TypeFormatSize = Asm->getTargetData().getPointerSize();
} else {
// Okay, we have actual filters or typeinfos to emit. As such, we need to
// pick a type encoding for them. We're about to emit a list of pointers to
@@ -674,7 +687,7 @@ void DwarfException::EmitExceptionTable() {
// in target-independent code.
//
TTypeEncoding = Asm->getObjFileLowering().getTTypeEncoding();
- TypeFormatSize = SizeOfEncodedValue(TTypeEncoding);
+ TypeFormatSize = Asm->GetSizeOfEncodedValue(TTypeEncoding);
}
// Begin the exception table.
@@ -684,16 +697,18 @@ void DwarfException::EmitExceptionTable() {
// Emit the LSDA.
MCSymbol *GCCETSym =
Asm->OutContext.GetOrCreateSymbol(Twine("GCC_except_table")+
- Twine(SubprogramCount));
+ Twine(Asm->getFunctionNumber()));
Asm->OutStreamer.EmitLabel(GCCETSym);
- Asm->OutStreamer.EmitLabel(getDWLabel("exception", SubprogramCount));
+ Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("exception",
+ Asm->getFunctionNumber()));
if (IsSJLJ)
- Asm->OutStreamer.EmitLabel(getDWLabel("_LSDA_", Asm->getFunctionNumber()));
+ Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("_LSDA_",
+ Asm->getFunctionNumber()));
// Emit the LSDA header.
- EmitEncodingByte(dwarf::DW_EH_PE_omit, "@LPStart");
- EmitEncodingByte(TTypeEncoding, "@TType");
+ Asm->EmitEncodingByte(dwarf::DW_EH_PE_omit, "@LPStart");
+ Asm->EmitEncodingByte(TTypeEncoding, "@TType");
// The type infos need to be aligned. GCC does this by inserting padding just
// before the type infos. However, this changes the size of the exception
@@ -730,16 +745,16 @@ void DwarfException::EmitExceptionTable() {
if (HaveTTData) {
// Account for any extra padding that will be added to the call site table
// length.
- EmitULEB128(TTypeBaseOffset, "@TType base offset", SizeAlign);
+ Asm->EmitULEB128(TTypeBaseOffset, "@TType base offset", SizeAlign);
SizeAlign = 0;
}
// SjLj Exception handling
if (IsSJLJ) {
- EmitEncodingByte(dwarf::DW_EH_PE_udata4, "Call site");
+ Asm->EmitEncodingByte(dwarf::DW_EH_PE_udata4, "Call site");
// Add extra padding if it wasn't added to the TType base offset.
- EmitULEB128(CallSiteTableLength, "Call site table length", SizeAlign);
+ Asm->EmitULEB128(CallSiteTableLength, "Call site table length", SizeAlign);
// Emit the landing pad site information.
unsigned idx = 0;
@@ -749,16 +764,16 @@ void DwarfException::EmitExceptionTable() {
// Offset of the landing pad, counted in 16-byte bundles relative to the
// @LPStart address.
- EmitULEB128(idx, "Landing pad");
+ Asm->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.
- EmitULEB128(S.Action, "Action");
+ Asm->EmitULEB128(S.Action, "Action");
}
} else {
// DWARF Exception handling
- assert(MAI->getExceptionHandlingType() == ExceptionHandling::Dwarf);
+ assert(Asm->MAI->getExceptionHandlingType() == ExceptionHandling::Dwarf);
// The call-site table is a list of all call sites that may throw an
// exception (including C++ 'throw' statements) in the procedure
@@ -779,32 +794,33 @@ void DwarfException::EmitExceptionTable() {
// supposed to throw.
// Emit the landing pad call site table.
- EmitEncodingByte(dwarf::DW_EH_PE_udata4, "Call site");
+ Asm->EmitEncodingByte(dwarf::DW_EH_PE_udata4, "Call site");
// Add extra padding if it wasn't added to the TType base offset.
- EmitULEB128(CallSiteTableLength, "Call site table length", SizeAlign);
+ Asm->EmitULEB128(CallSiteTableLength, "Call site table length", SizeAlign);
for (SmallVectorImpl<CallSiteEntry>::const_iterator
I = CallSites.begin(), E = CallSites.end(); I != E; ++I) {
const CallSiteEntry &S = *I;
- MCSymbol *EHFuncBeginSym = getDWLabel("eh_func_begin", SubprogramCount);
+ MCSymbol *EHFuncBeginSym =
+ Asm->GetTempSymbol("eh_func_begin", Asm->getFunctionNumber());
MCSymbol *BeginLabel = S.BeginLabel;
if (BeginLabel == 0)
BeginLabel = EHFuncBeginSym;
MCSymbol *EndLabel = S.EndLabel;
if (EndLabel == 0)
- EndLabel = getDWLabel("eh_func_end", SubprogramCount);
+ EndLabel = Asm->GetTempSymbol("eh_func_end", Asm->getFunctionNumber());
// Offset of the call site relative to the previous call site, counted in
// number of 16-byte bundles. The first call site is counted relative to
// the start of the procedure fragment.
Asm->OutStreamer.AddComment("Region start");
- EmitSectionOffset(BeginLabel, EHFuncBeginSym, true, true);
+ Asm->EmitLabelDifference(BeginLabel, EHFuncBeginSym, 4);
Asm->OutStreamer.AddComment("Region length");
- EmitDifference(EndLabel, BeginLabel, true);
+ Asm->EmitLabelDifference(EndLabel, BeginLabel, 4);
// Offset of the landing pad, counted in 16-byte bundles relative to the
@@ -813,12 +829,12 @@ void DwarfException::EmitExceptionTable() {
if (!S.PadLabel)
Asm->OutStreamer.EmitIntValue(0, 4/*size*/, 0/*addrspace*/);
else
- EmitSectionOffset(S.PadLabel, EHFuncBeginSym, true, true);
+ Asm->EmitLabelDifference(S.PadLabel, EHFuncBeginSym, 4);
// 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.
- EmitULEB128(S.Action, "Action");
+ Asm->EmitULEB128(S.Action, "Action");
}
}
@@ -838,13 +854,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.
- EmitSLEB128(Action.ValueForTypeID, " TypeInfo index");
+ Asm->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.
- EmitSLEB128(Action.NextAction, " Next action");
+ Asm->EmitSLEB128(Action.NextAction, " Next action");
}
// Emit the Catch TypeInfos.
@@ -858,9 +874,10 @@ void DwarfException::EmitExceptionTable() {
Asm->OutStreamer.AddComment("TypeInfo");
if (GV)
- EmitReference(GV, TTypeEncoding);
+ Asm->EmitReference(GV, TTypeEncoding);
else
- Asm->OutStreamer.EmitIntValue(0, SizeOfEncodedValue(TTypeEncoding), 0);
+ Asm->OutStreamer.EmitIntValue(0,Asm->GetSizeOfEncodedValue(TTypeEncoding),
+ 0);
}
// Emit the Exception Specifications.
@@ -871,7 +888,7 @@ void DwarfException::EmitExceptionTable() {
for (std::vector<unsigned>::const_iterator
I = FilterIds.begin(), E = FilterIds.end(); I < E; ++I) {
unsigned TypeID = *I;
- EmitULEB128(TypeID, TypeID != 0 ? "Exception specification" : 0);
+ Asm->EmitULEB128(TypeID, TypeID != 0 ? "Exception specification" : 0);
}
Asm->EmitAlignment(2, 0, 0, false);
@@ -880,7 +897,7 @@ void DwarfException::EmitExceptionTable() {
/// EndModule - Emit all exception information that should come after the
/// content.
void DwarfException::EndModule() {
- if (MAI->getExceptionHandlingType() != ExceptionHandling::Dwarf)
+ if (Asm->MAI->getExceptionHandlingType() != ExceptionHandling::Dwarf)
return;
if (!shouldEmitMovesModule && !shouldEmitTableModule)
@@ -901,21 +918,20 @@ void DwarfException::EndModule() {
/// BeginFunction - Gather pre-function exception information. Assumes it's
/// being emitted immediately after the function entry point.
void DwarfException::BeginFunction(const MachineFunction *MF) {
- if (!MMI || !MAI->doesSupportExceptionHandling()) return;
-
TimeRegion Timer(ExceptionTimer);
- this->MF = MF;
shouldEmitTable = shouldEmitMoves = false;
// If any landing pads survive, we need an EH table.
shouldEmitTable = !MMI->getLandingPads().empty();
// See if we need frame move info.
- shouldEmitMoves = !MF->getFunction()->doesNotThrow() || UnwindTablesMandatory;
+ shouldEmitMoves =
+ !Asm->MF->getFunction()->doesNotThrow() || UnwindTablesMandatory;
if (shouldEmitMoves || shouldEmitTable)
// Assumes in correct section after the entry point.
- Asm->OutStreamer.EmitLabel(getDWLabel("eh_func_begin", ++SubprogramCount));
+ Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("eh_func_begin",
+ Asm->getFunctionNumber()));
shouldEmitTableModule |= shouldEmitTable;
shouldEmitMovesModule |= shouldEmitMoves;
@@ -927,7 +943,8 @@ void DwarfException::EndFunction() {
if (!shouldEmitMoves && !shouldEmitTable) return;
TimeRegion Timer(ExceptionTimer);
- Asm->OutStreamer.EmitLabel(getDWLabel("eh_func_end", SubprogramCount));
+ Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("eh_func_end",
+ Asm->getFunctionNumber()));
// Record if this personality index uses a landing pad.
bool HasLandingPad = !MMI->getLandingPads().empty();
@@ -941,14 +958,15 @@ void DwarfException::EndFunction() {
const TargetLoweringObjectFile &TLOF = Asm->getObjFileLowering();
MCSymbol *FunctionEHSym =
- Asm->GetSymbolWithGlobalValueBase(MF->getFunction(), ".eh",
+ Asm->GetSymbolWithGlobalValueBase(Asm->MF->getFunction(), ".eh",
TLOF.isFunctionEHFrameSymbolPrivate());
// Save EH frame information
- EHFrames.push_back(FunctionEHFrameInfo(FunctionEHSym, SubprogramCount,
+ EHFrames.push_back(FunctionEHFrameInfo(FunctionEHSym,
+ Asm->getFunctionNumber(),
MMI->getPersonalityIndex(),
- MF->getFrameInfo()->hasCalls(),
+ Asm->MF->getFrameInfo()->hasCalls(),
!MMI->getLandingPads().empty(),
MMI->getFrameMoves(),
- MF->getFunction()));
+ Asm->MF->getFunction()));
}
diff --git a/lib/CodeGen/AsmPrinter/DwarfException.h b/lib/CodeGen/AsmPrinter/DwarfException.h
index 4bc4a458c04e..f35c0b616c1f 100644
--- a/lib/CodeGen/AsmPrinter/DwarfException.h
+++ b/lib/CodeGen/AsmPrinter/DwarfException.h
@@ -14,25 +14,34 @@
#ifndef LLVM_CODEGEN_ASMPRINTER_DWARFEXCEPTION_H
#define LLVM_CODEGEN_ASMPRINTER_DWARFEXCEPTION_H
-#include "DIE.h"
-#include "DwarfPrinter.h"
-#include "llvm/CodeGen/AsmPrinter.h"
#include "llvm/ADT/DenseMap.h"
-#include <string>
+#include <vector>
namespace llvm {
+template <typename T> class SmallVectorImpl;
struct LandingPadInfo;
class MachineModuleInfo;
+class MachineMove;
+class MachineInstr;
+class MachineFunction;
class MCAsmInfo;
class MCExpr;
+class MCSymbol;
class Timer;
-class raw_ostream;
+class Function;
+class AsmPrinter;
//===----------------------------------------------------------------------===//
/// DwarfException - Emits Dwarf exception handling directives.
///
-class DwarfException : public DwarfPrinter {
+class DwarfException {
+ /// Asm - Target of Dwarf emission.
+ AsmPrinter *Asm;
+
+ /// MMI - Collected machine module information.
+ MachineModuleInfo *MMI;
+
struct FunctionEHFrameInfo {
MCSymbol *FunctionEHSym; // L_foo.eh
unsigned Number;
@@ -166,15 +175,8 @@ public:
//===--------------------------------------------------------------------===//
// Main entry points.
//
- DwarfException(raw_ostream &OS, AsmPrinter *A, const MCAsmInfo *T);
- virtual ~DwarfException();
-
- /// BeginModule - Emit all exception information that should come prior to the
- /// content.
- void BeginModule(Module *m, MachineModuleInfo *mmi) {
- this->M = m;
- this->MMI = mmi;
- }
+ DwarfException(AsmPrinter *A);
+ ~DwarfException();
/// EndModule - Emit all exception information that should come after the
/// content.
diff --git a/lib/CodeGen/AsmPrinter/DwarfPrinter.cpp b/lib/CodeGen/AsmPrinter/DwarfPrinter.cpp
deleted file mode 100644
index 17eb2e872742..000000000000
--- a/lib/CodeGen/AsmPrinter/DwarfPrinter.cpp
+++ /dev/null
@@ -1,308 +0,0 @@
-//===--- lib/CodeGen/DwarfPrinter.cpp - Dwarf Printer ---------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// Emit general DWARF directives.
-//
-//===----------------------------------------------------------------------===//
-
-#include "DwarfPrinter.h"
-#include "llvm/Module.h"
-#include "llvm/CodeGen/AsmPrinter.h"
-#include "llvm/CodeGen/MachineFrameInfo.h"
-#include "llvm/CodeGen/MachineFunction.h"
-#include "llvm/CodeGen/MachineModuleInfo.h"
-#include "llvm/MC/MCAsmInfo.h"
-#include "llvm/MC/MCContext.h"
-#include "llvm/MC/MCExpr.h"
-#include "llvm/MC/MCStreamer.h"
-#include "llvm/MC/MCSymbol.h"
-#include "llvm/Target/TargetData.h"
-#include "llvm/Target/TargetFrameInfo.h"
-#include "llvm/Target/TargetLoweringObjectFile.h"
-#include "llvm/Target/TargetRegisterInfo.h"
-#include "llvm/Support/Dwarf.h"
-#include "llvm/Support/ErrorHandling.h"
-#include "llvm/ADT/SmallString.h"
-using namespace llvm;
-
-DwarfPrinter::DwarfPrinter(raw_ostream &OS, AsmPrinter *A, const MCAsmInfo *T)
-: O(OS), Asm(A), MAI(T), TD(Asm->TM.getTargetData()),
- RI(Asm->TM.getRegisterInfo()), M(NULL), MF(NULL), MMI(NULL),
- SubprogramCount(0) {}
-
-
-/// getDWLabel - Return the MCSymbol corresponding to the assembler temporary
-/// label with the specified stem and unique ID.
-MCSymbol *DwarfPrinter::getDWLabel(const char *Name, unsigned ID) const {
- // FIXME: REMOVE this. However, there is stuff in EH that passes counters in
- // here that can be zero.
-
- //assert(ID && "Should use getTempLabel if no ID");
- if (ID == 0) return getTempLabel(Name);
- return Asm->OutContext.GetOrCreateSymbol
- (Twine(MAI->getPrivateGlobalPrefix()) + Twine(Name) + Twine(ID));
-}
-
-/// getTempLabel - Return the MCSymbol corresponding to the assembler temporary
-/// label with the specified name.
-MCSymbol *DwarfPrinter::getTempLabel(const char *Name) const {
- return Asm->OutContext.GetOrCreateSymbol
- (Twine(MAI->getPrivateGlobalPrefix()) + Name);
-}
-
-
-/// SizeOfEncodedValue - Return the size of the encoding in bytes.
-unsigned DwarfPrinter::SizeOfEncodedValue(unsigned Encoding) const {
- if (Encoding == dwarf::DW_EH_PE_omit)
- return 0;
-
- switch (Encoding & 0x07) {
- case dwarf::DW_EH_PE_absptr:
- return TD->getPointerSize();
- case dwarf::DW_EH_PE_udata2:
- return 2;
- case dwarf::DW_EH_PE_udata4:
- return 4;
- case dwarf::DW_EH_PE_udata8:
- return 8;
- }
-
- assert(0 && "Invalid encoded value.");
- return 0;
-}
-
-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()) {
- // FIXME: MCize.
- 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,
- unsigned PadTo) const {
- if (Asm->VerboseAsm && Desc)
- Asm->OutStreamer.AddComment(Desc);
-
- if (MAI->hasLEB128() && PadTo == 0) {
- // FIXME: MCize.
- O << "\t.uleb128\t" << Value;
- Asm->OutStreamer.AddBlankLine();
- return;
- }
-
- // If we don't have .uleb128 or we want to emit padding, emit as .bytes.
- do {
- unsigned char Byte = static_cast<unsigned char>(Value & 0x7f);
- Value >>= 7;
- if (Value || PadTo != 0) Byte |= 0x80;
- Asm->OutStreamer.EmitIntValue(Byte, 1, /*addrspace*/0);
- } while (Value);
-
- if (PadTo) {
- if (PadTo > 1)
- Asm->OutStreamer.EmitFill(PadTo - 1, 0x80/*fillval*/, 0/*addrspace*/);
- Asm->OutStreamer.EmitFill(1, 0/*fillval*/, 0/*addrspace*/);
- }
-}
-
-
-void DwarfPrinter::EmitReference(const MCSymbol *Sym, unsigned Encoding) const {
- const TargetLoweringObjectFile &TLOF = Asm->getObjFileLowering();
-
- const MCExpr *Exp = TLOF.getExprForDwarfReference(Sym, Asm->Mang,
- Asm->MMI, Encoding,
- Asm->OutStreamer);
- Asm->OutStreamer.EmitValue(Exp, SizeOfEncodedValue(Encoding), /*addrspace*/0);
-}
-
-void DwarfPrinter::EmitReference(const GlobalValue *GV, unsigned Encoding)const{
- const TargetLoweringObjectFile &TLOF = Asm->getObjFileLowering();
-
- const MCExpr *Exp =
- TLOF.getExprForDwarfGlobalReference(GV, Asm->Mang, Asm->MMI, Encoding,
- Asm->OutStreamer);
- Asm->OutStreamer.EmitValue(Exp, SizeOfEncodedValue(Encoding), /*addrspace*/0);
-}
-
-/// EmitDifference - Emit the difference between two labels. If this assembler
-/// supports .set, we emit a .set of a temporary and then use it in the .word.
-void DwarfPrinter::EmitDifference(const MCSymbol *TagHi, const MCSymbol *TagLo,
- bool IsSmall) {
- unsigned Size = IsSmall ? 4 : TD->getPointerSize();
- Asm->EmitLabelDifference(TagHi, TagLo, Size);
-}
-
-void DwarfPrinter::EmitSectionOffset(const MCSymbol *Label,
- const MCSymbol *Section,
- bool IsSmall, bool isEH) {
- bool isAbsolute;
- if (isEH)
- isAbsolute = MAI->isAbsoluteEHSectionOffsets();
- else
- isAbsolute = MAI->isAbsoluteDebugSectionOffsets();
-
- if (!isAbsolute)
- return EmitDifference(Label, Section, IsSmall);
-
- // On COFF targets, we have to emit the weird .secrel32 directive.
- if (const char *SecOffDir = MAI->getDwarfSectionOffsetDirective()) {
- // FIXME: MCize.
- Asm->O << SecOffDir << Label->getName();
- Asm->OutStreamer.AddBlankLine();
- } else {
- unsigned Size = IsSmall ? 4 : TD->getPointerSize();
- Asm->OutStreamer.EmitSymbolValue(Label, Size, 0/*AddrSpace*/);
- }
-}
-
-/// EmitFrameMoves - Emit frame instructions to describe the layout of the
-/// frame.
-void DwarfPrinter::EmitFrameMoves(MCSymbol *BaseLabel,
- const std::vector<MachineMove> &Moves,
- bool isEH) {
- int stackGrowth = TD->getPointerSize();
- if (Asm->TM.getFrameInfo()->getStackGrowthDirection() !=
- TargetFrameInfo::StackGrowsUp)
- stackGrowth *= -1;
-
- for (unsigned i = 0, N = Moves.size(); i < N; ++i) {
- const MachineMove &Move = Moves[i];
- MCSymbol *Label = Move.getLabel();
- // Throw out move if the label is invalid.
- if (Label && !Label->isDefined()) continue; // Not emitted, in dead code.
-
- const MachineLocation &Dst = Move.getDestination();
- const MachineLocation &Src = Move.getSource();
-
- // Advance row if new location.
- if (BaseLabel && Label) {
- MCSymbol *ThisSym = Label;
- if (ThisSym != BaseLabel) {
- EmitCFAByte(dwarf::DW_CFA_advance_loc4);
- EmitDifference(ThisSym, BaseLabel, true);
- BaseLabel = ThisSym;
- }
- }
-
- // If advancing cfa.
- if (Dst.isReg() && Dst.getReg() == MachineLocation::VirtualFP) {
- if (!Src.isReg()) {
- if (Src.getReg() == MachineLocation::VirtualFP) {
- EmitCFAByte(dwarf::DW_CFA_def_cfa_offset);
- } else {
- EmitCFAByte(dwarf::DW_CFA_def_cfa);
- EmitULEB128(RI->getDwarfRegNum(Src.getReg(), isEH), "Register");
- }
-
- int Offset = -Src.getOffset();
- EmitULEB128(Offset, "Offset");
- } else {
- llvm_unreachable("Machine move not supported yet.");
- }
- } else if (Src.isReg() &&
- Src.getReg() == MachineLocation::VirtualFP) {
- if (Dst.isReg()) {
- EmitCFAByte(dwarf::DW_CFA_def_cfa_register);
- EmitULEB128(RI->getDwarfRegNum(Dst.getReg(), isEH), "Register");
- } else {
- llvm_unreachable("Machine move not supported yet.");
- }
- } else {
- unsigned Reg = RI->getDwarfRegNum(Src.getReg(), isEH);
- int Offset = Dst.getOffset() / stackGrowth;
-
- if (Offset < 0) {
- EmitCFAByte(dwarf::DW_CFA_offset_extended_sf);
- EmitULEB128(Reg, "Reg");
- EmitSLEB128(Offset, "Offset");
- } else if (Reg < 64) {
- EmitCFAByte(dwarf::DW_CFA_offset + Reg);
- EmitULEB128(Offset, "Offset");
- } else {
- 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
deleted file mode 100644
index 0b94645a8c7b..000000000000
--- a/lib/CodeGen/AsmPrinter/DwarfPrinter.h
+++ /dev/null
@@ -1,131 +0,0 @@
-//===--- lib/CodeGen/DwarfPrinter.h - Dwarf Printer -------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// Emit general DWARF directives.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef CODEGEN_ASMPRINTER_DWARFPRINTER_H__
-#define CODEGEN_ASMPRINTER_DWARFPRINTER_H__
-
-#include "llvm/CodeGen/MachineLocation.h"
-#include "llvm/Support/Compiler.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 GlobalValue;
-class MCSymbol;
-class Twine;
-
-class DwarfPrinter {
-protected:
- ~DwarfPrinter() {}
-
- //===-------------------------------------------------------------==---===//
- // 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.
- const MachineFunction *MF;
-
- /// MMI - Collected machine module information.
- MachineModuleInfo *MMI;
-
- /// SubprogramCount - The running count of functions being compiled.
- unsigned SubprogramCount;
-
- DwarfPrinter(raw_ostream &OS, AsmPrinter *A, const MCAsmInfo *T);
-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; }
-
- /// getDWLabel - Return the MCSymbol corresponding to the assembler temporary
- /// label with the specified stem and unique ID.
- MCSymbol *getDWLabel(const char *Name, unsigned ID) const;
-
- /// getTempLabel - Return an assembler temporary label with the specified
- /// name.
- MCSymbol *getTempLabel(const char *Name) const;
-
- /// SizeOfEncodedValue - Return the size of the encoding in bytes.
- unsigned SizeOfEncodedValue(unsigned Encoding) const;
-
- /// 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,
- unsigned PadTo = 0) const;
-
-
- /// EmitReference - Emit a reference to a label.
- ///
- void EmitReference(const MCSymbol *Sym, unsigned Encoding) const;
- void EmitReference(const GlobalValue *GV, unsigned Encoding) const;
-
- /// EmitDifference - Emit the difference between two labels.
- void EmitDifference(const MCSymbol *LabelHi, const MCSymbol *LabelLo,
- bool IsSmall = false);
-
- /// EmitSectionOffset - Emit Label-Section or use a special purpose directive
- /// to emit a section offset if the target has one.
- void EmitSectionOffset(const MCSymbol *Label, const MCSymbol *Section,
- bool IsSmall = false, bool isEH = false);
-
- /// EmitFrameMoves - Emit frame instructions to describe the layout of the
- /// frame.
- void EmitFrameMoves(MCSymbol *BaseLabel,
- const std::vector<MachineMove> &Moves, bool isEH);
-};
-
-} // end llvm namespace
-
-#endif
diff --git a/lib/CodeGen/AsmPrinter/DwarfWriter.cpp b/lib/CodeGen/AsmPrinter/DwarfWriter.cpp
deleted file mode 100644
index a2d7ab1224ee..000000000000
--- a/lib/CodeGen/AsmPrinter/DwarfWriter.cpp
+++ /dev/null
@@ -1,87 +0,0 @@
-//===-- llvm/CodeGen/DwarfWriter.cpp - Dwarf Framework --------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file contains support for writing dwarf info into asm files.
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/CodeGen/DwarfWriter.h"
-#include "DwarfDebug.h"
-#include "DwarfException.h"
-#include "llvm/CodeGen/MachineModuleInfo.h"
-
-using namespace llvm;
-
-static RegisterPass<DwarfWriter>
-X("dwarfwriter", "DWARF Information Writer");
-char DwarfWriter::ID = 0;
-
-//===----------------------------------------------------------------------===//
-/// DwarfWriter Implementation
-///
-
-DwarfWriter::DwarfWriter()
- : ImmutablePass(&ID), DD(0), DE(0) {}
-
-DwarfWriter::~DwarfWriter() {
- delete DE;
- delete DD;
-}
-
-/// BeginModule - Emit all Dwarf sections that should come prior to the
-/// content.
-void DwarfWriter::BeginModule(Module *M,
- MachineModuleInfo *MMI,
- raw_ostream &OS, AsmPrinter *A,
- const MCAsmInfo *T) {
- DE = new DwarfException(OS, A, T);
- DD = new DwarfDebug(OS, A, T);
- DE->BeginModule(M, MMI);
- DD->beginModule(M, MMI);
-}
-
-/// EndModule - Emit all Dwarf sections that should come after the content.
-///
-void DwarfWriter::EndModule() {
- DE->EndModule();
- DD->endModule();
- delete DD; DD = 0;
- delete DE; DE = 0;
-}
-
-/// BeginFunction - Gather pre-function debug information. Assumes being
-/// emitted immediately after the function entry point.
-void DwarfWriter::BeginFunction(const MachineFunction *MF) {
- DE->BeginFunction(MF);
- DD->beginFunction(MF);
-}
-
-/// EndFunction - Gather and emit post-function debug information.
-///
-void DwarfWriter::EndFunction(const MachineFunction *MF) {
- DD->endFunction(MF);
- DE->EndFunction();
-
- if (MachineModuleInfo *MMI = DD->getMMI() ? DD->getMMI() : DE->getMMI())
- // Clear function debug information.
- MMI->EndFunction();
-}
-
-/// ShouldEmitDwarfDebug - Returns true if Dwarf debugging declarations should
-/// be emitted.
-bool DwarfWriter::ShouldEmitDwarfDebug() const {
- return DD && DD->ShouldEmitDwarfDebug();
-}
-
-void DwarfWriter::BeginScope(const MachineInstr *MI) {
- DD->beginScope(MI);
-}
-void DwarfWriter::EndScope(const MachineInstr *MI) {
- DD->endScope(MI);
-}
diff --git a/lib/CodeGen/AsmPrinter/OcamlGCPrinter.cpp b/lib/CodeGen/AsmPrinter/OcamlGCPrinter.cpp
index fa840e133a5e..1db178f020ec 100644
--- a/lib/CodeGen/AsmPrinter/OcamlGCPrinter.cpp
+++ b/lib/CodeGen/AsmPrinter/OcamlGCPrinter.cpp
@@ -16,11 +16,14 @@
#include "llvm/CodeGen/GCMetadataPrinter.h"
#include "llvm/Module.h"
#include "llvm/MC/MCAsmInfo.h"
+#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCSymbol.h"
#include "llvm/MC/MCStreamer.h"
+#include "llvm/Target/Mangler.h"
#include "llvm/Target/TargetData.h"
#include "llvm/Target/TargetLoweringObjectFile.h"
#include "llvm/Target/TargetMachine.h"
+#include "llvm/ADT/SmallString.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/FormattedStream.h"
using namespace llvm;
@@ -29,11 +32,8 @@ namespace {
class OcamlGCMetadataPrinter : public GCMetadataPrinter {
public:
- void beginAssembly(raw_ostream &OS, AsmPrinter &AP,
- const MCAsmInfo &MAI);
-
- void finishAssembly(raw_ostream &OS, AsmPrinter &AP,
- const MCAsmInfo &MAI);
+ void beginAssembly(AsmPrinter &AP);
+ void finishAssembly(AsmPrinter &AP);
};
}
@@ -43,33 +43,34 @@ Y("ocaml", "ocaml 3.10-compatible collector");
void llvm::linkOcamlGCPrinter() { }
-static void EmitCamlGlobal(const Module &M, raw_ostream &OS, AsmPrinter &AP,
- const MCAsmInfo &MAI, const char *Id) {
+static void EmitCamlGlobal(const Module &M, AsmPrinter &AP, const char *Id) {
const std::string &MId = M.getModuleIdentifier();
- std::string Mangled;
- Mangled += MAI.getGlobalPrefix();
- Mangled += "caml";
- size_t Letter = Mangled.size();
- Mangled.append(MId.begin(), std::find(MId.begin(), MId.end(), '.'));
- Mangled += "__";
- Mangled += Id;
-
+ std::string SymName;
+ SymName += "caml";
+ size_t Letter = SymName.size();
+ SymName.append(MId.begin(), std::find(MId.begin(), MId.end(), '.'));
+ SymName += "__";
+ SymName += Id;
+
// Capitalize the first letter of the module name.
- Mangled[Letter] = toupper(Mangled[Letter]);
-
- if (const char *GlobalDirective = MAI.getGlobalDirective())
- OS << GlobalDirective << Mangled << "\n";
- OS << Mangled << ":\n";
+ SymName[Letter] = toupper(SymName[Letter]);
+
+ SmallString<128> TmpStr;
+ AP.Mang->getNameWithPrefix(TmpStr, SymName);
+
+ MCSymbol *Sym = AP.OutContext.GetOrCreateSymbol(TmpStr);
+
+ AP.OutStreamer.EmitSymbolAttribute(Sym, MCSA_Global);
+ AP.OutStreamer.EmitLabel(Sym);
}
-void OcamlGCMetadataPrinter::beginAssembly(raw_ostream &OS, AsmPrinter &AP,
- const MCAsmInfo &MAI) {
+void OcamlGCMetadataPrinter::beginAssembly(AsmPrinter &AP) {
AP.OutStreamer.SwitchSection(AP.getObjFileLowering().getTextSection());
- EmitCamlGlobal(getModule(), OS, AP, MAI, "code_begin");
+ EmitCamlGlobal(getModule(), AP, "code_begin");
AP.OutStreamer.SwitchSection(AP.getObjFileLowering().getDataSection());
- EmitCamlGlobal(getModule(), OS, AP, MAI, "data_begin");
+ EmitCamlGlobal(getModule(), AP, "data_begin");
}
/// emitAssembly - Print the frametable. The ocaml frametable format is thus:
@@ -88,28 +89,20 @@ void OcamlGCMetadataPrinter::beginAssembly(raw_ostream &OS, AsmPrinter &AP,
/// (FrameSize and LiveOffsets would overflow). FrameTablePrinter will abort if
/// either condition is detected in a function which uses the GC.
///
-void OcamlGCMetadataPrinter::finishAssembly(raw_ostream &OS, AsmPrinter &AP,
- const MCAsmInfo &MAI) {
- const char *AddressDirective;
- int AddressAlignLog;
- if (AP.TM.getTargetData()->getPointerSize() == sizeof(int32_t)) {
- AddressDirective = MAI.getData32bitsDirective();
- AddressAlignLog = 2;
- } else {
- AddressDirective = MAI.getData64bitsDirective();
- AddressAlignLog = 3;
- }
+void OcamlGCMetadataPrinter::finishAssembly(AsmPrinter &AP) {
+ unsigned IntPtrSize = AP.TM.getTargetData()->getPointerSize();
AP.OutStreamer.SwitchSection(AP.getObjFileLowering().getTextSection());
- EmitCamlGlobal(getModule(), OS, AP, MAI, "code_end");
+ EmitCamlGlobal(getModule(), AP, "code_end");
AP.OutStreamer.SwitchSection(AP.getObjFileLowering().getDataSection());
- EmitCamlGlobal(getModule(), OS, AP, MAI, "data_end");
+ EmitCamlGlobal(getModule(), AP, "data_end");
- OS << AddressDirective << 0 << '\n'; // FIXME: Why does ocaml emit this??
+ // FIXME: Why does ocaml emit this??
+ AP.OutStreamer.EmitIntValue(0, IntPtrSize, 0);
AP.OutStreamer.SwitchSection(AP.getObjFileLowering().getDataSection());
- EmitCamlGlobal(getModule(), OS, AP, MAI, "frametable");
+ EmitCamlGlobal(getModule(), AP, "frametable");
for (iterator I = begin(), IE = end(); I != IE; ++I) {
GCFunctionInfo &FI = **I;
@@ -125,8 +118,9 @@ void OcamlGCMetadataPrinter::finishAssembly(raw_ostream &OS, AsmPrinter &AP,
llvm_report_error(Msg.str()); // Very rude!
}
- OS << "\t" << MAI.getCommentString() << " live roots for "
- << FI.getFunction().getName() << "\n";
+ AP.OutStreamer.AddComment("live roots for " +
+ Twine(FI.getFunction().getName()));
+ AP.OutStreamer.AddBlankLine();
for (GCFunctionInfo::iterator J = FI.begin(), JE = FI.end(); J != JE; ++J) {
size_t LiveCount = FI.live_size(J);
@@ -139,10 +133,8 @@ void OcamlGCMetadataPrinter::finishAssembly(raw_ostream &OS, AsmPrinter &AP,
llvm_report_error(Msg.str()); // Very rude!
}
- OS << AddressDirective << J->Label->getName() << '\n';
-
+ AP.OutStreamer.EmitSymbolValue(J->Label, IntPtrSize, 0);
AP.EmitInt16(FrameSize);
-
AP.EmitInt16(LiveCount);
for (GCFunctionInfo::live_iterator K = FI.live_begin(J),
@@ -154,7 +146,7 @@ void OcamlGCMetadataPrinter::finishAssembly(raw_ostream &OS, AsmPrinter &AP,
AP.EmitInt32(K->StackOffset);
}
- AP.EmitAlignment(AddressAlignLog);
+ AP.EmitAlignment(IntPtrSize == 4 ? 2 : 3);
}
}
}
diff --git a/lib/CodeGen/GCMetadataPrinter.cpp b/lib/CodeGen/GCMetadataPrinter.cpp
index 752752f71ba3..f80e9ced0bc9 100644
--- a/lib/CodeGen/GCMetadataPrinter.cpp
+++ b/lib/CodeGen/GCMetadataPrinter.cpp
@@ -18,12 +18,10 @@ GCMetadataPrinter::GCMetadataPrinter() { }
GCMetadataPrinter::~GCMetadataPrinter() { }
-void GCMetadataPrinter::beginAssembly(raw_ostream &OS, AsmPrinter &AP,
- const MCAsmInfo &MAI) {
+void GCMetadataPrinter::beginAssembly(AsmPrinter &AP) {
// Default is no action.
}
-void GCMetadataPrinter::finishAssembly(raw_ostream &OS, AsmPrinter &AP,
- const MCAsmInfo &MAI) {
+void GCMetadataPrinter::finishAssembly(AsmPrinter &AP) {
// Default is no action.
}
diff --git a/lib/CodeGen/LLVMTargetMachine.cpp b/lib/CodeGen/LLVMTargetMachine.cpp
index 75e45efe4de1..ed57f4cb101f 100644
--- a/lib/CodeGen/LLVMTargetMachine.cpp
+++ b/lib/CodeGen/LLVMTargetMachine.cpp
@@ -123,18 +123,15 @@ bool LLVMTargetMachine::addPassesToEmitFile(PassManagerBase &PM,
const MCAsmInfo &MAI = *getMCAsmInfo();
OwningPtr<MCStreamer> AsmStreamer;
- formatted_raw_ostream *LegacyOutput;
switch (FileType) {
default: return true;
case CGFT_AssemblyFile: {
MCInstPrinter *InstPrinter =
- getTarget().createMCInstPrinter(MAI.getAssemblerDialect(), MAI, Out);
+ getTarget().createMCInstPrinter(MAI.getAssemblerDialect(), MAI);
AsmStreamer.reset(createAsmStreamer(*Context, Out,
getTargetData()->isLittleEndian(),
getVerboseAsm(), InstPrinter,
/*codeemitter*/0));
- // Set the AsmPrinter's "O" to the output file.
- LegacyOutput = &Out;
break;
}
case CGFT_ObjectFile: {
@@ -146,29 +143,17 @@ bool LLVMTargetMachine::addPassesToEmitFile(PassManagerBase &PM,
return true;
AsmStreamer.reset(createMachOStreamer(*Context, *TAB, Out, MCE));
-
- // Any output to the asmprinter's "O" stream is bad and needs to be fixed,
- // force it to come out stderr.
- // FIXME: this is horrible and leaks, eventually remove the raw_ostream from
- // asmprinter.
- LegacyOutput = new formatted_raw_ostream(errs());
break;
}
case CGFT_Null:
// The Null output is intended for use for performance analysis and testing,
// not real users.
AsmStreamer.reset(createNullStreamer(*Context));
- // Any output to the asmprinter's "O" stream is bad and needs to be fixed,
- // force it to come out stderr.
- // FIXME: this is horrible and leaks, eventually remove the raw_ostream from
- // asmprinter.
- LegacyOutput = new formatted_raw_ostream(errs());
break;
}
// Create the AsmPrinter, which takes ownership of AsmStreamer if successful.
- FunctionPass *Printer =
- getTarget().createAsmPrinter(*LegacyOutput, *this, *AsmStreamer);
+ FunctionPass *Printer = getTarget().createAsmPrinter(*this, *AsmStreamer);
if (Printer == 0)
return true;
diff --git a/lib/CodeGen/MachineFunction.cpp b/lib/CodeGen/MachineFunction.cpp
index beac0c630bb5..e4ed7dbac4e7 100644
--- a/lib/CodeGen/MachineFunction.cpp
+++ b/lib/CodeGen/MachineFunction.cpp
@@ -23,6 +23,7 @@
#include "llvm/CodeGen/MachineFrameInfo.h"
#include "llvm/CodeGen/MachineInstr.h"
#include "llvm/CodeGen/MachineJumpTableInfo.h"
+#include "llvm/CodeGen/MachineModuleInfo.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/CodeGen/Passes.h"
#include "llvm/MC/MCAsmInfo.h"
@@ -51,8 +52,8 @@ void ilist_traits<MachineBasicBlock>::deleteNode(MachineBasicBlock *MBB) {
}
MachineFunction::MachineFunction(Function *F, const TargetMachine &TM,
- unsigned FunctionNum, MCContext &ctx)
- : Fn(F), Target(TM), Ctx(ctx) {
+ unsigned FunctionNum, MachineModuleInfo &mmi)
+ : Fn(F), Target(TM), Ctx(mmi.getContext()), MMI(mmi) {
if (TM.getRegisterInfo())
RegInfo = new (Allocator) MachineRegisterInfo(*TM.getRegisterInfo());
else
diff --git a/lib/CodeGen/MachineFunctionAnalysis.cpp b/lib/CodeGen/MachineFunctionAnalysis.cpp
index d3f1d8296daa..3b2eb6d388b4 100644
--- a/lib/CodeGen/MachineFunctionAnalysis.cpp
+++ b/lib/CodeGen/MachineFunctionAnalysis.cpp
@@ -35,10 +35,23 @@ MachineFunctionAnalysis::~MachineFunctionAnalysis() {
assert(!MF && "MachineFunctionAnalysis left initialized!");
}
+void MachineFunctionAnalysis::getAnalysisUsage(AnalysisUsage &AU) const {
+ AU.setPreservesAll();
+ AU.addRequired<MachineModuleInfo>();
+}
+
+bool MachineFunctionAnalysis::doInitialization(Module &M) {
+ MachineModuleInfo *MMI = getAnalysisIfAvailable<MachineModuleInfo>();
+ assert(MMI && "MMI not around yet??");
+ MMI->setModule(&M);
+ NextFnNum = 1; return false;
+}
+
+
bool MachineFunctionAnalysis::runOnFunction(Function &F) {
assert(!MF && "MachineFunctionAnalysis already initialized!");
MF = new MachineFunction(&F, TM, NextFnNum++,
- getAnalysis<MachineModuleInfo>().getContext());
+ getAnalysis<MachineModuleInfo>());
return false;
}
@@ -46,8 +59,3 @@ void MachineFunctionAnalysis::releaseMemory() {
delete MF;
MF = 0;
}
-
-void MachineFunctionAnalysis::getAnalysisUsage(AnalysisUsage &AU) const {
- AU.setPreservesAll();
- AU.addRequired<MachineModuleInfo>();
-}
diff --git a/lib/CodeGen/MachineModuleInfo.cpp b/lib/CodeGen/MachineModuleInfo.cpp
index ad4f01b7a9ad..f813a553670b 100644
--- a/lib/CodeGen/MachineModuleInfo.cpp
+++ b/lib/CodeGen/MachineModuleInfo.cpp
@@ -262,6 +262,7 @@ MachineModuleInfo::MachineModuleInfo(const MCAsmInfo &MAI)
// Always emit some info, by default "no personality" info.
Personalities.push_back(NULL);
AddrLabelSymbols = 0;
+ TheModule = 0;
}
MachineModuleInfo::MachineModuleInfo()
diff --git a/lib/CodeGen/MachineSink.cpp b/lib/CodeGen/MachineSink.cpp
index e47ba7c2cc37..e65961901578 100644
--- a/lib/CodeGen/MachineSink.cpp
+++ b/lib/CodeGen/MachineSink.cpp
@@ -126,6 +126,11 @@ bool MachineSinking::ProcessBlock(MachineBasicBlock &MBB) {
// Can't sink anything out of a block that has less than two successors.
if (MBB.succ_size() <= 1 || MBB.empty()) return false;
+ // Don't bother sinking code out of unreachable blocks. In addition to being
+ // unprofitable, it can also lead to infinite looping, because in an unreachable
+ // loop there may be nowhere to stop.
+ if (!DT->isReachableFromEntry(&MBB)) return false;
+
bool MadeChange = false;
// Walk the basic block bottom-up. Remember if we saw a store.
diff --git a/lib/CodeGen/PrologEpilogInserter.cpp b/lib/CodeGen/PrologEpilogInserter.cpp
index 2d54cd427418..27cb566d9512 100644
--- a/lib/CodeGen/PrologEpilogInserter.cpp
+++ b/lib/CodeGen/PrologEpilogInserter.cpp
@@ -24,7 +24,6 @@
#include "llvm/CodeGen/MachineLoopInfo.h"
#include "llvm/CodeGen/MachineInstr.h"
#include "llvm/CodeGen/MachineFrameInfo.h"
-#include "llvm/CodeGen/MachineModuleInfo.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/CodeGen/RegisterScavenging.h"
#include "llvm/Target/TargetMachine.h"
@@ -59,11 +58,6 @@ bool PEI::runOnMachineFunction(MachineFunction &Fn) {
FrameIndexVirtualScavenging = TRI->requiresFrameIndexScavenging(Fn);
FrameConstantRegMap.clear();
- // Get MachineModuleInfo so that we can track the construction of the
- // frame.
- if (MachineModuleInfo *MMI = getAnalysisIfAvailable<MachineModuleInfo>())
- Fn.getFrameInfo()->setMachineModuleInfo(MMI);
-
// Calculate the MaxCallFrameSize and HasCalls variables for the function's
// frame information. Also eliminates call frame pseudo instructions.
calculateCallsInformation(Fn);
diff --git a/lib/CodeGen/SelectionDAG/FastISel.cpp b/lib/CodeGen/SelectionDAG/FastISel.cpp
index d6f8a205c1f6..4bf41f28c250 100644
--- a/lib/CodeGen/SelectionDAG/FastISel.cpp
+++ b/lib/CodeGen/SelectionDAG/FastISel.cpp
@@ -47,7 +47,6 @@
#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/CodeGen/MachineModuleInfo.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
-#include "llvm/CodeGen/DwarfWriter.h"
#include "llvm/Analysis/DebugInfo.h"
#include "llvm/Target/TargetData.h"
#include "llvm/Target/TargetInstrInfo.h"
@@ -326,8 +325,8 @@ bool FastISel::SelectCall(User *I) {
default: break;
case Intrinsic::dbg_declare: {
DbgDeclareInst *DI = cast<DbgDeclareInst>(I);
- if (!DIDescriptor::ValidDebugInfo(DI->getVariable(), CodeGenOpt::None)||!DW
- || !DW->ShouldEmitDwarfDebug())
+ if (!DIDescriptor::ValidDebugInfo(DI->getVariable(), CodeGenOpt::None) ||
+ !MF.getMMI().hasDebugInfo())
return true;
Value *Address = DI->getAddress();
@@ -341,7 +340,7 @@ bool FastISel::SelectCall(User *I) {
if (SI == StaticAllocaMap.end()) break; // VLAs.
int FI = SI->second;
if (!DI->getDebugLoc().isUnknown())
- MMI->setVariableDbgInfo(DI->getVariable(), FI, DI->getDebugLoc());
+ MF.getMMI().setVariableDbgInfo(DI->getVariable(), FI, DI->getDebugLoc());
// Building the map above is target independent. Generating DBG_VALUE
// inline is target dependent; do this now.
@@ -400,44 +399,39 @@ bool FastISel::SelectCall(User *I) {
switch (TLI.getOperationAction(ISD::EHSELECTION, VT)) {
default: break;
case TargetLowering::Expand: {
- if (MMI) {
- if (MBB->isLandingPad())
- AddCatchInfo(*cast<CallInst>(I), MMI, MBB);
- else {
+ if (MBB->isLandingPad())
+ AddCatchInfo(*cast<CallInst>(I), &MF.getMMI(), MBB);
+ else {
#ifndef NDEBUG
- CatchInfoLost.insert(cast<CallInst>(I));
+ CatchInfoLost.insert(cast<CallInst>(I));
#endif
- // FIXME: Mark exception selector register as live in. Hack for PR1508.
- unsigned Reg = TLI.getExceptionSelectorRegister();
- if (Reg) MBB->addLiveIn(Reg);
- }
-
+ // FIXME: Mark exception selector register as live in. Hack for PR1508.
unsigned Reg = TLI.getExceptionSelectorRegister();
- EVT SrcVT = TLI.getPointerTy();
- const TargetRegisterClass *RC = TLI.getRegClassFor(SrcVT);
- unsigned ResultReg = createResultReg(RC);
- bool InsertedCopy = TII.copyRegToReg(*MBB, MBB->end(), ResultReg, Reg,
- RC, RC);
- assert(InsertedCopy && "Can't copy address registers!");
- InsertedCopy = InsertedCopy;
-
- // Cast the register to the type of the selector.
- if (SrcVT.bitsGT(MVT::i32))
- ResultReg = FastEmit_r(SrcVT.getSimpleVT(), MVT::i32, ISD::TRUNCATE,
- ResultReg);
- else if (SrcVT.bitsLT(MVT::i32))
- ResultReg = FastEmit_r(SrcVT.getSimpleVT(), MVT::i32,
- ISD::SIGN_EXTEND, ResultReg);
- if (ResultReg == 0)
- // Unhandled operand. Halt "fast" selection and bail.
- return false;
-
- UpdateValueMap(I, ResultReg);
- } else {
- unsigned ResultReg =
- getRegForValue(Constant::getNullValue(I->getType()));
- UpdateValueMap(I, ResultReg);
+ if (Reg) MBB->addLiveIn(Reg);
}
+
+ unsigned Reg = TLI.getExceptionSelectorRegister();
+ EVT SrcVT = TLI.getPointerTy();
+ const TargetRegisterClass *RC = TLI.getRegClassFor(SrcVT);
+ unsigned ResultReg = createResultReg(RC);
+ bool InsertedCopy = TII.copyRegToReg(*MBB, MBB->end(), ResultReg, Reg,
+ RC, RC);
+ assert(InsertedCopy && "Can't copy address registers!");
+ InsertedCopy = InsertedCopy;
+
+ // Cast the register to the type of the selector.
+ if (SrcVT.bitsGT(MVT::i32))
+ ResultReg = FastEmit_r(SrcVT.getSimpleVT(), MVT::i32, ISD::TRUNCATE,
+ ResultReg);
+ else if (SrcVT.bitsLT(MVT::i32))
+ ResultReg = FastEmit_r(SrcVT.getSimpleVT(), MVT::i32,
+ ISD::SIGN_EXTEND, ResultReg);
+ if (ResultReg == 0)
+ // Unhandled operand. Halt "fast" selection and bail.
+ return false;
+
+ UpdateValueMap(I, ResultReg);
+
return true;
}
}
@@ -734,8 +728,6 @@ FastISel::SelectOperator(User *I, unsigned Opcode) {
}
FastISel::FastISel(MachineFunction &mf,
- MachineModuleInfo *mmi,
- DwarfWriter *dw,
DenseMap<const Value *, unsigned> &vm,
DenseMap<const BasicBlock *, MachineBasicBlock *> &bm,
DenseMap<const AllocaInst *, int> &am
@@ -751,8 +743,6 @@ FastISel::FastISel(MachineFunction &mf,
CatchInfoLost(cil),
#endif
MF(mf),
- MMI(mmi),
- DW(dw),
MRI(MF.getRegInfo()),
MFI(*MF.getFrameInfo()),
MCP(*MF.getConstantPool()),
diff --git a/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp b/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
index 63ca8e67000e..d35f0da393e4 100644
--- a/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
+++ b/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
@@ -16,7 +16,6 @@
#include "llvm/CodeGen/MachineFrameInfo.h"
#include "llvm/CodeGen/MachineJumpTableInfo.h"
#include "llvm/CodeGen/MachineModuleInfo.h"
-#include "llvm/CodeGen/DwarfWriter.h"
#include "llvm/Analysis/DebugInfo.h"
#include "llvm/CodeGen/PseudoSourceValue.h"
#include "llvm/Target/TargetFrameInfo.h"
diff --git a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
index 3643ea7c5315..8c0554d186d9 100644
--- a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
+++ b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
@@ -793,7 +793,7 @@ unsigned SelectionDAG::getEVTAlignment(EVT VT) const {
// EntryNode could meaningfully have debug info if we can find it...
SelectionDAG::SelectionDAG(TargetLowering &tli, FunctionLoweringInfo &fli)
- : TLI(tli), FLI(fli), DW(0),
+ : TLI(tli), FLI(fli),
EntryNode(ISD::EntryToken, DebugLoc(), getVTList(MVT::Other)),
Root(getEntryNode()), Ordering(0) {
AllNodes.push_back(&EntryNode);
@@ -801,11 +801,8 @@ SelectionDAG::SelectionDAG(TargetLowering &tli, FunctionLoweringInfo &fli)
DbgInfo = new SDDbgInfo();
}
-void SelectionDAG::init(MachineFunction &mf, MachineModuleInfo *mmi,
- DwarfWriter *dw) {
+void SelectionDAG::init(MachineFunction &mf) {
MF = &mf;
- MMI = mmi;
- DW = dw;
Context = &mf.getFunction()->getContext();
}
@@ -2258,8 +2255,7 @@ bool SelectionDAG::isVerifiedDebugInfoDesc(SDValue Op) const {
if (GA->getOffset() != 0) return false;
GlobalVariable *GV = dyn_cast<GlobalVariable>(GA->getGlobal());
if (!GV) return false;
- MachineModuleInfo *MMI = getMachineModuleInfo();
- return MMI && MMI->hasDebugInfo();
+ return MF->getMMI().hasDebugInfo();
}
@@ -3210,11 +3206,9 @@ static bool FindOptimalMemOpLowering(std::vector<EVT> &MemOps,
NonScalarIntSafe, DAG);
if (VT == MVT::Other) {
- VT = TLI.getPointerTy();
- const Type *Ty = VT.getTypeForEVT(*DAG.getContext());
- if (DstAlign >= TLI.getTargetData()->getABITypeAlignment(Ty) ||
+ if (DstAlign >= TLI.getTargetData()->getPointerPrefAlignment() ||
TLI.allowsUnalignedMemoryAccesses(VT)) {
- VT = MVT::i64;
+ VT = TLI.getPointerTy();
} else {
switch (DstAlign & 7) {
case 0: VT = MVT::i64; break;
@@ -3263,7 +3257,8 @@ static bool FindOptimalMemOpLowering(std::vector<EVT> &MemOps,
static SDValue getMemcpyLoadsAndStores(SelectionDAG &DAG, DebugLoc dl,
SDValue Chain, SDValue Dst,
SDValue Src, uint64_t Size,
- unsigned Align, bool AlwaysInline,
+ unsigned Align, bool isVol,
+ bool AlwaysInline,
const Value *DstSV, uint64_t DstSVOff,
const Value *SrcSV, uint64_t SrcSVOff) {
// Turn a memcpy of undef to nop.
@@ -3322,7 +3317,7 @@ static SDValue getMemcpyLoadsAndStores(SelectionDAG &DAG, DebugLoc dl,
Value = getMemsetStringVal(VT, dl, DAG, TLI, Str, SrcOff);
Store = DAG.getStore(Chain, dl, Value,
getMemBasePlusOffset(Dst, DstOff, DAG),
- DstSV, DstSVOff + DstOff, false, false, Align);
+ DstSV, DstSVOff + DstOff, isVol, false, Align);
} else {
// The type might not be legal for the target. This should only happen
// if the type is smaller than a legal type, as on PPC, so the right
@@ -3333,11 +3328,11 @@ static SDValue getMemcpyLoadsAndStores(SelectionDAG &DAG, DebugLoc dl,
assert(NVT.bitsGE(VT));
Value = DAG.getExtLoad(ISD::EXTLOAD, dl, NVT, Chain,
getMemBasePlusOffset(Src, SrcOff, DAG),
- SrcSV, SrcSVOff + SrcOff, VT, false, false,
+ SrcSV, SrcSVOff + SrcOff, VT, isVol, false,
MinAlign(SrcAlign, SrcOff));
Store = DAG.getTruncStore(Chain, dl, Value,
getMemBasePlusOffset(Dst, DstOff, DAG),
- DstSV, DstSVOff + DstOff, VT, false, false,
+ DstSV, DstSVOff + DstOff, VT, isVol, false,
Align);
}
OutChains.push_back(Store);
@@ -3352,7 +3347,8 @@ static SDValue getMemcpyLoadsAndStores(SelectionDAG &DAG, DebugLoc dl,
static SDValue getMemmoveLoadsAndStores(SelectionDAG &DAG, DebugLoc dl,
SDValue Chain, SDValue Dst,
SDValue Src, uint64_t Size,
- unsigned Align,bool AlwaysInline,
+ unsigned Align, bool isVol,
+ bool AlwaysInline,
const Value *DstSV, uint64_t DstSVOff,
const Value *SrcSV, uint64_t SrcSVOff) {
// Turn a memmove of undef to nop.
@@ -3403,7 +3399,7 @@ static SDValue getMemmoveLoadsAndStores(SelectionDAG &DAG, DebugLoc dl,
Value = DAG.getLoad(VT, dl, Chain,
getMemBasePlusOffset(Src, SrcOff, DAG),
- SrcSV, SrcSVOff + SrcOff, false, false, SrcAlign);
+ SrcSV, SrcSVOff + SrcOff, isVol, false, SrcAlign);
LoadValues.push_back(Value);
LoadChains.push_back(Value.getValue(1));
SrcOff += VTSize;
@@ -3418,7 +3414,7 @@ static SDValue getMemmoveLoadsAndStores(SelectionDAG &DAG, DebugLoc dl,
Store = DAG.getStore(Chain, dl, LoadValues[i],
getMemBasePlusOffset(Dst, DstOff, DAG),
- DstSV, DstSVOff + DstOff, false, false, Align);
+ DstSV, DstSVOff + DstOff, isVol, false, Align);
OutChains.push_back(Store);
DstOff += VTSize;
}
@@ -3430,7 +3426,7 @@ static SDValue getMemmoveLoadsAndStores(SelectionDAG &DAG, DebugLoc dl,
static SDValue getMemsetStores(SelectionDAG &DAG, DebugLoc dl,
SDValue Chain, SDValue Dst,
SDValue Src, uint64_t Size,
- unsigned Align,
+ unsigned Align, bool isVol,
const Value *DstSV, uint64_t DstSVOff) {
// Turn a memset of undef to nop.
if (Src.getOpcode() == ISD::UNDEF)
@@ -3472,7 +3468,7 @@ static SDValue getMemsetStores(SelectionDAG &DAG, DebugLoc dl,
SDValue Value = getMemsetValue(Src, VT, DAG, dl);
SDValue Store = DAG.getStore(Chain, dl, Value,
getMemBasePlusOffset(Dst, DstOff, DAG),
- DstSV, DstSVOff + DstOff, false, false, 0);
+ DstSV, DstSVOff + DstOff, isVol, false, 0);
OutChains.push_back(Store);
DstOff += VTSize;
}
@@ -3483,7 +3479,7 @@ static SDValue getMemsetStores(SelectionDAG &DAG, DebugLoc dl,
SDValue SelectionDAG::getMemcpy(SDValue Chain, DebugLoc dl, SDValue Dst,
SDValue Src, SDValue Size,
- unsigned Align, bool AlwaysInline,
+ unsigned Align, bool isVol, bool AlwaysInline,
const Value *DstSV, uint64_t DstSVOff,
const Value *SrcSV, uint64_t SrcSVOff) {
@@ -3497,7 +3493,7 @@ SDValue SelectionDAG::getMemcpy(SDValue Chain, DebugLoc dl, SDValue Dst,
SDValue Result = getMemcpyLoadsAndStores(*this, dl, Chain, Dst, Src,
ConstantSize->getZExtValue(),Align,
- false, DstSV, DstSVOff, SrcSV, SrcSVOff);
+ isVol, false, DstSV, DstSVOff, SrcSV, SrcSVOff);
if (Result.getNode())
return Result;
}
@@ -3506,7 +3502,7 @@ SDValue SelectionDAG::getMemcpy(SDValue Chain, DebugLoc dl, SDValue Dst,
// code. If the target chooses to do this, this is the next best.
SDValue Result =
TLI.EmitTargetCodeForMemcpy(*this, dl, Chain, Dst, Src, Size, Align,
- AlwaysInline,
+ isVol, AlwaysInline,
DstSV, DstSVOff, SrcSV, SrcSVOff);
if (Result.getNode())
return Result;
@@ -3516,10 +3512,16 @@ SDValue SelectionDAG::getMemcpy(SDValue Chain, DebugLoc dl, SDValue Dst,
if (AlwaysInline) {
assert(ConstantSize && "AlwaysInline requires a constant size!");
return getMemcpyLoadsAndStores(*this, dl, Chain, Dst, Src,
- ConstantSize->getZExtValue(), Align, true,
- DstSV, DstSVOff, SrcSV, SrcSVOff);
+ ConstantSize->getZExtValue(), Align, isVol,
+ true, DstSV, DstSVOff, SrcSV, SrcSVOff);
}
+ // FIXME: If the memcpy is volatile (isVol), lowering it to a plain libc
+ // memcpy is not guaranteed to be safe. libc memcpys aren't required to
+ // respect volatile, so they may do things like read or write memory
+ // beyond the given memory regions. But fixing this isn't easy, and most
+ // people don't care.
+
// Emit a library call.
TargetLowering::ArgListTy Args;
TargetLowering::ArgListEntry Entry;
@@ -3541,7 +3543,7 @@ SDValue SelectionDAG::getMemcpy(SDValue Chain, DebugLoc dl, SDValue Dst,
SDValue SelectionDAG::getMemmove(SDValue Chain, DebugLoc dl, SDValue Dst,
SDValue Src, SDValue Size,
- unsigned Align,
+ unsigned Align, bool isVol,
const Value *DstSV, uint64_t DstSVOff,
const Value *SrcSV, uint64_t SrcSVOff) {
@@ -3555,8 +3557,8 @@ SDValue SelectionDAG::getMemmove(SDValue Chain, DebugLoc dl, SDValue Dst,
SDValue Result =
getMemmoveLoadsAndStores(*this, dl, Chain, Dst, Src,
- ConstantSize->getZExtValue(),
- Align, false, DstSV, DstSVOff, SrcSV, SrcSVOff);
+ ConstantSize->getZExtValue(), Align, isVol,
+ false, DstSV, DstSVOff, SrcSV, SrcSVOff);
if (Result.getNode())
return Result;
}
@@ -3564,12 +3566,13 @@ SDValue SelectionDAG::getMemmove(SDValue Chain, DebugLoc dl, SDValue Dst,
// Then check to see if we should lower the memmove with target-specific
// code. If the target chooses to do this, this is the next best.
SDValue Result =
- TLI.EmitTargetCodeForMemmove(*this, dl, Chain, Dst, Src, Size, Align,
+ TLI.EmitTargetCodeForMemmove(*this, dl, Chain, Dst, Src, Size, Align, isVol,
DstSV, DstSVOff, SrcSV, SrcSVOff);
if (Result.getNode())
return Result;
// Emit a library call.
+ assert(!isVol && "library memmove does not support volatile");
TargetLowering::ArgListTy Args;
TargetLowering::ArgListEntry Entry;
Entry.Ty = TLI.getTargetData()->getIntPtrType(*getContext());
@@ -3590,7 +3593,7 @@ SDValue SelectionDAG::getMemmove(SDValue Chain, DebugLoc dl, SDValue Dst,
SDValue SelectionDAG::getMemset(SDValue Chain, DebugLoc dl, SDValue Dst,
SDValue Src, SDValue Size,
- unsigned Align,
+ unsigned Align, bool isVol,
const Value *DstSV, uint64_t DstSVOff) {
// Check to see if we should lower the memset to stores first.
@@ -3601,9 +3604,10 @@ SDValue SelectionDAG::getMemset(SDValue Chain, DebugLoc dl, SDValue Dst,
if (ConstantSize->isNullValue())
return Chain;
- SDValue Result = getMemsetStores(*this, dl, Chain, Dst, Src,
- ConstantSize->getZExtValue(),
- Align, DstSV, DstSVOff);
+ SDValue Result =
+ getMemsetStores(*this, dl, Chain, Dst, Src, ConstantSize->getZExtValue(),
+ Align, isVol, DstSV, DstSVOff);
+
if (Result.getNode())
return Result;
}
@@ -3611,12 +3615,13 @@ SDValue SelectionDAG::getMemset(SDValue Chain, DebugLoc dl, SDValue Dst,
// Then check to see if we should lower the memset with target-specific
// code. If the target chooses to do this, this is the next best.
SDValue Result =
- TLI.EmitTargetCodeForMemset(*this, dl, Chain, Dst, Src, Size, Align,
+ TLI.EmitTargetCodeForMemset(*this, dl, Chain, Dst, Src, Size, Align, isVol,
DstSV, DstSVOff);
if (Result.getNode())
return Result;
// Emit a library call.
+ assert(!isVol && "library memset does not support volatile");
const Type *IntPtrTy = TLI.getTargetData()->getIntPtrType(*getContext());
TargetLowering::ArgListTy Args;
TargetLowering::ArgListEntry Entry;
diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
index 879bdb2cbbb7..4bbb3dea92f4 100644
--- a/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
+++ b/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
@@ -40,7 +40,6 @@
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/CodeGen/PseudoSourceValue.h"
#include "llvm/CodeGen/SelectionDAG.h"
-#include "llvm/CodeGen/DwarfWriter.h"
#include "llvm/Analysis/DebugInfo.h"
#include "llvm/Target/TargetRegisterInfo.h"
#include "llvm/Target/TargetData.h"
@@ -3731,28 +3730,50 @@ SelectionDAGBuilder::visitIntrinsicCall(CallInst &I, unsigned Intrinsic) {
case Intrinsic::longjmp:
return "_longjmp"+!TLI.usesUnderscoreLongJmp();
case Intrinsic::memcpy: {
+ // Assert for address < 256 since we support only user defined address
+ // spaces.
+ assert(cast<PointerType>(I.getOperand(1)->getType())->getAddressSpace()
+ < 256 &&
+ cast<PointerType>(I.getOperand(2)->getType())->getAddressSpace()
+ < 256 &&
+ "Unknown address space");
SDValue Op1 = getValue(I.getOperand(1));
SDValue Op2 = getValue(I.getOperand(2));
SDValue Op3 = getValue(I.getOperand(3));
unsigned Align = cast<ConstantInt>(I.getOperand(4))->getZExtValue();
- DAG.setRoot(DAG.getMemcpy(getRoot(), dl, Op1, Op2, Op3, Align, false,
+ bool isVol = cast<ConstantInt>(I.getOperand(5))->getZExtValue();
+ DAG.setRoot(DAG.getMemcpy(getRoot(), dl, Op1, Op2, Op3, Align, isVol, false,
I.getOperand(1), 0, I.getOperand(2), 0));
return 0;
}
case Intrinsic::memset: {
+ // Assert for address < 256 since we support only user defined address
+ // spaces.
+ assert(cast<PointerType>(I.getOperand(1)->getType())->getAddressSpace()
+ < 256 &&
+ "Unknown address space");
SDValue Op1 = getValue(I.getOperand(1));
SDValue Op2 = getValue(I.getOperand(2));
SDValue Op3 = getValue(I.getOperand(3));
unsigned Align = cast<ConstantInt>(I.getOperand(4))->getZExtValue();
- DAG.setRoot(DAG.getMemset(getRoot(), dl, Op1, Op2, Op3, Align,
+ bool isVol = cast<ConstantInt>(I.getOperand(5))->getZExtValue();
+ DAG.setRoot(DAG.getMemset(getRoot(), dl, Op1, Op2, Op3, Align, isVol,
I.getOperand(1), 0));
return 0;
}
case Intrinsic::memmove: {
+ // Assert for address < 256 since we support only user defined address
+ // spaces.
+ assert(cast<PointerType>(I.getOperand(1)->getType())->getAddressSpace()
+ < 256 &&
+ cast<PointerType>(I.getOperand(2)->getType())->getAddressSpace()
+ < 256 &&
+ "Unknown address space");
SDValue Op1 = getValue(I.getOperand(1));
SDValue Op2 = getValue(I.getOperand(2));
SDValue Op3 = getValue(I.getOperand(3));
unsigned Align = cast<ConstantInt>(I.getOperand(4))->getZExtValue();
+ bool isVol = cast<ConstantInt>(I.getOperand(5))->getZExtValue();
// If the source and destination are known to not be aliases, we can
// lower memmove as memcpy.
@@ -3761,12 +3782,12 @@ SelectionDAGBuilder::visitIntrinsicCall(CallInst &I, unsigned Intrinsic) {
Size = C->getZExtValue();
if (AA->alias(I.getOperand(1), Size, I.getOperand(2), Size) ==
AliasAnalysis::NoAlias) {
- DAG.setRoot(DAG.getMemcpy(getRoot(), dl, Op1, Op2, Op3, Align, false,
- I.getOperand(1), 0, I.getOperand(2), 0));
+ DAG.setRoot(DAG.getMemcpy(getRoot(), dl, Op1, Op2, Op3, Align, isVol,
+ false, I.getOperand(1), 0, I.getOperand(2), 0));
return 0;
}
- DAG.setRoot(DAG.getMemmove(getRoot(), dl, Op1, Op2, Op3, Align,
+ DAG.setRoot(DAG.getMemmove(getRoot(), dl, Op1, Op2, Op3, Align, isVol,
I.getOperand(1), 0, I.getOperand(2), 0));
return 0;
}
@@ -3776,9 +3797,6 @@ SelectionDAGBuilder::visitIntrinsicCall(CallInst &I, unsigned Intrinsic) {
if (OptLevel != CodeGenOpt::None)
// FIXME: Variable debug info is not supported here.
return 0;
- DwarfWriter *DW = DAG.getDwarfWriter();
- if (!DW)
- return 0;
DbgDeclareInst &DI = cast<DbgDeclareInst>(I);
if (!DIDescriptor::ValidDebugInfo(DI.getVariable(), CodeGenOpt::None))
return 0;
@@ -3799,15 +3817,12 @@ SelectionDAGBuilder::visitIntrinsicCall(CallInst &I, unsigned Intrinsic) {
return 0; // VLAs.
int FI = SI->second;
- if (MachineModuleInfo *MMI = DAG.getMachineModuleInfo())
- if (!DI.getDebugLoc().isUnknown())
- MMI->setVariableDbgInfo(Variable, FI, DI.getDebugLoc());
+ MachineModuleInfo &MMI = DAG.getMachineFunction().getMMI();
+ if (!DI.getDebugLoc().isUnknown() && MMI.hasDebugInfo())
+ MMI.setVariableDbgInfo(Variable, FI, DI.getDebugLoc());
return 0;
}
case Intrinsic::dbg_value: {
- DwarfWriter *DW = DAG.getDwarfWriter();
- if (!DW)
- return 0;
DbgValueInst &DI = cast<DbgValueInst>(I);
if (!DIDescriptor::ValidDebugInfo(DI.getVariable(), CodeGenOpt::None))
return 0;
@@ -3852,9 +3867,9 @@ SelectionDAGBuilder::visitIntrinsicCall(CallInst &I, unsigned Intrinsic) {
return 0; // VLAs.
int FI = SI->second;
- if (MachineModuleInfo *MMI = DAG.getMachineModuleInfo())
- if (!DI.getDebugLoc().isUnknown())
- MMI->setVariableDbgInfo(Variable, FI, DI.getDebugLoc());
+ MachineModuleInfo &MMI = DAG.getMachineFunction().getMMI();
+ if (!DI.getDebugLoc().isUnknown() && MMI.hasDebugInfo())
+ MMI.setVariableDbgInfo(Variable, FI, DI.getDebugLoc());
return 0;
}
case Intrinsic::eh_exception: {
@@ -3870,10 +3885,9 @@ SelectionDAGBuilder::visitIntrinsicCall(CallInst &I, unsigned Intrinsic) {
}
case Intrinsic::eh_selector: {
- MachineModuleInfo *MMI = DAG.getMachineModuleInfo();
-
+ MachineModuleInfo &MMI = DAG.getMachineFunction().getMMI();
if (CurMBB->isLandingPad())
- AddCatchInfo(I, MMI, CurMBB);
+ AddCatchInfo(I, &MMI, CurMBB);
else {
#ifndef NDEBUG
FuncInfo.CatchInfoLost.insert(&I);
@@ -3895,40 +3909,25 @@ SelectionDAGBuilder::visitIntrinsicCall(CallInst &I, unsigned Intrinsic) {
}
case Intrinsic::eh_typeid_for: {
- MachineModuleInfo *MMI = DAG.getMachineModuleInfo();
-
- if (MMI) {
- // Find the type id for the given typeinfo.
- GlobalVariable *GV = ExtractTypeInfo(I.getOperand(1));
- unsigned TypeID = MMI->getTypeIDFor(GV);
- Res = DAG.getConstant(TypeID, MVT::i32);
- } else {
- // Return something different to eh_selector.
- Res = DAG.getConstant(1, MVT::i32);
- }
-
+ // Find the type id for the given typeinfo.
+ GlobalVariable *GV = ExtractTypeInfo(I.getOperand(1));
+ unsigned TypeID = DAG.getMachineFunction().getMMI().getTypeIDFor(GV);
+ Res = DAG.getConstant(TypeID, MVT::i32);
setValue(&I, Res);
return 0;
}
case Intrinsic::eh_return_i32:
case Intrinsic::eh_return_i64:
- if (MachineModuleInfo *MMI = DAG.getMachineModuleInfo()) {
- MMI->setCallsEHReturn(true);
- DAG.setRoot(DAG.getNode(ISD::EH_RETURN, dl,
- MVT::Other,
- getControlRoot(),
- getValue(I.getOperand(1)),
- getValue(I.getOperand(2))));
- } else {
- setValue(&I, DAG.getConstant(0, TLI.getPointerTy()));
- }
-
+ DAG.getMachineFunction().getMMI().setCallsEHReturn(true);
+ DAG.setRoot(DAG.getNode(ISD::EH_RETURN, dl,
+ MVT::Other,
+ getControlRoot(),
+ getValue(I.getOperand(1)),
+ getValue(I.getOperand(2))));
return 0;
case Intrinsic::eh_unwind_init:
- if (MachineModuleInfo *MMI = DAG.getMachineModuleInfo()) {
- MMI->setCallsUnwindInit(true);
- }
+ DAG.getMachineFunction().getMMI().setCallsUnwindInit(true);
return 0;
case Intrinsic::eh_dwarf_cfa: {
EVT VT = getValue(I.getOperand(1)).getValueType();
@@ -3947,12 +3946,12 @@ SelectionDAGBuilder::visitIntrinsicCall(CallInst &I, unsigned Intrinsic) {
return 0;
}
case Intrinsic::eh_sjlj_callsite: {
- MachineModuleInfo *MMI = DAG.getMachineModuleInfo();
+ MachineModuleInfo &MMI = DAG.getMachineFunction().getMMI();
ConstantInt *CI = dyn_cast<ConstantInt>(I.getOperand(1));
assert(CI && "Non-constant call site value in eh.sjlj.callsite!");
- assert(MMI->getCurrentCallSite() == 0 && "Overlapping call sites!");
+ assert(MMI.getCurrentCallSite() == 0 && "Overlapping call sites!");
- MMI->setCurrentCallSite(CI->getZExtValue());
+ MMI.setCurrentCallSite(CI->getZExtValue());
return 0;
}
@@ -4337,7 +4336,7 @@ void SelectionDAGBuilder::LowerCallTo(CallSite CS, SDValue Callee,
const PointerType *PT = cast<PointerType>(CS.getCalledValue()->getType());
const FunctionType *FTy = cast<FunctionType>(PT->getElementType());
const Type *RetTy = FTy->getReturnType();
- MachineModuleInfo *MMI = DAG.getMachineModuleInfo();
+ MachineModuleInfo &MMI = DAG.getMachineFunction().getMMI();
MCSymbol *BeginLabel = 0;
TargetLowering::ArgListTy Args;
@@ -4395,18 +4394,18 @@ void SelectionDAGBuilder::LowerCallTo(CallSite CS, SDValue Callee,
Args.push_back(Entry);
}
- if (LandingPad && MMI) {
+ if (LandingPad) {
// Insert a label before the invoke call to mark the try range. This can be
// used to detect deletion of the invoke via the MachineModuleInfo.
- BeginLabel = MMI->getContext().CreateTempSymbol();
+ BeginLabel = MMI.getContext().CreateTempSymbol();
// For SjLj, keep track of which landing pads go with which invokes
// so as to maintain the ordering of pads in the LSDA.
- unsigned CallSiteIndex = MMI->getCurrentCallSite();
+ unsigned CallSiteIndex = MMI.getCurrentCallSite();
if (CallSiteIndex) {
- MMI->setCallSiteBeginLabel(BeginLabel, CallSiteIndex);
+ MMI.setCallSiteBeginLabel(BeginLabel, CallSiteIndex);
// Now that the call site is handled, stop tracking it.
- MMI->setCurrentCallSite(0);
+ MMI.setCurrentCallSite(0);
}
// Both PendingLoads and PendingExports must be flushed here;
@@ -4497,14 +4496,14 @@ void SelectionDAGBuilder::LowerCallTo(CallSite CS, SDValue Callee,
else
HasTailCall = true;
- if (LandingPad && MMI) {
+ if (LandingPad) {
// Insert a label at the end of the invoke call to mark the try range. This
// can be used to detect deletion of the invoke via the MachineModuleInfo.
- MCSymbol *EndLabel = MMI->getContext().CreateTempSymbol();
+ MCSymbol *EndLabel = MMI.getContext().CreateTempSymbol();
DAG.setRoot(DAG.getEHLabel(getCurDebugLoc(), getRoot(), EndLabel));
// Inform MachineModuleInfo of range.
- MMI->addInvoke(LandingPad, BeginLabel, EndLabel);
+ MMI.addInvoke(LandingPad, BeginLabel, EndLabel);
}
}
diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h b/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h
index 9f027729b75e..fdcba0f0bc72 100644
--- a/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h
+++ b/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h
@@ -56,7 +56,6 @@ class InsertValueInst;
class Instruction;
class LoadInst;
class MachineBasicBlock;
-class MachineFunction;
class MachineInstr;
class MachineRegisterInfo;
class PHINode;
diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
index d54566b8cd3a..9b137a52f7c3 100644
--- a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
+++ b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
@@ -41,7 +41,6 @@
#include "llvm/CodeGen/ScheduleHazardRecognizer.h"
#include "llvm/CodeGen/SchedulerRegistry.h"
#include "llvm/CodeGen/SelectionDAG.h"
-#include "llvm/CodeGen/DwarfWriter.h"
#include "llvm/Target/TargetRegisterInfo.h"
#include "llvm/Target/TargetData.h"
#include "llvm/Target/TargetFrameInfo.h"
@@ -303,8 +302,6 @@ void SelectionDAGISel::getAnalysisUsage(AnalysisUsage &AU) const {
AU.addPreserved<AliasAnalysis>();
AU.addRequired<GCModuleInfo>();
AU.addPreserved<GCModuleInfo>();
- AU.addRequired<DwarfWriter>();
- AU.addPreserved<DwarfWriter>();
MachineFunctionPass::getAnalysisUsage(AU);
}
@@ -331,9 +328,7 @@ bool SelectionDAGISel::runOnMachineFunction(MachineFunction &mf) {
RegInfo = &MF->getRegInfo();
DEBUG(dbgs() << "\n\n\n=== " << Fn.getName() << "\n");
- MachineModuleInfo *MMI = getAnalysisIfAvailable<MachineModuleInfo>();
- DwarfWriter *DW = getAnalysisIfAvailable<DwarfWriter>();
- CurDAG->init(*MF, MMI, DW);
+ CurDAG->init(*MF);
FuncInfo->set(Fn, *MF, EnableFastISel);
SDB->init(GFI, *AA);
@@ -342,7 +337,7 @@ bool SelectionDAGISel::runOnMachineFunction(MachineFunction &mf) {
// Mark landing pad.
FuncInfo->MBBMap[Invoke->getSuccessor(1)]->setIsLandingPad();
- SelectAllBasicBlocks(Fn, *MF, MMI, DW, TII);
+ SelectAllBasicBlocks(Fn, *MF, TII);
// If the first basic block in the function has live ins that need to be
// copied into vregs, emit the copies into the top of the block before
@@ -844,15 +839,11 @@ void SelectionDAGISel::DoInstructionSelection() {
void SelectionDAGISel::SelectAllBasicBlocks(Function &Fn,
MachineFunction &MF,
- MachineModuleInfo *MMI,
- DwarfWriter *DW,
const TargetInstrInfo &TII) {
// Initialize the Fast-ISel state, if needed.
FastISel *FastIS = 0;
if (EnableFastISel)
- FastIS = TLI.createFastISel(MF, MMI, DW,
- FuncInfo->ValueMap,
- FuncInfo->MBBMap,
+ FastIS = TLI.createFastISel(MF, FuncInfo->ValueMap, FuncInfo->MBBMap,
FuncInfo->StaticAllocaMap
#ifndef NDEBUG
, FuncInfo->CatchInfoLost
@@ -888,10 +879,10 @@ void SelectionDAGISel::SelectAllBasicBlocks(Function &Fn,
}
}
- if (MMI && BB->isLandingPad()) {
+ if (BB->isLandingPad()) {
// Add a label to mark the beginning of the landing pad. Deletion of the
// landing pad can thus be detected via the MachineModuleInfo.
- MCSymbol *Label = MMI->addLandingPad(BB);
+ MCSymbol *Label = MF.getMMI().addLandingPad(BB);
const TargetInstrDesc &II = TII.get(TargetOpcode::EH_LABEL);
BuildMI(BB, SDB->getCurDebugLoc(), II).addSym(Label);
@@ -925,7 +916,7 @@ void SelectionDAGISel::SelectAllBasicBlocks(Function &Fn,
if (I == E)
// No catch info found - try to extract some from the successor.
- CopyCatchInfo(Br->getSuccessor(0), LLVMBB, MMI, *FuncInfo);
+ CopyCatchInfo(Br->getSuccessor(0), LLVMBB, &MF.getMMI(), *FuncInfo);
}
}