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