summaryrefslogtreecommitdiffstats
path: root/lib/CodeGen
diff options
context:
space:
mode:
authorrdivacky <rdivacky@FreeBSD.org>2010-04-02 08:54:30 +0000
committerrdivacky <rdivacky@FreeBSD.org>2010-04-02 08:54:30 +0000
commit20e856b2a58d12231aa42d5d13888b15ac03e5a4 (patch)
treecf5763d092b81cecc168fa28032247ee495d06e2 /lib/CodeGen
parent2f2afc1aae898651e26987a5c71f3febb19bca98 (diff)
downloadFreeBSD-src-20e856b2a58d12231aa42d5d13888b15ac03e5a4.zip
FreeBSD-src-20e856b2a58d12231aa42d5d13888b15ac03e5a4.tar.gz
Update LLVM to r100181.
Diffstat (limited to 'lib/CodeGen')
-rw-r--r--lib/CodeGen/AsmPrinter/AsmPrinter.cpp33
-rw-r--r--lib/CodeGen/AsmPrinter/DIE.cpp31
-rw-r--r--lib/CodeGen/AsmPrinter/DIE.h38
-rw-r--r--lib/CodeGen/AsmPrinter/DwarfDebug.cpp287
-rw-r--r--lib/CodeGen/AsmPrinter/DwarfDebug.h32
-rw-r--r--lib/CodeGen/AsmPrinter/DwarfException.cpp61
-rw-r--r--lib/CodeGen/AsmPrinter/DwarfPrinter.cpp4
-rw-r--r--lib/CodeGen/AsmPrinter/DwarfWriter.cpp17
-rw-r--r--lib/CodeGen/BranchFolding.cpp12
-rw-r--r--lib/CodeGen/DwarfEHPrepare.cpp322
-rw-r--r--lib/CodeGen/LiveInterval.cpp15
-rw-r--r--lib/CodeGen/LiveIntervalAnalysis.cpp19
-rw-r--r--lib/CodeGen/LiveStackAnalysis.cpp2
-rw-r--r--lib/CodeGen/LiveVariables.cpp10
-rw-r--r--lib/CodeGen/MachineBasicBlock.cpp64
-rw-r--r--lib/CodeGen/MachineCSE.cpp20
-rw-r--r--lib/CodeGen/MachineFunction.cpp4
-rw-r--r--lib/CodeGen/MachineModuleInfo.cpp6
-rw-r--r--lib/CodeGen/OptimizeExts.cpp25
-rw-r--r--lib/CodeGen/PHIElimination.cpp2
-rw-r--r--lib/CodeGen/PreAllocSplitting.cpp2
-rw-r--r--lib/CodeGen/RegAllocLocal.cpp584
-rw-r--r--lib/CodeGen/ScheduleDAGInstrs.cpp72
-rw-r--r--lib/CodeGen/SelectionDAG/DAGCombiner.cpp46
-rw-r--r--lib/CodeGen/SelectionDAG/FastISel.cpp7
-rw-r--r--lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp13
-rw-r--r--lib/CodeGen/SelectionDAG/InstrEmitter.cpp272
-rw-r--r--lib/CodeGen/SelectionDAG/InstrEmitter.h36
-rw-r--r--lib/CodeGen/SelectionDAG/SDNodeDbgValue.h14
-rw-r--r--lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.cpp137
-rw-r--r--lib/CodeGen/SelectionDAG/SelectionDAG.cpp284
-rw-r--r--lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp29
-rw-r--r--lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp117
-rw-r--r--lib/CodeGen/SelectionDAG/TargetLowering.cpp21
-rw-r--r--lib/CodeGen/SimpleRegisterCoalescing.cpp117
-rw-r--r--lib/CodeGen/TargetLoweringObjectFileImpl.cpp4
-rw-r--r--lib/CodeGen/TwoAddressInstructionPass.cpp12
-rw-r--r--lib/CodeGen/VirtRegRewriter.cpp22
38 files changed, 1647 insertions, 1146 deletions
diff --git a/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
index 1d4f7f7..3e71d18 100644
--- a/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
+++ b/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
@@ -62,7 +62,7 @@ AsmPrinter::AsmPrinter(formatted_raw_ostream &o, TargetMachine &tm,
TM(tm), MAI(tm.getMCAsmInfo()), TRI(tm.getRegisterInfo()),
OutContext(Streamer.getContext()),
OutStreamer(Streamer),
- LastMI(0), LastFn(0), Counter(~0U), SetCounter(0), PrevDLT(NULL) {
+ LastMI(0), LastFn(0), Counter(~0U), SetCounter(0) {
DW = 0; MMI = 0;
VerboseAsm = Streamer.isVerboseAsm();
}
@@ -922,8 +922,8 @@ void AsmPrinter::EmitLabelDifference(const MCSymbol *Hi, const MCSymbol *Lo,
// Otherwise, emit with .set (aka assignment).
MCSymbol *SetLabel =
- OutContext.GetOrCreateTemporarySymbol(Twine(MAI->getPrivateGlobalPrefix()) +
- "set" + Twine(SetCounter++));
+ OutContext.GetOrCreateSymbol(Twine(MAI->getPrivateGlobalPrefix()) +
+ "set" + Twine(SetCounter++));
OutStreamer.EmitAssignment(SetLabel, Diff);
OutStreamer.EmitSymbolValue(SetLabel, Size, 0/*AddrSpace*/);
}
@@ -1337,25 +1337,12 @@ void AsmPrinter::processDebugLoc(const MachineInstr *MI,
if (!MAI || !DW || !MAI->doesSupportDebugInformation()
|| !DW->ShouldEmitDwarfDebug())
return;
- if (MI->getOpcode() == TargetOpcode::DBG_VALUE)
- return;
- DebugLoc DL = MI->getDebugLoc();
- if (DL.isUnknown())
- return;
- DILocation CurDLT = MF->getDILocation(DL);
- if (!CurDLT.getScope().Verify())
- return;
- if (!BeforePrintingInsn) {
+ if (!BeforePrintingInsn)
// After printing instruction
DW->EndScope(MI);
- } else if (CurDLT.getNode() != PrevDLT) {
- MCSymbol *L = DW->RecordSourceLine(CurDLT.getLineNumber(),
- CurDLT.getColumnNumber(),
- CurDLT.getScope().getNode());
- DW->BeginScope(MI, L);
- PrevDLT = CurDLT.getNode();
- }
+ else
+ DW->BeginScope(MI);
}
@@ -1612,7 +1599,7 @@ MCSymbol *AsmPrinter::GetBlockAddressSymbol(const BasicBlock *BB) const {
/// GetCPISymbol - Return the symbol for the specified constant pool entry.
MCSymbol *AsmPrinter::GetCPISymbol(unsigned CPID) const {
- return OutContext.GetOrCreateTemporarySymbol
+ return OutContext.GetOrCreateSymbol
(Twine(MAI->getPrivateGlobalPrefix()) + "CPI" + Twine(getFunctionNumber())
+ "_" + Twine(CPID));
}
@@ -1625,7 +1612,7 @@ 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 {
- return OutContext.GetOrCreateTemporarySymbol
+ return OutContext.GetOrCreateSymbol
(Twine(MAI->getPrivateGlobalPrefix()) + Twine(getFunctionNumber()) + "_" +
Twine(UID) + "_set_" + Twine(MBBID));
}
@@ -1639,9 +1626,7 @@ MCSymbol *AsmPrinter::GetSymbolWithGlobalValueBase(const GlobalValue *GV,
SmallString<60> NameStr;
Mang->getNameWithPrefix(NameStr, GV, ForcePrivate);
NameStr.append(Suffix.begin(), Suffix.end());
- if (!GV->hasPrivateLinkage() && !ForcePrivate)
- return OutContext.GetOrCreateSymbol(NameStr.str());
- return OutContext.GetOrCreateTemporarySymbol(NameStr.str());
+ return OutContext.GetOrCreateSymbol(NameStr.str());
}
/// GetExternalSymbolSymbol - Return the MCSymbol for the specified
diff --git a/lib/CodeGen/AsmPrinter/DIE.cpp b/lib/CodeGen/AsmPrinter/DIE.cpp
index e97754e..e0e3ff7 100644
--- a/lib/CodeGen/AsmPrinter/DIE.cpp
+++ b/lib/CodeGen/AsmPrinter/DIE.cpp
@@ -19,6 +19,7 @@
#include "llvm/MC/MCStreamer.h"
#include "llvm/MC/MCSymbol.h"
#include "llvm/Target/TargetData.h"
+#include "llvm/Support/Allocator.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/Format.h"
@@ -114,10 +115,11 @@ DIE::~DIE() {
/// addSiblingOffset - Add a sibling offset field to the front of the DIE.
///
-void DIE::addSiblingOffset() {
- DIEInteger *DI = new DIEInteger(0);
+DIEValue *DIE::addSiblingOffset(BumpPtrAllocator &A) {
+ DIEInteger *DI = new (A) DIEInteger(0);
Values.insert(Values.begin(), DI);
Abbrev.AddFirstAttribute(dwarf::DW_AT_sibling, dwarf::DW_FORM_ref4);
+ return DI;
}
#ifndef NDEBUG
@@ -277,31 +279,6 @@ void DIELabel::print(raw_ostream &O) {
#endif
//===----------------------------------------------------------------------===//
-// DIESectionOffset Implementation
-//===----------------------------------------------------------------------===//
-
-/// EmitValue - Emit delta value.
-///
-void DIESectionOffset::EmitValue(DwarfPrinter *D, unsigned Form) const {
- bool IsSmall = Form == dwarf::DW_FORM_data4;
- D->EmitSectionOffset(Label, Section, IsSmall, IsEH);
-}
-
-/// SizeOf - Determine size of delta value in bytes.
-///
-unsigned DIESectionOffset::SizeOf(const TargetData *TD, unsigned Form) const {
- if (Form == dwarf::DW_FORM_data4) return 4;
- return TD->getPointerSize();
-}
-
-#ifndef NDEBUG
-void DIESectionOffset::print(raw_ostream &O) {
- O << "Off: " << Label->getName() << "-" << Section->getName()
- << "-" << IsEH;
-}
-#endif
-
-//===----------------------------------------------------------------------===//
// DIEDelta Implementation
//===----------------------------------------------------------------------===//
diff --git a/lib/CodeGen/AsmPrinter/DIE.h b/lib/CodeGen/AsmPrinter/DIE.h
index c5909fa..8b27ed2 100644
--- a/lib/CodeGen/AsmPrinter/DIE.h
+++ b/lib/CodeGen/AsmPrinter/DIE.h
@@ -153,7 +153,7 @@ namespace llvm {
unsigned getOffset() const { return Offset; }
unsigned getSize() const { return Size; }
const std::vector<DIE *> &getChildren() const { return Children; }
- SmallVector<DIEValue*, 32> &getValues() { return Values; }
+ const SmallVector<DIEValue*, 32> &getValues() const { return Values; }
DIE *getParent() const { return Parent; }
void setTag(unsigned Tag) { Abbrev.setTag(Tag); }
void setOffset(unsigned O) { Offset = O; }
@@ -171,8 +171,10 @@ namespace llvm {
unsigned getSiblingOffset() const { return Offset + Size; }
/// addSiblingOffset - Add a sibling offset field to the front of the DIE.
+ /// The caller is responsible for deleting the return value at or after the
+ /// same time it destroys this DIE.
///
- void addSiblingOffset();
+ DIEValue *addSiblingOffset(BumpPtrAllocator &A);
/// addChild - Add a child to the DIE.
///
@@ -328,38 +330,6 @@ namespace llvm {
};
//===--------------------------------------------------------------------===//
- /// DIESectionOffset - A section offset DIE.
- ///
- class DIESectionOffset : public DIEValue {
- const MCSymbol *Label;
- const MCSymbol *Section;
- bool IsEH : 1;
- public:
- DIESectionOffset(const MCSymbol *Lab, const MCSymbol *Sec,
- bool isEH = false)
- : DIEValue(isSectionOffset), Label(Lab), Section(Sec),
- IsEH(isEH) {}
-
- /// EmitValue - Emit section offset.
- ///
- virtual void EmitValue(DwarfPrinter *D, unsigned Form) const;
-
- /// SizeOf - Determine size of section offset value in bytes.
- ///
- virtual unsigned SizeOf(const TargetData *TD, unsigned Form) const;
-
- // Implement isa/cast/dyncast.
- static bool classof(const DIESectionOffset *) { return true; }
- static bool classof(const DIEValue *D) {
- return D->getType() == isSectionOffset;
- }
-
-#ifndef NDEBUG
- virtual void print(raw_ostream &O);
-#endif
- };
-
- //===--------------------------------------------------------------------===//
/// DIEDelta - A simple label difference DIE.
///
class DIEDelta : public DIEValue {
diff --git a/lib/CodeGen/AsmPrinter/DwarfDebug.cpp b/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
index 7153fe2..fb91d4f 100644
--- a/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
+++ b/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
@@ -92,11 +92,11 @@ public:
/// addGlobal - Add a new global entity to the compile unit.
///
- void addGlobal(const std::string &Name, DIE *Die) { Globals[Name] = Die; }
+ void addGlobal(StringRef Name, DIE *Die) { Globals[Name] = Die; }
/// addGlobalType - Add a new global type to the compile unit.
///
- void addGlobalType(const std::string &Name, DIE *Die) {
+ void addGlobalType(StringRef Name, DIE *Die) {
GlobalTypes[Name] = Die;
}
@@ -149,20 +149,26 @@ class DbgVariable {
DIVariable Var; // Variable Descriptor.
unsigned FrameIndex; // Variable frame index.
const MachineInstr *DbgValueMInsn; // DBG_VALUE
+ // DbgValueLabel - DBG_VALUE is effective from this label.
+ MCSymbol *DbgValueLabel;
DbgVariable *const AbstractVar; // Abstract variable for this variable.
DIE *TheDIE;
public:
// AbsVar may be NULL.
DbgVariable(DIVariable V, unsigned I, DbgVariable *AbsVar)
- : Var(V), FrameIndex(I), DbgValueMInsn(0), AbstractVar(AbsVar), TheDIE(0) {}
+ : Var(V), FrameIndex(I), DbgValueMInsn(0),
+ DbgValueLabel(0), AbstractVar(AbsVar), TheDIE(0) {}
DbgVariable(DIVariable V, const MachineInstr *MI, DbgVariable *AbsVar)
- : Var(V), FrameIndex(0), DbgValueMInsn(MI), AbstractVar(AbsVar), TheDIE(0)
+ : Var(V), FrameIndex(0), DbgValueMInsn(MI), DbgValueLabel(0),
+ AbstractVar(AbsVar), TheDIE(0)
{}
// Accessors.
DIVariable getVariable() const { return Var; }
unsigned getFrameIndex() const { return FrameIndex; }
const MachineInstr *getDbgValue() const { return DbgValueMInsn; }
+ MCSymbol *getDbgValueLabel() const { return DbgValueLabel; }
+ void setDbgValueLabel(MCSymbol *L) { DbgValueLabel = L; }
DbgVariable *getAbstractVariable() const { return AbstractVar; }
void setDIE(DIE *D) { TheDIE = D; }
DIE *getDIE() const { return TheDIE; }
@@ -224,14 +230,14 @@ public:
void fixInstructionMarkers(DenseMap<const MachineInstr *,
unsigned> &MIIndexMap) {
- assert (getFirstInsn() && "First instruction is missing!");
+ assert(getFirstInsn() && "First instruction is missing!");
// Use the end of last child scope as end of this scope.
const SmallVector<DbgScope *, 4> &Scopes = getScopes();
const MachineInstr *LastInsn = getFirstInsn();
unsigned LIndex = 0;
if (Scopes.empty()) {
- assert (getLastInsn() && "Inner most scope does not have last insn!");
+ assert(getLastInsn() && "Inner most scope does not have last insn!");
return;
}
for (SmallVector<DbgScope *, 4>::const_iterator SI = Scopes.begin(),
@@ -295,15 +301,15 @@ DbgScope::~DbgScope() {
DwarfDebug::DwarfDebug(raw_ostream &OS, AsmPrinter *A, const MCAsmInfo *T)
: DwarfPrinter(OS, A, T), ModuleCU(0),
AbbreviationsSet(InitAbbreviationsSetSize), Abbreviations(),
- DIEValues(), SectionSourceLines(), didInitial(false), shouldEmit(false),
- CurrentFnDbgScope(0), DebugTimer(0) {
+ DIEBlocks(), SectionSourceLines(), didInitial(false), shouldEmit(false),
+ CurrentFnDbgScope(0), PrevDILoc(0), DebugTimer(0) {
NextStringPoolNumber = 0;
if (TimePassesIsEnabled)
DebugTimer = new Timer("Dwarf Debug Writer");
}
DwarfDebug::~DwarfDebug() {
- for (unsigned j = 0, M = DIEValues.size(); j < M; ++j)
- delete DIEValues[j];
+ for (unsigned j = 0, M = DIEBlocks.size(); j < M; ++j)
+ DIEBlocks[j]->~DIEBlock();
delete DebugTimer;
}
@@ -343,8 +349,7 @@ void DwarfDebug::assignAbbrevNumber(DIEAbbrev &Abbrev) {
/// createDIEEntry - Creates a new DIEEntry to be a proxy for a debug
/// information entry.
DIEEntry *DwarfDebug::createDIEEntry(DIE *Entry) {
- DIEEntry *Value = new DIEEntry(Entry);
- DIEValues.push_back(Value);
+ DIEEntry *Value = new (DIEValueAllocator) DIEEntry(Entry);
return Value;
}
@@ -353,8 +358,7 @@ DIEEntry *DwarfDebug::createDIEEntry(DIE *Entry) {
void DwarfDebug::addUInt(DIE *Die, unsigned Attribute,
unsigned Form, uint64_t Integer) {
if (!Form) Form = DIEInteger::BestForm(false, Integer);
- DIEValue *Value = new DIEInteger(Integer);
- DIEValues.push_back(Value);
+ DIEValue *Value = new (DIEValueAllocator) DIEInteger(Integer);
Die->addValue(Attribute, Form, Value);
}
@@ -363,8 +367,7 @@ void DwarfDebug::addUInt(DIE *Die, unsigned Attribute,
void DwarfDebug::addSInt(DIE *Die, unsigned Attribute,
unsigned Form, int64_t Integer) {
if (!Form) Form = DIEInteger::BestForm(true, Integer);
- DIEValue *Value = new DIEInteger(Integer);
- DIEValues.push_back(Value);
+ DIEValue *Value = new (DIEValueAllocator) DIEInteger(Integer);
Die->addValue(Attribute, Form, Value);
}
@@ -372,8 +375,7 @@ void DwarfDebug::addSInt(DIE *Die, unsigned Attribute,
/// keeps string reference.
void DwarfDebug::addString(DIE *Die, unsigned Attribute, unsigned Form,
StringRef String) {
- DIEValue *Value = new DIEString(String);
- DIEValues.push_back(Value);
+ DIEValue *Value = new (DIEValueAllocator) DIEString(String);
Die->addValue(Attribute, Form, Value);
}
@@ -381,18 +383,7 @@ void DwarfDebug::addString(DIE *Die, unsigned Attribute, unsigned Form,
///
void DwarfDebug::addLabel(DIE *Die, unsigned Attribute, unsigned Form,
const MCSymbol *Label) {
- DIEValue *Value = new DIELabel(Label);
- DIEValues.push_back(Value);
- Die->addValue(Attribute, Form, Value);
-}
-
-/// addSectionOffset - Add a section offset label attribute data and value.
-///
-void DwarfDebug::addSectionOffset(DIE *Die, unsigned Attribute, unsigned Form,
- const MCSymbol *Label,const MCSymbol *Section,
- bool isEH) {
- DIEValue *Value = new DIESectionOffset(Label, Section, isEH);
- DIEValues.push_back(Value);
+ DIEValue *Value = new (DIEValueAllocator) DIELabel(Label);
Die->addValue(Attribute, Form, Value);
}
@@ -400,8 +391,7 @@ void DwarfDebug::addSectionOffset(DIE *Die, unsigned Attribute, unsigned Form,
///
void DwarfDebug::addDelta(DIE *Die, unsigned Attribute, unsigned Form,
const MCSymbol *Hi, const MCSymbol *Lo) {
- DIEValue *Value = new DIEDelta(Hi, Lo);
- DIEValues.push_back(Value);
+ DIEValue *Value = new (DIEValueAllocator) DIEDelta(Hi, Lo);
Die->addValue(Attribute, Form, Value);
}
@@ -410,7 +400,7 @@ void DwarfDebug::addDelta(DIE *Die, unsigned Attribute, unsigned Form,
void DwarfDebug::addBlock(DIE *Die, unsigned Attribute, unsigned Form,
DIEBlock *Block) {
Block->ComputeSize(TD);
- DIEValues.push_back(Block);
+ DIEBlocks.push_back(Block); // Memoize so we can call the destructor later on.
Die->addValue(Attribute, Block->BestForm(), Block);
}
@@ -457,8 +447,8 @@ void DwarfDebug::addSourceLine(DIE *Die, const DISubprogram *SP) {
unsigned Line = SP->getLineNumber();
if (!SP->getContext().Verify())
return;
- unsigned FileID = GetOrCreateSourceID(SP->getContext().getDirectory(),
- SP->getContext().getFilename());
+ unsigned FileID = GetOrCreateSourceID(SP->getDirectory(),
+ SP->getFilename());
assert(FileID && "Invalid file id");
addUInt(Die, dwarf::DW_AT_decl_file, 0, FileID);
addUInt(Die, dwarf::DW_AT_decl_line, 0, Line);
@@ -564,7 +554,7 @@ void DwarfDebug::addComplexAddress(DbgVariable *&DV, DIE *Die,
// Decode the original location, and use that as the start of the byref
// variable's location.
unsigned Reg = RI->getDwarfRegNum(Location.getReg(), false);
- DIEBlock *Block = new DIEBlock();
+ DIEBlock *Block = new (DIEValueAllocator) DIEBlock();
if (Location.isReg()) {
if (Reg < 32) {
@@ -696,15 +686,15 @@ void DwarfDebug::addBlockByrefAddress(DbgVariable *&DV, DIE *Die,
}
// Get the offsets for the forwarding field and the variable field.
- unsigned int forwardingFieldOffset =
+ unsigned forwardingFieldOffset =
DIDerivedType(forwardingField.getNode()).getOffsetInBits() >> 3;
- unsigned int varFieldOffset =
+ unsigned varFieldOffset =
DIDerivedType(varField.getNode()).getOffsetInBits() >> 3;
// Decode the original location, and use that as the start of the byref
// variable's location.
unsigned Reg = RI->getDwarfRegNum(Location.getReg(), false);
- DIEBlock *Block = new DIEBlock();
+ DIEBlock *Block = new (DIEValueAllocator) DIEBlock();
if (Location.isReg()) {
if (Reg < 32)
@@ -759,7 +749,7 @@ void DwarfDebug::addBlockByrefAddress(DbgVariable *&DV, DIE *Die,
void DwarfDebug::addAddress(DIE *Die, unsigned Attribute,
const MachineLocation &Location) {
unsigned Reg = RI->getDwarfRegNum(Location.getReg(), false);
- DIEBlock *Block = new DIEBlock();
+ DIEBlock *Block = new (DIEValueAllocator) DIEBlock();
if (Location.isReg()) {
if (Reg < 32) {
@@ -1106,7 +1096,7 @@ DIE *DwarfDebug::createMemberDIE(const DIDerivedType &DT) {
addSourceLine(MemberDie, &DT);
- DIEBlock *MemLocationDie = new DIEBlock();
+ DIEBlock *MemLocationDie = new (DIEValueAllocator) DIEBlock();
addUInt(MemLocationDie, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_plus_uconst);
uint64_t Size = DT.getSizeInBits();
@@ -1142,7 +1132,7 @@ DIE *DwarfDebug::createMemberDIE(const DIDerivedType &DT) {
// expression to extract appropriate offset from vtable.
// BaseAddr = ObAddr + *((*ObAddr) - Offset)
- DIEBlock *VBaseLocationDie = new DIEBlock();
+ DIEBlock *VBaseLocationDie = new (DIEValueAllocator) DIEBlock();
addUInt(VBaseLocationDie, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_dup);
addUInt(VBaseLocationDie, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_deref);
addUInt(VBaseLocationDie, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_constu);
@@ -1208,7 +1198,7 @@ DIE *DwarfDebug::createSubprogramDIE(const DISubprogram &SP, bool MakeDecl) {
unsigned VK = SP.getVirtuality();
if (VK) {
addUInt(SPDie, dwarf::DW_AT_virtuality, dwarf::DW_FORM_flag, VK);
- DIEBlock *Block = new DIEBlock();
+ DIEBlock *Block = new (DIEValueAllocator) DIEBlock();
addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_constu);
addUInt(Block, 0, dwarf::DW_FORM_data1, SP.getVirtualIndex());
addBlock(SPDie, dwarf::DW_AT_vtable_elem_location, 0, Block);
@@ -1244,13 +1234,13 @@ DIE *DwarfDebug::createSubprogramDIE(const DISubprogram &SP, bool MakeDecl) {
return SPDie;
}
-/// getUpdatedDbgScope - Find or create DbgScope assicated with the instruction.
-/// Initialize scope and update scope hierarchy.
+/// getUpdatedDbgScope - Find DbgScope assicated with the instruction.
+/// Update scope hierarchy. Create abstract scope if required.
DbgScope *DwarfDebug::getUpdatedDbgScope(MDNode *N, const MachineInstr *MI,
- MDNode *InlinedAt) {
- assert (N && "Invalid Scope encoding!");
- assert (MI && "Missing machine instruction!");
- bool GetConcreteScope = (MI && InlinedAt);
+ MDNode *InlinedAt) {
+ assert(N && "Invalid Scope encoding!");
+ assert(MI && "Missing machine instruction!");
+ bool isAConcreteScope = InlinedAt != 0;
DbgScope *NScope = NULL;
@@ -1258,17 +1248,17 @@ DbgScope *DwarfDebug::getUpdatedDbgScope(MDNode *N, const MachineInstr *MI,
NScope = DbgScopeMap.lookup(InlinedAt);
else
NScope = DbgScopeMap.lookup(N);
- assert (NScope && "Unable to find working scope!");
+ assert(NScope && "Unable to find working scope!");
if (NScope->getFirstInsn())
return NScope;
DbgScope *Parent = NULL;
- if (GetConcreteScope) {
+ if (isAConcreteScope) {
DILocation IL(InlinedAt);
Parent = getUpdatedDbgScope(IL.getScope().getNode(), MI,
IL.getOrigLocation().getNode());
- assert (Parent && "Unable to find Parent scope!");
+ assert(Parent && "Unable to find Parent scope!");
NScope->setParent(Parent);
Parent->addScope(NScope);
} else if (DIDescriptor(N).isLexicalBlock()) {
@@ -1286,7 +1276,7 @@ DbgScope *DwarfDebug::getUpdatedDbgScope(MDNode *N, const MachineInstr *MI,
CurrentFnDbgScope = NScope;
}
- if (GetConcreteScope) {
+ if (isAConcreteScope) {
ConcreteScopes[InlinedAt] = NScope;
getOrCreateAbstractScope(N);
}
@@ -1295,7 +1285,7 @@ DbgScope *DwarfDebug::getUpdatedDbgScope(MDNode *N, const MachineInstr *MI,
}
DbgScope *DwarfDebug::getOrCreateAbstractScope(MDNode *N) {
- assert (N && "Invalid Scope encoding!");
+ assert(N && "Invalid Scope encoding!");
DbgScope *AScope = AbstractScopes.lookup(N);
if (AScope)
@@ -1377,7 +1367,7 @@ DIE *DwarfDebug::updateSubprogramScopeDIE(MDNode *SPNode) {
DIE *DwarfDebug::constructLexicalScopeDIE(DbgScope *Scope) {
MCSymbol *Start = Scope->getStartLabel();
MCSymbol *End = Scope->getEndLabel();
- if (Start == 0) return 0;
+ if (Start == 0 || End == 0) return 0;
assert(Start->isDefined() && "Invalid starting label for an inlined scope!");
assert(End->isDefined() && "Invalid end label for an inlined scope!");
@@ -1400,7 +1390,7 @@ DIE *DwarfDebug::constructLexicalScopeDIE(DbgScope *Scope) {
DIE *DwarfDebug::constructInlinedScopeDIE(DbgScope *Scope) {
MCSymbol *StartLabel = Scope->getStartLabel();
MCSymbol *EndLabel = Scope->getEndLabel();
- if (StartLabel == 0) return 0;
+ if (StartLabel == 0 || EndLabel == 0) return 0;
assert(StartLabel->isDefined() &&
"Invalid starting label for an inlined scope!");
@@ -1413,7 +1403,7 @@ DIE *DwarfDebug::constructInlinedScopeDIE(DbgScope *Scope) {
DISubprogram InlinedSP = getDISubprogram(DS.getNode());
DIE *OriginDIE = ModuleCU->getDIE(InlinedSP.getNode());
- assert (OriginDIE && "Unable to find Origin DIE!");
+ assert(OriginDIE && "Unable to find Origin DIE!");
addDIEEntry(ScopeDIE, dwarf::DW_AT_abstract_origin,
dwarf::DW_FORM_ref4, OriginDIE);
@@ -1477,9 +1467,9 @@ DIE *DwarfDebug::constructVariableDIE(DbgVariable *DV, DbgScope *Scope) {
DISubprogram InlinedSP = getDISubprogram(DS.getNode());
DIE *OriginSPDIE = ModuleCU->getDIE(InlinedSP.getNode());
(void) OriginSPDIE;
- assert (OriginSPDIE && "Unable to find Origin DIE for the SP!");
+ assert(OriginSPDIE && "Unable to find Origin DIE for the SP!");
DIE *AbsDIE = DV->getAbstractVariable()->getDIE();
- assert (AbsDIE && "Unable to find Origin DIE for the Variable!");
+ assert(AbsDIE && "Unable to find Origin DIE for the Variable!");
addDIEEntry(VariableDie, dwarf::DW_AT_abstract_origin,
dwarf::DW_FORM_ref4, AbsDIE);
}
@@ -1508,12 +1498,18 @@ DIE *DwarfDebug::constructVariableDIE(DbgVariable *DV, DbgScope *Scope) {
MachineLocation Location;
Location.set(DbgValueInsn->getOperand(0).getReg());
addAddress(VariableDie, dwarf::DW_AT_location, Location);
+ if (MCSymbol *VS = DV->getDbgValueLabel())
+ addLabel(VariableDie, dwarf::DW_AT_start_scope, dwarf::DW_FORM_addr,
+ VS);
} else if (DbgValueInsn->getOperand(0).getType() ==
MachineOperand::MO_Immediate) {
- DIEBlock *Block = new DIEBlock();
+ DIEBlock *Block = new (DIEValueAllocator) DIEBlock();
unsigned Imm = DbgValueInsn->getOperand(0).getImm();
addUInt(Block, 0, dwarf::DW_FORM_udata, Imm);
addBlock(VariableDie, dwarf::DW_AT_const_value, 0, Block);
+ if (MCSymbol *VS = DV->getDbgValueLabel())
+ addLabel(VariableDie, dwarf::DW_AT_start_scope, dwarf::DW_FORM_addr,
+ VS);
} else {
//FIXME : Handle other operand types.
delete VariableDie;
@@ -1523,7 +1519,8 @@ DIE *DwarfDebug::constructVariableDIE(DbgVariable *DV, DbgScope *Scope) {
} else {
MachineLocation Location;
unsigned FrameReg;
- int Offset = RI->getFrameIndexReference(*MF, DV->getFrameIndex(), FrameReg);
+ int Offset = RI->getFrameIndexReference(*MF, DV->getFrameIndex(),
+ FrameReg);
Location.set(FrameReg, Offset);
if (VD.hasComplexAddress())
@@ -1576,10 +1573,9 @@ DIE *DwarfDebug::constructScopeDIE(DbgScope *Scope) {
else
ScopeDIE = updateSubprogramScopeDIE(DS.getNode());
}
- else {
+ else
ScopeDIE = constructLexicalScopeDIE(Scope);
- if (!ScopeDIE) return NULL;
- }
+ if (!ScopeDIE) return NULL;
// Add variables to scope.
const SmallVector<DbgVariable *, 8> &Variables = Scope->getVariables();
@@ -1608,7 +1604,7 @@ DIE *DwarfDebug::constructScopeDIE(DbgScope *Scope) {
/// source file names. If none currently exists, create a new id and insert it
/// in the SourceIds map. This can update DirectoryNames and SourceFileNames
/// maps as well.
-unsigned DwarfDebug::GetOrCreateSourceID(StringRef DirName, StringRef FileName) {
+unsigned DwarfDebug::GetOrCreateSourceID(StringRef DirName, StringRef FileName){
unsigned DId;
StringMap<unsigned>::iterator DI = DirectoryIdMap.find(DirName);
if (DI != DirectoryIdMap.end()) {
@@ -1666,15 +1662,19 @@ void 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,
- getTempLabel("section_line"), getTempLabel("section_line"),
- false);
addString(Die, dwarf::DW_AT_producer, dwarf::DW_FORM_string,
DIUnit.getProducer());
addUInt(Die, dwarf::DW_AT_language, dwarf::DW_FORM_data1,
DIUnit.getLanguage());
addString(Die, dwarf::DW_AT_name, dwarf::DW_FORM_string, FN);
+ addLabel(Die, dwarf::DW_AT_low_pc, dwarf::DW_FORM_addr,
+ getTempLabel("text_begin"));
+ addLabel(Die, dwarf::DW_AT_high_pc, dwarf::DW_FORM_addr,
+ getTempLabel("text_end"));
+ // DW_AT_stmt_list is a offset of line number information for this
+ // compile unit in debug_line section. It is always zero when only one
+ // compile unit is emitted in one object file.
+ addUInt(Die, dwarf::DW_AT_stmt_list, dwarf::DW_FORM_data4, 0);
if (!Dir.empty())
addString(Die, dwarf::DW_AT_comp_dir, dwarf::DW_FORM_string, Dir);
@@ -1717,13 +1717,13 @@ void DwarfDebug::constructGlobalVariableDIE(MDNode *N) {
DIDescriptor GVContext = DI_GV.getContext();
// Do not create specification DIE if context is either compile unit
// or a subprogram.
- if (DI_GV.isDefinition() && !GVContext.isCompileUnit()
- && !GVContext.isFile() && !GVContext.isSubprogram()) {
+ if (DI_GV.isDefinition() && !GVContext.isCompileUnit() &&
+ !GVContext.isFile() && !GVContext.isSubprogram()) {
// Create specification DIE.
DIE *VariableSpecDIE = new DIE(dwarf::DW_TAG_variable);
addDIEEntry(VariableSpecDIE, dwarf::DW_AT_specification,
dwarf::DW_FORM_ref4, VariableDie);
- DIEBlock *Block = new DIEBlock();
+ DIEBlock *Block = new (DIEValueAllocator) DIEBlock();
addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_addr);
addLabel(Block, 0, dwarf::DW_FORM_udata,
Asm->Mang->getSymbol(DI_GV.getGlobal()));
@@ -1731,7 +1731,7 @@ void DwarfDebug::constructGlobalVariableDIE(MDNode *N) {
addUInt(VariableDie, dwarf::DW_AT_declaration, dwarf::DW_FORM_flag, 1);
ModuleCU->addDie(VariableSpecDIE);
} else {
- DIEBlock *Block = new DIEBlock();
+ DIEBlock *Block = new (DIEValueAllocator) DIEBlock();
addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_addr);
addLabel(Block, 0, dwarf::DW_FORM_udata,
Asm->Mang->getSymbol(DI_GV.getGlobal()));
@@ -1745,7 +1745,7 @@ void DwarfDebug::constructGlobalVariableDIE(MDNode *N) {
DIType GTy = DI_GV.getType();
if (GTy.isCompositeType() && !GTy.getName().empty()) {
DIEEntry *Entry = ModuleCU->getDIEEntry(GTy.getNode());
- assert (Entry && "Missing global type!");
+ assert(Entry && "Missing global type!");
ModuleCU->addGlobalType(GTy.getName(), Entry->getEntry());
}
return;
@@ -1783,12 +1783,11 @@ void DwarfDebug::constructSubprogramDIE(MDNode *N) {
void DwarfDebug::beginModule(Module *M, MachineModuleInfo *mmi) {
this->M = M;
- if (TimePassesIsEnabled)
- DebugTimer->startTimer();
-
if (!MAI->doesSupportDebugInformation())
return;
+ TimeRegion Timer(DebugTimer);
+
DebugInfoFinder DbgFinder;
DbgFinder.processModule(*M);
@@ -1836,9 +1835,6 @@ void DwarfDebug::beginModule(Module *M, MachineModuleInfo *mmi) {
// Emit initial sections
emitInitial();
-
- if (TimePassesIsEnabled)
- DebugTimer->stopTimer();
}
/// endModule - Emit all Dwarf sections that should come after the content.
@@ -1847,8 +1843,7 @@ void DwarfDebug::endModule() {
if (!ModuleCU)
return;
- if (TimePassesIsEnabled)
- DebugTimer->startTimer();
+ TimeRegion Timer(DebugTimer);
// Attach DW_AT_inline attribute with inlined subprogram DIEs.
for (SmallPtrSet<DIE *, 4>::iterator AI = InlinedSubprogramDIEs.begin(),
@@ -1871,7 +1866,7 @@ void DwarfDebug::endModule() {
if (!NDie) continue;
addDIEEntry(SPDie, dwarf::DW_AT_containing_type, dwarf::DW_FORM_ref4, NDie);
// FIXME - This is not the correct approach.
- // addDIEEntry(NDie, dwarf::DW_AT_containing_type, dwarf::DW_FORM_ref4, NDie);
+ //addDIEEntry(NDie, dwarf::DW_AT_containing_type, dwarf::DW_FORM_ref4, NDie
}
// Standard sections final addresses.
@@ -1932,9 +1927,6 @@ void DwarfDebug::endModule() {
delete ModuleCU;
ModuleCU = NULL; // Reset for the next Module, if any.
-
- if (TimePassesIsEnabled)
- DebugTimer->stopTimer();
}
/// findAbstractVariable - Find abstract variable, if any, associated with Var.
@@ -1971,10 +1963,11 @@ DbgVariable *DwarfDebug::findAbstractVariable(DIVariable &Var,
if (!Scope)
return NULL;
- AbsDbgVariable = new DbgVariable(Var, MI,
+ AbsDbgVariable = new DbgVariable(Var, MI,
NULL /* No more-abstract variable*/);
Scope->addVariable(AbsDbgVariable);
AbstractVariables[Var.getNode()] = AbsDbgVariable;
+ DbgValueStartMap[MI] = AbsDbgVariable;
return AbsDbgVariable;
}
@@ -2010,16 +2003,19 @@ void DwarfDebug::collectVariableInfo() {
for (MachineBasicBlock::const_iterator II = I->begin(), IE = I->end();
II != IE; ++II) {
const MachineInstr *MInsn = II;
- if (MInsn->getOpcode() != TargetOpcode::DBG_VALUE)
+ if (!MInsn->isDebugValue())
continue;
+
// FIXME : Lift this restriction.
if (MInsn->getNumOperands() != 3)
continue;
- DIVariable DV((MDNode*)(MInsn->getOperand(MInsn->getNumOperands() - 1).getMetadata()));
+ DIVariable DV((MDNode*)(MInsn->getOperand(MInsn->getNumOperands()
+ - 1).getMetadata()));
if (DV.getTag() == dwarf::DW_TAG_arg_variable) {
// FIXME Handle inlined subroutine arguments.
DbgVariable *ArgVar = new DbgVariable(DV, MInsn, NULL);
CurrentFnDbgScope->addVariable(ArgVar);
+ DbgValueStartMap[MInsn] = ArgVar;
continue;
}
@@ -2034,19 +2030,54 @@ void DwarfDebug::collectVariableInfo() {
if (!Scope)
continue;
- DbgVariable *AbsDbgVariable = findAbstractVariable(DV, MInsn,
- ScopeLoc);
+ DbgVariable *AbsDbgVariable = findAbstractVariable(DV, MInsn, ScopeLoc);
DbgVariable *RegVar = new DbgVariable(DV, MInsn, AbsDbgVariable);
+ DbgValueStartMap[MInsn] = RegVar;
Scope->addVariable(RegVar);
}
}
}
-/// beginScope - Process beginning of a scope starting at Label.
-void DwarfDebug::beginScope(const MachineInstr *MI, MCSymbol *Label) {
+/// beginScope - Process beginning of a scope.
+void DwarfDebug::beginScope(const MachineInstr *MI) {
+ // Check location.
+ DebugLoc DL = MI->getDebugLoc();
+ if (DL.isUnknown())
+ return;
+ DILocation DILoc = MF->getDILocation(DL);
+ if (!DILoc.getScope().Verify())
+ return;
+
+ // Check and update last known location info.
+ if(DILoc.getNode() == PrevDILoc)
+ return;
+
+ // DBG_VALUE instruction establishes new value.
+ if (MI->isDebugValue()) {
+ DenseMap<const MachineInstr *, DbgVariable *>::iterator DI
+ = DbgValueStartMap.find(MI);
+ if (DI != DbgValueStartMap.end()) {
+ MCSymbol *Label = recordSourceLine(DILoc.getLineNumber(),
+ DILoc.getColumnNumber(),
+ DILoc.getScope().getNode());
+ PrevDILoc = DILoc.getNode();
+ DI->second->setDbgValueLabel(Label);
+ }
+ return;
+ }
+
+ // Emit a label to indicate location change. This is used for line
+ // table even if this instruction does start a new scope.
+ MCSymbol *Label = recordSourceLine(DILoc.getLineNumber(),
+ DILoc.getColumnNumber(),
+ DILoc.getScope().getNode());
+ PrevDILoc = DILoc.getNode();
+
+ // update DbgScope if this instruction starts a new scope.
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)
@@ -2055,6 +2086,19 @@ void DwarfDebug::beginScope(const MachineInstr *MI, MCSymbol *Label) {
/// endScope - Process end of a scope.
void DwarfDebug::endScope(const MachineInstr *MI) {
+ // Ignore DBG_VALUE instruction.
+ if (MI->isDebugValue())
+ return;
+
+ // Check location.
+ DebugLoc DL = MI->getDebugLoc();
+ if (DL.isUnknown())
+ return;
+ DILocation DILoc = MF->getDILocation(DL);
+ if (!DILoc.getScope().Verify())
+ return;
+
+ // Emit a label and update DbgScope if this instruction ends a scope.
InsnToDbgScopeMapTy::iterator I = DbgScopeEndMap.find(MI);
if (I == DbgScopeEndMap.end())
return;
@@ -2094,7 +2138,7 @@ void DwarfDebug::createDbgScope(MDNode *Scope, MDNode *InlinedAt) {
}
/// extractScopeInformation - Scan machine instructions in this function
-/// and collect DbgScopes. Return true, if atleast one scope was found.
+/// and collect DbgScopes. Return true, if at least one scope was found.
bool DwarfDebug::extractScopeInformation() {
// If scope information was extracted using .dbg intrinsics then there is not
// any need to extract these information by scanning each instruction.
@@ -2110,12 +2154,13 @@ bool DwarfDebug::extractScopeInformation() {
II != IE; ++II) {
const MachineInstr *MInsn = II;
// FIXME : Remove DBG_VALUE check.
- if (MInsn->getOpcode() == TargetOpcode::DBG_VALUE) continue;
+ if (MInsn->isDebugValue()) continue;
MIIndexMap[MInsn] = MIIndex++;
DebugLoc DL = MInsn->getDebugLoc();
if (DL.isUnknown()) continue;
DILocation DLT = MF->getDILocation(DL);
DIScope DLTScope = DLT.getScope();
+ if (!DLTScope.getNode()) 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.
@@ -2132,11 +2177,12 @@ bool DwarfDebug::extractScopeInformation() {
II != IE; ++II) {
const MachineInstr *MInsn = II;
// FIXME : Remove DBG_VALUE check.
- if (MInsn->getOpcode() == TargetOpcode::DBG_VALUE) continue;
+ if (MInsn->isDebugValue()) continue;
DebugLoc DL = MInsn->getDebugLoc();
if (DL.isUnknown()) continue;
DILocation DLT = MF->getDILocation(DL);
DIScope DLTScope = DLT.getScope();
+ if (!DLTScope.getNode()) 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,7 +2205,7 @@ bool DwarfDebug::extractScopeInformation() {
SmallVector<DbgScope *, 4> WorkList;
WorkList.push_back(CurrentFnDbgScope);
while (!WorkList.empty()) {
- DbgScope *S = WorkList.back(); WorkList.pop_back();
+ DbgScope *S = WorkList.pop_back_val();
const SmallVector<DbgScope *, 4> &Children = S->getScopes();
if (!Children.empty())
@@ -2170,7 +2216,7 @@ bool DwarfDebug::extractScopeInformation() {
if (S->isAbstractScope())
continue;
const MachineInstr *MI = S->getFirstInsn();
- assert (MI && "DbgScope does not have first instruction!");
+ assert(MI && "DbgScope does not have first instruction!");
InsnToDbgScopeMapTy::iterator IDI = DbgScopeBeginMap.find(MI);
if (IDI != DbgScopeBeginMap.end())
@@ -2179,7 +2225,7 @@ bool DwarfDebug::extractScopeInformation() {
DbgScopeBeginMap[MI].push_back(S);
MI = S->getLastInsn();
- assert (MI && "DbgScope does not have last instruction!");
+ assert(MI && "DbgScope does not have last instruction!");
IDI = DbgScopeEndMap.find(MI);
if (IDI != DbgScopeEndMap.end())
IDI->second.push_back(S);
@@ -2196,12 +2242,10 @@ void DwarfDebug::beginFunction(const MachineFunction *MF) {
this->MF = MF;
if (!ShouldEmitDwarfDebug()) return;
-
- if (TimePassesIsEnabled)
- DebugTimer->startTimer();
-
if (!extractScopeInformation())
return;
+
+ TimeRegion Timer(DebugTimer);
collectVariableInfo();
@@ -2225,20 +2269,15 @@ void DwarfDebug::beginFunction(const MachineFunction *MF) {
recordSourceLine(Line, Col, DLT.getScope().getNode());
}
- if (TimePassesIsEnabled)
- DebugTimer->stopTimer();
}
/// endFunction - Gather and emit post-function debug information.
///
void DwarfDebug::endFunction(const MachineFunction *MF) {
if (!ShouldEmitDwarfDebug()) return;
-
- if (TimePassesIsEnabled)
- DebugTimer->startTimer();
-
- if (DbgScopeMap.empty())
- return;
+ if (DbgScopeMap.empty()) return;
+
+ TimeRegion Timer(DebugTimer);
if (CurrentFnDbgScope) {
// Define end label for subprogram.
@@ -2271,14 +2310,12 @@ void DwarfDebug::endFunction(const MachineFunction *MF) {
DeleteContainerSeconds(DbgScopeMap);
DbgScopeBeginMap.clear();
DbgScopeEndMap.clear();
+ DbgValueStartMap.clear();
ConcreteScopes.clear();
DeleteContainerSeconds(AbstractScopes);
AbstractScopesList.clear();
AbstractVariables.clear();
Lines.clear();
-
- if (TimePassesIsEnabled)
- DebugTimer->stopTimer();
}
/// recordSourceLine - Register a source line with debug info. Returns the
@@ -2288,8 +2325,7 @@ MCSymbol *DwarfDebug::recordSourceLine(unsigned Line, unsigned Col, MDNode *S) {
if (!MMI)
return 0;
- if (TimePassesIsEnabled)
- DebugTimer->startTimer();
+ TimeRegion Timer(DebugTimer);
StringRef Dir;
StringRef Fn;
@@ -2314,9 +2350,6 @@ MCSymbol *DwarfDebug::recordSourceLine(unsigned Line, unsigned Col, MDNode *S) {
MCSymbol *Label = MMI->getContext().CreateTempSymbol();
Lines.push_back(SrcLineInfo(Line, Col, Src, Label));
- if (TimePassesIsEnabled)
- DebugTimer->stopTimer();
-
Asm->OutStreamer.EmitLabel(Label);
return Label;
}
@@ -2328,15 +2361,8 @@ MCSymbol *DwarfDebug::recordSourceLine(unsigned Line, unsigned Col, MDNode *S) {
/// well.
unsigned DwarfDebug::getOrCreateSourceID(const std::string &DirName,
const std::string &FileName) {
- if (TimePassesIsEnabled)
- DebugTimer->startTimer();
-
- unsigned SrcId = GetOrCreateSourceID(DirName.c_str(), FileName.c_str());
-
- if (TimePassesIsEnabled)
- DebugTimer->stopTimer();
-
- return SrcId;
+ TimeRegion Timer(DebugTimer);
+ return GetOrCreateSourceID(DirName.c_str(), FileName.c_str());
}
//===----------------------------------------------------------------------===//
@@ -2351,7 +2377,8 @@ DwarfDebug::computeSizeAndOffset(DIE *Die, unsigned Offset, bool Last) {
const std::vector<DIE *> &Children = Die->getChildren();
// If not last sibling and has children then add sibling offset attribute.
- if (!Last && !Children.empty()) Die->addSiblingOffset();
+ if (!Last && !Children.empty())
+ Die->addSiblingOffset(DIEValueAllocator);
// Record the abbreviation.
assignAbbrevNumber(Die->getAbbrev());
@@ -2465,7 +2492,7 @@ void DwarfDebug::emitDIE(DIE *Die) {
dwarf::TagString(Abbrev->getTag()));
EmitULEB128(AbbrevNumber);
- SmallVector<DIEValue*, 32> &Values = Die->getValues();
+ const SmallVector<DIEValue*, 32> &Values = Die->getValues();
const SmallVector<DIEAbbrevData, 8> &AbbrevData = Abbrev->getData();
// Emit the DIE attribute values.
diff --git a/lib/CodeGen/AsmPrinter/DwarfDebug.h b/lib/CodeGen/AsmPrinter/DwarfDebug.h
index d6634e1..ad6b0c2 100644
--- a/lib/CodeGen/AsmPrinter/DwarfDebug.h
+++ b/lib/CodeGen/AsmPrinter/DwarfDebug.h
@@ -19,6 +19,7 @@
#include "llvm/CodeGen/AsmPrinter.h"
#include "llvm/CodeGen/MachineLocation.h"
#include "llvm/Analysis/DebugInfo.h"
+#include "llvm/Support/Allocator.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/FoldingSet.h"
@@ -98,9 +99,11 @@ class DwarfDebug : public DwarfPrinter {
/// Lines - List of source line correspondence.
std::vector<SrcLineInfo> Lines;
- /// DIEValues - A list of all the unique values in use.
- ///
- std::vector<DIEValue *> DIEValues;
+ /// DIEBlocks - A list of all the DIEBlocks in use.
+ std::vector<DIEBlock *> DIEBlocks;
+
+ // DIEValueAllocator - All DIEValues are allocated through this allocator.
+ BumpPtrAllocator DIEValueAllocator;
/// StringPool - A String->Symbol mapping of strings used by indirect
/// references.
@@ -141,12 +144,21 @@ class DwarfDebug : public DwarfPrinter {
/// AbstractScopes - Tracks the abstract scopes a module. These scopes are
/// not included DbgScopeMap. AbstractScopes owns its DbgScope*s.
DenseMap<MDNode *, DbgScope *> AbstractScopes;
+
+ /// AbstractScopesList - Tracks abstract scopes constructed while processing
+ /// a function. This list is cleared during endFunction().
SmallVector<DbgScope *, 4>AbstractScopesList;
/// AbstractVariables - Collection on abstract variables. Owned by the
/// DbgScopes in AbstractScopes.
DenseMap<MDNode *, DbgVariable *> AbstractVariables;
+ /// DbgValueStartMap - Tracks starting scope of variable DIEs.
+ /// If the scope of an object begins sometime after the low pc value for the
+ /// scope most closely enclosing the object, the object entry may have a
+ /// DW_AT_start_scope attribute.
+ DenseMap<const MachineInstr *, DbgVariable *> DbgValueStartMap;
+
/// InliendSubprogramDIEs - Collection of subprgram DIEs that are marked
/// (at the end of the module) as DW_AT_inline.
SmallPtrSet<DIE *, 4> InlinedSubprogramDIEs;
@@ -181,6 +193,10 @@ class DwarfDebug : public DwarfPrinter {
/// function.
DenseMap<CompileUnit *, unsigned> CompileUnitOffsets;
+ /// Previous instruction's location information. This is used to determine
+ /// label location to indicate scope boundries in dwarf debug info.
+ mutable const MDNode *PrevDILoc;
+
/// DebugTimer - Timer for the Dwarf debug writer.
Timer *DebugTimer;
@@ -250,12 +266,6 @@ class DwarfDebug : public DwarfPrinter {
void addLabel(DIE *Die, unsigned Attribute, unsigned Form,
const MCSymbol *Label);
- /// addSectionOffset - Add a section offset label attribute data and value.
- ///
- void addSectionOffset(DIE *Die, unsigned Attribute, unsigned Form,
- 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,
@@ -545,8 +555,8 @@ public:
/// collectVariableInfo - Populate DbgScope entries with variables' info.
void collectVariableInfo();
- /// beginScope - Process beginning of a scope starting at Label.
- void beginScope(const MachineInstr *MI, MCSymbol *Label);
+ /// beginScope - Process beginning of a scope.
+ void beginScope(const MachineInstr *MI);
/// 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 4946b4c..8b616b0 100644
--- a/lib/CodeGen/AsmPrinter/DwarfException.cpp
+++ b/lib/CodeGen/AsmPrinter/DwarfException.cpp
@@ -419,23 +419,24 @@ bool DwarfException::CallToNoUnwindFunction(const MachineInstr *MI) {
for (unsigned I = 0, E = MI->getNumOperands(); I != E; ++I) {
const MachineOperand &MO = MI->getOperand(I);
- if (MO.isGlobal()) {
- if (Function *F = dyn_cast<Function>(MO.getGlobal())) {
- if (SawFunc) {
- // Be conservative. If we have more than one function operand for this
- // call, then we can't make the assumption that it's the callee and
- // not a parameter to the call.
- //
- // FIXME: Determine if there's a way to say that `F' is the callee or
- // parameter.
- MarkedNoUnwind = false;
- break;
- }
-
- MarkedNoUnwind = F->doesNotThrow();
- SawFunc = true;
- }
+ if (!MO.isGlobal()) continue;
+
+ Function *F = dyn_cast<Function>(MO.getGlobal());
+ if (F == 0) continue;
+
+ if (SawFunc) {
+ // Be conservative. If we have more than one function operand for this
+ // call, then we can't make the assumption that it's the callee and
+ // not a parameter to the call.
+ //
+ // FIXME: Determine if there's a way to say that `F' is the callee or
+ // parameter.
+ MarkedNoUnwind = false;
+ break;
}
+
+ MarkedNoUnwind = F->doesNotThrow();
+ SawFunc = true;
}
return MarkedNoUnwind;
@@ -504,7 +505,10 @@ ComputeCallSiteTable(SmallVectorImpl<CallSiteEntry> &CallSites,
LastLabel = LandingPad->EndLabels[P.RangeIndex];
assert(BeginLabel && LastLabel && "Invalid landing pad!");
- if (LandingPad->LandingPadLabel) {
+ if (!LandingPad->LandingPadLabel) {
+ // Create a gap.
+ PreviousIsInvoke = false;
+ } else {
// This try-range is for an invoke.
CallSiteEntry Site = {
BeginLabel,
@@ -536,9 +540,6 @@ ComputeCallSiteTable(SmallVectorImpl<CallSiteEntry> &CallSites,
CallSites[SiteNo - 1] = Site;
}
PreviousIsInvoke = true;
- } else {
- // Create a gap.
- PreviousIsInvoke = false;
}
}
}
@@ -885,8 +886,7 @@ void DwarfException::EndModule() {
if (!shouldEmitMovesModule && !shouldEmitTableModule)
return;
- if (TimePassesIsEnabled)
- ExceptionTimer->startTimer();
+ TimeRegion Timer(ExceptionTimer);
const std::vector<Function *> Personalities = MMI->getPersonalities();
@@ -896,9 +896,6 @@ void DwarfException::EndModule() {
for (std::vector<FunctionEHFrameInfo>::iterator
I = EHFrames.begin(), E = EHFrames.end(); I != E; ++I)
EmitFDE(*I);
-
- if (TimePassesIsEnabled)
- ExceptionTimer->stopTimer();
}
/// BeginFunction - Gather pre-function exception information. Assumes it's
@@ -906,9 +903,7 @@ void DwarfException::EndModule() {
void DwarfException::BeginFunction(const MachineFunction *MF) {
if (!MMI || !MAI->doesSupportExceptionHandling()) return;
- if (TimePassesIsEnabled)
- ExceptionTimer->startTimer();
-
+ TimeRegion Timer(ExceptionTimer);
this->MF = MF;
shouldEmitTable = shouldEmitMoves = false;
@@ -924,9 +919,6 @@ void DwarfException::BeginFunction(const MachineFunction *MF) {
shouldEmitTableModule |= shouldEmitTable;
shouldEmitMovesModule |= shouldEmitMoves;
-
- if (TimePassesIsEnabled)
- ExceptionTimer->stopTimer();
}
/// EndFunction - Gather and emit post-function exception information.
@@ -934,9 +926,7 @@ void DwarfException::BeginFunction(const MachineFunction *MF) {
void DwarfException::EndFunction() {
if (!shouldEmitMoves && !shouldEmitTable) return;
- if (TimePassesIsEnabled)
- ExceptionTimer->startTimer();
-
+ TimeRegion Timer(ExceptionTimer);
Asm->OutStreamer.EmitLabel(getDWLabel("eh_func_end", SubprogramCount));
// Record if this personality index uses a landing pad.
@@ -961,7 +951,4 @@ void DwarfException::EndFunction() {
!MMI->getLandingPads().empty(),
MMI->getFrameMoves(),
MF->getFunction()));
-
- if (TimePassesIsEnabled)
- ExceptionTimer->stopTimer();
}
diff --git a/lib/CodeGen/AsmPrinter/DwarfPrinter.cpp b/lib/CodeGen/AsmPrinter/DwarfPrinter.cpp
index e212696..17eb2e8 100644
--- a/lib/CodeGen/AsmPrinter/DwarfPrinter.cpp
+++ b/lib/CodeGen/AsmPrinter/DwarfPrinter.cpp
@@ -45,14 +45,14 @@ MCSymbol *DwarfPrinter::getDWLabel(const char *Name, unsigned ID) const {
//assert(ID && "Should use getTempLabel if no ID");
if (ID == 0) return getTempLabel(Name);
- return Asm->OutContext.GetOrCreateTemporarySymbol
+ return Asm->OutContext.GetOrCreateSymbol
(Twine(MAI->getPrivateGlobalPrefix()) + Twine(Name) + Twine(ID));
}
/// getTempLabel - Return the MCSymbol corresponding to the assembler temporary
/// label with the specified name.
MCSymbol *DwarfPrinter::getTempLabel(const char *Name) const {
- return Asm->OutContext.GetOrCreateTemporarySymbol
+ return Asm->OutContext.GetOrCreateSymbol
(Twine(MAI->getPrivateGlobalPrefix()) + Name);
}
diff --git a/lib/CodeGen/AsmPrinter/DwarfWriter.cpp b/lib/CodeGen/AsmPrinter/DwarfWriter.cpp
index 9fd4c44..a2d7ab1 100644
--- a/lib/CodeGen/AsmPrinter/DwarfWriter.cpp
+++ b/lib/CodeGen/AsmPrinter/DwarfWriter.cpp
@@ -73,27 +73,14 @@ void DwarfWriter::EndFunction(const MachineFunction *MF) {
MMI->EndFunction();
}
-/// 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);
-}
-
-/// getRecordSourceLineCount - Count source lines.
-unsigned DwarfWriter::getRecordSourceLineCount() {
- return DD->getSourceLineCount();
-}
-
/// ShouldEmitDwarfDebug - Returns true if Dwarf debugging declarations should
/// be emitted.
bool DwarfWriter::ShouldEmitDwarfDebug() const {
return DD && DD->ShouldEmitDwarfDebug();
}
-void DwarfWriter::BeginScope(const MachineInstr *MI, MCSymbol *L) {
- DD->beginScope(MI, L);
+void DwarfWriter::BeginScope(const MachineInstr *MI) {
+ DD->beginScope(MI);
}
void DwarfWriter::EndScope(const MachineInstr *MI) {
DD->endScope(MI);
diff --git a/lib/CodeGen/BranchFolding.cpp b/lib/CodeGen/BranchFolding.cpp
index 151e9cd..8f51940 100644
--- a/lib/CodeGen/BranchFolding.cpp
+++ b/lib/CodeGen/BranchFolding.cpp
@@ -972,15 +972,21 @@ static bool IsBetterFallthrough(MachineBasicBlock *MBB1,
// MBB1 doesn't, we prefer to fall through into MBB1. This allows us to
// optimize branches that branch to either a return block or an assert block
// into a fallthrough to the return.
- if (MBB1->empty() || MBB2->empty()) return false;
+ if (IsEmptyBlock(MBB1) || IsEmptyBlock(MBB2)) return false;
// If there is a clear successor ordering we make sure that one block
// will fall through to the next
if (MBB1->isSuccessor(MBB2)) return true;
if (MBB2->isSuccessor(MBB1)) return false;
- MachineInstr *MBB1I = --MBB1->end();
- MachineInstr *MBB2I = --MBB2->end();
+ // Neither block consists entirely of debug info (per IsEmptyBlock check),
+ // so we needn't test for falling off the beginning here.
+ MachineBasicBlock::iterator MBB1I = --MBB1->end();
+ while (MBB1I->isDebugValue())
+ --MBB1I;
+ MachineBasicBlock::iterator MBB2I = --MBB2->end();
+ while (MBB2I->isDebugValue())
+ --MBB2I;
return MBB2I->getDesc().isCall() && !MBB1I->getDesc().isCall();
}
diff --git a/lib/CodeGen/DwarfEHPrepare.cpp b/lib/CodeGen/DwarfEHPrepare.cpp
index 39fc85e..8bae9ed 100644
--- a/lib/CodeGen/DwarfEHPrepare.cpp
+++ b/lib/CodeGen/DwarfEHPrepare.cpp
@@ -8,19 +8,19 @@
//===----------------------------------------------------------------------===//
//
// This pass mulches exception handling code into a form adapted to code
-// generation. Required if using dwarf exception handling.
+// generation. Required if using dwarf exception handling.
//
//===----------------------------------------------------------------------===//
#define DEBUG_TYPE "dwarfehprepare"
-#include "llvm/ADT/Statistic.h"
-#include "llvm/Analysis/Dominators.h"
-#include "llvm/CodeGen/Passes.h"
#include "llvm/Function.h"
#include "llvm/Instructions.h"
#include "llvm/IntrinsicInst.h"
#include "llvm/Module.h"
#include "llvm/Pass.h"
+#include "llvm/ADT/Statistic.h"
+#include "llvm/Analysis/Dominators.h"
+#include "llvm/CodeGen/Passes.h"
#include "llvm/MC/MCAsmInfo.h"
#include "llvm/Target/TargetLowering.h"
#include "llvm/Transforms/Utils/BasicBlockUtils.h"
@@ -40,6 +40,15 @@ namespace {
// The eh.exception intrinsic.
Function *ExceptionValueIntrinsic;
+ // The eh.selector intrinsic.
+ Function *SelectorIntrinsic;
+
+ // _Unwind_Resume_or_Rethrow call.
+ Constant *URoR;
+
+ // The EH language-specific catch-all type.
+ GlobalVariable *EHCatchAllValue;
+
// _Unwind_Resume or the target equivalent.
Constant *RewindFunction;
@@ -67,18 +76,88 @@ namespace {
Instruction *CreateValueLoad(BasicBlock *BB);
/// CreateReadOfExceptionValue - Return the result of the eh.exception
- /// intrinsic by calling the intrinsic if in a landing pad, or loading
- /// it from the exception value variable otherwise.
+ /// intrinsic by calling the intrinsic if in a landing pad, or loading it
+ /// from the exception value variable otherwise.
Instruction *CreateReadOfExceptionValue(BasicBlock *BB) {
return LandingPads.count(BB) ?
CreateExceptionValueCall(BB) : CreateValueLoad(BB);
}
+ /// CleanupSelectors - Any remaining eh.selector intrinsic calls which still
+ /// use the ".llvm.eh.catch.all.value" call need to convert to using it's
+ /// initializer instead.
+ bool CleanupSelectors();
+
+ /// FindAllCleanupSelectors - Find all eh.selector calls that are clean-ups.
+ void FindAllCleanupSelectors(SmallPtrSet<IntrinsicInst*, 32> &Sels);
+
+ /// FindAllURoRInvokes - Find all URoR invokes in the function.
+ void FindAllURoRInvokes(SmallPtrSet<InvokeInst*, 32> &URoRInvokes);
+
+ /// HandleURoRInvokes - Handle invokes of "_Unwind_Resume_or_Rethrow"
+ /// calls. The "unwind" part of these invokes jump to a landing pad within
+ /// the current function. This is a candidate to merge the selector
+ /// associated with the URoR invoke with the one from the URoR's landing
+ /// pad.
+ bool HandleURoRInvokes();
+
+ /// FindSelectorAndURoR - Find the eh.selector call and URoR call associated
+ /// with the eh.exception call. This recursively looks past instructions
+ /// which don't change the EH pointer value, like casts or PHI nodes.
+ bool FindSelectorAndURoR(Instruction *Inst, bool &URoRInvoke,
+ SmallPtrSet<IntrinsicInst*, 8> &SelCalls);
+
+ /// DoMem2RegPromotion - Take an alloca call and promote it from memory to a
+ /// register.
+ bool DoMem2RegPromotion(Value *V) {
+ AllocaInst *AI = dyn_cast<AllocaInst>(V);
+ if (!AI || !isAllocaPromotable(AI)) return false;
+
+ // Turn the alloca into a register.
+ std::vector<AllocaInst*> Allocas(1, AI);
+ PromoteMemToReg(Allocas, *DT, *DF);
+ return true;
+ }
+
+ /// PromoteStoreInst - Perform Mem2Reg on a StoreInst.
+ bool PromoteStoreInst(StoreInst *SI) {
+ if (!SI || !DT || !DF) return false;
+ if (DoMem2RegPromotion(SI->getOperand(1)))
+ return true;
+ return false;
+ }
+
+ /// PromoteEHPtrStore - Promote the storing of an EH pointer into a
+ /// register. This should get rid of the store and subsequent loads.
+ bool PromoteEHPtrStore(IntrinsicInst *II) {
+ if (!DT || !DF) return false;
+
+ bool Changed = false;
+ StoreInst *SI;
+
+ while (1) {
+ SI = 0;
+ for (Value::use_iterator
+ I = II->use_begin(), E = II->use_end(); I != E; ++I) {
+ SI = dyn_cast<StoreInst>(I);
+ if (SI) break;
+ }
+
+ if (!PromoteStoreInst(SI))
+ break;
+
+ Changed = true;
+ }
+
+ return false;
+ }
+
public:
static char ID; // Pass identification, replacement for typeid.
DwarfEHPrepare(const TargetLowering *tli, bool fast) :
FunctionPass(&ID), TLI(tli), CompileFast(fast),
- ExceptionValueIntrinsic(0), RewindFunction(0) {}
+ ExceptionValueIntrinsic(0), SelectorIntrinsic(0),
+ URoR(0), EHCatchAllValue(0), RewindFunction(0) {}
virtual bool runOnFunction(Function &Fn);
@@ -105,6 +184,233 @@ FunctionPass *llvm::createDwarfEHPass(const TargetLowering *tli, bool fast) {
return new DwarfEHPrepare(tli, fast);
}
+/// FindAllCleanupSelectors - Find all eh.selector calls that are clean-ups.
+void DwarfEHPrepare::
+FindAllCleanupSelectors(SmallPtrSet<IntrinsicInst*, 32> &Sels) {
+ for (Value::use_iterator
+ I = SelectorIntrinsic->use_begin(),
+ E = SelectorIntrinsic->use_end(); I != E; ++I) {
+ IntrinsicInst *SI = cast<IntrinsicInst>(I);
+ if (!SI || SI->getParent()->getParent() != F) continue;
+
+ unsigned NumOps = SI->getNumOperands();
+ if (NumOps > 4) continue;
+ bool IsCleanUp = (NumOps == 3);
+
+ if (!IsCleanUp)
+ if (ConstantInt *CI = dyn_cast<ConstantInt>(SI->getOperand(3)))
+ IsCleanUp = (CI->getZExtValue() == 0);
+
+ if (IsCleanUp)
+ Sels.insert(SI);
+ }
+}
+
+/// FindAllURoRInvokes - Find all URoR invokes in the function.
+void DwarfEHPrepare::
+FindAllURoRInvokes(SmallPtrSet<InvokeInst*, 32> &URoRInvokes) {
+ for (Value::use_iterator
+ I = URoR->use_begin(),
+ E = URoR->use_end(); I != E; ++I) {
+ if (InvokeInst *II = dyn_cast<InvokeInst>(I))
+ URoRInvokes.insert(II);
+ }
+}
+
+/// CleanupSelectors - Any remaining eh.selector intrinsic calls which still use
+/// the ".llvm.eh.catch.all.value" call need to convert to using it's
+/// initializer instead.
+bool DwarfEHPrepare::CleanupSelectors() {
+ if (!EHCatchAllValue) return false;
+
+ if (!SelectorIntrinsic) {
+ SelectorIntrinsic =
+ Intrinsic::getDeclaration(F->getParent(), Intrinsic::eh_selector);
+ if (!SelectorIntrinsic) return false;
+ }
+
+ bool Changed = false;
+ for (Value::use_iterator
+ I = SelectorIntrinsic->use_begin(),
+ E = SelectorIntrinsic->use_end(); I != E; ++I) {
+ IntrinsicInst *Sel = dyn_cast<IntrinsicInst>(I);
+ if (!Sel || Sel->getParent()->getParent() != F) continue;
+
+ // Index of the ".llvm.eh.catch.all.value" variable.
+ unsigned OpIdx = Sel->getNumOperands() - 1;
+ GlobalVariable *GV = dyn_cast<GlobalVariable>(Sel->getOperand(OpIdx));
+ if (GV != EHCatchAllValue) continue;
+ Sel->setOperand(OpIdx, EHCatchAllValue->getInitializer());
+ Changed = true;
+ }
+
+ return Changed;
+}
+
+/// FindSelectorAndURoR - Find the eh.selector call associated with the
+/// eh.exception call. And indicate if there is a URoR "invoke" associated with
+/// the eh.exception call. This recursively looks past instructions which don't
+/// change the EH pointer value, like casts or PHI nodes.
+bool
+DwarfEHPrepare::FindSelectorAndURoR(Instruction *Inst, bool &URoRInvoke,
+ SmallPtrSet<IntrinsicInst*, 8> &SelCalls) {
+ SmallPtrSet<PHINode*, 32> SeenPHIs;
+ bool Changed = false;
+
+ restart:
+ for (Value::use_iterator
+ I = Inst->use_begin(), E = Inst->use_end(); I != E; ++I) {
+ Instruction *II = dyn_cast<Instruction>(I);
+ if (!II || II->getParent()->getParent() != F) continue;
+
+ if (IntrinsicInst *Sel = dyn_cast<IntrinsicInst>(II)) {
+ if (Sel->getIntrinsicID() == Intrinsic::eh_selector)
+ SelCalls.insert(Sel);
+ } else if (InvokeInst *Invoke = dyn_cast<InvokeInst>(II)) {
+ if (Invoke->getCalledFunction() == URoR)
+ URoRInvoke = true;
+ } else if (CastInst *CI = dyn_cast<CastInst>(II)) {
+ Changed |= FindSelectorAndURoR(CI, URoRInvoke, SelCalls);
+ } else if (StoreInst *SI = dyn_cast<StoreInst>(II)) {
+ if (!PromoteStoreInst(SI)) continue;
+ Changed = true;
+ SeenPHIs.clear();
+ goto restart; // Uses may have changed, restart loop.
+ } else if (PHINode *PN = dyn_cast<PHINode>(II)) {
+ if (SeenPHIs.insert(PN))
+ // Don't process a PHI node more than once.
+ Changed |= FindSelectorAndURoR(PN, URoRInvoke, SelCalls);
+ }
+ }
+
+ return Changed;
+}
+
+/// HandleURoRInvokes - Handle invokes of "_Unwind_Resume_or_Rethrow" calls. The
+/// "unwind" part of these invokes jump to a landing pad within the current
+/// function. This is a candidate to merge the selector associated with the URoR
+/// invoke with the one from the URoR's landing pad.
+bool DwarfEHPrepare::HandleURoRInvokes() {
+ if (!DT) return CleanupSelectors(); // We require DominatorTree information.
+
+ if (!EHCatchAllValue) {
+ EHCatchAllValue =
+ F->getParent()->getNamedGlobal(".llvm.eh.catch.all.value");
+ if (!EHCatchAllValue) return false;
+ }
+
+ if (!SelectorIntrinsic) {
+ SelectorIntrinsic =
+ Intrinsic::getDeclaration(F->getParent(), Intrinsic::eh_selector);
+ if (!SelectorIntrinsic) return false;
+ }
+
+ if (!URoR) {
+ URoR = F->getParent()->getFunction("_Unwind_Resume_or_Rethrow");
+ if (!URoR) return CleanupSelectors();
+ }
+
+ SmallPtrSet<IntrinsicInst*, 32> Sels;
+ SmallPtrSet<InvokeInst*, 32> URoRInvokes;
+ FindAllCleanupSelectors(Sels);
+ FindAllURoRInvokes(URoRInvokes);
+
+ SmallPtrSet<IntrinsicInst*, 32> SelsToConvert;
+
+ for (SmallPtrSet<IntrinsicInst*, 32>::iterator
+ SI = Sels.begin(), SE = Sels.end(); SI != SE; ++SI) {
+ const BasicBlock *SelBB = (*SI)->getParent();
+ for (SmallPtrSet<InvokeInst*, 32>::iterator
+ UI = URoRInvokes.begin(), UE = URoRInvokes.end(); UI != UE; ++UI) {
+ const BasicBlock *URoRBB = (*UI)->getParent();
+ if (SelBB == URoRBB || DT->dominates(SelBB, URoRBB)) {
+ SelsToConvert.insert(*SI);
+ break;
+ }
+ }
+ }
+
+ bool Changed = false;
+
+ if (Sels.size() != SelsToConvert.size()) {
+ // If we haven't been able to convert all of the clean-up selectors, then
+ // loop through the slow way to see if they still need to be converted.
+ if (!ExceptionValueIntrinsic) {
+ ExceptionValueIntrinsic =
+ Intrinsic::getDeclaration(F->getParent(), Intrinsic::eh_exception);
+ if (!ExceptionValueIntrinsic) return CleanupSelectors();
+ }
+
+ for (Value::use_iterator
+ I = ExceptionValueIntrinsic->use_begin(),
+ E = ExceptionValueIntrinsic->use_end(); I != E; ++I) {
+ IntrinsicInst *EHPtr = dyn_cast<IntrinsicInst>(I);
+ if (!EHPtr || EHPtr->getParent()->getParent() != F) continue;
+
+ Changed |= PromoteEHPtrStore(EHPtr);
+
+ bool URoRInvoke = false;
+ SmallPtrSet<IntrinsicInst*, 8> SelCalls;
+ Changed |= FindSelectorAndURoR(EHPtr, URoRInvoke, SelCalls);
+
+ if (URoRInvoke) {
+ // This EH pointer is being used by an invoke of an URoR instruction and
+ // an eh.selector intrinsic call. If the eh.selector is a 'clean-up', we
+ // need to convert it to a 'catch-all'.
+ for (SmallPtrSet<IntrinsicInst*, 8>::iterator
+ SI = SelCalls.begin(), SE = SelCalls.end(); SI != SE; ++SI) {
+ IntrinsicInst *II = *SI;
+ unsigned NumOps = II->getNumOperands();
+
+ if (NumOps <= 4) {
+ bool IsCleanUp = (NumOps == 3);
+
+ if (!IsCleanUp)
+ if (ConstantInt *CI = dyn_cast<ConstantInt>(II->getOperand(3)))
+ IsCleanUp = (CI->getZExtValue() == 0);
+
+ if (IsCleanUp)
+ SelsToConvert.insert(II);
+ }
+ }
+ }
+ }
+ }
+
+ if (!SelsToConvert.empty()) {
+ // Convert all clean-up eh.selectors, which are associated with "invokes" of
+ // URoR calls, into catch-all eh.selectors.
+ Changed = true;
+
+ for (SmallPtrSet<IntrinsicInst*, 8>::iterator
+ SI = SelsToConvert.begin(), SE = SelsToConvert.end();
+ SI != SE; ++SI) {
+ IntrinsicInst *II = *SI;
+ SmallVector<Value*, 8> Args;
+
+ // Use the exception object pointer and the personality function
+ // from the original selector.
+ Args.push_back(II->getOperand(1)); // Exception object pointer.
+ Args.push_back(II->getOperand(2)); // Personality function.
+ Args.push_back(EHCatchAllValue->getInitializer()); // Catch-all indicator.
+
+ CallInst *NewSelector =
+ CallInst::Create(SelectorIntrinsic, Args.begin(), Args.end(),
+ "eh.sel.catch.all", II);
+
+ NewSelector->setTailCall(II->isTailCall());
+ NewSelector->setAttributes(II->getAttributes());
+ NewSelector->setCallingConv(II->getCallingConv());
+
+ II->replaceAllUsesWith(NewSelector);
+ II->eraseFromParent();
+ }
+ }
+
+ Changed |= CleanupSelectors();
+ return Changed;
+}
+
/// NormalizeLandingPads - Normalize and discover landing pads, noting them
/// in the LandingPads set. A landing pad is normal if the only CFG edges
/// that end at it are unwind edges from invoke instructions. If we inlined
@@ -422,6 +728,8 @@ bool DwarfEHPrepare::runOnFunction(Function &Fn) {
if (!CompileFast)
Changed |= PromoteStackTemporaries();
+ Changed |= HandleURoRInvokes();
+
LandingPads.clear();
return Changed;
diff --git a/lib/CodeGen/LiveInterval.cpp b/lib/CodeGen/LiveInterval.cpp
index e207f60..025ad05 100644
--- a/lib/CodeGen/LiveInterval.cpp
+++ b/lib/CodeGen/LiveInterval.cpp
@@ -303,9 +303,7 @@ void LiveInterval::removeRange(SlotIndex Start, SlotIndex End,
// otherwise mark it as ~1U so it can be nuked later.
if (ValNo->id == getNumValNums()-1) {
do {
- VNInfo *VNI = valnos.back();
valnos.pop_back();
- VNI->~VNInfo();
} while (!valnos.empty() && valnos.back()->isUnused());
} else {
ValNo->setIsUnused(true);
@@ -351,9 +349,7 @@ void LiveInterval::removeValNo(VNInfo *ValNo) {
// otherwise mark it as ~1U so it can be nuked later.
if (ValNo->id == getNumValNums()-1) {
do {
- VNInfo *VNI = valnos.back();
valnos.pop_back();
- VNI->~VNInfo();
} while (!valnos.empty() && valnos.back()->isUnused());
} else {
ValNo->setIsUnused(true);
@@ -579,9 +575,7 @@ void LiveInterval::MergeValueInAsValue(
// mark it as ~1U so it can be nuked later.
if (V1->id == getNumValNums()-1) {
do {
- VNInfo *VNI = valnos.back();
valnos.pop_back();
- VNI->~VNInfo();
} while (!valnos.empty() && valnos.back()->isUnused());
} else {
V1->setIsUnused(true);
@@ -597,7 +591,7 @@ void LiveInterval::MergeValueInAsValue(
/// used with an unknown definition value.
void LiveInterval::MergeInClobberRanges(LiveIntervals &li_,
const LiveInterval &Clobbers,
- BumpPtrAllocator &VNInfoAllocator) {
+ VNInfo::Allocator &VNInfoAllocator) {
if (Clobbers.empty()) return;
DenseMap<VNInfo*, VNInfo*> ValNoMaps;
@@ -658,14 +652,13 @@ void LiveInterval::MergeInClobberRanges(LiveIntervals &li_,
if (UnusedValNo) {
// Delete the last unused val#.
valnos.pop_back();
- UnusedValNo->~VNInfo();
}
}
void LiveInterval::MergeInClobberRange(LiveIntervals &li_,
SlotIndex Start,
SlotIndex End,
- BumpPtrAllocator &VNInfoAllocator) {
+ VNInfo::Allocator &VNInfoAllocator) {
// Find a value # to use for the clobber ranges. If there is already a value#
// for unknown values, use it.
VNInfo *ClobberValNo =
@@ -749,9 +742,7 @@ VNInfo* LiveInterval::MergeValueNumberInto(VNInfo *V1, VNInfo *V2) {
// ~1U so it can be nuked later.
if (V1->id == getNumValNums()-1) {
do {
- VNInfo *VNI = valnos.back();
valnos.pop_back();
- VNI->~VNInfo();
} while (valnos.back()->isUnused());
} else {
V1->setIsUnused(true);
@@ -762,7 +753,7 @@ VNInfo* LiveInterval::MergeValueNumberInto(VNInfo *V1, VNInfo *V2) {
void LiveInterval::Copy(const LiveInterval &RHS,
MachineRegisterInfo *MRI,
- BumpPtrAllocator &VNInfoAllocator) {
+ VNInfo::Allocator &VNInfoAllocator) {
ranges.clear();
valnos.clear();
std::pair<unsigned, unsigned> Hint = MRI->getRegAllocationHint(RHS.reg);
diff --git a/lib/CodeGen/LiveIntervalAnalysis.cpp b/lib/CodeGen/LiveIntervalAnalysis.cpp
index b3e9216..23cff07 100644
--- a/lib/CodeGen/LiveIntervalAnalysis.cpp
+++ b/lib/CodeGen/LiveIntervalAnalysis.cpp
@@ -91,7 +91,7 @@ void LiveIntervals::releaseMemory() {
r2iMap_.clear();
// Release VNInfo memroy regions after all VNInfo objects are dtor'd.
- VNInfoAllocator.Reset();
+ VNInfoAllocator.DestroyAll();
while (!CloneMIs.empty()) {
MachineInstr *MI = CloneMIs.back();
CloneMIs.pop_back();
@@ -819,8 +819,9 @@ bool LiveIntervals::isReMaterializable(const LiveInterval &li,
unsigned ImpUse = getReMatImplicitUse(li, MI);
if (ImpUse) {
const LiveInterval &ImpLi = getInterval(ImpUse);
- for (MachineRegisterInfo::use_iterator ri = mri_->use_begin(li.reg),
- re = mri_->use_end(); ri != re; ++ri) {
+ for (MachineRegisterInfo::use_nodbg_iterator
+ ri = mri_->use_nodbg_begin(li.reg), re = mri_->use_nodbg_end();
+ ri != re; ++ri) {
MachineInstr *UseMI = &*ri;
SlotIndex UseIdx = getInstructionIndex(UseMI);
if (li.FindLiveRangeContaining(UseIdx)->valno != ValNo)
@@ -1052,7 +1053,7 @@ rewriteInstructionForSpills(const LiveInterval &li, const VNInfo *VNI,
// all of its uses are rematerialized, simply delete it.
if (MI == ReMatOrigDefMI && CanDelete) {
DEBUG(dbgs() << "\t\t\t\tErasing re-materializable def: "
- << MI << '\n');
+ << *MI << '\n');
RemoveMachineInstrFromMaps(MI);
vrm.RemoveMachineInstrFromMaps(MI);
MI->eraseFromParent();
@@ -1520,6 +1521,12 @@ LiveIntervals::handleSpilledImpDefs(const LiveInterval &li, VirtRegMap &vrm,
MachineOperand &O = ri.getOperand();
MachineInstr *MI = &*ri;
++ri;
+ if (MI->isDebugValue()) {
+ // Remove debug info for now.
+ O.setReg(0U);
+ DEBUG(dbgs() << "Removing debug info due to spill:" << "\t" << *MI);
+ continue;
+ }
if (O.isDef()) {
assert(MI->isImplicitDef() &&
"Register def was not rewritten?");
@@ -2012,6 +2019,8 @@ unsigned LiveIntervals::getNumConflictsWithPhysReg(const LiveInterval &li,
E = mri_->reg_end(); I != E; ++I) {
MachineOperand &O = I.getOperand();
MachineInstr *MI = O.getParent();
+ if (MI->isDebugValue())
+ continue;
SlotIndex Index = getInstructionIndex(MI);
if (pli.liveAt(Index))
++NumConflicts;
@@ -2052,7 +2061,7 @@ bool LiveIntervals::spillPhysRegAroundRegDefsUses(const LiveInterval &li,
E = mri_->reg_end(); I != E; ++I) {
MachineOperand &O = I.getOperand();
MachineInstr *MI = O.getParent();
- if (SeenMIs.count(MI))
+ if (MI->isDebugValue() || SeenMIs.count(MI))
continue;
SeenMIs.insert(MI);
SlotIndex Index = getInstructionIndex(MI);
diff --git a/lib/CodeGen/LiveStackAnalysis.cpp b/lib/CodeGen/LiveStackAnalysis.cpp
index d2f3775..798b9b9 100644
--- a/lib/CodeGen/LiveStackAnalysis.cpp
+++ b/lib/CodeGen/LiveStackAnalysis.cpp
@@ -36,7 +36,7 @@ void LiveStacks::getAnalysisUsage(AnalysisUsage &AU) const {
void LiveStacks::releaseMemory() {
// Release VNInfo memroy regions after all VNInfo objects are dtor'd.
- VNInfoAllocator.Reset();
+ VNInfoAllocator.DestroyAll();
S2IMap.clear();
S2RCMap.clear();
}
diff --git a/lib/CodeGen/LiveVariables.cpp b/lib/CodeGen/LiveVariables.cpp
index 519990e..ca8ecff 100644
--- a/lib/CodeGen/LiveVariables.cpp
+++ b/lib/CodeGen/LiveVariables.cpp
@@ -556,17 +556,21 @@ bool LiveVariables::runOnMachineFunction(MachineFunction &mf) {
if (MI->isPHI())
NumOperandsToProcess = 1;
+ // Clear kill and dead markers. LV will recompute them.
SmallVector<unsigned, 4> UseRegs;
SmallVector<unsigned, 4> DefRegs;
for (unsigned i = 0; i != NumOperandsToProcess; ++i) {
- const MachineOperand &MO = MI->getOperand(i);
+ MachineOperand &MO = MI->getOperand(i);
if (!MO.isReg() || MO.getReg() == 0)
continue;
unsigned MOReg = MO.getReg();
- if (MO.isUse())
+ if (MO.isUse()) {
+ MO.setIsKill(false);
UseRegs.push_back(MOReg);
- if (MO.isDef())
+ } else /*MO.isDef()*/ {
+ MO.setIsDead(false);
DefRegs.push_back(MOReg);
+ }
}
// Process all uses.
diff --git a/lib/CodeGen/MachineBasicBlock.cpp b/lib/CodeGen/MachineBasicBlock.cpp
index fc8ae5f..bd0ccb4 100644
--- a/lib/CodeGen/MachineBasicBlock.cpp
+++ b/lib/CodeGen/MachineBasicBlock.cpp
@@ -23,6 +23,7 @@
#include "llvm/Target/TargetMachine.h"
#include "llvm/Assembly/Writer.h"
#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/LeakDetector.h"
#include "llvm/Support/raw_ostream.h"
@@ -45,9 +46,9 @@ MCSymbol *MachineBasicBlock::getSymbol() const {
const MachineFunction *MF = getParent();
MCContext &Ctx = MF->getContext();
const char *Prefix = Ctx.getAsmInfo().getPrivateGlobalPrefix();
- return Ctx.GetOrCreateTemporarySymbol(Twine(Prefix) + "BB" +
- Twine(MF->getFunctionNumber()) + "_" +
- Twine(getNumber()));
+ return Ctx.GetOrCreateSymbol(Twine(Prefix) + "BB" +
+ Twine(MF->getFunctionNumber()) + "_" +
+ Twine(getNumber()));
}
@@ -459,54 +460,41 @@ bool MachineBasicBlock::CorrectExtraCFGEdges(MachineBasicBlock *DestA,
// conditional branch followed by an unconditional branch. DestA is the
// 'true' destination and DestB is the 'false' destination.
- bool MadeChange = false;
- bool AddedFallThrough = false;
+ bool Changed = false;
MachineFunction::iterator FallThru =
llvm::next(MachineFunction::iterator(this));
-
- if (isCond) {
- // If this block ends with a conditional branch that falls through to its
- // successor, set DestB as the successor.
- if (DestB == 0 && FallThru != getParent()->end()) {
+
+ if (DestA == 0 && DestB == 0) {
+ // Block falls through to successor.
+ DestA = FallThru;
+ DestB = FallThru;
+ } else if (DestA != 0 && DestB == 0) {
+ if (isCond)
+ // Block ends in conditional jump that falls through to successor.
DestB = FallThru;
- AddedFallThrough = true;
- }
} else {
- // If this is an unconditional branch with no explicit dest, it must just be
- // a fallthrough into DestA.
- if (DestA == 0 && FallThru != getParent()->end()) {
- DestA = FallThru;
- AddedFallThrough = true;
- }
+ assert(DestA && DestB && isCond &&
+ "CFG in a bad state. Cannot correct CFG edges");
}
-
+
+ // Remove superfluous edges. I.e., those which aren't destinations of this
+ // basic block, duplicate edges, or landing pads.
+ SmallPtrSet<const MachineBasicBlock*, 8> SeenMBBs;
MachineBasicBlock::succ_iterator SI = succ_begin();
- MachineBasicBlock *OrigDestA = DestA, *OrigDestB = DestB;
while (SI != succ_end()) {
const MachineBasicBlock *MBB = *SI;
- if (MBB == DestA) {
- DestA = 0;
- ++SI;
- } else if (MBB == DestB) {
- DestB = 0;
- ++SI;
- } else if (MBB->isLandingPad() &&
- MBB != OrigDestA && MBB != OrigDestB) {
- ++SI;
- } else {
- // Otherwise, this is a superfluous edge, remove it.
+ if (!SeenMBBs.insert(MBB) ||
+ (MBB != DestA && MBB != DestB && !MBB->isLandingPad())) {
+ // This is a superfluous edge, remove it.
SI = removeSuccessor(SI);
- MadeChange = true;
+ Changed = true;
+ } else {
+ ++SI;
}
}
- if (!AddedFallThrough)
- assert(DestA == 0 && DestB == 0 && "MachineCFG is missing edges!");
- else if (isCond)
- assert(DestA == 0 && "MachineCFG is missing edges!");
-
- return MadeChange;
+ return Changed;
}
/// findDebugLoc - find the next valid DebugLoc starting at MBBI, skipping
diff --git a/lib/CodeGen/MachineCSE.cpp b/lib/CodeGen/MachineCSE.cpp
index 91d3635..597d51d 100644
--- a/lib/CodeGen/MachineCSE.cpp
+++ b/lib/CodeGen/MachineCSE.cpp
@@ -117,17 +117,15 @@ bool MachineCSE::isPhysDefTriviallyDead(unsigned Reg,
MachineBasicBlock::const_iterator I,
MachineBasicBlock::const_iterator E) {
unsigned LookAheadLeft = 5;
- while (LookAheadLeft--) {
+ while (LookAheadLeft) {
+ // Skip over dbg_value's.
+ while (I != E && I->isDebugValue())
+ ++I;
+
if (I == E)
// Reached end of block, register is obviously dead.
return true;
- if (I->isDebugValue()) {
- // These must not count against the limit.
- ++LookAheadLeft;
- ++I;
- continue;
- }
bool SeenDef = false;
for (unsigned i = 0, e = I->getNumOperands(); i != e; ++i) {
const MachineOperand &MO = I->getOperand(i);
@@ -143,6 +141,8 @@ bool MachineCSE::isPhysDefTriviallyDead(unsigned Reg,
// See a def of Reg (or an alias) before encountering any use, it's
// trivially dead.
return true;
+
+ --LookAheadLeft;
++I;
}
return false;
@@ -294,8 +294,12 @@ bool MachineCSE::ProcessBlock(MachineDomTreeNode *Node) {
bool FoundCSE = VNT.count(MI);
if (!FoundCSE) {
// Look for trivial copy coalescing opportunities.
- if (PerformTrivialCoalescing(MI, MBB))
+ if (PerformTrivialCoalescing(MI, MBB)) {
+ // After coalescing MI itself may become a copy.
+ if (isCopy(MI, TII))
+ continue;
FoundCSE = VNT.count(MI);
+ }
}
// FIXME: commute commutable instructions?
diff --git a/lib/CodeGen/MachineFunction.cpp b/lib/CodeGen/MachineFunction.cpp
index 5772b2f..f6cc71f 100644
--- a/lib/CodeGen/MachineFunction.cpp
+++ b/lib/CodeGen/MachineFunction.cpp
@@ -460,9 +460,7 @@ MCSymbol *MachineFunction::getJTISymbol(unsigned JTI, MCContext &Ctx,
SmallString<60> Name;
raw_svector_ostream(Name)
<< Prefix << "JTI" << getFunctionNumber() << '_' << JTI;
- if (isLinkerPrivate)
- return Ctx.GetOrCreateSymbol(Name.str());
- return Ctx.GetOrCreateTemporarySymbol(Name.str());
+ return Ctx.GetOrCreateSymbol(Name.str());
}
diff --git a/lib/CodeGen/MachineModuleInfo.cpp b/lib/CodeGen/MachineModuleInfo.cpp
index af48e9e..ad4f01b 100644
--- a/lib/CodeGen/MachineModuleInfo.cpp
+++ b/lib/CodeGen/MachineModuleInfo.cpp
@@ -44,6 +44,10 @@ public:
MMIAddrLabelMapCallbackPtr() : Map(0) {}
MMIAddrLabelMapCallbackPtr(Value *V) : CallbackVH(V), Map(0) {}
+ void setPtr(BasicBlock *BB) {
+ ValueHandleBase::operator=(BB);
+ }
+
void setMap(MMIAddrLabelMap *map) { Map = map; }
virtual void deleted();
@@ -209,7 +213,7 @@ void MMIAddrLabelMap::UpdateForRAUWBlock(BasicBlock *Old, BasicBlock *New) {
// If New is not address taken, just move our symbol over to it.
if (NewEntry.Symbols.isNull()) {
- BBCallbacks[OldEntry.Index] = New; // Update the callback.
+ BBCallbacks[OldEntry.Index].setPtr(New); // Update the callback.
NewEntry = OldEntry; // Set New's entry.
return;
}
diff --git a/lib/CodeGen/OptimizeExts.cpp b/lib/CodeGen/OptimizeExts.cpp
index acb6869..41fc204 100644
--- a/lib/CodeGen/OptimizeExts.cpp
+++ b/lib/CodeGen/OptimizeExts.cpp
@@ -73,6 +73,9 @@ FunctionPass *llvm::createOptimizeExtsPass() { return new OptimizeExts(); }
/// the source, and if the source value is preserved as a sub-register of
/// the result, then replace all reachable uses of the source with the subreg
/// of the result.
+/// Do not generate an EXTRACT that is used only in a debug use, as this
+/// changes the code. Since this code does not currently share EXTRACTs, just
+/// ignore all debug uses.
bool OptimizeExts::OptimizeInstr(MachineInstr *MI, MachineBasicBlock *MBB,
SmallPtrSet<MachineInstr*, 8> &LocalMIs) {
bool Changed = false;
@@ -84,17 +87,17 @@ bool OptimizeExts::OptimizeInstr(MachineInstr *MI, MachineBasicBlock *MBB,
TargetRegisterInfo::isPhysicalRegister(SrcReg))
return false;
- MachineRegisterInfo::use_iterator UI = MRI->use_begin(SrcReg);
- if (++UI == MRI->use_end())
+ MachineRegisterInfo::use_nodbg_iterator UI = MRI->use_nodbg_begin(SrcReg);
+ if (++UI == MRI->use_nodbg_end())
// No other uses.
return false;
// Ok, the source has other uses. See if we can replace the other uses
// with use of the result of the extension.
SmallPtrSet<MachineBasicBlock*, 4> ReachedBBs;
- UI = MRI->use_begin(DstReg);
- for (MachineRegisterInfo::use_iterator UE = MRI->use_end(); UI != UE;
- ++UI)
+ UI = MRI->use_nodbg_begin(DstReg);
+ for (MachineRegisterInfo::use_nodbg_iterator UE = MRI->use_nodbg_end();
+ UI != UE; ++UI)
ReachedBBs.insert(UI->getParent());
bool ExtendLife = true;
@@ -103,9 +106,9 @@ bool OptimizeExts::OptimizeInstr(MachineInstr *MI, MachineBasicBlock *MBB,
// Uses that the result of the instruction can reach.
SmallVector<MachineOperand*, 8> ExtendedUses;
- UI = MRI->use_begin(SrcReg);
- for (MachineRegisterInfo::use_iterator UE = MRI->use_end(); UI != UE;
- ++UI) {
+ UI = MRI->use_nodbg_begin(SrcReg);
+ for (MachineRegisterInfo::use_nodbg_iterator UE = MRI->use_nodbg_end();
+ UI != UE; ++UI) {
MachineOperand &UseMO = UI.getOperand();
MachineInstr *UseMI = &*UI;
if (UseMI == MI)
@@ -147,9 +150,9 @@ bool OptimizeExts::OptimizeInstr(MachineInstr *MI, MachineBasicBlock *MBB,
// Look for PHI uses of the extended result, we don't want to extend the
// liveness of a PHI input. It breaks all kinds of assumptions down
// stream. A PHI use is expected to be the kill of its source values.
- UI = MRI->use_begin(DstReg);
- for (MachineRegisterInfo::use_iterator UE = MRI->use_end(); UI != UE;
- ++UI)
+ UI = MRI->use_nodbg_begin(DstReg);
+ for (MachineRegisterInfo::use_nodbg_iterator UE = MRI->use_nodbg_end();
+ UI != UE; ++UI)
if (UI->isPHI())
PHIBBs.insert(UI->getParent());
diff --git a/lib/CodeGen/PHIElimination.cpp b/lib/CodeGen/PHIElimination.cpp
index 8bbe0a7..f0057ce 100644
--- a/lib/CodeGen/PHIElimination.cpp
+++ b/lib/CodeGen/PHIElimination.cpp
@@ -74,7 +74,7 @@ bool llvm::PHIElimination::runOnMachineFunction(MachineFunction &Fn) {
E = ImpDefs.end(); I != E; ++I) {
MachineInstr *DefMI = *I;
unsigned DefReg = DefMI->getOperand(0).getReg();
- if (MRI->use_empty(DefReg))
+ if (MRI->use_nodbg_empty(DefReg))
DefMI->eraseFromParent();
}
diff --git a/lib/CodeGen/PreAllocSplitting.cpp b/lib/CodeGen/PreAllocSplitting.cpp
index 70e91aa..2d49beb 100644
--- a/lib/CodeGen/PreAllocSplitting.cpp
+++ b/lib/CodeGen/PreAllocSplitting.cpp
@@ -665,7 +665,7 @@ PreAllocSplitting::PerformPHIConstructionFallBack(MachineBasicBlock::iterator Us
/// ReconstructLiveInterval - Recompute a live interval from scratch.
void PreAllocSplitting::ReconstructLiveInterval(LiveInterval* LI) {
- BumpPtrAllocator& Alloc = LIs->getVNInfoAllocator();
+ VNInfo::Allocator& Alloc = LIs->getVNInfoAllocator();
// Clear the old ranges and valnos;
LI->clear();
diff --git a/lib/CodeGen/RegAllocLocal.cpp b/lib/CodeGen/RegAllocLocal.cpp
index 2c69065..0ef041e 100644
--- a/lib/CodeGen/RegAllocLocal.cpp
+++ b/lib/CodeGen/RegAllocLocal.cpp
@@ -118,8 +118,8 @@ namespace {
bool isVirtRegModified(unsigned Reg) const {
assert(TargetRegisterInfo::isVirtualRegister(Reg) && "Illegal VirtReg!");
- assert(Reg - TargetRegisterInfo::FirstVirtualRegister < VirtRegModified.size()
- && "Illegal virtual register!");
+ assert(Reg - TargetRegisterInfo::FirstVirtualRegister <
+ VirtRegModified.size() && "Illegal virtual register!");
return VirtRegModified[Reg - TargetRegisterInfo::FirstVirtualRegister];
}
@@ -135,15 +135,16 @@ namespace {
if (PhysRegsUseOrder.empty() ||
PhysRegsUseOrder.back() == Reg) return; // Already most recently used
- for (unsigned i = PhysRegsUseOrder.size(); i != 0; --i)
- if (areRegsEqual(Reg, PhysRegsUseOrder[i-1])) {
- unsigned RegMatch = PhysRegsUseOrder[i-1]; // remove from middle
- PhysRegsUseOrder.erase(PhysRegsUseOrder.begin()+i-1);
- // Add it to the end of the list
- PhysRegsUseOrder.push_back(RegMatch);
- if (RegMatch == Reg)
- return; // Found an exact match, exit early
- }
+ for (unsigned i = PhysRegsUseOrder.size(); i != 0; --i) {
+ unsigned RegMatch = PhysRegsUseOrder[i-1]; // remove from middle
+ if (!areRegsEqual(Reg, RegMatch)) continue;
+
+ PhysRegsUseOrder.erase(PhysRegsUseOrder.begin()+i-1);
+ // Add it to the end of the list
+ PhysRegsUseOrder.push_back(RegMatch);
+ if (RegMatch == Reg)
+ return; // Found an exact match, exit early
+ }
}
public:
@@ -267,7 +268,7 @@ int RALocal::getStackSpaceFor(unsigned VirtReg, const TargetRegisterClass *RC) {
int FrameIdx = MF->getFrameInfo()->CreateSpillStackObject(RC->getSize(),
RC->getAlignment());
- // Assign the slot...
+ // Assign the slot.
StackSlotForVirtReg[VirtReg] = FrameIdx;
return FrameIdx;
}
@@ -337,15 +338,19 @@ void RALocal::spillPhysReg(MachineBasicBlock &MBB, MachineInstr *I,
assert(PhysRegsUsed[PhysReg] != -2 && "Non allocable reg used!");
if (PhysRegsUsed[PhysReg] || !OnlyVirtRegs)
spillVirtReg(MBB, I, PhysRegsUsed[PhysReg], PhysReg);
- } else {
- // If the selected register aliases any other registers, we must make
- // sure that one of the aliases isn't alive.
- for (const unsigned *AliasSet = TRI->getAliasSet(PhysReg);
- *AliasSet; ++AliasSet)
- if (PhysRegsUsed[*AliasSet] != -1 && // Spill aliased register.
- PhysRegsUsed[*AliasSet] != -2) // If allocatable.
- if (PhysRegsUsed[*AliasSet])
- spillVirtReg(MBB, I, PhysRegsUsed[*AliasSet], *AliasSet);
+ return;
+ }
+
+ // If the selected register aliases any other registers, we must make
+ // sure that one of the aliases isn't alive.
+ for (const unsigned *AliasSet = TRI->getAliasSet(PhysReg);
+ *AliasSet; ++AliasSet) {
+ if (PhysRegsUsed[*AliasSet] == -1 || // Spill aliased register.
+ PhysRegsUsed[*AliasSet] == -2) // If allocatable.
+ continue;
+
+ if (PhysRegsUsed[*AliasSet])
+ spillVirtReg(MBB, I, PhysRegsUsed[*AliasSet], *AliasSet);
}
}
@@ -410,58 +415,63 @@ unsigned RALocal::getReg(MachineBasicBlock &MBB, MachineInstr *I,
// First check to see if we have a free register of the requested type...
unsigned PhysReg = NoFree ? 0 : getFreeReg(RC);
+ if (PhysReg != 0) {
+ // Assign the register.
+ assignVirtToPhysReg(VirtReg, PhysReg);
+ return PhysReg;
+ }
+
// If we didn't find an unused register, scavenge one now!
- if (PhysReg == 0) {
- assert(!PhysRegsUseOrder.empty() && "No allocated registers??");
-
- // Loop over all of the preallocated registers from the least recently used
- // to the most recently used. When we find one that is capable of holding
- // our register, use it.
- for (unsigned i = 0; PhysReg == 0; ++i) {
- assert(i != PhysRegsUseOrder.size() &&
- "Couldn't find a register of the appropriate class!");
-
- unsigned R = PhysRegsUseOrder[i];
-
- // We can only use this register if it holds a virtual register (ie, it
- // can be spilled). Do not use it if it is an explicitly allocated
- // physical register!
- assert(PhysRegsUsed[R] != -1 &&
- "PhysReg in PhysRegsUseOrder, but is not allocated?");
- if (PhysRegsUsed[R] && PhysRegsUsed[R] != -2) {
- // If the current register is compatible, use it.
- if (RC->contains(R)) {
- PhysReg = R;
- break;
- } else {
- // If one of the registers aliased to the current register is
- // compatible, use it.
- for (const unsigned *AliasIt = TRI->getAliasSet(R);
- *AliasIt; ++AliasIt) {
- if (RC->contains(*AliasIt) &&
- // If this is pinned down for some reason, don't use it. For
- // example, if CL is pinned, and we run across CH, don't use
- // CH as justification for using scavenging ECX (which will
- // fail).
- PhysRegsUsed[*AliasIt] != 0 &&
-
- // Make sure the register is allocatable. Don't allocate SIL on
- // x86-32.
- PhysRegsUsed[*AliasIt] != -2) {
- PhysReg = *AliasIt; // Take an aliased register
- break;
- }
- }
- }
+ assert(!PhysRegsUseOrder.empty() && "No allocated registers??");
+
+ // Loop over all of the preallocated registers from the least recently used
+ // to the most recently used. When we find one that is capable of holding
+ // our register, use it.
+ for (unsigned i = 0; PhysReg == 0; ++i) {
+ assert(i != PhysRegsUseOrder.size() &&
+ "Couldn't find a register of the appropriate class!");
+
+ unsigned R = PhysRegsUseOrder[i];
+
+ // We can only use this register if it holds a virtual register (ie, it
+ // can be spilled). Do not use it if it is an explicitly allocated
+ // physical register!
+ assert(PhysRegsUsed[R] != -1 &&
+ "PhysReg in PhysRegsUseOrder, but is not allocated?");
+ if (PhysRegsUsed[R] && PhysRegsUsed[R] != -2) {
+ // If the current register is compatible, use it.
+ if (RC->contains(R)) {
+ PhysReg = R;
+ break;
+ }
+
+ // If one of the registers aliased to the current register is
+ // compatible, use it.
+ for (const unsigned *AliasIt = TRI->getAliasSet(R);
+ *AliasIt; ++AliasIt) {
+ if (!RC->contains(*AliasIt)) continue;
+
+ // If this is pinned down for some reason, don't use it. For
+ // example, if CL is pinned, and we run across CH, don't use
+ // CH as justification for using scavenging ECX (which will
+ // fail).
+ if (PhysRegsUsed[*AliasIt] == 0) continue;
+
+ // Make sure the register is allocatable. Don't allocate SIL on
+ // x86-32.
+ if (PhysRegsUsed[*AliasIt] == -2) continue;
+
+ PhysReg = *AliasIt; // Take an aliased register
+ break;
}
}
+ }
- assert(PhysReg && "Physical register not assigned!?!?");
+ assert(PhysReg && "Physical register not assigned!?!?");
- // At this point PhysRegsUseOrder[i] is the least recently used register of
- // compatible register class. Spill it to memory and reap its remains.
- spillPhysReg(MBB, I, PhysReg);
- }
+ // At this point PhysRegsUseOrder[i] is the least recently used register of
+ // compatible register class. Spill it to memory and reap its remains.
+ spillPhysReg(MBB, I, PhysReg);
// Now that we know which register we need to assign this to, do it now!
assignVirtToPhysReg(VirtReg, PhysReg);
@@ -543,17 +553,17 @@ MachineInstr *RALocal::reloadVirtReg(MachineBasicBlock &MBB, MachineInstr *MI,
}
for (const unsigned *SubRegs = TRI->getSubRegisters(PhysReg);
*SubRegs; ++SubRegs) {
- if (!ReloadedRegs.insert(*SubRegs)) {
- std::string msg;
- raw_string_ostream Msg(msg);
- Msg << "Ran out of registers during register allocation!";
- if (MI->isInlineAsm()) {
- Msg << "\nPlease check your inline asm statement for invalid "
- << "constraints:\n";
- MI->print(Msg, TM);
- }
- llvm_report_error(Msg.str());
+ if (ReloadedRegs.insert(*SubRegs)) continue;
+
+ std::string msg;
+ raw_string_ostream Msg(msg);
+ Msg << "Ran out of registers during register allocation!";
+ if (MI->isInlineAsm()) {
+ Msg << "\nPlease check your inline asm statement for invalid "
+ << "constraints:\n";
+ MI->print(Msg, TM);
}
+ llvm_report_error(Msg.str());
}
return MI;
@@ -563,7 +573,7 @@ MachineInstr *RALocal::reloadVirtReg(MachineBasicBlock &MBB, MachineInstr *MI,
/// read/mod/write register, i.e. update partial register.
static bool isReadModWriteImplicitKill(MachineInstr *MI, unsigned Reg) {
for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
- MachineOperand& MO = MI->getOperand(i);
+ MachineOperand &MO = MI->getOperand(i);
if (MO.isReg() && MO.getReg() == Reg && MO.isImplicit() &&
MO.isDef() && !MO.isDead())
return true;
@@ -575,7 +585,7 @@ static bool isReadModWriteImplicitKill(MachineInstr *MI, unsigned Reg) {
/// read/mod/write register, i.e. update partial register.
static bool isReadModWriteImplicitDef(MachineInstr *MI, unsigned Reg) {
for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
- MachineOperand& MO = MI->getOperand(i);
+ MachineOperand &MO = MI->getOperand(i);
if (MO.isReg() && MO.getReg() == Reg && MO.isImplicit() &&
!MO.isDef() && MO.isKill())
return true;
@@ -606,7 +616,7 @@ static bool precedes(MachineBasicBlock::iterator A,
/// ComputeLocalLiveness - Computes liveness of registers within a basic
/// block, setting the killed/dead flags as appropriate.
void RALocal::ComputeLocalLiveness(MachineBasicBlock& MBB) {
- MachineRegisterInfo& MRI = MBB.getParent()->getRegInfo();
+ MachineRegisterInfo &MRI = MBB.getParent()->getRegInfo();
// Keep track of the most recently seen previous use or def of each reg,
// so that we can update them with dead/kill markers.
DenseMap<unsigned, std::pair<MachineInstr*, unsigned> > LastUseDef;
@@ -614,58 +624,60 @@ void RALocal::ComputeLocalLiveness(MachineBasicBlock& MBB) {
I != E; ++I) {
if (I->isDebugValue())
continue;
+
for (unsigned i = 0, e = I->getNumOperands(); i != e; ++i) {
- MachineOperand& MO = I->getOperand(i);
+ MachineOperand &MO = I->getOperand(i);
// Uses don't trigger any flags, but we need to save
// them for later. Also, we have to process these
// _before_ processing the defs, since an instr
// uses regs before it defs them.
- if (MO.isReg() && MO.getReg() && MO.isUse()) {
- LastUseDef[MO.getReg()] = std::make_pair(I, i);
-
+ if (!MO.isReg() || !MO.getReg() || !MO.isUse())
+ continue;
+
+ LastUseDef[MO.getReg()] = std::make_pair(I, i);
+
+ if (TargetRegisterInfo::isVirtualRegister(MO.getReg())) continue;
+
+ const unsigned *Aliases = TRI->getAliasSet(MO.getReg());
+ if (Aliases == 0)
+ continue;
+
+ while (*Aliases) {
+ DenseMap<unsigned, std::pair<MachineInstr*, unsigned> >::iterator
+ alias = LastUseDef.find(*Aliases);
- if (TargetRegisterInfo::isVirtualRegister(MO.getReg())) continue;
+ if (alias != LastUseDef.end() && alias->second.first != I)
+ LastUseDef[*Aliases] = std::make_pair(I, i);
- const unsigned* Aliases = TRI->getAliasSet(MO.getReg());
- if (Aliases) {
- while (*Aliases) {
- DenseMap<unsigned, std::pair<MachineInstr*, unsigned> >::iterator
- alias = LastUseDef.find(*Aliases);
-
- if (alias != LastUseDef.end() && alias->second.first != I)
- LastUseDef[*Aliases] = std::make_pair(I, i);
-
- ++Aliases;
- }
- }
+ ++Aliases;
}
}
for (unsigned i = 0, e = I->getNumOperands(); i != e; ++i) {
- MachineOperand& MO = I->getOperand(i);
+ MachineOperand &MO = I->getOperand(i);
// Defs others than 2-addr redefs _do_ trigger flag changes:
// - A def followed by a def is dead
// - A use followed by a def is a kill
- if (MO.isReg() && MO.getReg() && MO.isDef()) {
- DenseMap<unsigned, std::pair<MachineInstr*, unsigned> >::iterator
- last = LastUseDef.find(MO.getReg());
- if (last != LastUseDef.end()) {
- // Check if this is a two address instruction. If so, then
- // the def does not kill the use.
- if (last->second.first == I &&
- I->isRegTiedToUseOperand(i))
- continue;
-
- MachineOperand& lastUD =
- last->second.first->getOperand(last->second.second);
- if (lastUD.isDef())
- lastUD.setIsDead(true);
- else
- lastUD.setIsKill(true);
- }
+ if (!MO.isReg() || !MO.getReg() || !MO.isDef()) continue;
+
+ DenseMap<unsigned, std::pair<MachineInstr*, unsigned> >::iterator
+ last = LastUseDef.find(MO.getReg());
+ if (last != LastUseDef.end()) {
+ // Check if this is a two address instruction. If so, then
+ // the def does not kill the use.
+ if (last->second.first == I &&
+ I->isRegTiedToUseOperand(i))
+ continue;
- LastUseDef[MO.getReg()] = std::make_pair(I, i);
+ MachineOperand &lastUD =
+ last->second.first->getOperand(last->second.second);
+ if (lastUD.isDef())
+ lastUD.setIsDead(true);
+ else
+ lastUD.setIsKill(true);
}
+
+ LastUseDef[MO.getReg()] = std::make_pair(I, i);
}
}
@@ -687,9 +699,9 @@ void RALocal::ComputeLocalLiveness(MachineBasicBlock& MBB) {
// in the block and determine if it is dead.
for (DenseMap<unsigned, std::pair<MachineInstr*, unsigned> >::iterator
I = LastUseDef.begin(), E = LastUseDef.end(); I != E; ++I) {
- MachineInstr* MI = I->second.first;
+ MachineInstr *MI = I->second.first;
unsigned idx = I->second.second;
- MachineOperand& MO = MI->getOperand(idx);
+ MachineOperand &MO = MI->getOperand(idx);
bool isPhysReg = TargetRegisterInfo::isPhysicalRegister(MO.getReg());
@@ -712,20 +724,21 @@ void RALocal::ComputeLocalLiveness(MachineBasicBlock& MBB) {
// Two cases:
// - used in another block
// - used in the same block before it is defined (loop)
- if (UI->getParent() != &MBB ||
- (MO.isDef() && UI.getOperand().isUse() && precedes(&*UI, MI))) {
- if (UI->isDebugValue()) {
- UsedByDebugValueOnly = true;
- continue;
- }
-
- // A non-DBG_VALUE use means we can leave DBG_VALUE uses alone.
- UsedInMultipleBlocks.set(MO.getReg() -
- TargetRegisterInfo::FirstVirtualRegister);
- usedOutsideBlock = true;
- UsedByDebugValueOnly = false;
- break;
+ if (UI->getParent() == &MBB &&
+ !(MO.isDef() && UI.getOperand().isUse() && precedes(&*UI, MI)))
+ continue;
+
+ if (UI->isDebugValue()) {
+ UsedByDebugValueOnly = true;
+ continue;
}
+
+ // A non-DBG_VALUE use means we can leave DBG_VALUE uses alone.
+ UsedInMultipleBlocks.set(MO.getReg() -
+ TargetRegisterInfo::FirstVirtualRegister);
+ usedOutsideBlock = true;
+ UsedByDebugValueOnly = false;
+ break;
}
if (UsedByDebugValueOnly)
@@ -770,11 +783,11 @@ void RALocal::AllocateBasicBlock(MachineBasicBlock &MBB) {
AddToPhysRegsUseOrder(Reg);
for (const unsigned *SubRegs = TRI->getSubRegisters(Reg);
*SubRegs; ++SubRegs) {
- if (PhysRegsUsed[*SubRegs] != -2) {
- AddToPhysRegsUseOrder(*SubRegs);
- PhysRegsUsed[*SubRegs] = 0; // It is free and reserved now
- MF->getRegInfo().setPhysRegUsed(*SubRegs);
- }
+ if (PhysRegsUsed[*SubRegs] == -2) continue;
+
+ AddToPhysRegsUseOrder(*SubRegs);
+ PhysRegsUsed[*SubRegs] = 0; // It is free and reserved now
+ MF->getRegInfo().setPhysRegUsed(*SubRegs);
}
}
@@ -813,16 +826,16 @@ void RALocal::AllocateBasicBlock(MachineBasicBlock &MBB) {
SmallVector<unsigned, 8> Kills;
for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
- MachineOperand& MO = MI->getOperand(i);
- if (MO.isReg() && MO.isKill()) {
- if (!MO.isImplicit())
- Kills.push_back(MO.getReg());
- else if (!isReadModWriteImplicitKill(MI, MO.getReg()))
- // These are extra physical register kills when a sub-register
- // is defined (def of a sub-register is a read/mod/write of the
- // larger registers). Ignore.
- Kills.push_back(MO.getReg());
- }
+ MachineOperand &MO = MI->getOperand(i);
+ if (!MO.isReg() || !MO.isKill()) continue;
+
+ if (!MO.isImplicit())
+ Kills.push_back(MO.getReg());
+ else if (!isReadModWriteImplicitKill(MI, MO.getReg()))
+ // These are extra physical register kills when a sub-register
+ // is defined (def of a sub-register is a read/mod/write of the
+ // larger registers). Ignore.
+ Kills.push_back(MO.getReg());
}
// If any physical regs are earlyclobber, spill any value they might
@@ -830,45 +843,45 @@ void RALocal::AllocateBasicBlock(MachineBasicBlock &MBB) {
// If any virtual regs are earlyclobber, allocate them now (before
// freeing inputs that are killed).
if (MI->isInlineAsm()) {
- for (unsigned i = 0; i != MI->getNumOperands(); ++i) {
- MachineOperand& MO = MI->getOperand(i);
- if (MO.isReg() && MO.isDef() && MO.isEarlyClobber() &&
- MO.getReg()) {
- if (TargetRegisterInfo::isVirtualRegister(MO.getReg())) {
- unsigned DestVirtReg = MO.getReg();
- unsigned DestPhysReg;
-
- // If DestVirtReg already has a value, use it.
- if (!(DestPhysReg = getVirt2PhysRegMapSlot(DestVirtReg)))
- DestPhysReg = getReg(MBB, MI, DestVirtReg);
- MF->getRegInfo().setPhysRegUsed(DestPhysReg);
- markVirtRegModified(DestVirtReg);
- getVirtRegLastUse(DestVirtReg) =
- std::make_pair((MachineInstr*)0, 0);
- DEBUG(dbgs() << " Assigning " << TRI->getName(DestPhysReg)
- << " to %reg" << DestVirtReg << "\n");
- MO.setReg(DestPhysReg); // Assign the earlyclobber register
- } else {
- unsigned Reg = MO.getReg();
- if (PhysRegsUsed[Reg] == -2) continue; // Something like ESP.
- // These are extra physical register defs when a sub-register
- // is defined (def of a sub-register is a read/mod/write of the
- // larger registers). Ignore.
- if (isReadModWriteImplicitDef(MI, MO.getReg())) continue;
-
- MF->getRegInfo().setPhysRegUsed(Reg);
- spillPhysReg(MBB, MI, Reg, true); // Spill any existing value in reg
- PhysRegsUsed[Reg] = 0; // It is free and reserved now
- AddToPhysRegsUseOrder(Reg);
-
- for (const unsigned *SubRegs = TRI->getSubRegisters(Reg);
- *SubRegs; ++SubRegs) {
- if (PhysRegsUsed[*SubRegs] != -2) {
- MF->getRegInfo().setPhysRegUsed(*SubRegs);
- PhysRegsUsed[*SubRegs] = 0; // It is free and reserved now
- AddToPhysRegsUseOrder(*SubRegs);
- }
- }
+ for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
+ MachineOperand &MO = MI->getOperand(i);
+ if (!MO.isReg() || !MO.isDef() || !MO.isEarlyClobber() ||
+ !MO.getReg())
+ continue;
+
+ if (TargetRegisterInfo::isVirtualRegister(MO.getReg())) {
+ unsigned DestVirtReg = MO.getReg();
+ unsigned DestPhysReg;
+
+ // If DestVirtReg already has a value, use it.
+ if (!(DestPhysReg = getVirt2PhysRegMapSlot(DestVirtReg)))
+ DestPhysReg = getReg(MBB, MI, DestVirtReg);
+ MF->getRegInfo().setPhysRegUsed(DestPhysReg);
+ markVirtRegModified(DestVirtReg);
+ getVirtRegLastUse(DestVirtReg) =
+ std::make_pair((MachineInstr*)0, 0);
+ DEBUG(dbgs() << " Assigning " << TRI->getName(DestPhysReg)
+ << " to %reg" << DestVirtReg << "\n");
+ MO.setReg(DestPhysReg); // Assign the earlyclobber register
+ } else {
+ unsigned Reg = MO.getReg();
+ if (PhysRegsUsed[Reg] == -2) continue; // Something like ESP.
+ // These are extra physical register defs when a sub-register
+ // is defined (def of a sub-register is a read/mod/write of the
+ // larger registers). Ignore.
+ if (isReadModWriteImplicitDef(MI, MO.getReg())) continue;
+
+ MF->getRegInfo().setPhysRegUsed(Reg);
+ spillPhysReg(MBB, MI, Reg, true); // Spill any existing value in reg
+ PhysRegsUsed[Reg] = 0; // It is free and reserved now
+ AddToPhysRegsUseOrder(Reg);
+
+ for (const unsigned *SubRegs = TRI->getSubRegisters(Reg);
+ *SubRegs; ++SubRegs) {
+ if (PhysRegsUsed[*SubRegs] == -2) continue;
+ MF->getRegInfo().setPhysRegUsed(*SubRegs);
+ PhysRegsUsed[*SubRegs] = 0; // It is free and reserved now
+ AddToPhysRegsUseOrder(*SubRegs);
}
}
}
@@ -894,7 +907,7 @@ void RALocal::AllocateBasicBlock(MachineBasicBlock &MBB) {
//
SmallSet<unsigned, 4> ReloadedRegs;
for (unsigned i = 0; i != MI->getNumOperands(); ++i) {
- MachineOperand& MO = MI->getOperand(i);
+ MachineOperand &MO = MI->getOperand(i);
// here we are looking for only used operands (never def&use)
if (MO.isReg() && !MO.isDef() && MO.getReg() && !MO.isImplicit() &&
TargetRegisterInfo::isVirtualRegister(MO.getReg()))
@@ -923,18 +936,18 @@ void RALocal::AllocateBasicBlock(MachineBasicBlock &MBB) {
"Silently clearing a virtual register?");
}
- if (PhysReg) {
- DEBUG(dbgs() << " Last use of " << TRI->getName(PhysReg)
- << "[%reg" << VirtReg <<"], removing it from live set\n");
- removePhysReg(PhysReg);
- for (const unsigned *SubRegs = TRI->getSubRegisters(PhysReg);
- *SubRegs; ++SubRegs) {
- if (PhysRegsUsed[*SubRegs] != -2) {
- DEBUG(dbgs() << " Last use of "
- << TRI->getName(*SubRegs) << "[%reg" << VirtReg
- <<"], removing it from live set\n");
- removePhysReg(*SubRegs);
- }
+ if (!PhysReg) continue;
+
+ DEBUG(dbgs() << " Last use of " << TRI->getName(PhysReg)
+ << "[%reg" << VirtReg <<"], removing it from live set\n");
+ removePhysReg(PhysReg);
+ for (const unsigned *SubRegs = TRI->getSubRegisters(PhysReg);
+ *SubRegs; ++SubRegs) {
+ if (PhysRegsUsed[*SubRegs] != -2) {
+ DEBUG(dbgs() << " Last use of "
+ << TRI->getName(*SubRegs) << "[%reg" << VirtReg
+ <<"], removing it from live set\n");
+ removePhysReg(*SubRegs);
}
}
}
@@ -942,30 +955,31 @@ void RALocal::AllocateBasicBlock(MachineBasicBlock &MBB) {
// Loop over all of the operands of the instruction, spilling registers that
// are defined, and marking explicit destinations in the PhysRegsUsed map.
for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
- MachineOperand& MO = MI->getOperand(i);
- if (MO.isReg() && MO.isDef() && !MO.isImplicit() && MO.getReg() &&
- !MO.isEarlyClobber() &&
- TargetRegisterInfo::isPhysicalRegister(MO.getReg())) {
- unsigned Reg = MO.getReg();
- if (PhysRegsUsed[Reg] == -2) continue; // Something like ESP.
- // These are extra physical register defs when a sub-register
- // is defined (def of a sub-register is a read/mod/write of the
- // larger registers). Ignore.
- if (isReadModWriteImplicitDef(MI, MO.getReg())) continue;
-
- MF->getRegInfo().setPhysRegUsed(Reg);
- spillPhysReg(MBB, MI, Reg, true); // Spill any existing value in reg
- PhysRegsUsed[Reg] = 0; // It is free and reserved now
- AddToPhysRegsUseOrder(Reg);
-
- for (const unsigned *SubRegs = TRI->getSubRegisters(Reg);
- *SubRegs; ++SubRegs) {
- if (PhysRegsUsed[*SubRegs] != -2) {
- MF->getRegInfo().setPhysRegUsed(*SubRegs);
- PhysRegsUsed[*SubRegs] = 0; // It is free and reserved now
- AddToPhysRegsUseOrder(*SubRegs);
- }
- }
+ MachineOperand &MO = MI->getOperand(i);
+ if (!MO.isReg() || !MO.isDef() || MO.isImplicit() || !MO.getReg() ||
+ MO.isEarlyClobber() ||
+ !TargetRegisterInfo::isPhysicalRegister(MO.getReg()))
+ continue;
+
+ unsigned Reg = MO.getReg();
+ if (PhysRegsUsed[Reg] == -2) continue; // Something like ESP.
+ // These are extra physical register defs when a sub-register
+ // is defined (def of a sub-register is a read/mod/write of the
+ // larger registers). Ignore.
+ if (isReadModWriteImplicitDef(MI, MO.getReg())) continue;
+
+ MF->getRegInfo().setPhysRegUsed(Reg);
+ spillPhysReg(MBB, MI, Reg, true); // Spill any existing value in reg
+ PhysRegsUsed[Reg] = 0; // It is free and reserved now
+ AddToPhysRegsUseOrder(Reg);
+
+ for (const unsigned *SubRegs = TRI->getSubRegisters(Reg);
+ *SubRegs; ++SubRegs) {
+ if (PhysRegsUsed[*SubRegs] == -2) continue;
+
+ MF->getRegInfo().setPhysRegUsed(*SubRegs);
+ PhysRegsUsed[*SubRegs] = 0; // It is free and reserved now
+ AddToPhysRegsUseOrder(*SubRegs);
}
}
@@ -982,18 +996,18 @@ void RALocal::AllocateBasicBlock(MachineBasicBlock &MBB) {
MF->getRegInfo().setPhysRegUsed(Reg);
for (const unsigned *SubRegs = TRI->getSubRegisters(Reg);
*SubRegs; ++SubRegs) {
- if (PhysRegsUsed[*SubRegs] != -2) {
- AddToPhysRegsUseOrder(*SubRegs);
- PhysRegsUsed[*SubRegs] = 0; // It is free and reserved now
- MF->getRegInfo().setPhysRegUsed(*SubRegs);
- }
+ if (PhysRegsUsed[*SubRegs] == -2) continue;
+
+ AddToPhysRegsUseOrder(*SubRegs);
+ PhysRegsUsed[*SubRegs] = 0; // It is free and reserved now
+ MF->getRegInfo().setPhysRegUsed(*SubRegs);
}
}
}
SmallVector<unsigned, 8> DeadDefs;
for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
- MachineOperand& MO = MI->getOperand(i);
+ MachineOperand &MO = MI->getOperand(i);
if (MO.isReg() && MO.isDead())
DeadDefs.push_back(MO.getReg());
}
@@ -1004,45 +1018,46 @@ void RALocal::AllocateBasicBlock(MachineBasicBlock &MBB) {
// we need to scavenge a register.
//
for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
- MachineOperand& MO = MI->getOperand(i);
- if (MO.isReg() && MO.isDef() && MO.getReg() &&
- !MO.isEarlyClobber() &&
- TargetRegisterInfo::isVirtualRegister(MO.getReg())) {
- unsigned DestVirtReg = MO.getReg();
- unsigned DestPhysReg;
-
- // If DestVirtReg already has a value, use it.
- if (!(DestPhysReg = getVirt2PhysRegMapSlot(DestVirtReg))) {
- // If this is a copy try to reuse the input as the output;
- // that will make the copy go away.
- // If this is a copy, the source reg is a phys reg, and
- // that reg is available, use that phys reg for DestPhysReg.
- // If this is a copy, the source reg is a virtual reg, and
- // the phys reg that was assigned to that virtual reg is now
- // available, use that phys reg for DestPhysReg. (If it's now
- // available that means this was the last use of the source.)
- if (isCopy &&
- TargetRegisterInfo::isPhysicalRegister(SrcCopyReg) &&
- isPhysRegAvailable(SrcCopyReg)) {
- DestPhysReg = SrcCopyReg;
- assignVirtToPhysReg(DestVirtReg, DestPhysReg);
- } else if (isCopy &&
- TargetRegisterInfo::isVirtualRegister(SrcCopyReg) &&
- SrcCopyPhysReg && isPhysRegAvailable(SrcCopyPhysReg) &&
- MF->getRegInfo().getRegClass(DestVirtReg)->
- contains(SrcCopyPhysReg)) {
- DestPhysReg = SrcCopyPhysReg;
- assignVirtToPhysReg(DestVirtReg, DestPhysReg);
- } else
- DestPhysReg = getReg(MBB, MI, DestVirtReg);
- }
- MF->getRegInfo().setPhysRegUsed(DestPhysReg);
- markVirtRegModified(DestVirtReg);
- getVirtRegLastUse(DestVirtReg) = std::make_pair((MachineInstr*)0, 0);
- DEBUG(dbgs() << " Assigning " << TRI->getName(DestPhysReg)
- << " to %reg" << DestVirtReg << "\n");
- MO.setReg(DestPhysReg); // Assign the output register
+ MachineOperand &MO = MI->getOperand(i);
+ if (!MO.isReg() || !MO.isDef() || !MO.getReg() ||
+ MO.isEarlyClobber() ||
+ !TargetRegisterInfo::isVirtualRegister(MO.getReg()))
+ continue;
+
+ unsigned DestVirtReg = MO.getReg();
+ unsigned DestPhysReg;
+
+ // If DestVirtReg already has a value, use it.
+ if (!(DestPhysReg = getVirt2PhysRegMapSlot(DestVirtReg))) {
+ // If this is a copy try to reuse the input as the output;
+ // that will make the copy go away.
+ // If this is a copy, the source reg is a phys reg, and
+ // that reg is available, use that phys reg for DestPhysReg.
+ // If this is a copy, the source reg is a virtual reg, and
+ // the phys reg that was assigned to that virtual reg is now
+ // available, use that phys reg for DestPhysReg. (If it's now
+ // available that means this was the last use of the source.)
+ if (isCopy &&
+ TargetRegisterInfo::isPhysicalRegister(SrcCopyReg) &&
+ isPhysRegAvailable(SrcCopyReg)) {
+ DestPhysReg = SrcCopyReg;
+ assignVirtToPhysReg(DestVirtReg, DestPhysReg);
+ } else if (isCopy &&
+ TargetRegisterInfo::isVirtualRegister(SrcCopyReg) &&
+ SrcCopyPhysReg && isPhysRegAvailable(SrcCopyPhysReg) &&
+ MF->getRegInfo().getRegClass(DestVirtReg)->
+ contains(SrcCopyPhysReg)) {
+ DestPhysReg = SrcCopyPhysReg;
+ assignVirtToPhysReg(DestVirtReg, DestPhysReg);
+ } else
+ DestPhysReg = getReg(MBB, MI, DestVirtReg);
}
+ MF->getRegInfo().setPhysRegUsed(DestPhysReg);
+ markVirtRegModified(DestVirtReg);
+ getVirtRegLastUse(DestVirtReg) = std::make_pair((MachineInstr*)0, 0);
+ DEBUG(dbgs() << " Assigning " << TRI->getName(DestPhysReg)
+ << " to %reg" << DestVirtReg << "\n");
+ MO.setReg(DestPhysReg); // Assign the output register
}
// If this instruction defines any registers that are immediately dead,
@@ -1059,21 +1074,20 @@ void RALocal::AllocateBasicBlock(MachineBasicBlock &MBB) {
} else if (PhysRegsUsed[PhysReg] == -2) {
// Unallocatable register dead, ignore.
continue;
- }
-
- if (PhysReg) {
- DEBUG(dbgs() << " Register " << TRI->getName(PhysReg)
- << " [%reg" << VirtReg
- << "] is never used, removing it from live set\n");
- removePhysReg(PhysReg);
- for (const unsigned *AliasSet = TRI->getAliasSet(PhysReg);
- *AliasSet; ++AliasSet) {
- if (PhysRegsUsed[*AliasSet] != -2) {
- DEBUG(dbgs() << " Register " << TRI->getName(*AliasSet)
- << " [%reg" << *AliasSet
- << "] is never used, removing it from live set\n");
- removePhysReg(*AliasSet);
- }
+ } else if (!PhysReg)
+ continue;
+
+ DEBUG(dbgs() << " Register " << TRI->getName(PhysReg)
+ << " [%reg" << VirtReg
+ << "] is never used, removing it from live set\n");
+ removePhysReg(PhysReg);
+ for (const unsigned *AliasSet = TRI->getAliasSet(PhysReg);
+ *AliasSet; ++AliasSet) {
+ if (PhysRegsUsed[*AliasSet] != -2) {
+ DEBUG(dbgs() << " Register " << TRI->getName(*AliasSet)
+ << " [%reg" << *AliasSet
+ << "] is never used, removing it from live set\n");
+ removePhysReg(*AliasSet);
}
}
}
@@ -1143,8 +1157,10 @@ bool RALocal::runOnMachineFunction(MachineFunction &Fn) {
StackSlotForVirtReg.grow(LastVirtReg);
Virt2PhysRegMap.grow(LastVirtReg);
Virt2LastUseMap.grow(LastVirtReg);
- VirtRegModified.resize(LastVirtReg+1-TargetRegisterInfo::FirstVirtualRegister);
- UsedInMultipleBlocks.resize(LastVirtReg+1-TargetRegisterInfo::FirstVirtualRegister);
+ VirtRegModified.resize(LastVirtReg+1 -
+ TargetRegisterInfo::FirstVirtualRegister);
+ UsedInMultipleBlocks.resize(LastVirtReg+1 -
+ TargetRegisterInfo::FirstVirtualRegister);
// Loop over all of the basic blocks, eliminating virtual register references
for (MachineFunction::iterator MBB = Fn.begin(), MBBe = Fn.end();
diff --git a/lib/CodeGen/ScheduleDAGInstrs.cpp b/lib/CodeGen/ScheduleDAGInstrs.cpp
index e532ade..ecc49e2 100644
--- a/lib/CodeGen/ScheduleDAGInstrs.cpp
+++ b/lib/CodeGen/ScheduleDAGInstrs.cpp
@@ -248,48 +248,47 @@ void ScheduleDAGInstrs::BuildSchedGraph(AliasAnalysis *AA) {
unsigned DataLatency = SU->Latency;
for (unsigned i = 0, e = UseList.size(); i != e; ++i) {
SUnit *UseSU = UseList[i];
- if (UseSU != SU) {
- unsigned LDataLatency = DataLatency;
- // Optionally add in a special extra latency for nodes that
- // feed addresses.
- // TODO: Do this for register aliases too.
- // TODO: Perhaps we should get rid of
- // SpecialAddressLatency and just move this into
- // adjustSchedDependency for the targets that care about
- // it.
- if (SpecialAddressLatency != 0 && !UnitLatencies) {
- MachineInstr *UseMI = UseSU->getInstr();
- const TargetInstrDesc &UseTID = UseMI->getDesc();
- int RegUseIndex = UseMI->findRegisterUseOperandIdx(Reg);
- assert(RegUseIndex >= 0 && "UseMI doesn's use register!");
- if ((UseTID.mayLoad() || UseTID.mayStore()) &&
- (unsigned)RegUseIndex < UseTID.getNumOperands() &&
- UseTID.OpInfo[RegUseIndex].isLookupPtrRegClass())
- LDataLatency += SpecialAddressLatency;
- }
- // Adjust the dependence latency using operand def/use
- // information (if any), and then allow the target to
- // perform its own adjustments.
- const SDep& dep = SDep(SU, SDep::Data, LDataLatency, Reg);
- if (!UnitLatencies) {
- ComputeOperandLatency(SU, UseSU, (SDep &)dep);
- ST.adjustSchedDependency(SU, UseSU, (SDep &)dep);
- }
- UseSU->addPred(dep);
+ if (UseSU == SU)
+ continue;
+ unsigned LDataLatency = DataLatency;
+ // Optionally add in a special extra latency for nodes that
+ // feed addresses.
+ // TODO: Do this for register aliases too.
+ // TODO: Perhaps we should get rid of
+ // SpecialAddressLatency and just move this into
+ // adjustSchedDependency for the targets that care about it.
+ if (SpecialAddressLatency != 0 && !UnitLatencies) {
+ MachineInstr *UseMI = UseSU->getInstr();
+ const TargetInstrDesc &UseTID = UseMI->getDesc();
+ int RegUseIndex = UseMI->findRegisterUseOperandIdx(Reg);
+ assert(RegUseIndex >= 0 && "UseMI doesn's use register!");
+ if ((UseTID.mayLoad() || UseTID.mayStore()) &&
+ (unsigned)RegUseIndex < UseTID.getNumOperands() &&
+ UseTID.OpInfo[RegUseIndex].isLookupPtrRegClass())
+ LDataLatency += SpecialAddressLatency;
}
+ // Adjust the dependence latency using operand def/use
+ // information (if any), and then allow the target to
+ // perform its own adjustments.
+ const SDep& dep = SDep(SU, SDep::Data, LDataLatency, Reg);
+ if (!UnitLatencies) {
+ ComputeOperandLatency(SU, UseSU, (SDep &)dep);
+ ST.adjustSchedDependency(SU, UseSU, (SDep &)dep);
+ }
+ UseSU->addPred(dep);
}
for (const unsigned *Alias = TRI->getAliasSet(Reg); *Alias; ++Alias) {
std::vector<SUnit *> &UseList = Uses[*Alias];
for (unsigned i = 0, e = UseList.size(); i != e; ++i) {
SUnit *UseSU = UseList[i];
- if (UseSU != SU) {
- const SDep& dep = SDep(SU, SDep::Data, DataLatency, *Alias);
- if (!UnitLatencies) {
- ComputeOperandLatency(SU, UseSU, (SDep &)dep);
- ST.adjustSchedDependency(SU, UseSU, (SDep &)dep);
- }
- UseSU->addPred(dep);
+ if (UseSU == SU)
+ continue;
+ const SDep& dep = SDep(SU, SDep::Data, DataLatency, *Alias);
+ if (!UnitLatencies) {
+ ComputeOperandLatency(SU, UseSU, (SDep &)dep);
+ ST.adjustSchedDependency(SU, UseSU, (SDep &)dep);
}
+ UseSU->addPred(dep);
}
}
@@ -528,7 +527,8 @@ void ScheduleDAGInstrs::ComputeOperandLatency(SUnit *Def, SUnit *Use,
MachineInstr *DefMI = Def->getInstr();
int DefIdx = DefMI->findRegisterDefOperandIdx(Reg);
if (DefIdx != -1) {
- int DefCycle = InstrItins.getOperandCycle(DefMI->getDesc().getSchedClass(), DefIdx);
+ int DefCycle = InstrItins.getOperandCycle(DefMI->getDesc().getSchedClass(),
+ DefIdx);
if (DefCycle >= 0) {
MachineInstr *UseMI = Use->getInstr();
const unsigned UseClass = UseMI->getDesc().getSchedClass();
diff --git a/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
index aa283ad..a336e0a 100644
--- a/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
+++ b/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
@@ -5022,18 +5022,6 @@ SDValue DAGCombiner::visitLOAD(SDNode *N) {
SDValue Chain = LD->getChain();
SDValue Ptr = LD->getBasePtr();
- // Try to infer better alignment information than the load already has.
- if (OptLevel != CodeGenOpt::None && LD->isUnindexed()) {
- if (unsigned Align = DAG.InferPtrAlignment(Ptr)) {
- if (Align > LD->getAlignment())
- return DAG.getExtLoad(LD->getExtensionType(), N->getDebugLoc(),
- LD->getValueType(0),
- Chain, Ptr, LD->getSrcValue(),
- LD->getSrcValueOffset(), LD->getMemoryVT(),
- LD->isVolatile(), LD->isNonTemporal(), Align);
- }
- }
-
// If load is not volatile and there are no uses of the loaded value (and
// the updated indexed value in case of indexed loads), change uses of the
// chain value into uses of the chain input (i.e. delete the dead load).
@@ -5099,6 +5087,18 @@ SDValue DAGCombiner::visitLOAD(SDNode *N) {
}
}
+ // Try to infer better alignment information than the load already has.
+ if (OptLevel != CodeGenOpt::None && LD->isUnindexed()) {
+ if (unsigned Align = DAG.InferPtrAlignment(Ptr)) {
+ if (Align > LD->getAlignment())
+ return DAG.getExtLoad(LD->getExtensionType(), N->getDebugLoc(),
+ LD->getValueType(0),
+ Chain, Ptr, LD->getSrcValue(),
+ LD->getSrcValueOffset(), LD->getMemoryVT(),
+ LD->isVolatile(), LD->isNonTemporal(), Align);
+ }
+ }
+
if (CombinerAA) {
// Walk up chain skipping non-aliasing memory nodes.
SDValue BetterChain = FindBetterChain(N, Chain);
@@ -5250,17 +5250,6 @@ SDValue DAGCombiner::visitSTORE(SDNode *N) {
SDValue Value = ST->getValue();
SDValue Ptr = ST->getBasePtr();
- // Try to infer better alignment information than the store already has.
- if (OptLevel != CodeGenOpt::None && ST->isUnindexed()) {
- if (unsigned Align = DAG.InferPtrAlignment(Ptr)) {
- if (Align > ST->getAlignment())
- return DAG.getTruncStore(Chain, N->getDebugLoc(), Value,
- Ptr, ST->getSrcValue(),
- ST->getSrcValueOffset(), ST->getMemoryVT(),
- ST->isVolatile(), ST->isNonTemporal(), Align);
- }
- }
-
// If this is a store of a bit convert, store the input value if the
// resultant store does not need a higher alignment than the original.
if (Value.getOpcode() == ISD::BIT_CONVERT && !ST->isTruncatingStore() &&
@@ -5351,6 +5340,17 @@ SDValue DAGCombiner::visitSTORE(SDNode *N) {
}
}
+ // Try to infer better alignment information than the store already has.
+ if (OptLevel != CodeGenOpt::None && ST->isUnindexed()) {
+ if (unsigned Align = DAG.InferPtrAlignment(Ptr)) {
+ if (Align > ST->getAlignment())
+ return DAG.getTruncStore(Chain, N->getDebugLoc(), Value,
+ Ptr, ST->getSrcValue(),
+ ST->getSrcValueOffset(), ST->getMemoryVT(),
+ ST->isVolatile(), ST->isNonTemporal(), Align);
+ }
+ }
+
if (CombinerAA) {
// Walk up chain skipping non-aliasing memory nodes.
SDValue BetterChain = FindBetterChain(N, Chain);
diff --git a/lib/CodeGen/SelectionDAG/FastISel.cpp b/lib/CodeGen/SelectionDAG/FastISel.cpp
index 3fc30ff..e4e9ef4 100644
--- a/lib/CodeGen/SelectionDAG/FastISel.cpp
+++ b/lib/CodeGen/SelectionDAG/FastISel.cpp
@@ -340,10 +340,9 @@ bool FastISel::SelectCall(User *I) {
StaticAllocaMap.find(AI);
if (SI == StaticAllocaMap.end()) break; // VLAs.
int FI = SI->second;
- if (MMI) {
- if (MDNode *Dbg = DI->getMetadata("dbg"))
- MMI->setVariableDbgInfo(DI->getVariable(), FI, Dbg);
- }
+ if (MDNode *Dbg = DI->getDbgMetadata())
+ MMI->setVariableDbgInfo(DI->getVariable(), FI, Dbg);
+
// Building the map above is target independent. Generating DBG_VALUE
// inline is target dependent; do this now.
(void)TargetSelectInstruction(cast<Instruction>(I));
diff --git a/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp b/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp
index 50f4c32..4fb2aa2 100644
--- a/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp
+++ b/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp
@@ -281,8 +281,17 @@ unsigned FunctionLoweringInfo::CreateRegForValue(const Value *V) {
GlobalVariable *llvm::ExtractTypeInfo(Value *V) {
V = V->stripPointerCasts();
GlobalVariable *GV = dyn_cast<GlobalVariable>(V);
- assert ((GV || isa<ConstantPointerNull>(V)) &&
- "TypeInfo must be a global variable or NULL");
+
+ if (GV && GV->getName() == ".llvm.eh.catch.all.value") {
+ assert(GV->hasInitializer() &&
+ "The EH catch-all value must have an initializer");
+ Value *Init = GV->getInitializer();
+ GV = dyn_cast<GlobalVariable>(Init);
+ if (!GV) V = cast<ConstantPointerNull>(Init);
+ }
+
+ assert((GV || isa<ConstantPointerNull>(V)) &&
+ "TypeInfo must be a global variable or NULL");
return GV;
}
diff --git a/lib/CodeGen/SelectionDAG/InstrEmitter.cpp b/lib/CodeGen/SelectionDAG/InstrEmitter.cpp
index fda094d3..28ba343 100644
--- a/lib/CodeGen/SelectionDAG/InstrEmitter.cpp
+++ b/lib/CodeGen/SelectionDAG/InstrEmitter.cpp
@@ -264,7 +264,8 @@ void
InstrEmitter::AddRegisterOperand(MachineInstr *MI, SDValue Op,
unsigned IIOpNum,
const TargetInstrDesc *II,
- DenseMap<SDValue, unsigned> &VRBaseMap) {
+ DenseMap<SDValue, unsigned> &VRBaseMap,
+ bool IsDebug) {
assert(Op.getValueType() != MVT::Other &&
Op.getValueType() != MVT::Flag &&
"Chain and flag operands should occur at end of operand list!");
@@ -295,7 +296,11 @@ InstrEmitter::AddRegisterOperand(MachineInstr *MI, SDValue Op,
}
}
- MI->addOperand(MachineOperand::CreateReg(VReg, isOptDef));
+ MI->addOperand(MachineOperand::CreateReg(VReg, isOptDef,
+ false/*isImp*/, false/*isKill*/,
+ false/*isDead*/, false/*isUndef*/,
+ false/*isEarlyClobber*/,
+ 0/*SubReg*/, IsDebug));
}
/// AddOperand - Add the specified operand to the specified machine instr. II
@@ -305,9 +310,10 @@ InstrEmitter::AddRegisterOperand(MachineInstr *MI, SDValue Op,
void InstrEmitter::AddOperand(MachineInstr *MI, SDValue Op,
unsigned IIOpNum,
const TargetInstrDesc *II,
- DenseMap<SDValue, unsigned> &VRBaseMap) {
+ DenseMap<SDValue, unsigned> &VRBaseMap,
+ bool IsDebug) {
if (Op.isMachineOpcode()) {
- AddRegisterOperand(MI, Op, IIOpNum, II, VRBaseMap);
+ AddRegisterOperand(MI, Op, IIOpNum, II, VRBaseMap, IsDebug);
} else if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(Op)) {
MI->addOperand(MachineOperand::CreateImm(C->getSExtValue()));
} else if (ConstantFPSDNode *F = dyn_cast<ConstantFPSDNode>(Op)) {
@@ -356,7 +362,7 @@ void InstrEmitter::AddOperand(MachineInstr *MI, SDValue Op,
assert(Op.getValueType() != MVT::Other &&
Op.getValueType() != MVT::Flag &&
"Chain and flag operands should occur at end of operand list!");
- AddRegisterOperand(MI, Op, IIOpNum, II, VRBaseMap);
+ AddRegisterOperand(MI, Op, IIOpNum, II, VRBaseMap, IsDebug);
}
}
@@ -498,164 +504,156 @@ InstrEmitter::EmitCopyToRegClassNode(SDNode *Node,
assert(isNew && "Node emitted out of order - early");
}
-/// EmitDbgValue - Generate any debug info that refers to this Node. Constant
-/// dbg_value is not handled here.
-void
-InstrEmitter::EmitDbgValue(SDNode *Node,
- DenseMap<SDValue, unsigned> &VRBaseMap,
- SDDbgValue *sd) {
- if (!Node->getHasDebugValue())
- return;
- if (!sd)
- return;
- assert(sd->getKind() == SDDbgValue::SDNODE);
- unsigned VReg = getVR(SDValue(sd->getSDNode(), sd->getResNo()), VRBaseMap);
- const TargetInstrDesc &II = TII->get(TargetOpcode::DBG_VALUE);
- DebugLoc DL = sd->getDebugLoc();
- MachineInstr *MI;
- if (VReg) {
- MI = BuildMI(*MF, DL, II).addReg(VReg, RegState::Debug).
- addImm(sd->getOffset()).
- addMetadata(sd->getMDPtr());
- } else {
- // Insert an Undef so we can see what we dropped.
- MI = BuildMI(*MF, DL, II).addReg(0U).addImm(sd->getOffset()).
- addMetadata(sd->getMDPtr());
- }
- MBB->insert(InsertPos, MI);
-}
-
-/// EmitDbgValue - Generate debug info that does not refer to a SDNode.
-void
-InstrEmitter::EmitDbgValue(SDDbgValue *sd,
+/// EmitDbgValue - Generate machine instruction for a dbg_value node.
+///
+MachineInstr *InstrEmitter::EmitDbgValue(SDDbgValue *SD,
+ MachineBasicBlock *InsertBB,
+ DenseMap<SDValue, unsigned> &VRBaseMap,
DenseMap<MachineBasicBlock*, MachineBasicBlock*> *EM) {
- if (!sd)
- return;
+ uint64_t Offset = SD->getOffset();
+ MDNode* MDPtr = SD->getMDPtr();
+ DebugLoc DL = SD->getDebugLoc();
+
const TargetInstrDesc &II = TII->get(TargetOpcode::DBG_VALUE);
- uint64_t Offset = sd->getOffset();
- MDNode* mdPtr = sd->getMDPtr();
- SDDbgValue::DbgValueKind kind = sd->getKind();
- DebugLoc DL = sd->getDebugLoc();
- MachineInstr* MI;
- if (kind == SDDbgValue::CONST) {
- Value *V = sd->getConst();
+ MachineInstrBuilder MIB = BuildMI(*MF, DL, II);
+ if (SD->getKind() == SDDbgValue::SDNODE) {
+ AddOperand(&*MIB, SDValue(SD->getSDNode(), SD->getResNo()),
+ (*MIB).getNumOperands(), &II, VRBaseMap, true /*IsDebug*/);
+ } else if (SD->getKind() == SDDbgValue::CONST) {
+ Value *V = SD->getConst();
if (ConstantInt *CI = dyn_cast<ConstantInt>(V)) {
- MI = BuildMI(*MF, DL, II).addImm(CI->getZExtValue()).
- addImm(Offset).addMetadata(mdPtr);
+ MIB.addImm(CI->getSExtValue());
} else if (ConstantFP *CF = dyn_cast<ConstantFP>(V)) {
- MI = BuildMI(*MF, DL, II).addFPImm(CF).
- addImm(Offset).addMetadata(mdPtr);
+ MIB.addFPImm(CF);
} else {
// Could be an Undef. In any case insert an Undef so we can see what we
// dropped.
- MI = BuildMI(*MF, DL, II).addReg(0U).
- addImm(Offset).addMetadata(mdPtr);
+ MIB.addReg(0U);
}
- } else if (kind == SDDbgValue::FRAMEIX) {
- unsigned FrameIx = sd->getFrameIx();
+ } else if (SD->getKind() == SDDbgValue::FRAMEIX) {
+ unsigned FrameIx = SD->getFrameIx();
// Stack address; this needs to be lowered in target-dependent fashion.
// FIXME test that the target supports this somehow; if not emit Undef.
// Create a pseudo for EmitInstrWithCustomInserter's consumption.
- MI = BuildMI(*MF, DL, II).addImm(FrameIx).
- addImm(Offset).addMetadata(mdPtr);
- MBB = TLI->EmitInstrWithCustomInserter(MI, MBB, EM);
- InsertPos = MBB->end();
- return;
+ MIB.addImm(FrameIx).addImm(Offset).addMetadata(MDPtr);
+ abort();
+ TLI->EmitInstrWithCustomInserter(&*MIB, InsertBB, EM);
+ return 0;
} else {
// Insert an Undef so we can see what we dropped.
- MI = BuildMI(*MF, DL, II).addReg(0U).
- addImm(Offset).addMetadata(mdPtr);
+ MIB.addReg(0U);
}
- MBB->insert(InsertPos, MI);
+
+ MIB.addImm(Offset).addMetadata(MDPtr);
+ return &*MIB;
}
-/// EmitNode - Generate machine code for a node and needed dependencies.
+/// EmitMachineNode - Generate machine code for a target-specific node and
+/// needed dependencies.
///
-void InstrEmitter::EmitNode(SDNode *Node, bool IsClone, bool IsCloned,
- DenseMap<SDValue, unsigned> &VRBaseMap,
- DenseMap<MachineBasicBlock*, MachineBasicBlock*> *EM) {
- // If machine instruction
- if (Node->isMachineOpcode()) {
- unsigned Opc = Node->getMachineOpcode();
-
- // Handle subreg insert/extract specially
- if (Opc == TargetOpcode::EXTRACT_SUBREG ||
- Opc == TargetOpcode::INSERT_SUBREG ||
- Opc == TargetOpcode::SUBREG_TO_REG) {
- EmitSubregNode(Node, VRBaseMap);
- return;
- }
+void InstrEmitter::
+EmitMachineNode(SDNode *Node, bool IsClone, bool IsCloned,
+ DenseMap<SDValue, unsigned> &VRBaseMap,
+ DenseMap<MachineBasicBlock*, MachineBasicBlock*> *EM) {
+ unsigned Opc = Node->getMachineOpcode();
+
+ // Handle subreg insert/extract specially
+ if (Opc == TargetOpcode::EXTRACT_SUBREG ||
+ Opc == TargetOpcode::INSERT_SUBREG ||
+ Opc == TargetOpcode::SUBREG_TO_REG) {
+ EmitSubregNode(Node, VRBaseMap);
+ return;
+ }
- // Handle COPY_TO_REGCLASS specially.
- if (Opc == TargetOpcode::COPY_TO_REGCLASS) {
- EmitCopyToRegClassNode(Node, VRBaseMap);
- return;
- }
+ // Handle COPY_TO_REGCLASS specially.
+ if (Opc == TargetOpcode::COPY_TO_REGCLASS) {
+ EmitCopyToRegClassNode(Node, VRBaseMap);
+ return;
+ }
- if (Opc == TargetOpcode::IMPLICIT_DEF)
- // We want a unique VR for each IMPLICIT_DEF use.
- return;
-
- const TargetInstrDesc &II = TII->get(Opc);
- unsigned NumResults = CountResults(Node);
- unsigned NodeOperands = CountOperands(Node);
- bool HasPhysRegOuts = (NumResults > II.getNumDefs()) &&
- II.getImplicitDefs() != 0;
+ if (Opc == TargetOpcode::IMPLICIT_DEF)
+ // We want a unique VR for each IMPLICIT_DEF use.
+ return;
+
+ const TargetInstrDesc &II = TII->get(Opc);
+ unsigned NumResults = CountResults(Node);
+ unsigned NodeOperands = CountOperands(Node);
+ bool HasPhysRegOuts = NumResults > II.getNumDefs() && II.getImplicitDefs()!=0;
#ifndef NDEBUG
- unsigned NumMIOperands = NodeOperands + NumResults;
- assert((II.getNumOperands() == NumMIOperands ||
- HasPhysRegOuts || II.isVariadic()) &&
- "#operands for dag node doesn't match .td file!");
+ unsigned NumMIOperands = NodeOperands + NumResults;
+ if (II.isVariadic())
+ assert(NumMIOperands >= II.getNumOperands() &&
+ "Too few operands for a variadic node!");
+ else
+ assert(NumMIOperands >= II.getNumOperands() &&
+ NumMIOperands <= II.getNumOperands()+II.getNumImplicitDefs() &&
+ "#operands for dag node doesn't match .td file!");
#endif
- // Create the new machine instruction.
- MachineInstr *MI = BuildMI(*MF, Node->getDebugLoc(), II);
-
- // Add result register values for things that are defined by this
- // instruction.
- if (NumResults)
- CreateVirtualRegisters(Node, MI, II, IsClone, IsCloned, VRBaseMap);
-
- // Emit all of the actual operands of this instruction, adding them to the
- // instruction as appropriate.
- bool HasOptPRefs = II.getNumDefs() > NumResults;
- assert((!HasOptPRefs || !HasPhysRegOuts) &&
- "Unable to cope with optional defs and phys regs defs!");
- unsigned NumSkip = HasOptPRefs ? II.getNumDefs() - NumResults : 0;
- for (unsigned i = NumSkip; i != NodeOperands; ++i)
- AddOperand(MI, Node->getOperand(i), i-NumSkip+II.getNumDefs(), &II,
- VRBaseMap);
-
- // Transfer all of the memory reference descriptions of this instruction.
- MI->setMemRefs(cast<MachineSDNode>(Node)->memoperands_begin(),
- cast<MachineSDNode>(Node)->memoperands_end());
-
- if (II.usesCustomInsertionHook()) {
- // Insert this instruction into the basic block using a target
- // specific inserter which may returns a new basic block.
- MBB = TLI->EmitInstrWithCustomInserter(MI, MBB, EM);
- InsertPos = MBB->end();
- } else {
- MBB->insert(InsertPos, MI);
- }
+ // Create the new machine instruction.
+ MachineInstr *MI = BuildMI(*MF, Node->getDebugLoc(), II);
+
+ // Add result register values for things that are defined by this
+ // instruction.
+ if (NumResults)
+ CreateVirtualRegisters(Node, MI, II, IsClone, IsCloned, VRBaseMap);
+
+ // Emit all of the actual operands of this instruction, adding them to the
+ // instruction as appropriate.
+ bool HasOptPRefs = II.getNumDefs() > NumResults;
+ assert((!HasOptPRefs || !HasPhysRegOuts) &&
+ "Unable to cope with optional defs and phys regs defs!");
+ unsigned NumSkip = HasOptPRefs ? II.getNumDefs() - NumResults : 0;
+ for (unsigned i = NumSkip; i != NodeOperands; ++i)
+ AddOperand(MI, Node->getOperand(i), i-NumSkip+II.getNumDefs(), &II,
+ VRBaseMap);
+
+ // Transfer all of the memory reference descriptions of this instruction.
+ MI->setMemRefs(cast<MachineSDNode>(Node)->memoperands_begin(),
+ cast<MachineSDNode>(Node)->memoperands_end());
+
+ if (II.usesCustomInsertionHook()) {
+ // Insert this instruction into the basic block using a target
+ // specific inserter which may returns a new basic block.
+ MBB = TLI->EmitInstrWithCustomInserter(MI, MBB, EM);
+ InsertPos = MBB->end();
+ return;
+ }
+
+ MBB->insert(InsertPos, MI);
- // Additional results must be an physical register def.
- if (HasPhysRegOuts) {
- for (unsigned i = II.getNumDefs(); i < NumResults; ++i) {
- unsigned Reg = II.getImplicitDefs()[i - II.getNumDefs()];
- if (Node->hasAnyUseOfValue(i))
- EmitCopyFromReg(Node, i, IsClone, IsCloned, Reg, VRBaseMap);
- // If there are no uses, mark the register as dead now, so that
- // MachineLICM/Sink can see that it's dead. Don't do this if the
- // node has a Flag value, for the benefit of targets still using
- // Flag for values in physregs.
- else if (Node->getValueType(Node->getNumValues()-1) != MVT::Flag)
- MI->addRegisterDead(Reg, TRI);
- }
+ // Additional results must be an physical register def.
+ if (HasPhysRegOuts) {
+ for (unsigned i = II.getNumDefs(); i < NumResults; ++i) {
+ unsigned Reg = II.getImplicitDefs()[i - II.getNumDefs()];
+ if (Node->hasAnyUseOfValue(i))
+ EmitCopyFromReg(Node, i, IsClone, IsCloned, Reg, VRBaseMap);
+ // If there are no uses, mark the register as dead now, so that
+ // MachineLICM/Sink can see that it's dead. Don't do this if the
+ // node has a Flag value, for the benefit of targets still using
+ // Flag for values in physregs.
+ else if (Node->getValueType(Node->getNumValues()-1) != MVT::Flag)
+ MI->addRegisterDead(Reg, TRI);
}
- return;
}
+
+ // If the instruction has implicit defs and the node doesn't, mark the
+ // implicit def as dead. If the node has any flag outputs, we don't do this
+ // because we don't know what implicit defs are being used by flagged nodes.
+ if (Node->getValueType(Node->getNumValues()-1) != MVT::Flag)
+ if (const unsigned *IDList = II.getImplicitDefs()) {
+ for (unsigned i = NumResults, e = II.getNumDefs()+II.getNumImplicitDefs();
+ i != e; ++i)
+ MI->addRegisterDead(IDList[i-II.getNumDefs()], TRI);
+ }
+ return;
+}
+/// EmitSpecialNode - Generate machine code for a target-independent node and
+/// needed dependencies.
+void InstrEmitter::
+EmitSpecialNode(SDNode *Node, bool IsClone, bool IsCloned,
+ DenseMap<SDValue, unsigned> &VRBaseMap) {
switch (Node->getOpcode()) {
default:
#ifndef NDEBUG
diff --git a/lib/CodeGen/SelectionDAG/InstrEmitter.h b/lib/CodeGen/SelectionDAG/InstrEmitter.h
index eefcd73..baabb75 100644
--- a/lib/CodeGen/SelectionDAG/InstrEmitter.h
+++ b/lib/CodeGen/SelectionDAG/InstrEmitter.h
@@ -64,7 +64,8 @@ class InstrEmitter {
void AddRegisterOperand(MachineInstr *MI, SDValue Op,
unsigned IIOpNum,
const TargetInstrDesc *II,
- DenseMap<SDValue, unsigned> &VRBaseMap);
+ DenseMap<SDValue, unsigned> &VRBaseMap,
+ bool IsDebug = false);
/// AddOperand - Add the specified operand to the specified machine instr. II
/// specifies the instruction information for the node, and IIOpNum is the
@@ -73,7 +74,8 @@ class InstrEmitter {
void AddOperand(MachineInstr *MI, SDValue Op,
unsigned IIOpNum,
const TargetInstrDesc *II,
- DenseMap<SDValue, unsigned> &VRBaseMap);
+ DenseMap<SDValue, unsigned> &VRBaseMap,
+ bool IsDebug = false);
/// EmitSubregNode - Generate machine code for subreg nodes.
///
@@ -98,22 +100,23 @@ public:
/// MachineInstr.
static unsigned CountOperands(SDNode *Node);
- /// EmitDbgValue - Generate any debug info that refers to this Node. Constant
- /// dbg_value is not handled here.
- void EmitDbgValue(SDNode *Node,
- DenseMap<SDValue, unsigned> &VRBaseMap,
- SDDbgValue* sd);
-
-
- /// EmitDbgValue - Generate a constant DBG_VALUE. No node is involved.
- void EmitDbgValue(SDDbgValue* sd,
- DenseMap<MachineBasicBlock*, MachineBasicBlock*> *EM);
+ /// EmitDbgValue - Generate machine instruction for a dbg_value node.
+ ///
+ MachineInstr *EmitDbgValue(SDDbgValue *SD,
+ MachineBasicBlock *InsertBB,
+ DenseMap<SDValue, unsigned> &VRBaseMap,
+ DenseMap<MachineBasicBlock*, MachineBasicBlock*> *EM);
/// EmitNode - Generate machine code for a node and needed dependencies.
///
void EmitNode(SDNode *Node, bool IsClone, bool IsCloned,
DenseMap<SDValue, unsigned> &VRBaseMap,
- DenseMap<MachineBasicBlock*, MachineBasicBlock*> *EM);
+ DenseMap<MachineBasicBlock*, MachineBasicBlock*> *EM) {
+ if (Node->isMachineOpcode())
+ EmitMachineNode(Node, IsClone, IsCloned, VRBaseMap, EM);
+ else
+ EmitSpecialNode(Node, IsClone, IsCloned, VRBaseMap);
+ }
/// getBlock - Return the current basic block.
MachineBasicBlock *getBlock() { return MBB; }
@@ -124,6 +127,13 @@ public:
/// InstrEmitter - Construct an InstrEmitter and set it to start inserting
/// at the given position in the given block.
InstrEmitter(MachineBasicBlock *mbb, MachineBasicBlock::iterator insertpos);
+
+private:
+ void EmitMachineNode(SDNode *Node, bool IsClone, bool IsCloned,
+ DenseMap<SDValue, unsigned> &VRBaseMap,
+ DenseMap<MachineBasicBlock*, MachineBasicBlock*> *EM);
+ void EmitSpecialNode(SDNode *Node, bool IsClone, bool IsCloned,
+ DenseMap<SDValue, unsigned> &VRBaseMap);
};
}
diff --git a/lib/CodeGen/SelectionDAG/SDNodeDbgValue.h b/lib/CodeGen/SelectionDAG/SDNodeDbgValue.h
index dbbd753..7638ea2 100644
--- a/lib/CodeGen/SelectionDAG/SDNodeDbgValue.h
+++ b/lib/CodeGen/SelectionDAG/SDNodeDbgValue.h
@@ -47,10 +47,12 @@ private:
uint64_t Offset;
DebugLoc DL;
unsigned Order;
+ bool Invalid;
public:
// Constructor for non-constants.
SDDbgValue(MDNode *mdP, SDNode *N, unsigned R, uint64_t off, DebugLoc dl,
- unsigned O) : mdPtr(mdP), Offset(off), DL(dl), Order(O) {
+ unsigned O) : mdPtr(mdP), Offset(off), DL(dl), Order(O),
+ Invalid(false) {
kind = SDNODE;
u.s.Node = N;
u.s.ResNo = R;
@@ -58,14 +60,14 @@ public:
// Constructor for constants.
SDDbgValue(MDNode *mdP, Value *C, uint64_t off, DebugLoc dl, unsigned O) :
- mdPtr(mdP), Offset(off), DL(dl), Order(O) {
+ mdPtr(mdP), Offset(off), DL(dl), Order(O), Invalid(false) {
kind = CONST;
u.Const = C;
}
// Constructor for frame indices.
SDDbgValue(MDNode *mdP, unsigned FI, uint64_t off, DebugLoc dl, unsigned O) :
- mdPtr(mdP), Offset(off), DL(dl), Order(O) {
+ mdPtr(mdP), Offset(off), DL(dl), Order(O), Invalid(false) {
kind = FRAMEIX;
u.FrameIx = FI;
}
@@ -97,6 +99,12 @@ public:
// Returns the SDNodeOrder. This is the order of the preceding node in the
// input.
unsigned getOrder() { return Order; }
+
+ // setIsInvalidated / isInvalidated - Setter / getter of the "Invalidated"
+ // property. A SDDbgValue is invalid if the SDNode that produces the value is
+ // deleted.
+ void setIsInvalidated() { Invalid = true; }
+ bool isInvalidated() { return Invalid; }
};
} // end llvm namespace
diff --git a/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.cpp b/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.cpp
index c13565a..e7ab2f0 100644
--- a/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.cpp
+++ b/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodes.cpp
@@ -23,6 +23,7 @@
#include "llvm/Target/TargetSubtarget.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/ADT/SmallSet.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/Support/Debug.h"
@@ -407,19 +408,65 @@ void ScheduleDAGSDNodes::dumpNode(const SUnit *SU) const {
}
}
+namespace {
+ struct OrderSorter {
+ bool operator()(const std::pair<unsigned, MachineInstr*> &A,
+ const std::pair<unsigned, MachineInstr*> &B) {
+ return A.first < B.first;
+ }
+ };
+}
+
+// ProcessSourceNode - Process nodes with source order numbers. These are added
+// to a vector which EmitSchedule use to determine how to insert dbg_value
+// instructions in the right order.
+static void ProcessSourceNode(SDNode *N, SelectionDAG *DAG,
+ InstrEmitter &Emitter,
+ DenseMap<MachineBasicBlock*, MachineBasicBlock*> *EM,
+ DenseMap<SDValue, unsigned> &VRBaseMap,
+ SmallVector<std::pair<unsigned, MachineInstr*>, 32> &Orders,
+ SmallSet<unsigned, 8> &Seen) {
+ unsigned Order = DAG->GetOrdering(N);
+ if (!Order || !Seen.insert(Order))
+ return;
+
+ MachineBasicBlock *BB = Emitter.getBlock();
+ if (BB->empty() || BB->back().isPHI()) {
+ // Did not insert any instruction.
+ Orders.push_back(std::make_pair(Order, (MachineInstr*)0));
+ return;
+ }
+
+ Orders.push_back(std::make_pair(Order, &BB->back()));
+ if (!N->getHasDebugValue())
+ return;
+ // Opportunistically insert immediate dbg_value uses, i.e. those with source
+ // order number right after the N.
+ MachineBasicBlock::iterator InsertPos = Emitter.getInsertPos();
+ SmallVector<SDDbgValue*,2> &DVs = DAG->GetDbgValues(N);
+ for (unsigned i = 0, e = DVs.size(); i != e; ++i) {
+ if (DVs[i]->isInvalidated())
+ continue;
+ unsigned DVOrder = DVs[i]->getOrder();
+ if (DVOrder == ++Order) {
+ MachineInstr *DbgMI = Emitter.EmitDbgValue(DVs[i], BB, VRBaseMap, EM);
+ Orders.push_back(std::make_pair(DVOrder, DbgMI));
+ BB->insert(InsertPos, DbgMI);
+ DVs[i]->setIsInvalidated();
+ }
+ }
+}
+
+
/// EmitSchedule - Emit the machine code in scheduled order.
MachineBasicBlock *ScheduleDAGSDNodes::
EmitSchedule(DenseMap<MachineBasicBlock*, MachineBasicBlock*> *EM) {
InstrEmitter Emitter(BB, InsertPos);
DenseMap<SDValue, unsigned> VRBaseMap;
DenseMap<SUnit*, unsigned> CopyVRBaseMap;
-
- // For now, any constant debug info nodes go at the beginning.
- for (SDDbgInfo::ConstDbgIterator I = DAG->DbgConstBegin(),
- E = DAG->DbgConstEnd(); I!=E; I++) {
- Emitter.EmitDbgValue(*I, EM);
- delete *I;
- }
+ SmallVector<std::pair<unsigned, MachineInstr*>, 32> Orders;
+ SmallSet<unsigned, 8> Seen;
+ bool HasDbg = DAG->hasDebugValues();
for (unsigned i = 0, e = Sequence.size(); i != e; i++) {
SUnit *SU = Sequence[i];
@@ -442,22 +489,80 @@ EmitSchedule(DenseMap<MachineBasicBlock*, MachineBasicBlock*> *EM) {
N = N->getFlaggedNode())
FlaggedNodes.push_back(N);
while (!FlaggedNodes.empty()) {
+ SDNode *N = FlaggedNodes.back();
Emitter.EmitNode(FlaggedNodes.back(), SU->OrigNode != SU, SU->isCloned,
VRBaseMap, EM);
- if (FlaggedNodes.back()->getHasDebugValue())
- if (SDDbgValue *sd = DAG->GetDbgInfo(FlaggedNodes.back())) {
- Emitter.EmitDbgValue(FlaggedNodes.back(), VRBaseMap, sd);
- delete sd;
- }
+ // Remember the the source order of the inserted instruction.
+ if (HasDbg)
+ ProcessSourceNode(N, DAG, Emitter, EM, VRBaseMap, Orders, Seen);
FlaggedNodes.pop_back();
}
Emitter.EmitNode(SU->getNode(), SU->OrigNode != SU, SU->isCloned,
VRBaseMap, EM);
- if (SU->getNode()->getHasDebugValue())
- if (SDDbgValue *sd = DAG->GetDbgInfo(SU->getNode())) {
- Emitter.EmitDbgValue(SU->getNode(), VRBaseMap, sd);
- delete sd;
+ // Remember the the source order of the inserted instruction.
+ if (HasDbg)
+ ProcessSourceNode(SU->getNode(), DAG, Emitter, EM, VRBaseMap, Orders,
+ Seen);
+ }
+
+ // Insert all the dbg_value which have not already been inserted in source
+ // order sequence.
+ if (HasDbg) {
+ MachineBasicBlock::iterator BBBegin = BB->empty() ? BB->end() : BB->begin();
+ while (BBBegin != BB->end() && BBBegin->isPHI())
+ ++BBBegin;
+
+ // Sort the source order instructions and use the order to insert debug
+ // values.
+ std::sort(Orders.begin(), Orders.end(), OrderSorter());
+
+ SDDbgInfo::DbgIterator DI = DAG->DbgBegin();
+ SDDbgInfo::DbgIterator DE = DAG->DbgEnd();
+ // Now emit the rest according to source order.
+ unsigned LastOrder = 0;
+ MachineInstr *LastMI = 0;
+ for (unsigned i = 0, e = Orders.size(); i != e && DI != DE; ++i) {
+ unsigned Order = Orders[i].first;
+ MachineInstr *MI = Orders[i].second;
+ // Insert all SDDbgValue's whose order(s) are before "Order".
+ if (!MI)
+ continue;
+ MachineBasicBlock *MIBB = MI->getParent();
+#ifndef NDEBUG
+ unsigned LastDIOrder = 0;
+#endif
+ for (; DI != DE &&
+ (*DI)->getOrder() >= LastOrder && (*DI)->getOrder() < Order; ++DI) {
+#ifndef NDEBUG
+ assert((*DI)->getOrder() >= LastDIOrder &&
+ "SDDbgValue nodes must be in source order!");
+ LastDIOrder = (*DI)->getOrder();
+#endif
+ if ((*DI)->isInvalidated())
+ continue;
+ MachineInstr *DbgMI = Emitter.EmitDbgValue(*DI, MIBB, VRBaseMap, EM);
+ if (!LastOrder)
+ // Insert to start of the BB (after PHIs).
+ BB->insert(BBBegin, DbgMI);
+ else {
+ MachineBasicBlock::iterator Pos = MI;
+ MIBB->insert(llvm::next(Pos), DbgMI);
+ }
}
+ LastOrder = Order;
+ LastMI = MI;
+ }
+ // Add trailing DbgValue's before the terminator. FIXME: May want to add
+ // some of them before one or more conditional branches?
+ while (DI != DE) {
+ MachineBasicBlock *InsertBB = Emitter.getBlock();
+ MachineBasicBlock::iterator Pos= Emitter.getBlock()->getFirstTerminator();
+ if (!(*DI)->isInvalidated()) {
+ MachineInstr *DbgMI= Emitter.EmitDbgValue(*DI, InsertBB, VRBaseMap, EM);
+ InsertBB->insert(Pos, DbgMI);
+ }
+ ++DI;
+ }
}
BB = Emitter.getBlock();
diff --git a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
index ed9146d..0ba65ab 100644
--- a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
+++ b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
@@ -598,8 +598,10 @@ void SelectionDAG::DeallocateNode(SDNode *N) {
// Remove the ordering of this node.
Ordering->remove(N);
- // And its entry in the debug info table, if any.
- DbgInfo->remove(N);
+ // If any of the SDDbgValue nodes refer to this SDNode, invalidate them.
+ SmallVector<SDDbgValue*, 2> &DbgVals = DbgInfo->getSDDbgValues(N);
+ for (unsigned i = 0, e = DbgVals.size(); i != e; ++i)
+ DbgVals[i]->setIsInvalidated();
}
/// RemoveNodeFromCSEMaps - Take the specified node out of the CSE map that
@@ -811,6 +813,7 @@ void SelectionDAG::init(MachineFunction &mf, MachineModuleInfo *mmi,
SelectionDAG::~SelectionDAG() {
allnodes_clear();
delete Ordering;
+ DbgInfo->clear();
delete DbgInfo;
}
@@ -839,6 +842,7 @@ void SelectionDAG::clear() {
Root = getEntryNode();
delete Ordering;
Ordering = new SDNodeOrdering();
+ DbgInfo->clear();
delete DbgInfo;
DbgInfo = new SDDbgInfo();
}
@@ -3128,11 +3132,17 @@ static SDValue getMemsetStringVal(EVT VT, DebugLoc dl, SelectionDAG &DAG,
if (Str.empty()) {
if (VT.isInteger())
return DAG.getConstant(0, VT);
- unsigned NumElts = VT.getVectorNumElements();
- MVT EltVT = (VT.getVectorElementType() == MVT::f32) ? MVT::i32 : MVT::i64;
- return DAG.getNode(ISD::BIT_CONVERT, dl, VT,
- DAG.getConstant(0,
- EVT::getVectorVT(*DAG.getContext(), EltVT, NumElts)));
+ else if (VT.getSimpleVT().SimpleTy == MVT::f32 ||
+ VT.getSimpleVT().SimpleTy == MVT::f64)
+ return DAG.getConstantFP(0.0, VT);
+ else if (VT.isVector()) {
+ unsigned NumElts = VT.getVectorNumElements();
+ MVT EltVT = (VT.getVectorElementType() == MVT::f32) ? MVT::i32 : MVT::i64;
+ return DAG.getNode(ISD::BIT_CONVERT, dl, VT,
+ DAG.getConstant(0, EVT::getVectorVT(*DAG.getContext(),
+ EltVT, NumElts)));
+ } else
+ llvm_unreachable("Expected type!");
}
assert(!VT.isVector() && "Can't handle vector type here!");
@@ -3180,51 +3190,33 @@ static bool isMemSrcFromString(SDValue Src, std::string &Str) {
return false;
}
-/// MeetsMaxMemopRequirement - Determines if the number of memory ops required
-/// to replace the memset / memcpy is below the threshold. It also returns the
-/// types of the sequence of memory ops to perform memset / memcpy.
-static
-bool MeetsMaxMemopRequirement(std::vector<EVT> &MemOps,
- SDValue Dst, SDValue Src,
- unsigned Limit, uint64_t Size, unsigned &Align,
- std::string &Str, bool &isSrcStr,
- SelectionDAG &DAG,
- const TargetLowering &TLI) {
- isSrcStr = isMemSrcFromString(Src, Str);
- bool isSrcConst = isa<ConstantSDNode>(Src);
- EVT VT = TLI.getOptimalMemOpType(Size, Align, isSrcConst, isSrcStr, DAG);
- bool AllowUnalign = TLI.allowsUnalignedMemoryAccesses(VT);
- 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.
- if (NewAlign > Align && (isSrcConst || AllowUnalign)) {
- if (Dst.getOpcode() != ISD::FrameIndex) {
- // Can't change destination alignment. It requires a unaligned store.
- if (AllowUnalign)
- 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::Other;
- } else {
- // Give the stack frame object a larger alignment if needed.
- if (MFI->getObjectAlignment(FI) < NewAlign)
- MFI->setObjectAlignment(FI, NewAlign);
- Align = NewAlign;
- }
- }
- }
- }
+/// FindOptimalMemOpLowering - Determines the optimial series memory ops
+/// to replace the memset / memcpy. Return true if the number of memory ops
+/// is below the threshold. It returns the types of the sequence of
+/// memory ops to perform memset / memcpy by reference.
+static bool FindOptimalMemOpLowering(std::vector<EVT> &MemOps,
+ unsigned Limit, uint64_t Size,
+ unsigned DstAlign, unsigned SrcAlign,
+ bool SafeToUseFP,
+ SelectionDAG &DAG,
+ const TargetLowering &TLI) {
+ assert((SrcAlign == 0 || SrcAlign >= DstAlign) &&
+ "Expecting memcpy / memset source to meet alignment requirement!");
+ // If 'SrcAlign' is zero, that means the memory operation does not need load
+ // the value, i.e. memset or memcpy from constant string. Otherwise, it's
+ // the inferred alignment of the source. 'DstAlign', on the other hand, is the
+ // specified alignment of the memory operation. If it is zero, that means
+ // it's possible to change the alignment of the destination.
+ EVT VT = TLI.getOptimalMemOpType(Size, DstAlign, SrcAlign, SafeToUseFP, DAG);
if (VT == MVT::Other) {
- if (TLI.allowsUnalignedMemoryAccesses(MVT::i64)) {
+ VT = TLI.getPointerTy();
+ const Type *Ty = VT.getTypeForEVT(*DAG.getContext());
+ if (DstAlign >= TLI.getTargetData()->getABITypeAlignment(Ty) ||
+ TLI.allowsUnalignedMemoryAccesses(VT)) {
VT = MVT::i64;
} else {
- switch (Align & 7) {
+ switch (DstAlign & 7) {
case 0: VT = MVT::i64; break;
case 4: VT = MVT::i32; break;
case 2: VT = MVT::i16; break;
@@ -3246,7 +3238,7 @@ bool MeetsMaxMemopRequirement(std::vector<EVT> &MemOps,
unsigned VTSize = VT.getSizeInBits() / 8;
while (VTSize > Size) {
// For now, only use non-vector load / store's for the left-over pieces.
- if (VT.isVector()) {
+ if (VT.isVector() || VT.isFloatingPoint()) {
VT = MVT::i64;
while (!TLI.isTypeLegal(VT))
VT = (MVT::SimpleValueType)(VT.getSimpleVT().SimpleTy - 1);
@@ -3269,11 +3261,11 @@ bool MeetsMaxMemopRequirement(std::vector<EVT> &MemOps,
}
static SDValue getMemcpyLoadsAndStores(SelectionDAG &DAG, DebugLoc dl,
- SDValue Chain, SDValue Dst,
- SDValue Src, uint64_t Size,
- unsigned Align, bool AlwaysInline,
- const Value *DstSV, uint64_t DstSVOff,
- const Value *SrcSV, uint64_t SrcSVOff){
+ SDValue Chain, SDValue Dst,
+ SDValue Src, uint64_t Size,
+ unsigned Align, bool AlwaysInline,
+ const Value *DstSV, uint64_t DstSVOff,
+ const Value *SrcSV, uint64_t SrcSVOff) {
const TargetLowering &TLI = DAG.getTargetLoweringInfo();
// Expand memcpy to a series of load and store ops if the size operand falls
@@ -3282,15 +3274,33 @@ static SDValue getMemcpyLoadsAndStores(SelectionDAG &DAG, DebugLoc dl,
uint64_t Limit = -1ULL;
if (!AlwaysInline)
Limit = TLI.getMaxStoresPerMemcpy();
- unsigned DstAlign = Align; // Destination alignment can change.
+ bool DstAlignCanChange = false;
+ MachineFrameInfo *MFI = DAG.getMachineFunction().getFrameInfo();
+ FrameIndexSDNode *FI = dyn_cast<FrameIndexSDNode>(Dst);
+ if (FI && !MFI->isFixedObjectIndex(FI->getIndex()))
+ DstAlignCanChange = true;
+ unsigned SrcAlign = DAG.InferPtrAlignment(Src);
+ if (Align > SrcAlign)
+ SrcAlign = Align;
std::string Str;
- bool CopyFromStr;
- if (!MeetsMaxMemopRequirement(MemOps, Dst, Src, Limit, Size, DstAlign,
- Str, CopyFromStr, DAG, TLI))
+ bool CopyFromStr = isMemSrcFromString(Src, Str);
+ bool isZeroStr = CopyFromStr && Str.empty();
+ if (!FindOptimalMemOpLowering(MemOps, Limit, Size,
+ (DstAlignCanChange ? 0 : Align),
+ (isZeroStr ? 0 : SrcAlign), true, DAG, TLI))
return SDValue();
+ if (DstAlignCanChange) {
+ const Type *Ty = MemOps[0].getTypeForEVT(*DAG.getContext());
+ unsigned NewAlign = (unsigned) TLI.getTargetData()->getABITypeAlignment(Ty);
+ if (NewAlign > Align) {
+ // Give the stack frame object a larger alignment if needed.
+ if (MFI->getObjectAlignment(FI->getIndex()) < NewAlign)
+ MFI->setObjectAlignment(FI->getIndex(), NewAlign);
+ Align = NewAlign;
+ }
+ }
- bool isZeroStr = CopyFromStr && Str.empty();
SmallVector<SDValue, 8> OutChains;
unsigned NumMemOps = MemOps.size();
uint64_t SrcOff = 0, DstOff = 0;
@@ -3299,16 +3309,17 @@ static SDValue getMemcpyLoadsAndStores(SelectionDAG &DAG, DebugLoc dl,
unsigned VTSize = VT.getSizeInBits() / 8;
SDValue Value, Store;
- if (CopyFromStr && (isZeroStr || !VT.isVector())) {
+ if (CopyFromStr &&
+ (isZeroStr || (VT.isInteger() && !VT.isVector()))) {
// It's unlikely a store of a vector immediate can be done in a single
// instruction. It would require a load from a constantpool first.
- // We also handle store a vector with all zero's.
+ // We only handle zero vectors here.
// FIXME: Handle other cases where store of vector immediate is done in
// a single instruction.
Value = getMemsetStringVal(VT, dl, DAG, TLI, Str, SrcOff);
Store = DAG.getStore(Chain, dl, Value,
getMemBasePlusOffset(Dst, DstOff, DAG),
- DstSV, DstSVOff + DstOff, false, false, DstAlign);
+ DstSV, DstSVOff + DstOff, false, false, Align);
} else {
// The type might not be legal for the target. This should only happen
// if the type is smaller than a legal type, as on PPC, so the right
@@ -3319,11 +3330,12 @@ static SDValue getMemcpyLoadsAndStores(SelectionDAG &DAG, DebugLoc dl,
assert(NVT.bitsGE(VT));
Value = DAG.getExtLoad(ISD::EXTLOAD, dl, NVT, Chain,
getMemBasePlusOffset(Src, SrcOff, DAG),
- SrcSV, SrcSVOff + SrcOff, VT, false, false, Align);
+ SrcSV, SrcSVOff + SrcOff, VT, false, false,
+ MinAlign(SrcAlign, SrcOff));
Store = DAG.getTruncStore(Chain, dl, Value,
getMemBasePlusOffset(Dst, DstOff, DAG),
DstSV, DstSVOff + DstOff, VT, false, false,
- DstAlign);
+ Align);
}
OutChains.push_back(Store);
SrcOff += VTSize;
@@ -3335,11 +3347,11 @@ static SDValue getMemcpyLoadsAndStores(SelectionDAG &DAG, DebugLoc dl,
}
static SDValue getMemmoveLoadsAndStores(SelectionDAG &DAG, DebugLoc dl,
- SDValue Chain, SDValue Dst,
- SDValue Src, uint64_t Size,
- unsigned Align, bool AlwaysInline,
- const Value *DstSV, uint64_t DstSVOff,
- const Value *SrcSV, uint64_t SrcSVOff){
+ SDValue Chain, SDValue Dst,
+ SDValue Src, uint64_t Size,
+ unsigned Align,bool AlwaysInline,
+ const Value *DstSV, uint64_t DstSVOff,
+ const Value *SrcSV, uint64_t SrcSVOff) {
const TargetLowering &TLI = DAG.getTargetLoweringInfo();
// Expand memmove to a series of load and store ops if the size operand falls
@@ -3348,15 +3360,32 @@ static SDValue getMemmoveLoadsAndStores(SelectionDAG &DAG, DebugLoc dl,
uint64_t Limit = -1ULL;
if (!AlwaysInline)
Limit = TLI.getMaxStoresPerMemmove();
- unsigned DstAlign = Align; // Destination alignment can change.
- std::string Str;
- bool CopyFromStr;
- if (!MeetsMaxMemopRequirement(MemOps, Dst, Src, Limit, Size, DstAlign,
- Str, CopyFromStr, DAG, TLI))
+ bool DstAlignCanChange = false;
+ MachineFrameInfo *MFI = DAG.getMachineFunction().getFrameInfo();
+ FrameIndexSDNode *FI = dyn_cast<FrameIndexSDNode>(Dst);
+ if (FI && !MFI->isFixedObjectIndex(FI->getIndex()))
+ DstAlignCanChange = true;
+ unsigned SrcAlign = DAG.InferPtrAlignment(Src);
+ if (Align > SrcAlign)
+ SrcAlign = Align;
+
+ if (!FindOptimalMemOpLowering(MemOps, Limit, Size,
+ (DstAlignCanChange ? 0 : Align),
+ SrcAlign, true, DAG, TLI))
return SDValue();
- uint64_t SrcOff = 0, DstOff = 0;
+ if (DstAlignCanChange) {
+ const Type *Ty = MemOps[0].getTypeForEVT(*DAG.getContext());
+ unsigned NewAlign = (unsigned) TLI.getTargetData()->getABITypeAlignment(Ty);
+ if (NewAlign > Align) {
+ // Give the stack frame object a larger alignment if needed.
+ if (MFI->getObjectAlignment(FI->getIndex()) < NewAlign)
+ MFI->setObjectAlignment(FI->getIndex(), NewAlign);
+ Align = NewAlign;
+ }
+ }
+ uint64_t SrcOff = 0, DstOff = 0;
SmallVector<SDValue, 8> LoadValues;
SmallVector<SDValue, 8> LoadChains;
SmallVector<SDValue, 8> OutChains;
@@ -3368,7 +3397,7 @@ static SDValue getMemmoveLoadsAndStores(SelectionDAG &DAG, DebugLoc dl,
Value = DAG.getLoad(VT, dl, Chain,
getMemBasePlusOffset(Src, SrcOff, DAG),
- SrcSV, SrcSVOff + SrcOff, false, false, Align);
+ SrcSV, SrcSVOff + SrcOff, false, false, SrcAlign);
LoadValues.push_back(Value);
LoadChains.push_back(Value.getValue(1));
SrcOff += VTSize;
@@ -3383,7 +3412,7 @@ static SDValue getMemmoveLoadsAndStores(SelectionDAG &DAG, DebugLoc dl,
Store = DAG.getStore(Chain, dl, LoadValues[i],
getMemBasePlusOffset(Dst, DstOff, DAG),
- DstSV, DstSVOff + DstOff, false, false, DstAlign);
+ DstSV, DstSVOff + DstOff, false, false, Align);
OutChains.push_back(Store);
DstOff += VTSize;
}
@@ -3393,24 +3422,40 @@ static SDValue getMemmoveLoadsAndStores(SelectionDAG &DAG, DebugLoc dl,
}
static SDValue getMemsetStores(SelectionDAG &DAG, DebugLoc dl,
- SDValue Chain, SDValue Dst,
- SDValue Src, uint64_t Size,
- unsigned Align,
- const Value *DstSV, uint64_t DstSVOff) {
+ SDValue Chain, SDValue Dst,
+ SDValue Src, uint64_t Size,
+ unsigned Align,
+ const Value *DstSV, uint64_t DstSVOff) {
const TargetLowering &TLI = DAG.getTargetLoweringInfo();
// Expand memset to a series of load/store ops if the size operand
// falls below a certain threshold.
std::vector<EVT> MemOps;
- std::string Str;
- bool CopyFromStr;
- if (!MeetsMaxMemopRequirement(MemOps, Dst, Src, TLI.getMaxStoresPerMemset(),
- Size, Align, Str, CopyFromStr, DAG, TLI))
+ bool DstAlignCanChange = false;
+ MachineFrameInfo *MFI = DAG.getMachineFunction().getFrameInfo();
+ FrameIndexSDNode *FI = dyn_cast<FrameIndexSDNode>(Dst);
+ if (FI && !MFI->isFixedObjectIndex(FI->getIndex()))
+ DstAlignCanChange = true;
+ bool IsZero = isa<ConstantSDNode>(Src) &&
+ cast<ConstantSDNode>(Src)->isNullValue();
+ if (!FindOptimalMemOpLowering(MemOps, TLI.getMaxStoresPerMemset(),
+ Size, (DstAlignCanChange ? 0 : Align), 0,
+ IsZero, DAG, TLI))
return SDValue();
+ if (DstAlignCanChange) {
+ const Type *Ty = MemOps[0].getTypeForEVT(*DAG.getContext());
+ unsigned NewAlign = (unsigned) TLI.getTargetData()->getABITypeAlignment(Ty);
+ if (NewAlign > Align) {
+ // Give the stack frame object a larger alignment if needed.
+ if (MFI->getObjectAlignment(FI->getIndex()) < NewAlign)
+ MFI->setObjectAlignment(FI->getIndex(), NewAlign);
+ Align = NewAlign;
+ }
+ }
+
SmallVector<SDValue, 8> OutChains;
uint64_t DstOff = 0;
-
unsigned NumMemOps = MemOps.size();
for (unsigned i = 0; i < NumMemOps; i++) {
EVT VT = MemOps[i];
@@ -3441,10 +3486,9 @@ SDValue SelectionDAG::getMemcpy(SDValue Chain, DebugLoc dl, SDValue Dst,
if (ConstantSize->isNullValue())
return Chain;
- SDValue Result =
- getMemcpyLoadsAndStores(*this, dl, Chain, Dst, Src,
- ConstantSize->getZExtValue(),
- Align, false, DstSV, DstSVOff, SrcSV, SrcSVOff);
+ SDValue Result = getMemcpyLoadsAndStores(*this, dl, Chain, Dst, Src,
+ ConstantSize->getZExtValue(),Align,
+ false, DstSV, DstSVOff, SrcSV, SrcSVOff);
if (Result.getNode())
return Result;
}
@@ -4846,6 +4890,26 @@ SDNode *SelectionDAG::getNodeIfExists(unsigned Opcode, SDVTList VTList,
return NULL;
}
+/// getDbgValue - Creates a SDDbgValue node.
+///
+SDDbgValue *
+SelectionDAG::getDbgValue(MDNode *MDPtr, SDNode *N, unsigned R, uint64_t Off,
+ DebugLoc DL, unsigned O) {
+ return new (Allocator) SDDbgValue(MDPtr, N, R, Off, DL, O);
+}
+
+SDDbgValue *
+SelectionDAG::getDbgValue(MDNode *MDPtr, Value *C, uint64_t Off,
+ DebugLoc DL, unsigned O) {
+ return new (Allocator) SDDbgValue(MDPtr, C, Off, DL, O);
+}
+
+SDDbgValue *
+SelectionDAG::getDbgValue(MDNode *MDPtr, unsigned FI, uint64_t Off,
+ DebugLoc DL, unsigned O) {
+ return new (Allocator) SDDbgValue(MDPtr, FI, Off, DL, O);
+}
+
namespace {
/// RAUWUpdateListener - Helper for ReplaceAllUsesWith - When the node
@@ -5241,24 +5305,12 @@ unsigned SelectionDAG::GetOrdering(const SDNode *SD) const {
return Ordering->getOrder(SD);
}
-/// AssignDbgInfo - Assign debug info to the SDNode.
-void SelectionDAG::AssignDbgInfo(SDNode* SD, SDDbgValue* db) {
- assert(SD && "Trying to assign dbg info to a null node!");
- DbgInfo->add(SD, db);
- SD->setHasDebugValue(true);
-}
-
-/// RememberDbgInfo - Remember debug info which is not assigned to an SDNode.
-void SelectionDAG::RememberDbgInfo(SDDbgValue* db) {
- DbgInfo->add(db);
-}
-
-/// GetDbgInfo - Get the debug info, if any, for the SDNode.
-SDDbgValue* SelectionDAG::GetDbgInfo(const SDNode *SD) {
- assert(SD && "Trying to get the order of a null node!");
- if (SD->getHasDebugValue())
- return DbgInfo->getSDDbgValue(SD);
- return 0;
+/// AddDbgValue - Add a dbg_value SDNode. If SD is non-null that means the
+/// value is produced by SD.
+void SelectionDAG::AddDbgValue(SDDbgValue *DB, SDNode *SD) {
+ DbgInfo->add(DB, SD);
+ if (SD)
+ SD->setHasDebugValue(true);
}
//===----------------------------------------------------------------------===//
@@ -6094,8 +6146,20 @@ unsigned SelectionDAG::InferPtrAlignment(SDValue Ptr) const {
// If this is a GlobalAddress + cst, return the alignment.
GlobalValue *GV;
int64_t GVOffset = 0;
- if (TLI.isGAPlusOffset(Ptr.getNode(), GV, GVOffset))
- return MinAlign(GV->getAlignment(), GVOffset);
+ if (TLI.isGAPlusOffset(Ptr.getNode(), GV, GVOffset)) {
+ // If GV has specified alignment, then use it. Otherwise, use the preferred
+ // alignment.
+ unsigned Align = GV->getAlignment();
+ if (!Align) {
+ if (GlobalVariable *GVar = dyn_cast<GlobalVariable>(GV)) {
+ if (GVar->hasInitializer()) {
+ const TargetData *TD = TLI.getTargetData();
+ Align = TD->getPreferredAlignment(GVar);
+ }
+ }
+ }
+ return MinAlign(Align, GVOffset);
+ }
// If this is a direct reference to a stack slot, use information about the
// stack slot's alignment.
diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
index 12096b9..922c6e8 100644
--- a/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
+++ b/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
@@ -3800,7 +3800,7 @@ SelectionDAGBuilder::visitIntrinsicCall(CallInst &I, unsigned Intrinsic) {
int FI = SI->second;
if (MachineModuleInfo *MMI = DAG.getMachineModuleInfo())
- if (MDNode *Dbg = DI.getMetadata("dbg"))
+ if (MDNode *Dbg = DI.getDbgMetadata())
MMI->setVariableDbgInfo(Variable, FI, Dbg);
return 0;
}
@@ -3824,22 +3824,19 @@ SelectionDAGBuilder::visitIntrinsicCall(CallInst &I, unsigned Intrinsic) {
// debug info exists.
++SDNodeOrder;
if (isa<ConstantInt>(V) || isa<ConstantFP>(V)) {
- SDDbgValue* dv = new SDDbgValue(Variable, V, Offset, dl, SDNodeOrder);
- DAG.RememberDbgInfo(dv);
+ DAG.AddDbgValue(DAG.getDbgValue(Variable, V, Offset, dl, SDNodeOrder));
} else {
SDValue &N = NodeMap[V];
- if (N.getNode()) {
- SDDbgValue *dv = new SDDbgValue(Variable, N.getNode(),
- N.getResNo(), Offset, dl, SDNodeOrder);
- DAG.AssignDbgInfo(N.getNode(), dv);
- } else {
+ if (N.getNode())
+ DAG.AddDbgValue(DAG.getDbgValue(Variable, N.getNode(),
+ N.getResNo(), Offset, dl, SDNodeOrder),
+ N.getNode());
+ else
// We may expand this to cover more cases. One case where we have no
// data available is an unreferenced parameter; we need this fallback.
- SDDbgValue* dv = new SDDbgValue(Variable,
+ DAG.AddDbgValue(DAG.getDbgValue(Variable,
UndefValue::get(V->getType()),
- Offset, dl, SDNodeOrder);
- DAG.RememberDbgInfo(dv);
- }
+ Offset, dl, SDNodeOrder));
}
// Build a debug info table entry.
@@ -3855,7 +3852,7 @@ SelectionDAGBuilder::visitIntrinsicCall(CallInst &I, unsigned Intrinsic) {
return 0; // VLAs.
int FI = SI->second;
if (MachineModuleInfo *MMI = DAG.getMachineModuleInfo())
- if (MDNode *Dbg = DI.getMetadata("dbg"))
+ if (MDNode *Dbg = DI.getDbgMetadata())
MMI->setVariableDbgInfo(Variable, FI, Dbg);
return 0;
}
@@ -6054,8 +6051,10 @@ void SelectionDAGISel::LowerArguments(BasicBlock *LLVMBB) {
}
if (!I->use_empty()) {
- SDValue Res = DAG.getMergeValues(&ArgValues[0], NumValues,
- SDB->getCurDebugLoc());
+ SDValue Res;
+ if (!ArgValues.empty())
+ Res = DAG.getMergeValues(&ArgValues[0], NumValues,
+ SDB->getCurDebugLoc());
SDB->setValue(I, Res);
// If this argument is live outside of the entry block, insert a copy from
diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
index cbbe431..ea96b21 100644
--- a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
+++ b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
@@ -61,6 +61,7 @@
using namespace llvm;
STATISTIC(NumFastIselFailures, "Number of instructions fast isel failed on");
+STATISTIC(NumDAGIselRetries,"Number of times dag isel has to try another path");
static cl::opt<bool>
EnableFastISelVerbose("fast-isel-verbose", cl::Hidden,
@@ -365,23 +366,23 @@ bool SelectionDAGISel::runOnMachineFunction(MachineFunction &mf) {
/// SetDebugLoc - Update MF's and SDB's DebugLocs if debug information is
/// attached with this instruction.
-static void SetDebugLoc(unsigned MDDbgKind, Instruction *I,
- SelectionDAGBuilder *SDB,
+static void SetDebugLoc(Instruction *I, SelectionDAGBuilder *SDB,
FastISel *FastIS, MachineFunction *MF) {
- if (MDNode *Dbg = I->getMetadata(MDDbgKind)) {
- DILocation DILoc(Dbg);
- DebugLoc Loc = ExtractDebugLocation(DILoc, MF->getDebugLocInfo());
+ MDNode *Dbg = I->getDbgMetadata();
+ if (Dbg == 0) return;
+
+ DILocation DILoc(Dbg);
+ DebugLoc Loc = ExtractDebugLocation(DILoc, MF->getDebugLocInfo());
- SDB->setCurDebugLoc(Loc);
+ SDB->setCurDebugLoc(Loc);
- if (FastIS)
- FastIS->setCurDebugLoc(Loc);
+ if (FastIS)
+ FastIS->setCurDebugLoc(Loc);
- // If the function doesn't have a default debug location yet, set
- // it. This is kind of a hack.
- if (MF->getDefaultDebugLoc().isUnknown())
- MF->setDefaultDebugLoc(Loc);
- }
+ // If the function doesn't have a default debug location yet, set
+ // it. This is kind of a hack.
+ if (MF->getDefaultDebugLoc().isUnknown())
+ MF->setDefaultDebugLoc(Loc);
}
/// ResetDebugLoc - Set MF's and SDB's DebugLocs to Unknown.
@@ -396,12 +397,11 @@ void SelectionDAGISel::SelectBasicBlock(BasicBlock *LLVMBB,
BasicBlock::iterator End,
bool &HadTailCall) {
SDB->setCurrentBasicBlock(BB);
- unsigned MDDbgKind = LLVMBB->getContext().getMDKindID("dbg");
// Lower all of the non-terminator instructions. If a call is emitted
// as a tail call, cease emitting nodes for this block.
for (BasicBlock::iterator I = Begin; I != End && !SDB->HasTailCall; ++I) {
- SetDebugLoc(MDDbgKind, I, SDB, 0, MF);
+ SetDebugLoc(I, SDB, 0, MF);
if (!isa<TerminatorInst>(I)) {
SDB->visit(*I);
@@ -424,7 +424,7 @@ void SelectionDAGISel::SelectBasicBlock(BasicBlock *LLVMBB,
HandlePHINodesInSuccessorBlocks(LLVMBB);
// Lower the terminator after the copies are emitted.
- SetDebugLoc(MDDbgKind, LLVMBB->getTerminator(), SDB, 0, MF);
+ SetDebugLoc(LLVMBB->getTerminator(), SDB, 0, MF);
SDB->visit(*LLVMBB->getTerminator());
ResetDebugLoc(SDB, 0);
}
@@ -842,9 +842,6 @@ void SelectionDAGISel::DoInstructionSelection() {
DEBUG(errs() << "===== Instruction selection ends:\n");
PostprocessISelDAG();
-
- // FIXME: This shouldn't be needed, remove it.
- CurDAG->RemoveDeadNodes();
}
@@ -865,8 +862,6 @@ void SelectionDAGISel::SelectAllBasicBlocks(Function &Fn,
#endif
);
- unsigned MDDbgKind = Fn.getContext().getMDKindID("dbg");
-
// Iterate over all basic blocks in the function.
for (Function::iterator I = Fn.begin(), E = Fn.end(); I != E; ++I) {
BasicBlock *LLVMBB = &*I;
@@ -964,7 +959,7 @@ void SelectionDAGISel::SelectAllBasicBlocks(Function &Fn,
break;
}
- SetDebugLoc(MDDbgKind, BI, SDB, FastIS, &MF);
+ SetDebugLoc(BI, SDB, FastIS, &MF);
// Try to select the instruction with FastISel.
if (FastIS->SelectInstruction(BI)) {
@@ -1592,8 +1587,9 @@ UpdateChainsAndFlags(SDNode *NodeToMatch, SDValue InputChain,
assert(ChainVal.getValueType() == MVT::Other && "Not a chain?");
CurDAG->ReplaceAllUsesOfValueWith(ChainVal, InputChain, &ISU);
- // If the node became dead, delete it.
- if (ChainNode->use_empty())
+ // If the node became dead and we haven't already seen it, delete it.
+ if (ChainNode->use_empty() &&
+ !std::count(NowDeadNodes.begin(), NowDeadNodes.end(), ChainNode))
NowDeadNodes.push_back(ChainNode);
}
}
@@ -1614,8 +1610,9 @@ UpdateChainsAndFlags(SDNode *NodeToMatch, SDValue InputChain,
CurDAG->ReplaceAllUsesOfValueWith(SDValue(FRN, FRN->getNumValues()-1),
InputFlag, &ISU);
- // If the node became dead, delete it.
- if (FRN->use_empty())
+ // If the node became dead and we haven't already seen it, delete it.
+ if (FRN->use_empty() &&
+ !std::count(NowDeadNodes.begin(), NowDeadNodes.end(), FRN))
NowDeadNodes.push_back(FRN);
}
}
@@ -1810,9 +1807,9 @@ MorphNode(SDNode *Node, unsigned TargetOpc, SDVTList VTList,
// It is possible we're using MorphNodeTo to replace a node with no
// normal results with one that has a normal result (or we could be
// adding a chain) and the input could have flags and chains as well.
- // In this case we need to shifting the operands down.
+ // In this case we need to shift the operands down.
// FIXME: This is a horrible hack and broken in obscure cases, no worse
- // than the old isel though. We should sink this into MorphNodeTo.
+ // than the old isel though.
int OldFlagResultNo = -1, OldChainResultNo = -1;
unsigned NTMNumResults = Node->getNumValues();
@@ -1888,7 +1885,9 @@ CheckNodePredicate(const unsigned char *MatcherTable, unsigned &MatcherIndex,
ALWAYS_INLINE static bool
CheckOpcode(const unsigned char *MatcherTable, unsigned &MatcherIndex,
SDNode *N) {
- return N->getOpcode() == MatcherTable[MatcherIndex++];
+ uint16_t Opc = MatcherTable[MatcherIndex++];
+ Opc |= (unsigned short)MatcherTable[MatcherIndex++] << 8;
+ return N->getOpcode() == Opc;
}
ALWAYS_INLINE static bool
@@ -2142,7 +2141,8 @@ SelectCodeCommon(SDNode *NodeToMatch, const unsigned char *MatcherTable,
if (CaseSize == 0) break;
// Get the opcode, add the index to the table.
- unsigned Opc = MatcherTable[Idx++];
+ uint16_t Opc = MatcherTable[Idx++];
+ Opc |= (unsigned short)MatcherTable[Idx++] << 8;
if (Opc >= OpcodeOffset.size())
OpcodeOffset.resize((Opc+1)*2);
OpcodeOffset[Opc] = Idx;
@@ -2181,6 +2181,9 @@ SelectCodeCommon(SDNode *NodeToMatch, const unsigned char *MatcherTable,
FailIndex = MatcherIndex+NumToSkip;
+ unsigned MatcherIndexOfPredicate = MatcherIndex;
+ (void)MatcherIndexOfPredicate; // silence warning.
+
// If we can't evaluate this predicate without pushing a scope (e.g. if
// it is a 'MoveParent') or if the predicate succeeds on this node, we
// push the scope and evaluate the full predicate chain.
@@ -2190,9 +2193,10 @@ SelectCodeCommon(SDNode *NodeToMatch, const unsigned char *MatcherTable,
if (!Result)
break;
- DEBUG(errs() << " Skipped scope entry at index " << MatcherIndex
- << " continuing at " << FailIndex << "\n");
-
+ DEBUG(errs() << " Skipped scope entry (due to false predicate) at "
+ << "index " << MatcherIndexOfPredicate
+ << ", continuing at " << FailIndex << "\n");
+ ++NumDAGIselRetries;
// Otherwise, we know that this case of the Scope is guaranteed to fail,
// move to the next case.
@@ -2298,8 +2302,11 @@ SelectCodeCommon(SDNode *NodeToMatch, const unsigned char *MatcherTable,
CaseSize = GetVBR(CaseSize, MatcherTable, MatcherIndex);
if (CaseSize == 0) break;
+ uint16_t Opc = MatcherTable[MatcherIndex++];
+ Opc |= (unsigned short)MatcherTable[MatcherIndex++] << 8;
+
// If the opcode matches, then we will execute this case.
- if (CurNodeOpcode == MatcherTable[MatcherIndex++])
+ if (CurNodeOpcode == Opc)
break;
// Otherwise, skip over this case.
@@ -2428,6 +2435,35 @@ SelectCodeCommon(SDNode *NodeToMatch, const unsigned char *MatcherTable,
continue;
}
+ case OPC_EmitMergeInputChains1_0: // OPC_EmitMergeInputChains, 1, 0
+ case OPC_EmitMergeInputChains1_1: { // OPC_EmitMergeInputChains, 1, 1
+ // These are space-optimized forms of OPC_EmitMergeInputChains.
+ assert(InputChain.getNode() == 0 &&
+ "EmitMergeInputChains should be the first chain producing node");
+ assert(ChainNodesMatched.empty() &&
+ "Should only have one EmitMergeInputChains per match");
+
+ // Read all of the chained nodes.
+ unsigned RecNo = Opcode == OPC_EmitMergeInputChains1_1;
+ assert(RecNo < RecordedNodes.size() && "Invalid CheckSame");
+ ChainNodesMatched.push_back(RecordedNodes[RecNo].getNode());
+
+ // FIXME: What if other value results of the node have uses not matched
+ // by this pattern?
+ if (ChainNodesMatched.back() != NodeToMatch &&
+ !RecordedNodes[RecNo].hasOneUse()) {
+ ChainNodesMatched.clear();
+ break;
+ }
+
+ // Merge the input chains if they are not intra-pattern references.
+ InputChain = HandleMergeInputChains(ChainNodesMatched, CurDAG);
+
+ if (InputChain.getNode() == 0)
+ break; // Failed to merge.
+ continue;
+ }
+
case OPC_EmitMergeInputChains: {
assert(InputChain.getNode() == 0 &&
"EmitMergeInputChains should be the first chain producing node");
@@ -2646,14 +2682,10 @@ SelectCodeCommon(SDNode *NodeToMatch, const unsigned char *MatcherTable,
assert(ResSlot < RecordedNodes.size() && "Invalid CheckSame");
SDValue Res = RecordedNodes[ResSlot];
- // FIXME2: Eliminate this horrible hack by fixing the 'Gen' program
- // after (parallel) on input patterns are removed. This would also
- // allow us to stop encoding #results in OPC_CompleteMatch's table
- // entry.
- if (NodeToMatch->getNumValues() <= i ||
- NodeToMatch->getValueType(i) == MVT::Other ||
- NodeToMatch->getValueType(i) == MVT::Flag)
- break;
+ assert(i < NodeToMatch->getNumValues() &&
+ NodeToMatch->getValueType(i) != MVT::Other &&
+ NodeToMatch->getValueType(i) != MVT::Flag &&
+ "Invalid number of results to complete!");
assert((NodeToMatch->getValueType(i) == Res.getValueType() ||
NodeToMatch->getValueType(i) == MVT::iPTR ||
Res.getValueType() == MVT::iPTR ||
@@ -2685,6 +2717,7 @@ SelectCodeCommon(SDNode *NodeToMatch, const unsigned char *MatcherTable,
// 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");
+ ++NumDAGIselRetries;
while (1) {
if (MatchScopes.empty()) {
CannotYetSelect(NodeToMatch);
diff --git a/lib/CodeGen/SelectionDAG/TargetLowering.cpp b/lib/CodeGen/SelectionDAG/TargetLowering.cpp
index f7ef2d6..ea2ff2f 100644
--- a/lib/CodeGen/SelectionDAG/TargetLowering.cpp
+++ b/lib/CodeGen/SelectionDAG/TargetLowering.cpp
@@ -186,11 +186,13 @@ static void InitLibcallNames(const char **Names) {
Names[RTLIB::FPROUND_PPCF128_F32] = "__trunctfsf2";
Names[RTLIB::FPROUND_F80_F64] = "__truncxfdf2";
Names[RTLIB::FPROUND_PPCF128_F64] = "__trunctfdf2";
- Names[RTLIB::FPTOSINT_F32_I8] = "__fixsfi8";
- Names[RTLIB::FPTOSINT_F32_I16] = "__fixsfi16";
+ Names[RTLIB::FPTOSINT_F32_I8] = "__fixsfqi";
+ Names[RTLIB::FPTOSINT_F32_I16] = "__fixsfhi";
Names[RTLIB::FPTOSINT_F32_I32] = "__fixsfsi";
Names[RTLIB::FPTOSINT_F32_I64] = "__fixsfdi";
Names[RTLIB::FPTOSINT_F32_I128] = "__fixsfti";
+ Names[RTLIB::FPTOSINT_F64_I8] = "__fixdfqi";
+ Names[RTLIB::FPTOSINT_F64_I16] = "__fixdfhi";
Names[RTLIB::FPTOSINT_F64_I32] = "__fixdfsi";
Names[RTLIB::FPTOSINT_F64_I64] = "__fixdfdi";
Names[RTLIB::FPTOSINT_F64_I128] = "__fixdfti";
@@ -200,11 +202,13 @@ static void InitLibcallNames(const char **Names) {
Names[RTLIB::FPTOSINT_PPCF128_I32] = "__fixtfsi";
Names[RTLIB::FPTOSINT_PPCF128_I64] = "__fixtfdi";
Names[RTLIB::FPTOSINT_PPCF128_I128] = "__fixtfti";
- Names[RTLIB::FPTOUINT_F32_I8] = "__fixunssfi8";
- Names[RTLIB::FPTOUINT_F32_I16] = "__fixunssfi16";
+ Names[RTLIB::FPTOUINT_F32_I8] = "__fixunssfqi";
+ Names[RTLIB::FPTOUINT_F32_I16] = "__fixunssfhi";
Names[RTLIB::FPTOUINT_F32_I32] = "__fixunssfsi";
Names[RTLIB::FPTOUINT_F32_I64] = "__fixunssfdi";
Names[RTLIB::FPTOUINT_F32_I128] = "__fixunssfti";
+ Names[RTLIB::FPTOUINT_F64_I8] = "__fixunsdfqi";
+ Names[RTLIB::FPTOUINT_F64_I16] = "__fixunsdfhi";
Names[RTLIB::FPTOUINT_F64_I32] = "__fixunsdfsi";
Names[RTLIB::FPTOUINT_F64_I64] = "__fixunsdfdi";
Names[RTLIB::FPTOUINT_F64_I128] = "__fixunsdfti";
@@ -314,6 +318,10 @@ RTLIB::Libcall RTLIB::getFPTOSINT(EVT OpVT, EVT RetVT) {
if (RetVT == MVT::i128)
return FPTOSINT_F32_I128;
} else if (OpVT == MVT::f64) {
+ if (RetVT == MVT::i8)
+ return FPTOSINT_F64_I8;
+ if (RetVT == MVT::i16)
+ return FPTOSINT_F64_I16;
if (RetVT == MVT::i32)
return FPTOSINT_F64_I32;
if (RetVT == MVT::i64)
@@ -353,6 +361,10 @@ RTLIB::Libcall RTLIB::getFPTOUINT(EVT OpVT, EVT RetVT) {
if (RetVT == MVT::i128)
return FPTOUINT_F32_I128;
} else if (OpVT == MVT::f64) {
+ if (RetVT == MVT::i8)
+ return FPTOUINT_F64_I8;
+ if (RetVT == MVT::i16)
+ return FPTOUINT_F64_I16;
if (RetVT == MVT::i32)
return FPTOUINT_F64_I32;
if (RetVT == MVT::i64)
@@ -475,7 +487,6 @@ TargetLowering::TargetLowering(TargetMachine &tm,TargetLoweringObjectFile *tlof)
memset(LoadExtActions, 0, sizeof(LoadExtActions));
memset(TruncStoreActions, 0, sizeof(TruncStoreActions));
memset(IndexedModeActions, 0, sizeof(IndexedModeActions));
- memset(ConvertActions, 0, sizeof(ConvertActions));
memset(CondCodeActions, 0, sizeof(CondCodeActions));
// Set default actions for various operations.
diff --git a/lib/CodeGen/SimpleRegisterCoalescing.cpp b/lib/CodeGen/SimpleRegisterCoalescing.cpp
index 97e858f..15ca374 100644
--- a/lib/CodeGen/SimpleRegisterCoalescing.cpp
+++ b/lib/CodeGen/SimpleRegisterCoalescing.cpp
@@ -59,11 +59,6 @@ DisableCrossClassJoin("disable-cross-class-join",
cl::desc("Avoid coalescing cross register class copies"),
cl::init(false), cl::Hidden);
-static cl::opt<bool>
-PhysJoinTweak("tweak-phys-join-heuristics",
- cl::desc("Tweak heuristics for joining phys reg with vr"),
- cl::init(false), cl::Hidden);
-
static RegisterPass<SimpleRegisterCoalescing>
X("simple-register-coalescing", "Simple Register Coalescing");
@@ -1445,7 +1440,6 @@ bool SimpleRegisterCoalescing::JoinCopy(CopyRec &TheCopy, bool &Again) {
const TargetRegisterClass *SrcRC= SrcIsPhys ? 0 : mri_->getRegClass(SrcReg);
const TargetRegisterClass *DstRC= DstIsPhys ? 0 : mri_->getRegClass(DstReg);
const TargetRegisterClass *NewRC = NULL;
- MachineBasicBlock *CopyMBB = CopyMI->getParent();
unsigned RealDstReg = 0;
unsigned RealSrcReg = 0;
if (isExtSubReg || isInsSubReg || isSubRegToReg) {
@@ -1646,8 +1640,8 @@ bool SimpleRegisterCoalescing::JoinCopy(CopyRec &TheCopy, bool &Again) {
else if (RealSrcReg)
SavedLI.reset(li_->dupInterval(&DstInt));
- // Check if it is necessary to propagate "isDead" property.
if (!isExtSubReg && !isInsSubReg && !isSubRegToReg) {
+ // Check if it is necessary to propagate "isDead" property.
MachineOperand *mopd = CopyMI->findRegisterDefOperand(DstReg, false);
bool isDead = mopd->isDead();
@@ -1656,60 +1650,42 @@ bool SimpleRegisterCoalescing::JoinCopy(CopyRec &TheCopy, bool &Again) {
// these are not spillable! If the destination interval uses are far away,
// think twice about coalescing them!
if (!isDead && (SrcIsPhys || DstIsPhys)) {
- // If the copy is in a loop, take care not to coalesce aggressively if the
- // src is coming in from outside the loop (or the dst is out of the loop).
- // If it's not in a loop, then determine whether to join them base purely
- // by the length of the interval.
- if (PhysJoinTweak) {
- if (SrcIsPhys) {
- if (!isWinToJoinVRWithSrcPhysReg(CopyMI, CopyMBB, DstInt, SrcInt)) {
- mri_->setRegAllocationHint(DstInt.reg, 0, SrcReg);
- ++numAborts;
- DEBUG(dbgs() << "\tMay tie down a physical register, abort!\n");
- Again = true; // May be possible to coalesce later.
- return false;
- }
- } else {
- if (!isWinToJoinVRWithDstPhysReg(CopyMI, CopyMBB, DstInt, SrcInt)) {
- mri_->setRegAllocationHint(SrcInt.reg, 0, DstReg);
- ++numAborts;
- DEBUG(dbgs() << "\tMay tie down a physical register, abort!\n");
- Again = true; // May be possible to coalesce later.
- return false;
- }
- }
- } else {
- // If the virtual register live interval is long but it has low use
- // 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;
- }
+ // If the virtual register live interval is long but it has low use
+ // 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 live interval too complicated, abort!\n");
+ return false;
+ }
- const TargetRegisterClass *RC = mri_->getRegClass(JoinVReg);
- unsigned Threshold = allocatableRCRegs_[RC].count() * 2;
- unsigned Length = li_->getApproximateInstructionCount(JoinVInt);
- float Ratio = 1.0 / Threshold;
- if (Length > Threshold &&
- (((float)std::distance(mri_->use_nodbg_begin(JoinVReg),
- mri_->use_nodbg_end()) / Length) < Ratio)) {
- mri_->setRegAllocationHint(JoinVInt.reg, 0, JoinPReg);
- ++numAborts;
- DEBUG(dbgs() << "\tMay tie down a physical register, abort!\n");
- Again = true; // May be possible to coalesce later.
- return false;
- }
+ const TargetRegisterClass *RC = mri_->getRegClass(JoinVReg);
+ unsigned Threshold = allocatableRCRegs_[RC].count() * 2;
+ unsigned Length = li_->getApproximateInstructionCount(JoinVInt);
+ float Ratio = 1.0 / Threshold;
+ if (Length > Threshold &&
+ (((float)std::distance(mri_->use_nodbg_begin(JoinVReg),
+ mri_->use_nodbg_end()) / Length) < Ratio)) {
+ // Before giving up coalescing, if definition of source is defined by
+ // trivial computation, try rematerializing it.
+ if (ReMaterializeTrivialDef(SrcInt, DstReg, DstSubIdx, CopyMI))
+ return true;
+
+ mri_->setRegAllocationHint(JoinVInt.reg, 0, JoinPReg);
+ ++numAborts;
+ DEBUG(dbgs() << "\tMay tie down a physical register, abort!\n");
+ Again = true; // May be possible to coalesce later.
+ return false;
}
}
}
@@ -1720,16 +1696,15 @@ bool SimpleRegisterCoalescing::JoinCopy(CopyRec &TheCopy, bool &Again) {
// been modified, so we can use this information below to update aliases.
bool Swapped = false;
// If SrcInt is implicitly defined, it's safe to coalesce.
- bool isEmpty = SrcInt.empty();
- if (isEmpty && !CanCoalesceWithImpDef(CopyMI, DstInt, SrcInt)) {
- // Only coalesce an empty interval (defined by implicit_def) with
- // another interval which has a valno defined by the CopyMI and the CopyMI
- // is a kill of the implicit def.
- DEBUG(dbgs() << "Not profitable!\n");
- return false;
- }
-
- if (!isEmpty && !JoinIntervals(DstInt, SrcInt, Swapped)) {
+ if (SrcInt.empty()) {
+ if (!CanCoalesceWithImpDef(CopyMI, DstInt, SrcInt)) {
+ // Only coalesce an empty interval (defined by implicit_def) with
+ // another interval which has a valno defined by the CopyMI and the CopyMI
+ // is a kill of the implicit def.
+ DEBUG(dbgs() << "Not profitable!\n");
+ return false;
+ }
+ } else if (!JoinIntervals(DstInt, SrcInt, Swapped)) {
// Coalescing failed.
// If definition of source is defined by trivial computation, try
@@ -2800,7 +2775,7 @@ bool SimpleRegisterCoalescing::runOnMachineFunction(MachineFunction &fn) {
if (MO.isDead())
continue;
if (TargetRegisterInfo::isPhysicalRegister(Reg) ||
- !mri_->use_empty(Reg)) {
+ !mri_->use_nodbg_empty(Reg)) {
isDead = false;
break;
}
diff --git a/lib/CodeGen/TargetLoweringObjectFileImpl.cpp b/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
index b62cca3..d6bdb10 100644
--- a/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
+++ b/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
@@ -406,7 +406,7 @@ getExprForDwarfGlobalReference(const GlobalValue *GV, Mangler *Mang,
// Add information about the stub reference to ELFMMI so that the stub
// gets emitted by the asmprinter.
- MCSymbol *SSym = getContext().GetOrCreateTemporarySymbol(Name.str());
+ MCSymbol *SSym = getContext().GetOrCreateSymbol(Name.str());
MachineModuleInfoImpl::StubValueTy &StubSym = ELFMMI.getGVStubEntry(SSym);
if (StubSym.getPointer() == 0) {
MCSymbol *Sym = Mang->getSymbol(GV);
@@ -759,7 +759,7 @@ getExprForDwarfGlobalReference(const GlobalValue *GV, Mangler *Mang,
// Add information about the stub reference to MachOMMI so that the stub
// gets emitted by the asmprinter.
- MCSymbol *SSym = getContext().GetOrCreateTemporarySymbol(Name.str());
+ MCSymbol *SSym = getContext().GetOrCreateSymbol(Name.str());
MachineModuleInfoImpl::StubValueTy &StubSym = MachOMMI.getGVStubEntry(SSym);
if (StubSym.getPointer() == 0) {
MCSymbol *Sym = Mang->getSymbol(GV);
diff --git a/lib/CodeGen/TwoAddressInstructionPass.cpp b/lib/CodeGen/TwoAddressInstructionPass.cpp
index c840b39..c288ae0 100644
--- a/lib/CodeGen/TwoAddressInstructionPass.cpp
+++ b/lib/CodeGen/TwoAddressInstructionPass.cpp
@@ -188,8 +188,9 @@ bool TwoAddressInstructionPass::Sink3AddrInstruction(MachineBasicBlock *MBB,
// Find the instruction that kills SavedReg.
MachineInstr *KillMI = NULL;
- for (MachineRegisterInfo::use_iterator UI = MRI->use_begin(SavedReg),
- UE = MRI->use_end(); UI != UE; ++UI) {
+ for (MachineRegisterInfo::use_nodbg_iterator
+ UI = MRI->use_nodbg_begin(SavedReg),
+ UE = MRI->use_nodbg_end(); UI != UE; ++UI) {
MachineOperand &UseMO = UI.getOperand();
if (!UseMO.isKill())
continue;
@@ -280,8 +281,8 @@ TwoAddressInstructionPass::isProfitableToReMat(unsigned Reg,
MachineInstr *MI, MachineInstr *DefMI,
MachineBasicBlock *MBB, unsigned Loc) {
bool OtherUse = false;
- for (MachineRegisterInfo::use_iterator UI = MRI->use_begin(Reg),
- UE = MRI->use_end(); UI != UE; ++UI) {
+ for (MachineRegisterInfo::use_nodbg_iterator UI = MRI->use_nodbg_begin(Reg),
+ UE = MRI->use_nodbg_end(); UI != UE; ++UI) {
MachineOperand &UseMO = UI.getOperand();
MachineInstr *UseMI = UseMO.getParent();
MachineBasicBlock *UseMBB = UseMI->getParent();
@@ -927,6 +928,7 @@ bool TwoAddressInstructionPass::runOnMachineFunction(MachineFunction &MF) {
mi = nmi;
continue;
}
+
const TargetInstrDesc &TID = mi->getDesc();
bool FirstTied = true;
@@ -1101,7 +1103,7 @@ bool TwoAddressInstructionPass::runOnMachineFunction(MachineFunction &MF) {
// Some remat'ed instructions are dead.
int VReg = ReMatRegs.find_first();
while (VReg != -1) {
- if (MRI->use_empty(VReg)) {
+ if (MRI->use_nodbg_empty(VReg)) {
MachineInstr *DefMI = MRI->getVRegDef(VReg);
DefMI->eraseFromParent();
}
diff --git a/lib/CodeGen/VirtRegRewriter.cpp b/lib/CodeGen/VirtRegRewriter.cpp
index 44d5311..0b7fde7 100644
--- a/lib/CodeGen/VirtRegRewriter.cpp
+++ b/lib/CodeGen/VirtRegRewriter.cpp
@@ -572,6 +572,9 @@ static bool InvalidateRegDef(MachineBasicBlock::iterator I,
static void UpdateKills(MachineInstr &MI, const TargetRegisterInfo* TRI,
BitVector &RegKills,
std::vector<MachineOperand*> &KillOps) {
+ // These do not affect kill info at all.
+ if (MI.isDebugValue())
+ return;
for (unsigned i = 0, e = MI.getNumOperands(); i != e; ++i) {
MachineOperand &MO = MI.getOperand(i);
if (!MO.isReg() || !MO.isUse() || MO.isUndef())
@@ -987,10 +990,17 @@ static unsigned FindFreeRegister(MachineBasicBlock::iterator MII,
SmallVector<unsigned, 4> Kills;
// Take a look at 2 instructions at most.
- for (unsigned Count = 0; Count < 2; ++Count) {
+ unsigned Count = 0;
+ while (Count < 2) {
if (MII == MBB.begin())
break;
MachineInstr *PrevMI = prior(MII);
+ MII = PrevMI;
+
+ if (PrevMI->isDebugValue())
+ continue; // Skip over dbg_value instructions.
+ ++Count;
+
for (unsigned i = 0, e = PrevMI->getNumOperands(); i != e; ++i) {
MachineOperand &MO = PrevMI->getOperand(i);
if (!MO.isReg() || MO.getReg() == 0)
@@ -1019,8 +1029,6 @@ static unsigned FindFreeRegister(MachineBasicBlock::iterator MII,
for (const unsigned *AS = TRI->getAliasSet(Reg); *AS; ++AS)
Uses.set(*AS);
}
-
- MII = PrevMI;
}
return 0;
@@ -1210,6 +1218,9 @@ OptimizeByUnfold2(unsigned VirtReg, int SS,
std::vector<MachineOperand*> &KillOps) {
MachineBasicBlock::iterator NextMII = llvm::next(MII);
+ // Skip over dbg_value instructions.
+ while (NextMII != MBB->end() && NextMII->isDebugValue())
+ NextMII = llvm::next(NextMII);
if (NextMII == MBB->end())
return false;
@@ -1274,6 +1285,9 @@ OptimizeByUnfold2(unsigned VirtReg, int SS,
VRM->RemoveMachineInstrFromMaps(&NextMI);
MBB->erase(&NextMI);
++NumModRefUnfold;
+ // Skip over dbg_value instructions.
+ while (NextMII != MBB->end() && NextMII->isDebugValue())
+ NextMII = llvm::next(NextMII);
if (NextMII == MBB->end())
break;
} while (FoldsStackSlotModRef(*NextMII, SS, PhysReg, TII, TRI, *VRM));
@@ -1619,7 +1633,7 @@ TransferDeadness(unsigned Reg, BitVector &RegKills,
for (MachineRegisterInfo::reg_iterator RI = MRI->reg_begin(Reg),
RE = MRI->reg_end(); RI != RE; ++RI) {
MachineInstr *UDMI = &*RI;
- if (UDMI->getParent() != MBB)
+ if (UDMI->isDebugValue() || UDMI->getParent() != MBB)
continue;
DenseMap<MachineInstr*, unsigned>::iterator DI = DistanceMap.find(UDMI);
if (DI == DistanceMap.end())
OpenPOWER on IntegriCloud