summaryrefslogtreecommitdiffstats
path: root/lib/CodeGen
diff options
context:
space:
mode:
Diffstat (limited to 'lib/CodeGen')
-rw-r--r--lib/CodeGen/AsmPrinter/AsmPrinter.cpp66
-rw-r--r--lib/CodeGen/AsmPrinter/DIE.cpp1
-rw-r--r--lib/CodeGen/AsmPrinter/DIE.h6
-rw-r--r--lib/CodeGen/AsmPrinter/DwarfDebug.cpp120
-rw-r--r--lib/CodeGen/AsmPrinter/DwarfDebug.h23
-rw-r--r--lib/CodeGen/AsmPrinter/DwarfException.h11
-rw-r--r--lib/CodeGen/AsmPrinter/DwarfWriter.cpp6
-rw-r--r--lib/CodeGen/AsmPrinter/Makefile2
-rw-r--r--lib/CodeGen/CMakeLists.txt2
-rw-r--r--lib/CodeGen/ELF.h10
-rw-r--r--lib/CodeGen/ELFCodeEmitter.cpp48
-rw-r--r--lib/CodeGen/ELFCodeEmitter.h17
-rw-r--r--lib/CodeGen/ELFWriter.cpp41
-rw-r--r--lib/CodeGen/ELFWriter.h6
-rw-r--r--lib/CodeGen/IfConversion.cpp4
-rw-r--r--lib/CodeGen/IntrinsicLowering.cpp97
-rw-r--r--lib/CodeGen/LiveInterval.cpp3
-rw-r--r--lib/CodeGen/LiveIntervalAnalysis.cpp4
-rw-r--r--lib/CodeGen/MachineFunction.cpp39
-rw-r--r--lib/CodeGen/MachineInstr.cpp88
-rw-r--r--lib/CodeGen/ScheduleDAGPrinter.cpp10
-rw-r--r--lib/CodeGen/SelectionDAG/LegalizeDAG.cpp2
-rw-r--r--lib/CodeGen/SelectionDAG/LegalizeTypes.h2
-rw-r--r--lib/CodeGen/SelectionDAG/Makefile2
-rw-r--r--lib/CodeGen/SelectionDAG/ScheduleDAGSDNodesEmit.cpp21
-rw-r--r--lib/CodeGen/SelectionDAG/SelectionDAG.cpp122
-rw-r--r--lib/CodeGen/SelectionDAG/SelectionDAGPrinter.cpp147
-rw-r--r--lib/CodeGen/SelectionDAG/TargetLowering.cpp2
-rw-r--r--lib/CodeGen/Spiller.cpp157
-rw-r--r--lib/CodeGen/VirtRegRewriter.h5
30 files changed, 529 insertions, 535 deletions
diff --git a/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
index e931904..bc3af9a 100644
--- a/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
+++ b/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
@@ -45,8 +45,9 @@ AsmPrinter::AsmPrinter(raw_ostream &o, TargetMachine &tm,
const TargetAsmInfo *T, CodeGenOpt::Level OL, bool VDef)
: MachineFunctionPass(&ID), FunctionNumber(0), OptLevel(OL), O(o),
TM(tm), TAI(T), TRI(tm.getRegisterInfo()),
- IsInTextSection(false)
-{
+ IsInTextSection(false), LastMI(0), LastFn(0), Counter(~0U),
+ PrevDLT(0, ~0U, ~0U) {
+ DW = 0; MMI = 0;
switch (AsmVerbose) {
case cl::BOU_UNSET: VerboseAsm = VDef; break;
case cl::BOU_TRUE: VerboseAsm = true; break;
@@ -177,28 +178,44 @@ bool AsmPrinter::doInitialization(Module &M) {
SwitchToDataSection(""); // Reset back to no section.
- if (TAI->doesSupportDebugInformation()
- || TAI->doesSupportExceptionHandling()) {
- MachineModuleInfo *MMI = getAnalysisIfAvailable<MachineModuleInfo>();
- if (MMI) {
+ if (TAI->doesSupportDebugInformation() ||
+ TAI->doesSupportExceptionHandling()) {
+ MMI = getAnalysisIfAvailable<MachineModuleInfo>();
+ if (MMI)
MMI->AnalyzeModule(M);
- DW = getAnalysisIfAvailable<DwarfWriter>();
- if (DW)
- DW->BeginModule(&M, MMI, O, this, TAI);
- }
+ DW = getAnalysisIfAvailable<DwarfWriter>();
+ if (DW)
+ DW->BeginModule(&M, MMI, O, this, TAI);
}
return false;
}
bool AsmPrinter::doFinalization(Module &M) {
+ // Emit final debug information.
+ if (TAI->doesSupportDebugInformation() || TAI->doesSupportExceptionHandling())
+ DW->EndModule();
+
+ // If the target wants to know about weak references, print them all.
if (TAI->getWeakRefDirective()) {
- if (!ExtWeakSymbols.empty())
- SwitchToDataSection("");
-
- for (std::set<const GlobalValue*>::iterator i = ExtWeakSymbols.begin(),
- e = ExtWeakSymbols.end(); i != e; ++i)
- O << TAI->getWeakRefDirective() << Mang->getValueName(*i) << '\n';
+ // FIXME: This is not lazy, it would be nice to only print weak references
+ // to stuff that is actually used. Note that doing so would require targets
+ // to notice uses in operands (due to constant exprs etc). This should
+ // happen with the MC stuff eventually.
+ SwitchToDataSection("");
+
+ // Print out module-level global variables here.
+ for (Module::const_global_iterator I = M.global_begin(), E = M.global_end();
+ I != E; ++I) {
+ if (I->hasExternalWeakLinkage())
+ O << TAI->getWeakRefDirective() << Mang->getValueName(I) << '\n';
+ }
+
+ for (Module::const_iterator I = M.begin(), E = M.end();
+ I != E; ++I) {
+ if (I->hasExternalWeakLinkage())
+ O << TAI->getWeakRefDirective() << Mang->getValueName(I) << '\n';
+ }
}
if (TAI->getSetDirective()) {
@@ -207,7 +224,7 @@ bool AsmPrinter::doFinalization(Module &M) {
O << '\n';
for (Module::const_alias_iterator I = M.alias_begin(), E = M.alias_end();
- I!=E; ++I) {
+ I != E; ++I) {
std::string Name = Mang->getValueName(I);
std::string Target;
@@ -235,12 +252,13 @@ bool AsmPrinter::doFinalization(Module &M) {
// If we don't have any trampolines, then we don't require stack memory
// to be executable. Some targets have a directive to declare this.
- Function* InitTrampolineIntrinsic = M.getFunction("llvm.init.trampoline");
+ Function *InitTrampolineIntrinsic = M.getFunction("llvm.init.trampoline");
if (!InitTrampolineIntrinsic || InitTrampolineIntrinsic->use_empty())
if (TAI->getNonexecutableStackDirective())
O << TAI->getNonexecutableStackDirective() << '\n';
delete Mang; Mang = 0;
+ DW = 0; MMI = 0;
return false;
}
@@ -1298,20 +1316,15 @@ void AsmPrinter::PrintSpecial(const MachineInstr *MI, const char *Code) const {
if (VerboseAsm)
O << TAI->getCommentString();
} else if (!strcmp(Code, "uid")) {
- // Assign a unique ID to this machine instruction.
- static const MachineInstr *LastMI = 0;
- static const Function *F = 0;
- static unsigned Counter = 0U-1;
-
// Comparing the address of MI isn't sufficient, because machineinstrs may
// be allocated to the same address across functions.
const Function *ThisF = MI->getParent()->getParent()->getFunction();
- // If this is a new machine instruction, bump the counter.
- if (LastMI != MI || F != ThisF) {
+ // If this is a new LastFn instruction, bump the counter.
+ if (LastMI != MI || LastFn != ThisF) {
++Counter;
LastMI = MI;
- F = ThisF;
+ LastFn = ThisF;
}
O << Counter;
} else {
@@ -1326,7 +1339,6 @@ void AsmPrinter::PrintSpecial(const MachineInstr *MI, const char *Code) const {
void AsmPrinter::processDebugLoc(DebugLoc DL) {
if (TAI->doesSupportDebugInformation() && DW->ShouldEmitDwarfDebug()) {
if (!DL.isUnknown()) {
- static DebugLocTuple PrevDLT(0, ~0U, ~0U);
DebugLocTuple CurDLT = MF->getDebugLocTuple(DL);
if (CurDLT.CompileUnit != 0 && PrevDLT != CurDLT)
diff --git a/lib/CodeGen/AsmPrinter/DIE.cpp b/lib/CodeGen/AsmPrinter/DIE.cpp
index dc149cf..01c431c 100644
--- a/lib/CodeGen/AsmPrinter/DIE.cpp
+++ b/lib/CodeGen/AsmPrinter/DIE.cpp
@@ -126,7 +126,6 @@ void DIE::Profile(FoldingSetNodeID &ID) {
#ifndef NDEBUG
void DIE::print(std::ostream &O, unsigned IncIndent) {
- static unsigned IndentCount = 0;
IndentCount += IncIndent;
const std::string Indent(IndentCount, ' ');
bool isBlock = Abbrev.getTag() == 0;
diff --git a/lib/CodeGen/AsmPrinter/DIE.h b/lib/CodeGen/AsmPrinter/DIE.h
index b14d91c..5b60327 100644
--- a/lib/CodeGen/AsmPrinter/DIE.h
+++ b/lib/CodeGen/AsmPrinter/DIE.h
@@ -141,9 +141,13 @@ namespace llvm {
/// Abstract compile unit.
CompileUnit *AbstractCU;
+
+ // Private data for print()
+ mutable unsigned IndentCount;
public:
explicit DIE(unsigned Tag)
- : Abbrev(Tag, dwarf::DW_CHILDREN_no), Offset(0), Size(0) {}
+ : Abbrev(Tag, dwarf::DW_CHILDREN_no), Offset(0),
+ Size(0), IndentCount(0) {}
virtual ~DIE();
// Accessors.
diff --git a/lib/CodeGen/AsmPrinter/DwarfDebug.cpp b/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
index 9d340e3..cbe542b 100644
--- a/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
+++ b/lib/CodeGen/AsmPrinter/DwarfDebug.cpp
@@ -141,9 +141,12 @@ class VISIBILITY_HIDDEN DbgScope {
SmallVector<DbgScope *, 4> Scopes; // Scopes defined in scope.
SmallVector<DbgVariable *, 8> Variables;// Variables declared in scope.
SmallVector<DbgConcreteScope *, 8> ConcreteInsts;// Concrete insts of funcs.
+
+ // Private state for dump()
+ mutable unsigned IndentLevel;
public:
DbgScope(DbgScope *P, DIDescriptor D)
- : Parent(P), Desc(D), StartLabelID(0), EndLabelID(0) {}
+ : Parent(P), Desc(D), StartLabelID(0), EndLabelID(0), IndentLevel(0) {}
virtual ~DbgScope();
// Accessors.
@@ -176,7 +179,6 @@ public:
#ifndef NDEBUG
void DbgScope::dump() const {
- static unsigned IndentLevel = 0;
std::string Indent(IndentLevel, ' ');
cerr << Indent; Desc.dump();
@@ -1240,27 +1242,7 @@ void DwarfDebug::ConstructCompileUnit(GlobalVariable *GV) {
CompileUnits.push_back(Unit);
}
-/// ConstructCompileUnits - Create a compile unit DIEs.
-void DwarfDebug::ConstructCompileUnits() {
- GlobalVariable *Root = M->getGlobalVariable("llvm.dbg.compile_units");
- if (!Root)
- return;
- assert(Root->hasLinkOnceLinkage() && Root->hasOneUse() &&
- "Malformed compile unit descriptor anchor type");
- Constant *RootC = cast<Constant>(*Root->use_begin());
- assert(RootC->hasNUsesOrMore(1) &&
- "Malformed compile unit descriptor anchor type");
-
- for (Value::use_iterator UI = RootC->use_begin(), UE = Root->use_end();
- UI != UE; ++UI)
- for (Value::use_iterator UUI = UI->use_begin(), UUE = UI->use_end();
- UUI != UUE; ++UUI) {
- GlobalVariable *GV = cast<GlobalVariable>(*UUI);
- ConstructCompileUnit(GV);
- }
-}
-
-bool DwarfDebug::ConstructGlobalVariableDIE(GlobalVariable *GV) {
+void DwarfDebug::ConstructGlobalVariableDIE(GlobalVariable *GV) {
DIGlobalVariable DI_GV(GV);
CompileUnit *DW_Unit = MainCU;
if (!DW_Unit)
@@ -1269,7 +1251,7 @@ bool DwarfDebug::ConstructGlobalVariableDIE(GlobalVariable *GV) {
// Check for pre-existence.
DIE *&Slot = DW_Unit->getDieMapSlotFor(DI_GV.getGV());
if (Slot)
- return false;
+ return;
DIE *VariableDie = CreateGlobalVariableDIE(DW_Unit, DI_GV);
@@ -1290,33 +1272,10 @@ bool DwarfDebug::ConstructGlobalVariableDIE(GlobalVariable *GV) {
// Expose as global. FIXME - need to check external flag.
std::string Name;
DW_Unit->AddGlobal(DI_GV.getName(Name), VariableDie);
- return true;
+ return;
}
-/// ConstructGlobalVariableDIEs - Create DIEs for each of the externally visible
-/// global variables. Return true if at least one global DIE is created.
-bool DwarfDebug::ConstructGlobalVariableDIEs() {
- GlobalVariable *Root = M->getGlobalVariable("llvm.dbg.global_variables");
- if (!Root)
- return false;
-
- assert(Root->hasLinkOnceLinkage() && Root->hasOneUse() &&
- "Malformed global variable descriptor anchor type");
- Constant *RootC = cast<Constant>(*Root->use_begin());
- assert(RootC->hasNUsesOrMore(1) &&
- "Malformed global variable descriptor anchor type");
-
- bool Result = false;
- for (Value::use_iterator UI = RootC->use_begin(), UE = Root->use_end();
- UI != UE; ++UI)
- for (Value::use_iterator UUI = UI->use_begin(), UUE = UI->use_end();
- UUI != UUE; ++UUI)
- Result |= ConstructGlobalVariableDIE(cast<GlobalVariable>(*UUI));
-
- return Result;
-}
-
-bool DwarfDebug::ConstructSubprogram(GlobalVariable *GV) {
+void DwarfDebug::ConstructSubprogram(GlobalVariable *GV) {
DISubprogram SP(GV);
CompileUnit *Unit = MainCU;
if (!Unit)
@@ -1325,12 +1284,12 @@ bool DwarfDebug::ConstructSubprogram(GlobalVariable *GV) {
// Check for pre-existence.
DIE *&Slot = Unit->getDieMapSlotFor(GV);
if (Slot)
- return false;
+ return;
if (!SP.isDefinition())
// This is a method declaration which will be handled while constructing
// class type.
- return false;
+ return;
DIE *SubprogramDie = CreateSubprogramDIE(Unit, SP);
@@ -1343,40 +1302,27 @@ bool DwarfDebug::ConstructSubprogram(GlobalVariable *GV) {
// Expose as global.
std::string Name;
Unit->AddGlobal(SP.getName(Name), SubprogramDie);
- return true;
+ return;
}
-/// ConstructSubprograms - Create DIEs for each of the externally visible
-/// subprograms. Return true if at least one subprogram DIE is created.
-bool DwarfDebug::ConstructSubprograms() {
- GlobalVariable *Root = M->getGlobalVariable("llvm.dbg.subprograms");
- if (!Root)
- return false;
-
- assert(Root->hasLinkOnceLinkage() && Root->hasOneUse() &&
- "Malformed subprogram descriptor anchor type");
- Constant *RootC = cast<Constant>(*Root->use_begin());
- assert(RootC->hasNUsesOrMore(1) &&
- "Malformed subprogram descriptor anchor type");
+ /// BeginModule - Emit all Dwarf sections that should come prior to the
+ /// content. Create global DIEs and emit initial debug info sections.
+ /// This is inovked by the target AsmPrinter.
+void DwarfDebug::BeginModule(Module *M, MachineModuleInfo *mmi) {
+ this->M = M;
- bool Result = false;
- for (Value::use_iterator UI = RootC->use_begin(), UE = Root->use_end();
- UI != UE; ++UI)
- for (Value::use_iterator UUI = UI->use_begin(), UUE = UI->use_end();
- UUI != UUE; ++UUI)
- Result |= ConstructSubprogram(cast<GlobalVariable>(*UUI));
-
- return Result;
-}
-
-/// SetDebugInfo - Create global DIEs and emit initial debug info sections.
-/// This is inovked by the target AsmPrinter.
-void DwarfDebug::SetDebugInfo(MachineModuleInfo *mmi) {
if (TimePassesIsEnabled)
DebugTimer->startTimer();
+ SmallVector<GlobalVariable *, 2> CUs;
+ SmallVector<GlobalVariable *, 4> GVs;
+ SmallVector<GlobalVariable *, 4> SPs;
+ CollectDebugInfoAnchors(*M, CUs, GVs, SPs);
+
// Create all the compile unit DIEs.
- ConstructCompileUnits();
+ for (SmallVector<GlobalVariable *, 2>::iterator I = CUs.begin(),
+ E = CUs.end(); I != E; ++I)
+ ConstructCompileUnit(*I);
if (CompileUnits.empty()) {
if (TimePassesIsEnabled)
@@ -1385,21 +1331,25 @@ void DwarfDebug::SetDebugInfo(MachineModuleInfo *mmi) {
return;
}
- // Create DIEs for each of the externally visible global variables.
- bool globalDIEs = ConstructGlobalVariableDIEs();
-
- // Create DIEs for each of the externally visible subprograms.
- bool subprogramDIEs = ConstructSubprograms();
-
// If there is not any debug info available for any global variables and any
// subprograms then there is not any debug info to emit.
- if (!globalDIEs && !subprogramDIEs) {
+ if (GVs.empty() && SPs.empty()) {
if (TimePassesIsEnabled)
DebugTimer->stopTimer();
return;
}
+ // Create DIEs for each of the externally visible global variables.
+ for (SmallVector<GlobalVariable *, 4>::iterator I = GVs.begin(),
+ E = GVs.end(); I != E; ++I)
+ ConstructGlobalVariableDIE(*I);
+
+ // Create DIEs for each of the externally visible subprograms.
+ for (SmallVector<GlobalVariable *, 4>::iterator I = SPs.begin(),
+ E = SPs.end(); I != E; ++I)
+ ConstructSubprogram(*I);
+
MMI = mmi;
shouldEmit = true;
MMI->setDebugInfoAvailability(true);
diff --git a/lib/CodeGen/AsmPrinter/DwarfDebug.h b/lib/CodeGen/AsmPrinter/DwarfDebug.h
index 9824566..111ec33 100644
--- a/lib/CodeGen/AsmPrinter/DwarfDebug.h
+++ b/lib/CodeGen/AsmPrinter/DwarfDebug.h
@@ -460,21 +460,10 @@ class VISIBILITY_HIDDEN DwarfDebug : public Dwarf {
void ConstructCompileUnit(GlobalVariable *GV);
- /// ConstructCompileUnits - Create a compile unit DIEs.
- void ConstructCompileUnits();
+ void ConstructGlobalVariableDIE(GlobalVariable *GV);
- bool ConstructGlobalVariableDIE(GlobalVariable *GV);
+ void ConstructSubprogram(GlobalVariable *GV);
- /// ConstructGlobalVariableDIEs - Create DIEs for each of the externally
- /// visible global variables. Return true if at least one global DIE is
- /// created.
- bool ConstructGlobalVariableDIEs();
-
- bool ConstructSubprogram(GlobalVariable *GV);
-
- /// ConstructSubprograms - Create DIEs for each of the externally visible
- /// subprograms. Return true if at least one subprogram DIE is created.
- bool ConstructSubprograms();
public:
//===--------------------------------------------------------------------===//
// Main entry points.
@@ -486,15 +475,9 @@ public:
/// be emitted.
bool ShouldEmitDwarfDebug() const { return shouldEmit; }
- /// SetDebugInfo - Create global DIEs and emit initial debug info sections.
- /// This is inovked by the target AsmPrinter.
- void SetDebugInfo(MachineModuleInfo *mmi);
-
/// BeginModule - Emit all Dwarf sections that should come prior to the
/// content.
- void BeginModule(Module *M) {
- this->M = M;
- }
+ void BeginModule(Module *M, MachineModuleInfo *MMI);
/// EndModule - Emit all Dwarf sections that should come after the content.
///
diff --git a/lib/CodeGen/AsmPrinter/DwarfException.h b/lib/CodeGen/AsmPrinter/DwarfException.h
index 4479af2..f1c3e56 100644
--- a/lib/CodeGen/AsmPrinter/DwarfException.h
+++ b/lib/CodeGen/AsmPrinter/DwarfException.h
@@ -149,16 +149,11 @@ public:
DwarfException(raw_ostream &OS, AsmPrinter *A, const TargetAsmInfo *T);
virtual ~DwarfException();
- /// SetModuleInfo - Set machine module information when it's known that pass
- /// manager has created it. Set by the target AsmPrinter.
- void SetModuleInfo(MachineModuleInfo *mmi) {
- MMI = mmi;
- }
-
/// BeginModule - Emit all exception information that should come prior to the
/// content.
- void BeginModule(Module *M) {
- this->M = M;
+ void BeginModule(Module *m, MachineModuleInfo *mmi) {
+ this->M = m;
+ this->MMI = mmi;
}
/// EndModule - Emit all exception information that should come after the
diff --git a/lib/CodeGen/AsmPrinter/DwarfWriter.cpp b/lib/CodeGen/AsmPrinter/DwarfWriter.cpp
index 483ee559..89084989 100644
--- a/lib/CodeGen/AsmPrinter/DwarfWriter.cpp
+++ b/lib/CodeGen/AsmPrinter/DwarfWriter.cpp
@@ -42,10 +42,8 @@ void DwarfWriter::BeginModule(Module *M,
const TargetAsmInfo *T) {
DE = new DwarfException(OS, A, T);
DD = new DwarfDebug(OS, A, T);
- DE->BeginModule(M);
- DD->BeginModule(M);
- DD->SetDebugInfo(MMI);
- DE->SetModuleInfo(MMI);
+ DE->BeginModule(M, MMI);
+ DD->BeginModule(M, MMI);
}
/// EndModule - Emit all Dwarf sections that should come after the content.
diff --git a/lib/CodeGen/AsmPrinter/Makefile b/lib/CodeGen/AsmPrinter/Makefile
index cb5b3f6..8f65d8d 100644
--- a/lib/CodeGen/AsmPrinter/Makefile
+++ b/lib/CodeGen/AsmPrinter/Makefile
@@ -9,7 +9,5 @@
LEVEL = ../../..
LIBRARYNAME = LLVMAsmPrinter
PARALLEL_DIRS =
-BUILD_ARCHIVE = 1
-DONT_BUILD_RELINKED = 1
include $(LEVEL)/Makefile.common
diff --git a/lib/CodeGen/CMakeLists.txt b/lib/CodeGen/CMakeLists.txt
index 5ba8b3c..eeefe31 100644
--- a/lib/CodeGen/CMakeLists.txt
+++ b/lib/CodeGen/CMakeLists.txt
@@ -63,3 +63,5 @@ add_llvm_library(LLVMCodeGen
VirtRegMap.cpp
VirtRegRewriter.cpp
)
+
+target_link_libraries (LLVMCodeGen LLVMCore)
diff --git a/lib/CodeGen/ELF.h b/lib/CodeGen/ELF.h
index 28b6be8..8d92373 100644
--- a/lib/CodeGen/ELF.h
+++ b/lib/CodeGen/ELF.h
@@ -144,6 +144,9 @@ namespace llvm {
uint8_t Other;
unsigned short SectionIdx;
+ // Symbol index into the Symbol table
+ unsigned SymTabIdx;
+
enum {
STB_LOCAL = 0,
STB_GLOBAL = 1,
@@ -168,7 +171,8 @@ namespace llvm {
ELFSym(const GlobalValue *gv) : GV(gv), IsCommon(false), IsBss(false),
IsConstant(false), NameIdx(0), Value(0),
Size(0), Info(0), Other(STV_DEFAULT),
- SectionIdx(ELFSection::SHN_UNDEF) {
+ SectionIdx(ELFSection::SHN_UNDEF),
+ SymTabIdx(0) {
if (!GV)
return;
@@ -191,6 +195,10 @@ namespace llvm {
return (Info >> 4) & 0xf;
}
+ unsigned getType() {
+ return Info & 0xf;
+ }
+
void setBind(unsigned X) {
assert(X == (X & 0xF) && "Bind value out of range!");
Info = (Info & 0x0F) | (X << 4);
diff --git a/lib/CodeGen/ELFCodeEmitter.cpp b/lib/CodeGen/ELFCodeEmitter.cpp
index 8cb7c94..168fed5 100644
--- a/lib/CodeGen/ELFCodeEmitter.cpp
+++ b/lib/CodeGen/ELFCodeEmitter.cpp
@@ -16,6 +16,7 @@
#include "llvm/CodeGen/BinaryObject.h"
#include "llvm/CodeGen/MachineConstantPool.h"
#include "llvm/CodeGen/MachineJumpTableInfo.h"
+#include "llvm/Target/TargetData.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Support/Debug.h"
@@ -103,21 +104,28 @@ bool ELFCodeEmitter::finishFunction(MachineFunction &MF) {
break;
}
+ // Emit constant pool to appropriate section(s)
+ emitConstantPool(MF.getConstantPool());
+
// Relocations
// -----------
- // If we have emitted any relocations to function-specific objects such as
+ // If we have emitted any relocations to function-specific objects such as
// basic blocks, constant pools entries, or jump tables, record their
// addresses now so that we can rewrite them with the correct addresses
// later.
for (unsigned i = 0, e = Relocations.size(); i != e; ++i) {
MachineRelocation &MR = Relocations[i];
intptr_t Addr;
- if (MR.isBasicBlock()) {
+ if (MR.isGlobalValue()) {
+ EW.PendingGlobals.insert(MR.getGlobalValue());
+ } else if (MR.isBasicBlock()) {
Addr = getMachineBasicBlockAddress(MR.getBasicBlock());
MR.setConstantVal(ES->SectionIdx);
MR.setResultPointer((void*)Addr);
- } else if (MR.isGlobalValue()) {
- EW.PendingGlobals.insert(MR.getGlobalValue());
+ } else if (MR.isConstantPoolIndex()) {
+ Addr = getConstantPoolEntryAddress(MR.getConstantPoolIndex());
+ MR.setConstantVal(CPSections[MR.getConstantPoolIndex()]);
+ MR.setResultPointer((void*)Addr);
} else {
assert(0 && "Unhandled relocation type");
}
@@ -128,4 +136,36 @@ bool ELFCodeEmitter::finishFunction(MachineFunction &MF) {
return false;
}
+/// emitConstantPool - For each constant pool entry, figure out which section
+/// the constant should live in and emit the constant
+void ELFCodeEmitter::emitConstantPool(MachineConstantPool *MCP) {
+ const std::vector<MachineConstantPoolEntry> &CP = MCP->getConstants();
+ if (CP.empty()) return;
+
+ // TODO: handle PIC codegen
+ assert(TM.getRelocationModel() != Reloc::PIC_ &&
+ "PIC codegen not yet handled for elf constant pools!");
+
+ const TargetAsmInfo *TAI = TM.getTargetAsmInfo();
+ for (unsigned i = 0, e = CP.size(); i != e; ++i) {
+ MachineConstantPoolEntry CPE = CP[i];
+
+ // Get the right ELF Section for this constant pool entry
+ std::string CstPoolName =
+ TAI->SelectSectionForMachineConst(CPE.getType())->getName();
+ ELFSection &CstPoolSection =
+ EW.getConstantPoolSection(CstPoolName, CPE.getAlignment());
+
+ // Record the constant pool location and the section index
+ CPLocations.push_back(CstPoolSection.size());
+ CPSections.push_back(CstPoolSection.SectionIdx);
+
+ if (CPE.isMachineConstantPoolEntry())
+ assert("CPE.isMachineConstantPoolEntry not supported yet");
+
+ // Emit the constant to constant pool section
+ EW.EmitGlobalConstant(CPE.Val.ConstVal, CstPoolSection);
+ }
+}
+
} // end namespace llvm
diff --git a/lib/CodeGen/ELFCodeEmitter.h b/lib/CodeGen/ELFCodeEmitter.h
index c0289da..c309ef7 100644
--- a/lib/CodeGen/ELFCodeEmitter.h
+++ b/lib/CodeGen/ELFCodeEmitter.h
@@ -31,6 +31,14 @@ namespace llvm {
/// emitted.
std::vector<MachineRelocation> Relocations;
+ /// CPLocations - This is a map of constant pool indices to offsets from the
+ /// start of the section for that constant pool index.
+ std::vector<uintptr_t> CPLocations;
+
+ /// CPSections - This is a map of constant pool indices to the MachOSection
+ /// containing the constant pool entry for that index.
+ std::vector<unsigned> CPSections;
+
/// MBBLocations - This vector is a mapping from MBB ID's to their address.
/// It is filled in by the StartMachineBasicBlock callback and queried by
/// the getMachineBasicBlockAddress callback.
@@ -62,9 +70,10 @@ namespace llvm {
}
virtual uintptr_t getConstantPoolEntryAddress(unsigned Index) const {
- assert(0 && "CP not implementated yet!");
- return 0;
+ assert(CPLocations.size() > Index && "CP not emitted!");
+ return CPLocations[Index];
}
+
virtual uintptr_t getJumpTableEntryAddress(unsigned Index) const {
assert(0 && "JT not implementated yet!");
return 0;
@@ -86,6 +95,10 @@ namespace llvm {
abort();
}
+ /// emitConstantPool - For each constant pool entry, figure out which section
+ /// the constant should live in and emit the constant.
+ void emitConstantPool(MachineConstantPool *MCP);
+
virtual void setModuleInfo(llvm::MachineModuleInfo* MMI) { }
/// JIT SPECIFIC FUNCTIONS - DO NOT IMPLEMENT THESE HERE!
diff --git a/lib/CodeGen/ELFWriter.cpp b/lib/CodeGen/ELFWriter.cpp
index 03db656..041defa 100644
--- a/lib/CodeGen/ELFWriter.cpp
+++ b/lib/CodeGen/ELFWriter.cpp
@@ -389,6 +389,24 @@ bool ELFWriter::doFinalization(Module &M) {
if (TAI->getNonexecutableStackDirective())
getNonExecStackSection();
+ // Emit a symbol for each section created until now
+ for (std::map<std::string, ELFSection*>::iterator I = SectionLookup.begin(),
+ E = SectionLookup.end(); I != E; ++I) {
+ ELFSection *ES = I->second;
+
+ // Skip null section
+ if (ES->SectionIdx == 0) continue;
+
+ ELFSym SectionSym(0);
+ SectionSym.SectionIdx = ES->SectionIdx;
+ SectionSym.Size = 0;
+ SectionSym.setBind(ELFSym::STB_LOCAL);
+ SectionSym.setType(ELFSym::STT_SECTION);
+
+ // Local symbols go in the list front
+ SymbolList.push_front(SectionSym);
+ }
+
// Emit string table
EmitStringTable();
@@ -451,15 +469,25 @@ void ELFWriter::EmitRelocations() {
// Constant addend used to compute the value to be stored
// into the relocatable field
- int64_t Addend = TEW->getAddendForRelTy(RelType);
+ int64_t Addend = 0;
// There are several machine relocations types, and each one of
// them needs a different approach to retrieve the symbol table index.
if (MR.isGlobalValue()) {
const GlobalValue *G = MR.getGlobalValue();
SymIdx = GblSymLookup[G];
+ Addend = TEW->getAddendForRelTy(RelType);
} else {
- assert(0 && "dunno how to handle other relocation types");
+ unsigned SectionIdx = MR.getConstantVal();
+ // TODO: use a map for this.
+ for (std::list<ELFSym>::iterator I = SymbolList.begin(),
+ E = SymbolList.end(); I != E; ++I)
+ if ((SectionIdx == I->SectionIdx) &&
+ (I->getType() == ELFSym::STT_SECTION)) {
+ SymIdx = I->SymTabIdx;
+ break;
+ }
+ Addend = (uint64_t)MR.getResultPointer();
}
// Get the relocation entry and emit to the relocation section
@@ -540,7 +568,8 @@ void ELFWriter::EmitStringTable() {
E = SymbolList.end(); I != E; ++I) {
// Use the name mangler to uniquify the LLVM symbol.
- std::string Name = Mang->getValueName(I->GV);
+ std::string Name;
+ if (I->GV) Name.append(Mang->getValueName(I->GV));
if (Name.empty()) {
I->NameIdx = 0;
@@ -589,7 +618,11 @@ void ELFWriter::EmitSymbolTable() {
EmitSymbol(SymTab, *I);
// Record the symbol table index for each global value
- GblSymLookup[I->GV] = Index;
+ if (I->GV)
+ GblSymLookup[I->GV] = Index;
+
+ // Keep track on the symbol index into the symbol table
+ I->SymTabIdx = Index;
}
SymTab.Info = FirstNonLocalSymbol;
diff --git a/lib/CodeGen/ELFWriter.h b/lib/CodeGen/ELFWriter.h
index 39577d9..e0e71d0 100644
--- a/lib/CodeGen/ELFWriter.h
+++ b/lib/CodeGen/ELFWriter.h
@@ -147,6 +147,12 @@ namespace llvm {
ELFSection::SHF_EXECINSTR | ELFSection::SHF_ALLOC);
}
+ /// Get a constant pool section based on the section name returned by TAI
+ ELFSection &getConstantPoolSection(std::string SName, unsigned Align) {
+ return getSection(SName, ELFSection::SHT_PROGBITS,
+ ELFSection::SHF_MERGE | ELFSection::SHF_ALLOC, Align);
+ }
+
/// Return the relocation section of section 'S'. 'RelA' is true
/// if the relocation section contains entries with addends.
ELFSection &getRelocSection(std::string SName, bool RelA) {
diff --git a/lib/CodeGen/IfConversion.cpp b/lib/CodeGen/IfConversion.cpp
index 4d5c3c2..d5e7ea5 100644
--- a/lib/CodeGen/IfConversion.cpp
+++ b/lib/CodeGen/IfConversion.cpp
@@ -144,9 +144,10 @@ namespace {
const TargetLowering *TLI;
const TargetInstrInfo *TII;
bool MadeChange;
+ int FnNum;
public:
static char ID;
- IfConverter() : MachineFunctionPass(&ID) {}
+ IfConverter() : MachineFunctionPass(&ID), FnNum(-1) {}
virtual bool runOnMachineFunction(MachineFunction &MF);
virtual const char *getPassName() const { return "If Converter"; }
@@ -225,7 +226,6 @@ bool IfConverter::runOnMachineFunction(MachineFunction &MF) {
TII = MF.getTarget().getInstrInfo();
if (!TII) return false;
- static int FnNum = -1;
DOUT << "\nIfcvt: function (" << ++FnNum << ") \'"
<< MF.getFunction()->getName() << "\'";
diff --git a/lib/CodeGen/IntrinsicLowering.cpp b/lib/CodeGen/IntrinsicLowering.cpp
index e6912b8..052334a 100644
--- a/lib/CodeGen/IntrinsicLowering.cpp
+++ b/lib/CodeGen/IntrinsicLowering.cpp
@@ -61,18 +61,16 @@ static void EnsureFPIntrinsicsExist(Module &M, Function *Fn,
template <class ArgIt>
static CallInst *ReplaceCallWith(const char *NewFn, CallInst *CI,
ArgIt ArgBegin, ArgIt ArgEnd,
- const Type *RetTy, Constant *&FCache) {
- if (!FCache) {
- // If we haven't already looked up this function, check to see if the
- // program already contains a function with this name.
- Module *M = CI->getParent()->getParent()->getParent();
- // Get or insert the definition now.
- std::vector<const Type *> ParamTys;
- for (ArgIt I = ArgBegin; I != ArgEnd; ++I)
- ParamTys.push_back((*I)->getType());
- FCache = M->getOrInsertFunction(NewFn,
- FunctionType::get(RetTy, ParamTys, false));
- }
+ const Type *RetTy) {
+ // If we haven't already looked up this function, check to see if the
+ // program already contains a function with this name.
+ Module *M = CI->getParent()->getParent()->getParent();
+ // Get or insert the definition now.
+ std::vector<const Type *> ParamTys;
+ for (ArgIt I = ArgBegin; I != ArgEnd; ++I)
+ ParamTys.push_back((*I)->getType());
+ Constant* FCache = M->getOrInsertFunction(NewFn,
+ FunctionType::get(RetTy, ParamTys, false));
IRBuilder<> Builder(CI->getParent(), CI);
SmallVector<Value *, 8> Args(ArgBegin, ArgEnd);
@@ -624,25 +622,24 @@ static Instruction *LowerPartSet(CallInst *CI) {
return NewCI;
}
-static void ReplaceFPIntrinsicWithCall(CallInst *CI, Constant *FCache,
- Constant *DCache, Constant *LDCache,
- const char *Fname, const char *Dname,
+static void ReplaceFPIntrinsicWithCall(CallInst *CI, const char *Fname,
+ const char *Dname,
const char *LDname) {
switch (CI->getOperand(1)->getType()->getTypeID()) {
default: assert(0 && "Invalid type in intrinsic"); abort();
case Type::FloatTyID:
ReplaceCallWith(Fname, CI, CI->op_begin() + 1, CI->op_end(),
- Type::FloatTy, FCache);
+ Type::FloatTy);
break;
case Type::DoubleTyID:
ReplaceCallWith(Dname, CI, CI->op_begin() + 1, CI->op_end(),
- Type::DoubleTy, DCache);
+ Type::DoubleTy);
break;
case Type::X86_FP80TyID:
case Type::FP128TyID:
case Type::PPC_FP128TyID:
ReplaceCallWith(LDname, CI, CI->op_begin() + 1, CI->op_end(),
- CI->getOperand(1)->getType(), LDCache);
+ CI->getOperand(1)->getType());
break;
}
}
@@ -668,9 +665,8 @@ void IntrinsicLowering::LowerIntrinsicCall(CallInst *CI) {
// by the lowerinvoke pass. In both cases, the right thing to do is to
// convert the call to an explicit setjmp or longjmp call.
case Intrinsic::setjmp: {
- static Constant *SetjmpFCache = 0;
Value *V = ReplaceCallWith("setjmp", CI, CI->op_begin() + 1, CI->op_end(),
- Type::Int32Ty, SetjmpFCache);
+ Type::Int32Ty);
if (CI->getType() != Type::VoidTy)
CI->replaceAllUsesWith(V);
break;
@@ -681,17 +677,15 @@ void IntrinsicLowering::LowerIntrinsicCall(CallInst *CI) {
break;
case Intrinsic::longjmp: {
- static Constant *LongjmpFCache = 0;
ReplaceCallWith("longjmp", CI, CI->op_begin() + 1, CI->op_end(),
- Type::VoidTy, LongjmpFCache);
+ Type::VoidTy);
break;
}
case Intrinsic::siglongjmp: {
// Insert the call to abort
- static Constant *AbortFCache = 0;
ReplaceCallWith("abort", CI, CI->op_end(), CI->op_end(),
- Type::VoidTy, AbortFCache);
+ Type::VoidTy);
break;
}
case Intrinsic::ctpop:
@@ -728,7 +722,6 @@ void IntrinsicLowering::LowerIntrinsicCall(CallInst *CI) {
case Intrinsic::stacksave:
case Intrinsic::stackrestore: {
- static bool Warned = false;
if (!Warned)
cerr << "WARNING: this target does not support the llvm.stack"
<< (Callee->getIntrinsicID() == Intrinsic::stacksave ?
@@ -783,7 +776,6 @@ void IntrinsicLowering::LowerIntrinsicCall(CallInst *CI) {
break; // Strip out annotate intrinsic
case Intrinsic::memcpy: {
- static Constant *MemcpyFCache = 0;
const IntegerType *IntPtr = TD.getIntPtrType();
Value *Size = Builder.CreateIntCast(CI->getOperand(3), IntPtr,
/* isSigned */ false);
@@ -791,12 +783,10 @@ void IntrinsicLowering::LowerIntrinsicCall(CallInst *CI) {
Ops[0] = CI->getOperand(1);
Ops[1] = CI->getOperand(2);
Ops[2] = Size;
- ReplaceCallWith("memcpy", CI, Ops, Ops+3, CI->getOperand(1)->getType(),
- MemcpyFCache);
+ ReplaceCallWith("memcpy", CI, Ops, Ops+3, CI->getOperand(1)->getType());
break;
}
case Intrinsic::memmove: {
- static Constant *MemmoveFCache = 0;
const IntegerType *IntPtr = TD.getIntPtrType();
Value *Size = Builder.CreateIntCast(CI->getOperand(3), IntPtr,
/* isSigned */ false);
@@ -804,12 +794,10 @@ void IntrinsicLowering::LowerIntrinsicCall(CallInst *CI) {
Ops[0] = CI->getOperand(1);
Ops[1] = CI->getOperand(2);
Ops[2] = Size;
- ReplaceCallWith("memmove", CI, Ops, Ops+3, CI->getOperand(1)->getType(),
- MemmoveFCache);
+ ReplaceCallWith("memmove", CI, Ops, Ops+3, CI->getOperand(1)->getType());
break;
}
case Intrinsic::memset: {
- static Constant *MemsetFCache = 0;
const IntegerType *IntPtr = TD.getIntPtrType();
Value *Size = Builder.CreateIntCast(CI->getOperand(3), IntPtr,
/* isSigned */ false);
@@ -819,64 +807,35 @@ void IntrinsicLowering::LowerIntrinsicCall(CallInst *CI) {
Ops[1] = Builder.CreateIntCast(CI->getOperand(2), Type::Int32Ty,
/* isSigned */ false);
Ops[2] = Size;
- ReplaceCallWith("memset", CI, Ops, Ops+3, CI->getOperand(1)->getType(),
- MemsetFCache);
+ ReplaceCallWith("memset", CI, Ops, Ops+3, CI->getOperand(1)->getType());
break;
}
case Intrinsic::sqrt: {
- static Constant *sqrtFCache = 0;
- static Constant *sqrtDCache = 0;
- static Constant *sqrtLDCache = 0;
- ReplaceFPIntrinsicWithCall(CI, sqrtFCache, sqrtDCache, sqrtLDCache,
- "sqrtf", "sqrt", "sqrtl");
+ ReplaceFPIntrinsicWithCall(CI, "sqrtf", "sqrt", "sqrtl");
break;
}
case Intrinsic::log: {
- static Constant *logFCache = 0;
- static Constant *logDCache = 0;
- static Constant *logLDCache = 0;
- ReplaceFPIntrinsicWithCall(CI, logFCache, logDCache, logLDCache,
- "logf", "log", "logl");
+ ReplaceFPIntrinsicWithCall(CI, "logf", "log", "logl");
break;
}
case Intrinsic::log2: {
- static Constant *log2FCache = 0;
- static Constant *log2DCache = 0;
- static Constant *log2LDCache = 0;
- ReplaceFPIntrinsicWithCall(CI, log2FCache, log2DCache, log2LDCache,
- "log2f", "log2", "log2l");
+ ReplaceFPIntrinsicWithCall(CI, "log2f", "log2", "log2l");
break;
}
case Intrinsic::log10: {
- static Constant *log10FCache = 0;
- static Constant *log10DCache = 0;
- static Constant *log10LDCache = 0;
- ReplaceFPIntrinsicWithCall(CI, log10FCache, log10DCache, log10LDCache,
- "log10f", "log10", "log10l");
+ ReplaceFPIntrinsicWithCall(CI, "log10f", "log10", "log10l");
break;
}
case Intrinsic::exp: {
- static Constant *expFCache = 0;
- static Constant *expDCache = 0;
- static Constant *expLDCache = 0;
- ReplaceFPIntrinsicWithCall(CI, expFCache, expDCache, expLDCache,
- "expf", "exp", "expl");
+ ReplaceFPIntrinsicWithCall(CI, "expf", "exp", "expl");
break;
}
case Intrinsic::exp2: {
- static Constant *exp2FCache = 0;
- static Constant *exp2DCache = 0;
- static Constant *exp2LDCache = 0;
- ReplaceFPIntrinsicWithCall(CI, exp2FCache, exp2DCache, exp2LDCache,
- "exp2f", "exp2", "exp2l");
+ ReplaceFPIntrinsicWithCall(CI, "exp2f", "exp2", "exp2l");
break;
}
case Intrinsic::pow: {
- static Constant *powFCache = 0;
- static Constant *powDCache = 0;
- static Constant *powLDCache = 0;
- ReplaceFPIntrinsicWithCall(CI, powFCache, powDCache, powLDCache,
- "powf", "pow", "powl");
+ ReplaceFPIntrinsicWithCall(CI, "powf", "pow", "powl");
break;
}
case Intrinsic::flt_rounds:
diff --git a/lib/CodeGen/LiveInterval.cpp b/lib/CodeGen/LiveInterval.cpp
index cac9253..26722a3 100644
--- a/lib/CodeGen/LiveInterval.cpp
+++ b/lib/CodeGen/LiveInterval.cpp
@@ -373,7 +373,8 @@ void LiveInterval::scaleNumbering(unsigned factor) {
for (vni_iterator VNI = vni_begin(), VNIE = vni_end(); VNI != VNIE; ++VNI) {
VNInfo *vni = *VNI;
- vni->def = InstrSlots::scale(vni->def, factor);
+ if (vni->isDefAccurate())
+ vni->def = InstrSlots::scale(vni->def, factor);
for (unsigned i = 0; i < vni->kills.size(); ++i) {
if (vni->kills[i] != 0)
diff --git a/lib/CodeGen/LiveIntervalAnalysis.cpp b/lib/CodeGen/LiveIntervalAnalysis.cpp
index d6931df..21bb5dc 100644
--- a/lib/CodeGen/LiveIntervalAnalysis.cpp
+++ b/lib/CodeGen/LiveIntervalAnalysis.cpp
@@ -947,6 +947,10 @@ unsigned LiveIntervals::getReMatImplicitUse(const LiveInterval &li,
unsigned Reg = MO.getReg();
if (Reg == 0 || Reg == li.reg)
continue;
+
+ if (TargetRegisterInfo::isPhysicalRegister(Reg) &&
+ !allocatableRegs_[Reg])
+ continue;
// FIXME: For now, only remat MI with at most one register operand.
assert(!RegOp &&
"Can't rematerialize instruction with multiple register operand!");
diff --git a/lib/CodeGen/MachineFunction.cpp b/lib/CodeGen/MachineFunction.cpp
index cacfed1..2d2b59e 100644
--- a/lib/CodeGen/MachineFunction.cpp
+++ b/lib/CodeGen/MachineFunction.cpp
@@ -124,25 +124,28 @@ MachineFunction::MachineFunction(const Function *F,
MachineFrameInfo(*TM.getFrameInfo());
ConstantPool = new (Allocator.Allocate<MachineConstantPool>())
MachineConstantPool(TM.getTargetData());
-
+
// Set up jump table.
const TargetData &TD = *TM.getTargetData();
bool IsPic = TM.getRelocationModel() == Reloc::PIC_;
unsigned EntrySize = IsPic ? 4 : TD.getPointerSize();
- unsigned Alignment = IsPic ? TD.getABITypeAlignment(Type::Int32Ty)
- : TD.getPointerABIAlignment();
+ unsigned TyAlignment = IsPic ? TD.getABITypeAlignment(Type::Int32Ty)
+ : TD.getPointerABIAlignment();
JumpTableInfo = new (Allocator.Allocate<MachineJumpTableInfo>())
- MachineJumpTableInfo(EntrySize, Alignment);
+ MachineJumpTableInfo(EntrySize, TyAlignment);
}
MachineFunction::~MachineFunction() {
BasicBlocks.clear();
InstructionRecycler.clear(Allocator);
BasicBlockRecycler.clear(Allocator);
- if (RegInfo)
- RegInfo->~MachineRegisterInfo(); Allocator.Deallocate(RegInfo);
+ if (RegInfo) {
+ RegInfo->~MachineRegisterInfo();
+ Allocator.Deallocate(RegInfo);
+ }
if (MFInfo) {
- MFInfo->~MachineFunctionInfo(); Allocator.Deallocate(MFInfo);
+ MFInfo->~MachineFunctionInfo();
+ Allocator.Deallocate(MFInfo);
}
FrameInfo->~MachineFrameInfo(); Allocator.Deallocate(FrameInfo);
ConstantPool->~MachineConstantPool(); Allocator.Deallocate(ConstantPool);
@@ -295,12 +298,6 @@ void MachineFunction::print(std::ostream &OS) const {
OS << "\n# End machine code for " << Fn->getName () << "().\n\n";
}
-/// CFGOnly flag - This is used to control whether or not the CFG graph printer
-/// prints out the contents of basic blocks or not. This is acceptable because
-/// this code is only really used for debugging purposes.
-///
-static bool CFGOnly = false;
-
namespace llvm {
template<>
struct DOTGraphTraits<const MachineFunction*> : public DefaultDOTGraphTraits {
@@ -309,13 +306,14 @@ namespace llvm {
}
static std::string getNodeLabel(const MachineBasicBlock *Node,
- const MachineFunction *Graph) {
- if (CFGOnly && Node->getBasicBlock() &&
+ const MachineFunction *Graph,
+ bool ShortNames) {
+ if (ShortNames && Node->getBasicBlock() &&
!Node->getBasicBlock()->getName().empty())
return Node->getBasicBlock()->getName() + ":";
std::ostringstream Out;
- if (CFGOnly) {
+ if (ShortNames) {
Out << Node->getNumber() << ':';
return Out.str();
}
@@ -348,9 +346,12 @@ void MachineFunction::viewCFG() const
void MachineFunction::viewCFGOnly() const
{
- CFGOnly = true;
- viewCFG();
- CFGOnly = false;
+#ifndef NDEBUG
+ ViewGraph(this, "mf" + getFunction()->getName(), true);
+#else
+ cerr << "SelectionDAG::viewGraph is only available in debug builds on "
+ << "systems with Graphviz or gv!\n";
+#endif // NDEBUG
}
// The next two methods are used to construct and to retrieve
diff --git a/lib/CodeGen/MachineInstr.cpp b/lib/CodeGen/MachineInstr.cpp
index c351593..c977508 100644
--- a/lib/CodeGen/MachineInstr.cpp
+++ b/lib/CodeGen/MachineInstr.cpp
@@ -150,7 +150,9 @@ void MachineOperand::ChangeToRegister(unsigned Reg, bool isDef, bool isImp,
/// isIdenticalTo - Return true if this operand is identical to the specified
/// operand.
bool MachineOperand::isIdenticalTo(const MachineOperand &Other) const {
- if (getType() != Other.getType()) return false;
+ if (getType() != Other.getType() ||
+ getTargetFlags() != Other.getTargetFlags())
+ return false;
switch (getType()) {
default: assert(0 && "Unrecognized operand type");
@@ -205,70 +207,72 @@ void MachineOperand::print(raw_ostream &OS, const TargetMachine *TM) const {
}
if (getSubReg() != 0) {
- OS << ":" << getSubReg();
+ OS << ':' << getSubReg();
}
if (isDef() || isKill() || isDead() || isImplicit() || isEarlyClobber()) {
- OS << "<";
+ OS << '<';
bool NeedComma = false;
if (isImplicit()) {
- if (NeedComma) OS << ",";
+ if (NeedComma) OS << ',';
OS << (isDef() ? "imp-def" : "imp-use");
NeedComma = true;
} else if (isDef()) {
- if (NeedComma) OS << ",";
+ if (NeedComma) OS << ',';
if (isEarlyClobber())
OS << "earlyclobber,";
OS << "def";
NeedComma = true;
}
if (isKill() || isDead()) {
- if (NeedComma) OS << ",";
+ if (NeedComma) OS << ',';
if (isKill()) OS << "kill";
if (isDead()) OS << "dead";
}
- OS << ">";
+ OS << '>';
}
break;
case MachineOperand::MO_Immediate:
OS << getImm();
break;
case MachineOperand::MO_FPImmediate:
- if (getFPImm()->getType() == Type::FloatTy) {
+ if (getFPImm()->getType() == Type::FloatTy)
OS << getFPImm()->getValueAPF().convertToFloat();
- } else {
+ else
OS << getFPImm()->getValueAPF().convertToDouble();
- }
break;
case MachineOperand::MO_MachineBasicBlock:
OS << "mbb<"
<< ((Value*)getMBB()->getBasicBlock())->getName()
- << "," << (void*)getMBB() << ">";
+ << "," << (void*)getMBB() << '>';
break;
case MachineOperand::MO_FrameIndex:
- OS << "<fi#" << getIndex() << ">";
+ OS << "<fi#" << getIndex() << '>';
break;
case MachineOperand::MO_ConstantPoolIndex:
OS << "<cp#" << getIndex();
if (getOffset()) OS << "+" << getOffset();
- OS << ">";
+ OS << '>';
break;
case MachineOperand::MO_JumpTableIndex:
- OS << "<jt#" << getIndex() << ">";
+ OS << "<jt#" << getIndex() << '>';
break;
case MachineOperand::MO_GlobalAddress:
OS << "<ga:" << ((Value*)getGlobal())->getName();
if (getOffset()) OS << "+" << getOffset();
- OS << ">";
+ OS << '>';
break;
case MachineOperand::MO_ExternalSymbol:
OS << "<es:" << getSymbolName();
if (getOffset()) OS << "+" << getOffset();
- OS << ">";
+ OS << '>';
break;
default:
assert(0 && "Unrecognized operand type");
}
+
+ if (unsigned TF = getTargetFlags())
+ OS << "[TF=" << TF << ']';
}
//===----------------------------------------------------------------------===//
@@ -716,31 +720,37 @@ isRegTiedToUseOperand(unsigned DefOpIdx, unsigned *UseOpIdx) const {
const MachineOperand &MO = getOperand(DefOpIdx);
if (!MO.isReg() || !MO.isDef() || MO.getReg() == 0)
return false;
- // Determine the actual operand no corresponding to this index.
+ // Determine the actual operand index that corresponds to this index.
unsigned DefNo = 0;
+ unsigned DefPart = 0;
for (unsigned i = 1, e = getNumOperands(); i < e; ) {
const MachineOperand &FMO = getOperand(i);
assert(FMO.isImm());
// Skip over this def.
- i += InlineAsm::getNumOperandRegisters(FMO.getImm()) + 1;
- if (i > DefOpIdx)
+ unsigned NumOps = InlineAsm::getNumOperandRegisters(FMO.getImm());
+ unsigned PrevDef = i + 1;
+ i = PrevDef + NumOps;
+ if (i > DefOpIdx) {
+ DefPart = DefOpIdx - PrevDef;
break;
+ }
++DefNo;
}
- for (unsigned i = 0, e = getNumOperands(); i != e; ++i) {
+ for (unsigned i = 1, e = getNumOperands(); i != e; ++i) {
const MachineOperand &FMO = getOperand(i);
if (!FMO.isImm())
continue;
if (i+1 >= e || !getOperand(i+1).isReg() || !getOperand(i+1).isUse())
continue;
unsigned Idx;
- if (InlineAsm::isUseOperandTiedToDef(FMO.getImm(), Idx) &&
+ if (InlineAsm::isUseOperandTiedToDef(FMO.getImm(), Idx) &&
Idx == DefNo) {
if (UseOpIdx)
- *UseOpIdx = (unsigned)i + 1;
+ *UseOpIdx = (unsigned)i + 1 + DefPart;
return true;
}
}
+ return false;
}
assert(getOperand(DefOpIdx).isDef() && "DefOpIdx is not a def!");
@@ -766,10 +776,16 @@ isRegTiedToDefOperand(unsigned UseOpIdx, unsigned *DefOpIdx) const {
const MachineOperand &MO = getOperand(UseOpIdx);
if (!MO.isReg() || !MO.isUse() || MO.getReg() == 0)
return false;
- assert(UseOpIdx > 0);
- const MachineOperand &UFMO = getOperand(UseOpIdx-1);
- if (!UFMO.isImm())
- return false; // Must be physreg uses.
+ int FlagIdx = UseOpIdx - 1;
+ if (FlagIdx < 1)
+ return false;
+ while (!getOperand(FlagIdx).isImm()) {
+ if (--FlagIdx == 0)
+ return false;
+ }
+ const MachineOperand &UFMO = getOperand(FlagIdx);
+ if (FlagIdx + InlineAsm::getNumOperandRegisters(UFMO.getImm()) < UseOpIdx)
+ return false;
unsigned DefNo;
if (InlineAsm::isUseOperandTiedToDef(UFMO.getImm(), DefNo)) {
if (!DefOpIdx)
@@ -785,7 +801,7 @@ isRegTiedToDefOperand(unsigned UseOpIdx, unsigned *DefOpIdx) const {
DefIdx += InlineAsm::getNumOperandRegisters(FMO.getImm()) + 1;
--DefNo;
}
- *DefOpIdx = DefIdx+1;
+ *DefOpIdx = DefIdx + UseOpIdx - FlagIdx;
return true;
}
return false;
@@ -1092,13 +1108,13 @@ bool MachineInstr::addRegisterDead(unsigned IncomingReg,
// If not found, this means an alias of one of the operands is dead. Add a
// new implicit operand if required.
- if (!Found && AddIfNotFound) {
- addOperand(MachineOperand::CreateReg(IncomingReg,
- true /*IsDef*/,
- true /*IsImp*/,
- false /*IsKill*/,
- true /*IsDead*/));
- return true;
- }
- return Found;
+ if (Found || !AddIfNotFound)
+ return Found;
+
+ addOperand(MachineOperand::CreateReg(IncomingReg,
+ true /*IsDef*/,
+ true /*IsImp*/,
+ false /*IsKill*/,
+ true /*IsDead*/));
+ return true;
}
diff --git a/lib/CodeGen/ScheduleDAGPrinter.cpp b/lib/CodeGen/ScheduleDAGPrinter.cpp
index 594c24d..5efd274 100644
--- a/lib/CodeGen/ScheduleDAGPrinter.cpp
+++ b/lib/CodeGen/ScheduleDAGPrinter.cpp
@@ -59,7 +59,8 @@ namespace llvm {
static std::string getNodeLabel(const SUnit *Node,
- const ScheduleDAG *Graph);
+ const ScheduleDAG *Graph,
+ bool ShortNames);
static std::string getNodeAttributes(const SUnit *N,
const ScheduleDAG *Graph) {
return "shape=Mrecord";
@@ -73,7 +74,8 @@ namespace llvm {
}
std::string DOTGraphTraits<ScheduleDAG*>::getNodeLabel(const SUnit *SU,
- const ScheduleDAG *G) {
+ const ScheduleDAG *G,
+ bool ShortNames) {
return G->getGraphNodeLabel(SU);
}
@@ -84,11 +86,11 @@ void ScheduleDAG::viewGraph() {
// This code is only for debugging!
#ifndef NDEBUG
if (BB->getBasicBlock())
- ViewGraph(this, "dag." + MF.getFunction()->getName(),
+ ViewGraph(this, "dag." + MF.getFunction()->getName(), false,
"Scheduling-Units Graph for " + MF.getFunction()->getName() + ':' +
BB->getBasicBlock()->getName());
else
- ViewGraph(this, "dag." + MF.getFunction()->getName(),
+ ViewGraph(this, "dag." + MF.getFunction()->getName(), false,
"Scheduling-Units Graph for " + MF.getFunction()->getName());
#else
cerr << "ScheduleDAG::viewGraph is only available in debug builds on "
diff --git a/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp b/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
index 1bb8090..ef365e6 100644
--- a/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
+++ b/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
@@ -211,7 +211,7 @@ SelectionDAGLegalize::SelectionDAGLegalize(SelectionDAG &dag,
CodeGenOpt::Level ol)
: TLI(dag.getTargetLoweringInfo()), DAG(dag), OptLevel(ol),
ValueTypeActions(TLI.getValueTypeActions()) {
- assert(MVT::LAST_VALUETYPE <= 32 &&
+ assert(MVT::LAST_VALUETYPE <= MVT::MAX_ALLOWED_VALUETYPE &&
"Too many value types for ValueTypeActions to hold!");
}
diff --git a/lib/CodeGen/SelectionDAG/LegalizeTypes.h b/lib/CodeGen/SelectionDAG/LegalizeTypes.h
index 75c8924..02b0732 100644
--- a/lib/CodeGen/SelectionDAG/LegalizeTypes.h
+++ b/lib/CodeGen/SelectionDAG/LegalizeTypes.h
@@ -159,7 +159,7 @@ public:
explicit DAGTypeLegalizer(SelectionDAG &dag)
: TLI(dag.getTargetLoweringInfo()), DAG(dag),
ValueTypeActions(TLI.getValueTypeActions()) {
- assert(MVT::LAST_VALUETYPE <= 32 &&
+ assert(MVT::LAST_VALUETYPE <= MVT::MAX_ALLOWED_VALUETYPE &&
"Too many value types for ValueTypeActions to hold!");
}
diff --git a/lib/CodeGen/SelectionDAG/Makefile b/lib/CodeGen/SelectionDAG/Makefile
index 185222a..73f0b5d 100644
--- a/lib/CodeGen/SelectionDAG/Makefile
+++ b/lib/CodeGen/SelectionDAG/Makefile
@@ -9,7 +9,5 @@
LEVEL = ../../..
LIBRARYNAME = LLVMSelectionDAG
PARALLEL_DIRS =
-BUILD_ARCHIVE = 1
-DONT_BUILD_RELINKED = 1
include $(LEVEL)/Makefile.common
diff --git a/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodesEmit.cpp b/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodesEmit.cpp
index fb5e207..e372b5b 100644
--- a/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodesEmit.cpp
+++ b/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodesEmit.cpp
@@ -30,10 +30,9 @@ using namespace llvm;
/// EmitCopyFromReg - Generate machine code for an CopyFromReg node or an
/// implicit physical register output.
-void ScheduleDAGSDNodes::EmitCopyFromReg(SDNode *Node, unsigned ResNo,
- bool IsClone, bool IsCloned,
- unsigned SrcReg,
- DenseMap<SDValue, unsigned> &VRBaseMap) {
+void ScheduleDAGSDNodes::
+EmitCopyFromReg(SDNode *Node, unsigned ResNo, bool IsClone, bool IsCloned,
+ unsigned SrcReg, DenseMap<SDValue, unsigned> &VRBaseMap) {
unsigned VRBase = 0;
if (TargetRegisterInfo::isVirtualRegister(SrcReg)) {
// Just use the input register directly!
@@ -281,13 +280,15 @@ void ScheduleDAGSDNodes::AddOperand(MachineInstr *MI, SDValue Op,
} else if (RegisterSDNode *R = dyn_cast<RegisterSDNode>(Op)) {
MI->addOperand(MachineOperand::CreateReg(R->getReg(), false));
} else if (GlobalAddressSDNode *TGA = dyn_cast<GlobalAddressSDNode>(Op)) {
- MI->addOperand(MachineOperand::CreateGA(TGA->getGlobal(),TGA->getOffset()));
+ MI->addOperand(MachineOperand::CreateGA(TGA->getGlobal(), TGA->getOffset(),
+ TGA->getTargetFlags()));
} else if (BasicBlockSDNode *BBNode = dyn_cast<BasicBlockSDNode>(Op)) {
MI->addOperand(MachineOperand::CreateMBB(BBNode->getBasicBlock()));
} else if (FrameIndexSDNode *FI = dyn_cast<FrameIndexSDNode>(Op)) {
MI->addOperand(MachineOperand::CreateFI(FI->getIndex()));
} else if (JumpTableSDNode *JT = dyn_cast<JumpTableSDNode>(Op)) {
- MI->addOperand(MachineOperand::CreateJTI(JT->getIndex()));
+ MI->addOperand(MachineOperand::CreateJTI(JT->getIndex(),
+ JT->getTargetFlags()));
} else if (ConstantPoolSDNode *CP = dyn_cast<ConstantPoolSDNode>(Op)) {
int Offset = CP->getOffset();
unsigned Align = CP->getAlignment();
@@ -306,9 +307,11 @@ void ScheduleDAGSDNodes::AddOperand(MachineInstr *MI, SDValue Op,
Idx = ConstPool->getConstantPoolIndex(CP->getMachineCPVal(), Align);
else
Idx = ConstPool->getConstantPoolIndex(CP->getConstVal(), Align);
- MI->addOperand(MachineOperand::CreateCPI(Idx, Offset));
+ MI->addOperand(MachineOperand::CreateCPI(Idx, Offset,
+ CP->getTargetFlags()));
} else if (ExternalSymbolSDNode *ES = dyn_cast<ExternalSymbolSDNode>(Op)) {
- MI->addOperand(MachineOperand::CreateES(ES->getSymbol()));
+ MI->addOperand(MachineOperand::CreateES(ES->getSymbol(), 0,
+ ES->getTargetFlags()));
} else {
assert(Op.getValueType() != MVT::Other &&
Op.getValueType() != MVT::Flag &&
@@ -335,7 +338,7 @@ getSuperRegisterRegClass(const TargetRegisterClass *TRC,
/// EmitSubregNode - Generate machine code for subreg nodes.
///
void ScheduleDAGSDNodes::EmitSubregNode(SDNode *Node,
- DenseMap<SDValue, unsigned> &VRBaseMap) {
+ DenseMap<SDValue, unsigned> &VRBaseMap){
unsigned VRBase = 0;
unsigned Opc = Node->getMachineOpcode();
diff --git a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
index ce01d53..0342f67 100644
--- a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
+++ b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
@@ -31,8 +31,10 @@
#include "llvm/Target/TargetInstrInfo.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/ManagedStatic.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/raw_ostream.h"
+#include "llvm/System/Mutex.h"
#include "llvm/ADT/SetVector.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallSet.h"
@@ -359,6 +361,9 @@ static void AddNodeIDNode(FoldingSetNodeID &ID,
/// the NodeID data.
static void AddNodeIDCustom(FoldingSetNodeID &ID, const SDNode *N) {
switch (N->getOpcode()) {
+ case ISD::TargetExternalSymbol:
+ case ISD::ExternalSymbol:
+ assert(0 && "Should only be used on nodes with operands");
default: break; // Normal nodes don't need extra info.
case ISD::ARG_FLAGS:
ID.AddInteger(cast<ARG_FLAGSSDNode>(N)->getArgFlags().getRawBits());
@@ -379,6 +384,7 @@ static void AddNodeIDCustom(FoldingSetNodeID &ID, const SDNode *N) {
const GlobalAddressSDNode *GA = cast<GlobalAddressSDNode>(N);
ID.AddPointer(GA->getGlobal());
ID.AddInteger(GA->getOffset());
+ ID.AddInteger(GA->getTargetFlags());
break;
}
case ISD::BasicBlock:
@@ -409,6 +415,7 @@ static void AddNodeIDCustom(FoldingSetNodeID &ID, const SDNode *N) {
case ISD::JumpTable:
case ISD::TargetJumpTable:
ID.AddInteger(cast<JumpTableSDNode>(N)->getIndex());
+ ID.AddInteger(cast<JumpTableSDNode>(N)->getTargetFlags());
break;
case ISD::ConstantPool:
case ISD::TargetConstantPool: {
@@ -419,6 +426,7 @@ static void AddNodeIDCustom(FoldingSetNodeID &ID, const SDNode *N) {
CP->getMachineCPVal()->AddSelectionDAGCSEId(ID);
else
ID.AddPointer(CP->getConstVal());
+ ID.AddInteger(CP->getTargetFlags());
break;
}
case ISD::CALL: {
@@ -630,10 +638,13 @@ bool SelectionDAG::RemoveNodeFromCSEMaps(SDNode *N) {
case ISD::ExternalSymbol:
Erased = ExternalSymbols.erase(cast<ExternalSymbolSDNode>(N)->getSymbol());
break;
- case ISD::TargetExternalSymbol:
- Erased =
- TargetExternalSymbols.erase(cast<ExternalSymbolSDNode>(N)->getSymbol());
+ case ISD::TargetExternalSymbol: {
+ ExternalSymbolSDNode *ESN = cast<ExternalSymbolSDNode>(N);
+ Erased = TargetExternalSymbols.erase(
+ std::pair<std::string,unsigned char>(ESN->getSymbol(),
+ ESN->getTargetFlags()));
break;
+ }
case ISD::VALUETYPE: {
MVT VT = cast<VTSDNode>(N)->getVT();
if (VT.isExtended()) {
@@ -953,9 +964,11 @@ SDValue SelectionDAG::getConstantFP(double Val, MVT VT, bool isTarget) {
SDValue SelectionDAG::getGlobalAddress(const GlobalValue *GV,
MVT VT, int64_t Offset,
- bool isTargetGA) {
- unsigned Opc;
-
+ bool isTargetGA,
+ unsigned char TargetFlags) {
+ assert((TargetFlags == 0 || isTargetGA) &&
+ "Cannot set target flags on target-independent globals");
+
// Truncate (with sign-extension) the offset value to the pointer size.
unsigned BitWidth = TLI.getPointerTy().getSizeInBits();
if (BitWidth < 64)
@@ -968,6 +981,7 @@ SDValue SelectionDAG::getGlobalAddress(const GlobalValue *GV,
GVar = dyn_cast_or_null<GlobalVariable>(GA->resolveAliasedGlobal(false));
}
+ unsigned Opc;
if (GVar && GVar->isThreadLocal())
Opc = isTargetGA ? ISD::TargetGlobalTLSAddress : ISD::GlobalTLSAddress;
else
@@ -977,11 +991,12 @@ SDValue SelectionDAG::getGlobalAddress(const GlobalValue *GV,
AddNodeIDNode(ID, Opc, getVTList(VT), 0, 0);
ID.AddPointer(GV);
ID.AddInteger(Offset);
+ ID.AddInteger(TargetFlags);
void *IP = 0;
if (SDNode *E = CSEMap.FindNodeOrInsertPos(ID, IP))
return SDValue(E, 0);
SDNode *N = NodeAllocator.Allocate<GlobalAddressSDNode>();
- new (N) GlobalAddressSDNode(isTargetGA, GV, VT, Offset);
+ new (N) GlobalAddressSDNode(Opc, GV, VT, Offset, TargetFlags);
CSEMap.InsertNode(N, IP);
AllNodes.push_back(N);
return SDValue(N, 0);
@@ -1002,16 +1017,20 @@ SDValue SelectionDAG::getFrameIndex(int FI, MVT VT, bool isTarget) {
return SDValue(N, 0);
}
-SDValue SelectionDAG::getJumpTable(int JTI, MVT VT, bool isTarget){
+SDValue SelectionDAG::getJumpTable(int JTI, MVT VT, bool isTarget,
+ unsigned char TargetFlags) {
+ assert((TargetFlags == 0 || isTarget) &&
+ "Cannot set target flags on target-independent jump tables");
unsigned Opc = isTarget ? ISD::TargetJumpTable : ISD::JumpTable;
FoldingSetNodeID ID;
AddNodeIDNode(ID, Opc, getVTList(VT), 0, 0);
ID.AddInteger(JTI);
+ ID.AddInteger(TargetFlags);
void *IP = 0;
if (SDNode *E = CSEMap.FindNodeOrInsertPos(ID, IP))
return SDValue(E, 0);
SDNode *N = NodeAllocator.Allocate<JumpTableSDNode>();
- new (N) JumpTableSDNode(JTI, VT, isTarget);
+ new (N) JumpTableSDNode(JTI, VT, isTarget, TargetFlags);
CSEMap.InsertNode(N, IP);
AllNodes.push_back(N);
return SDValue(N, 0);
@@ -1019,7 +1038,10 @@ SDValue SelectionDAG::getJumpTable(int JTI, MVT VT, bool isTarget){
SDValue SelectionDAG::getConstantPool(Constant *C, MVT VT,
unsigned Alignment, int Offset,
- bool isTarget) {
+ bool isTarget,
+ unsigned char TargetFlags) {
+ assert((TargetFlags == 0 || isTarget) &&
+ "Cannot set target flags on target-independent globals");
if (Alignment == 0)
Alignment = TLI.getTargetData()->getPrefTypeAlignment(C->getType());
unsigned Opc = isTarget ? ISD::TargetConstantPool : ISD::ConstantPool;
@@ -1028,11 +1050,12 @@ SDValue SelectionDAG::getConstantPool(Constant *C, MVT VT,
ID.AddInteger(Alignment);
ID.AddInteger(Offset);
ID.AddPointer(C);
+ ID.AddInteger(TargetFlags);
void *IP = 0;
if (SDNode *E = CSEMap.FindNodeOrInsertPos(ID, IP))
return SDValue(E, 0);
SDNode *N = NodeAllocator.Allocate<ConstantPoolSDNode>();
- new (N) ConstantPoolSDNode(isTarget, C, VT, Offset, Alignment);
+ new (N) ConstantPoolSDNode(isTarget, C, VT, Offset, Alignment, TargetFlags);
CSEMap.InsertNode(N, IP);
AllNodes.push_back(N);
return SDValue(N, 0);
@@ -1041,7 +1064,10 @@ SDValue SelectionDAG::getConstantPool(Constant *C, MVT VT,
SDValue SelectionDAG::getConstantPool(MachineConstantPoolValue *C, MVT VT,
unsigned Alignment, int Offset,
- bool isTarget) {
+ bool isTarget,
+ unsigned char TargetFlags) {
+ assert((TargetFlags == 0 || isTarget) &&
+ "Cannot set target flags on target-independent globals");
if (Alignment == 0)
Alignment = TLI.getTargetData()->getPrefTypeAlignment(C->getType());
unsigned Opc = isTarget ? ISD::TargetConstantPool : ISD::ConstantPool;
@@ -1050,11 +1076,12 @@ SDValue SelectionDAG::getConstantPool(MachineConstantPoolValue *C, MVT VT,
ID.AddInteger(Alignment);
ID.AddInteger(Offset);
C->AddSelectionDAGCSEId(ID);
+ ID.AddInteger(TargetFlags);
void *IP = 0;
if (SDNode *E = CSEMap.FindNodeOrInsertPos(ID, IP))
return SDValue(E, 0);
SDNode *N = NodeAllocator.Allocate<ConstantPoolSDNode>();
- new (N) ConstantPoolSDNode(isTarget, C, VT, Offset, Alignment);
+ new (N) ConstantPoolSDNode(isTarget, C, VT, Offset, Alignment, TargetFlags);
CSEMap.InsertNode(N, IP);
AllNodes.push_back(N);
return SDValue(N, 0);
@@ -1106,16 +1133,19 @@ SDValue SelectionDAG::getExternalSymbol(const char *Sym, MVT VT) {
SDNode *&N = ExternalSymbols[Sym];
if (N) return SDValue(N, 0);
N = NodeAllocator.Allocate<ExternalSymbolSDNode>();
- new (N) ExternalSymbolSDNode(false, Sym, VT);
+ new (N) ExternalSymbolSDNode(false, Sym, 0, VT);
AllNodes.push_back(N);
return SDValue(N, 0);
}
-SDValue SelectionDAG::getTargetExternalSymbol(const char *Sym, MVT VT) {
- SDNode *&N = TargetExternalSymbols[Sym];
+SDValue SelectionDAG::getTargetExternalSymbol(const char *Sym, MVT VT,
+ unsigned char TargetFlags) {
+ SDNode *&N =
+ TargetExternalSymbols[std::pair<std::string,unsigned char>(Sym,
+ TargetFlags)];
if (N) return SDValue(N, 0);
N = NodeAllocator.Allocate<ExternalSymbolSDNode>();
- new (N) ExternalSymbolSDNode(true, Sym, VT);
+ new (N) ExternalSymbolSDNode(true, Sym, TargetFlags, VT);
AllNodes.push_back(N);
return SDValue(N, 0);
}
@@ -3181,27 +3211,17 @@ static SDValue getMemcpyLoadsAndStores(SelectionDAG &DAG, DebugLoc dl,
} 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
- // thing to do is generate a LoadExt/StoreTrunc pair.
+ // thing to do is generate a LoadExt/StoreTrunc pair. These simplify
+ // to Load/Store if NVT==VT.
// FIXME does the case above also need this?
- if (TLI.isTypeLegal(VT)) {
- Value = DAG.getLoad(VT, dl, Chain,
- getMemBasePlusOffset(Src, SrcOff, DAG),
- SrcSV, SrcSVOff + SrcOff, false, Align);
- Store = DAG.getStore(Chain, dl, Value,
+ MVT NVT = TLI.getTypeToTransformTo(VT);
+ assert(NVT.bitsGE(VT));
+ Value = DAG.getExtLoad(ISD::EXTLOAD, dl, NVT, Chain,
+ getMemBasePlusOffset(Src, SrcOff, DAG),
+ SrcSV, SrcSVOff + SrcOff, VT, false, Align);
+ Store = DAG.getTruncStore(Chain, dl, Value,
getMemBasePlusOffset(Dst, DstOff, DAG),
- DstSV, DstSVOff + DstOff, false, DstAlign);
- } else {
- MVT NVT = VT;
- while (!TLI.isTypeLegal(NVT)) {
- NVT = (MVT::SimpleValueType(NVT.getSimpleVT() + 1));
- }
- Value = DAG.getExtLoad(ISD::EXTLOAD, dl, NVT, Chain,
- getMemBasePlusOffset(Src, SrcOff, DAG),
- SrcSV, SrcSVOff + SrcOff, VT, false, Align);
- Store = DAG.getTruncStore(Chain, dl, Value,
- getMemBasePlusOffset(Dst, DstOff, DAG),
- DstSV, DstSVOff + DstOff, VT, false, DstAlign);
- }
+ DstSV, DstSVOff + DstOff, VT, false, DstAlign);
}
OutChains.push_back(Store);
SrcOff += VTSize;
@@ -4915,15 +4935,10 @@ HandleSDNode::~HandleSDNode() {
DropOperands();
}
-GlobalAddressSDNode::GlobalAddressSDNode(bool isTarget, const GlobalValue *GA,
- MVT VT, int64_t o)
- : SDNode(isa<GlobalVariable>(GA) &&
- cast<GlobalVariable>(GA)->isThreadLocal() ?
- // Thread Local
- (isTarget ? ISD::TargetGlobalTLSAddress : ISD::GlobalTLSAddress) :
- // Non Thread Local
- (isTarget ? ISD::TargetGlobalAddress : ISD::GlobalAddress),
- DebugLoc::getUnknownLoc(), getSDVTList(VT)), Offset(o) {
+GlobalAddressSDNode::GlobalAddressSDNode(unsigned Opc, const GlobalValue *GA,
+ MVT VT, int64_t o, unsigned char TF)
+ : SDNode(Opc, DebugLoc::getUnknownLoc(), getSDVTList(VT)),
+ Offset(o), TargetFlags(TF) {
TheGlobal = const_cast<GlobalValue*>(GA);
}
@@ -4987,14 +5002,17 @@ void SDNode::Profile(FoldingSetNodeID &ID) const {
AddNodeIDNode(ID, this);
}
+static ManagedStatic<std::set<MVT, MVT::compareRawBits> > EVTs;
+static MVT VTs[MVT::LAST_VALUETYPE];
+static ManagedStatic<sys::SmartMutex<true> > VTMutex;
+
/// getValueTypeList - Return a pointer to the specified value type.
///
const MVT *SDNode::getValueTypeList(MVT VT) {
+ sys::SmartScopedLock<true> Lock(&*VTMutex);
if (VT.isExtended()) {
- static std::set<MVT, MVT::compareRawBits> EVTs;
- return &(*EVTs.insert(VT).first);
+ return &(*EVTs->insert(VT).first);
} else {
- static MVT VTs[MVT::LAST_VALUETYPE];
VTs[VT.getSimpleVT()] = VT;
return &VTs[VT.getSimpleVT()];
}
@@ -5486,10 +5504,14 @@ void SDNode::print_details(raw_ostream &OS, const SelectionDAG *G) const {
OS << " + " << offset;
else
OS << " " << offset;
+ if (unsigned char TF = GADN->getTargetFlags())
+ OS << " [TF=" << TF << ']';
} else if (const FrameIndexSDNode *FIDN = dyn_cast<FrameIndexSDNode>(this)) {
OS << "<" << FIDN->getIndex() << ">";
} else if (const JumpTableSDNode *JTDN = dyn_cast<JumpTableSDNode>(this)) {
OS << "<" << JTDN->getIndex() << ">";
+ if (unsigned char TF = JTDN->getTargetFlags())
+ OS << " [TF=" << TF << ']';
} else if (const ConstantPoolSDNode *CP = dyn_cast<ConstantPoolSDNode>(this)){
int offset = CP->getOffset();
if (CP->isMachineConstantPoolEntry())
@@ -5500,6 +5522,8 @@ void SDNode::print_details(raw_ostream &OS, const SelectionDAG *G) const {
OS << " + " << offset;
else
OS << " " << offset;
+ if (unsigned char TF = CP->getTargetFlags())
+ OS << " [TF=" << TF << ']';
} else if (const BasicBlockSDNode *BBDN = dyn_cast<BasicBlockSDNode>(this)) {
OS << "<";
const Value *LBB = (const Value*)BBDN->getBasicBlock()->getBasicBlock();
@@ -5516,6 +5540,8 @@ void SDNode::print_details(raw_ostream &OS, const SelectionDAG *G) const {
} else if (const ExternalSymbolSDNode *ES =
dyn_cast<ExternalSymbolSDNode>(this)) {
OS << "'" << ES->getSymbol() << "'";
+ if (unsigned char TF = ES->getTargetFlags())
+ OS << " [TF=" << TF << ']';
} else if (const SrcValueSDNode *M = dyn_cast<SrcValueSDNode>(this)) {
if (M->getValue())
OS << "<" << M->getValue() << ">";
diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGPrinter.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGPrinter.cpp
index 3eec684..6fd5df2 100644
--- a/lib/CodeGen/SelectionDAG/SelectionDAGPrinter.cpp
+++ b/lib/CodeGen/SelectionDAG/SelectionDAGPrinter.cpp
@@ -94,7 +94,8 @@ namespace llvm {
static std::string getNodeLabel(const SDNode *Node,
- const SelectionDAG *Graph);
+ const SelectionDAG *Graph,
+ bool ShortNames);
static std::string getNodeAttributes(const SDNode *N,
const SelectionDAG *Graph) {
#ifndef NDEBUG
@@ -120,139 +121,14 @@ namespace llvm {
}
std::string DOTGraphTraits<SelectionDAG*>::getNodeLabel(const SDNode *Node,
- const SelectionDAG *G) {
- std::string Op = Node->getOperationName(G);
-
- if (const ConstantSDNode *CSDN = dyn_cast<ConstantSDNode>(Node)) {
- Op += ": " + utostr(CSDN->getZExtValue());
- } else if (const ConstantFPSDNode *CSDN = dyn_cast<ConstantFPSDNode>(Node)) {
- Op += ": " + ftostr(CSDN->getValueAPF());
- } else if (const GlobalAddressSDNode *GADN =
- dyn_cast<GlobalAddressSDNode>(Node)) {
- Op += ": " + GADN->getGlobal()->getName();
- if (int64_t Offset = GADN->getOffset()) {
- if (Offset > 0)
- Op += "+" + itostr(Offset);
- else
- Op += itostr(Offset);
- }
- } else if (const FrameIndexSDNode *FIDN = dyn_cast<FrameIndexSDNode>(Node)) {
- Op += " " + itostr(FIDN->getIndex());
- } else if (const JumpTableSDNode *JTDN = dyn_cast<JumpTableSDNode>(Node)) {
- Op += " " + itostr(JTDN->getIndex());
- } else if (const ConstantPoolSDNode *CP = dyn_cast<ConstantPoolSDNode>(Node)){
- if (CP->isMachineConstantPoolEntry()) {
- Op += '<';
- {
- raw_string_ostream OSS(Op);
- OSS << *CP->getMachineCPVal();
- }
- Op += '>';
- } else {
- if (ConstantFP *CFP = dyn_cast<ConstantFP>(CP->getConstVal()))
- Op += "<" + ftostr(CFP->getValueAPF()) + ">";
- else if (ConstantInt *CI = dyn_cast<ConstantInt>(CP->getConstVal()))
- Op += "<" + utostr(CI->getZExtValue()) + ">";
- else {
- Op += '<';
- {
- raw_string_ostream OSS(Op);
- WriteAsOperand(OSS, CP->getConstVal(), false);
- }
- Op += '>';
- }
- }
- Op += " A=" + itostr(CP->getAlignment());
- } else if (const BasicBlockSDNode *BBDN = dyn_cast<BasicBlockSDNode>(Node)) {
- Op = "BB: ";
- const Value *LBB = (const Value*)BBDN->getBasicBlock()->getBasicBlock();
- if (LBB)
- Op += LBB->getName();
- //Op += " " + (const void*)BBDN->getBasicBlock();
- } else if (const RegisterSDNode *R = dyn_cast<RegisterSDNode>(Node)) {
- if (G && R->getReg() != 0 &&
- TargetRegisterInfo::isPhysicalRegister(R->getReg())) {
- Op = Op + " " +
- G->getTarget().getRegisterInfo()->getName(R->getReg());
- } else {
- Op += " #" + utostr(R->getReg());
- }
- } else if (const DbgStopPointSDNode *D = dyn_cast<DbgStopPointSDNode>(Node)) {
- DICompileUnit CU(cast<GlobalVariable>(D->getCompileUnit()));
- std::string FN;
- Op += ": " + CU.getFilename(FN);
- Op += ":" + utostr(D->getLine());
- if (D->getColumn() != 0)
- Op += ":" + utostr(D->getColumn());
- } else if (const LabelSDNode *L = dyn_cast<LabelSDNode>(Node)) {
- Op += ": LabelID=" + utostr(L->getLabelID());
- } else if (const CallSDNode *C = dyn_cast<CallSDNode>(Node)) {
- Op += ": CallingConv=" + utostr(C->getCallingConv());
- if (C->isVarArg())
- Op += ", isVarArg";
- if (C->isTailCall())
- Op += ", isTailCall";
- } else if (const ExternalSymbolSDNode *ES =
- dyn_cast<ExternalSymbolSDNode>(Node)) {
- Op += "'" + std::string(ES->getSymbol()) + "'";
- } else if (const SrcValueSDNode *M = dyn_cast<SrcValueSDNode>(Node)) {
- if (M->getValue())
- Op += "<" + M->getValue()->getName() + ">";
- else
- Op += "<null>";
- } else if (const MemOperandSDNode *M = dyn_cast<MemOperandSDNode>(Node)) {
- const Value *V = M->MO.getValue();
- Op += '<';
- if (!V) {
- Op += "(unknown)";
- } else if (const PseudoSourceValue *PSV = dyn_cast<PseudoSourceValue>(V)) {
- // PseudoSourceValues don't have names, so use their print method.
- raw_string_ostream OSS(Op);
- PSV->print(OSS);
- } else {
- Op += V->getName();
- }
- Op += '+' + itostr(M->MO.getOffset()) + '>';
- } else if (const ARG_FLAGSSDNode *N = dyn_cast<ARG_FLAGSSDNode>(Node)) {
- Op = Op + " AF=" + N->getArgFlags().getArgFlagsString();
- } else if (const VTSDNode *N = dyn_cast<VTSDNode>(Node)) {
- Op = Op + " VT=" + N->getVT().getMVTString();
- } else if (const LoadSDNode *LD = dyn_cast<LoadSDNode>(Node)) {
- bool doExt = true;
- switch (LD->getExtensionType()) {
- default: doExt = false; break;
- case ISD::EXTLOAD:
- Op = Op + "<anyext ";
- break;
- case ISD::SEXTLOAD:
- Op = Op + " <sext ";
- break;
- case ISD::ZEXTLOAD:
- Op = Op + " <zext ";
- break;
- }
- if (doExt)
- Op += LD->getMemoryVT().getMVTString() + ">";
- if (LD->isVolatile())
- Op += "<V>";
- Op += LD->getIndexedModeName(LD->getAddressingMode());
- if (LD->getAlignment() > 1)
- Op += " A=" + utostr(LD->getAlignment());
- } else if (const StoreSDNode *ST = dyn_cast<StoreSDNode>(Node)) {
- if (ST->isTruncatingStore())
- Op += "<trunc " + ST->getMemoryVT().getMVTString() + ">";
- if (ST->isVolatile())
- Op += "<V>";
- Op += ST->getIndexedModeName(ST->getAddressingMode());
- if (ST->getAlignment() > 1)
- Op += " A=" + utostr(ST->getAlignment());
+ const SelectionDAG *G,
+ bool ShortNames) {
+ std::string Result = Node->getOperationName(G);
+ {
+ raw_string_ostream OS(Result);
+ Node->print_details(OS, G);
}
-
-#if 0
- Op += " Id=" + itostr(Node->getNodeId());
-#endif
-
- return Op;
+ return Result;
}
@@ -262,7 +138,7 @@ std::string DOTGraphTraits<SelectionDAG*>::getNodeLabel(const SDNode *Node,
void SelectionDAG::viewGraph(const std::string &Title) {
// This code is only for debugging!
#ifndef NDEBUG
- ViewGraph(this, "dag." + getMachineFunction().getFunction()->getName(),
+ ViewGraph(this, "dag." + getMachineFunction().getFunction()->getName(), false,
Title);
#else
cerr << "SelectionDAG::viewGraph is only available in debug builds on "
@@ -393,7 +269,8 @@ std::string ScheduleDAGSDNodes::getGraphNodeLabel(const SUnit *SU) const {
for (SDNode *N = SU->getNode(); N; N = N->getFlaggedNode())
FlaggedNodes.push_back(N);
while (!FlaggedNodes.empty()) {
- O << DOTGraphTraits<SelectionDAG*>::getNodeLabel(FlaggedNodes.back(), DAG);
+ O << DOTGraphTraits<SelectionDAG*>::getNodeLabel(FlaggedNodes.back(),
+ DAG, false);
FlaggedNodes.pop_back();
if (!FlaggedNodes.empty())
O << "\n ";
diff --git a/lib/CodeGen/SelectionDAG/TargetLowering.cpp b/lib/CodeGen/SelectionDAG/TargetLowering.cpp
index a771d46..83357e0 100644
--- a/lib/CodeGen/SelectionDAG/TargetLowering.cpp
+++ b/lib/CodeGen/SelectionDAG/TargetLowering.cpp
@@ -527,7 +527,7 @@ TargetLowering::~TargetLowering() {}
/// computeRegisterProperties - Once all of the register classes are added,
/// this allows us to compute derived properties we expose.
void TargetLowering::computeRegisterProperties() {
- assert(MVT::LAST_VALUETYPE <= 32 &&
+ assert(MVT::LAST_VALUETYPE <= MVT::MAX_ALLOWED_VALUETYPE &&
"Too many value types for ValueTypeActions to hold!");
// Everything defaults to needing one register.
diff --git a/lib/CodeGen/Spiller.cpp b/lib/CodeGen/Spiller.cpp
index 919a0ce..405cd80 100644
--- a/lib/CodeGen/Spiller.cpp
+++ b/lib/CodeGen/Spiller.cpp
@@ -78,24 +78,21 @@ protected:
return miIdx;
}
-
/// Insert a store of the given vreg to the given stack slot immediately
/// after the given instruction. Returns the base index of the inserted
/// instruction. The caller is responsible for adding an appropriate
/// LiveInterval to the LiveIntervals analysis.
- unsigned insertStoreFor(MachineInstr *mi, unsigned ss,
+ unsigned insertStoreAfter(MachineInstr *mi, unsigned ss,
unsigned vreg,
const TargetRegisterClass *trc) {
- MachineBasicBlock::iterator nextInstItr(mi);
- ++nextInstItr;
+ MachineBasicBlock::iterator nextInstItr(next(mi));
unsigned miIdx = makeSpaceAfter(mi);
tii->storeRegToStackSlot(*mi->getParent(), nextInstItr, vreg,
true, ss, trc);
- MachineBasicBlock::iterator storeInstItr(mi);
- ++storeInstItr;
+ MachineBasicBlock::iterator storeInstItr(next(mi));
MachineInstr *storeInst = &*storeInstItr;
unsigned storeInstIdx = miIdx + LiveInterval::InstrSlots::NUM;
@@ -107,37 +104,81 @@ protected:
return storeInstIdx;
}
- void insertStoreOnInterval(LiveInterval *li,
- MachineInstr *mi, unsigned ss,
- unsigned vreg,
- const TargetRegisterClass *trc) {
+ /// Insert a store of the given vreg to the given stack slot immediately
+ /// before the given instructnion. Returns the base index of the inserted
+ /// Instruction.
+ unsigned insertStoreBefore(MachineInstr *mi, unsigned ss,
+ unsigned vreg,
+ const TargetRegisterClass *trc) {
+ unsigned miIdx = makeSpaceBefore(mi);
+
+ tii->storeRegToStackSlot(*mi->getParent(), mi, vreg, true, ss, trc);
+ MachineBasicBlock::iterator storeInstItr(prior(mi));
+ MachineInstr *storeInst = &*storeInstItr;
+ unsigned storeInstIdx = miIdx - LiveInterval::InstrSlots::NUM;
+
+ assert(lis->getInstructionFromIndex(storeInstIdx) == 0 &&
+ "Store inst index already in use.");
+
+ lis->InsertMachineInstrInMaps(storeInst, storeInstIdx);
+
+ return storeInstIdx;
+ }
+
+ void insertStoreAfterInstOnInterval(LiveInterval *li,
+ MachineInstr *mi, unsigned ss,
+ unsigned vreg,
+ const TargetRegisterClass *trc) {
- unsigned storeInstIdx = insertStoreFor(mi, ss, vreg, trc);
+ unsigned storeInstIdx = insertStoreAfter(mi, ss, vreg, trc);
unsigned start = lis->getDefIndex(lis->getInstructionIndex(mi)),
end = lis->getUseIndex(storeInstIdx);
VNInfo *vni =
li->getNextValue(storeInstIdx, 0, true, lis->getVNInfoAllocator());
vni->kills.push_back(storeInstIdx);
+ DOUT << " Inserting store range: [" << start << ", " << end << ")\n";
LiveRange lr(start, end, vni);
li->addRange(lr);
}
- /// Insert a load of the given veg from the given stack slot immediately
+ /// Insert a load of the given vreg from the given stack slot immediately
+ /// after the given instruction. Returns the base index of the inserted
+ /// instruction. The caller is responsibel for adding/removing an appropriate
+ /// range vreg's LiveInterval.
+ unsigned insertLoadAfter(MachineInstr *mi, unsigned ss,
+ unsigned vreg,
+ const TargetRegisterClass *trc) {
+
+ MachineBasicBlock::iterator nextInstItr(next(mi));
+
+ unsigned miIdx = makeSpaceAfter(mi);
+
+ tii->loadRegFromStackSlot(*mi->getParent(), nextInstItr, vreg, ss, trc);
+ MachineBasicBlock::iterator loadInstItr(next(mi));
+ MachineInstr *loadInst = &*loadInstItr;
+ unsigned loadInstIdx = miIdx + LiveInterval::InstrSlots::NUM;
+
+ assert(lis->getInstructionFromIndex(loadInstIdx) == 0 &&
+ "Store inst index already in use.");
+
+ lis->InsertMachineInstrInMaps(loadInst, loadInstIdx);
+
+ return loadInstIdx;
+ }
+
+ /// Insert a load of the given vreg from the given stack slot immediately
/// before the given instruction. Returns the base index of the inserted
/// instruction. The caller is responsible for adding an appropriate
/// LiveInterval to the LiveIntervals analysis.
- unsigned insertLoadFor(MachineInstr *mi, unsigned ss,
- unsigned vreg,
- const TargetRegisterClass *trc) {
- MachineBasicBlock::iterator useInstItr(mi);
-
+ unsigned insertLoadBefore(MachineInstr *mi, unsigned ss,
+ unsigned vreg,
+ const TargetRegisterClass *trc) {
unsigned miIdx = makeSpaceBefore(mi);
- tii->loadRegFromStackSlot(*mi->getParent(), useInstItr, vreg, ss, trc);
- MachineBasicBlock::iterator loadInstItr(mi);
- --loadInstItr;
+ tii->loadRegFromStackSlot(*mi->getParent(), mi, vreg, ss, trc);
+ MachineBasicBlock::iterator loadInstItr(prior(mi));
MachineInstr *loadInst = &*loadInstItr;
unsigned loadInstIdx = miIdx - LiveInterval::InstrSlots::NUM;
@@ -149,18 +190,19 @@ protected:
return loadInstIdx;
}
- void insertLoadOnInterval(LiveInterval *li,
- MachineInstr *mi, unsigned ss,
- unsigned vreg,
- const TargetRegisterClass *trc) {
+ void insertLoadBeforeInstOnInterval(LiveInterval *li,
+ MachineInstr *mi, unsigned ss,
+ unsigned vreg,
+ const TargetRegisterClass *trc) {
- unsigned loadInstIdx = insertLoadFor(mi, ss, vreg, trc);
+ unsigned loadInstIdx = insertLoadBefore(mi, ss, vreg, trc);
unsigned start = lis->getDefIndex(loadInstIdx),
end = lis->getUseIndex(lis->getInstructionIndex(mi));
VNInfo *vni =
li->getNextValue(loadInstIdx, 0, true, lis->getVNInfoAllocator());
vni->kills.push_back(lis->getInstructionIndex(mi));
+ DOUT << " Intserting load range: [" << start << ", " << end << ")\n";
LiveRange lr(start, end, vni);
li->addRange(lr);
@@ -180,6 +222,8 @@ protected:
assert(!li->isStackSlot() &&
"Trying to spill a stack slot.");
+ DOUT << "Trivial spill everywhere of reg" << li->reg << "\n";
+
std::vector<LiveInterval*> added;
const TargetRegisterClass *trc = mri->getRegClass(li->reg);
@@ -189,6 +233,9 @@ protected:
regItr = mri->reg_begin(li->reg); regItr != mri->reg_end();) {
MachineInstr *mi = &*regItr;
+
+ DOUT << " Processing " << *mi;
+
do {
++regItr;
} while (regItr != mri->reg_end() && (&*regItr == mi));
@@ -227,11 +274,11 @@ protected:
assert(hasUse || hasDef);
if (hasUse) {
- insertLoadOnInterval(newLI, mi, ss, newVReg, trc);
+ insertLoadBeforeInstOnInterval(newLI, mi, ss, newVReg, trc);
}
if (hasDef) {
- insertStoreOnInterval(newLI, mi, ss, newVReg, trc);
+ insertStoreAfterInstOnInterval(newLI, mi, ss, newVReg, trc);
}
added.push_back(newLI);
@@ -258,29 +305,53 @@ public:
std::vector<LiveInterval*> intraBlockSplit(LiveInterval *li, VNInfo *valno) {
std::vector<LiveInterval*> spillIntervals;
- MachineBasicBlock::iterator storeInsertPoint;
+
+ if (!valno->isDefAccurate() && !valno->isPHIDef()) {
+ // Early out for values which have no well defined def point.
+ return spillIntervals;
+ }
+
+ // Ok.. we should be able to proceed...
+ const TargetRegisterClass *trc = mri->getRegClass(li->reg);
+ unsigned ss = vrm->assignVirt2StackSlot(li->reg);
+ vrm->grow();
+ vrm->assignVirt2StackSlot(li->reg, ss);
+
+ MachineInstr *mi = 0;
+ unsigned storeIdx = 0;
if (valno->isDefAccurate()) {
// If we have an accurate def we can just grab an iterator to the instr
// after the def.
- storeInsertPoint =
- next(MachineBasicBlock::iterator(lis->getInstructionFromIndex(valno->def)));
+ mi = lis->getInstructionFromIndex(valno->def);
+ storeIdx = insertStoreAfter(mi, ss, li->reg, trc) +
+ LiveInterval::InstrSlots::DEF;
} else {
- // If the def info isn't accurate we check if this is a PHI def.
- // If it is then def holds the index of the defining Basic Block, and we
- // can use that to get an insertion point.
- if (valno->isPHIDef()) {
-
- } else {
- // We have no usable def info. We can't split this value sensibly.
- // FIXME: Need sensible feedback for "failure to split", an empty
- // set of spill intervals could be reasonably returned from a
- // split where both the store and load are folded.
- return spillIntervals;
- }
+ // if we get here we have a PHI def.
+ mi = &lis->getMBBFromIndex(valno->def)->front();
+ storeIdx = insertStoreBefore(mi, ss, li->reg, trc) +
+ LiveInterval::InstrSlots::DEF;
+ }
+
+ MachineBasicBlock *defBlock = mi->getParent();
+ unsigned loadIdx = 0;
+
+ // Now we need to find the load...
+ MachineBasicBlock::iterator useItr(mi);
+ for (; !useItr->readsRegister(li->reg); ++useItr) {}
+
+ if (useItr != defBlock->end()) {
+ MachineInstr *loadInst = useItr;
+ loadIdx = insertLoadBefore(loadInst, ss, li->reg, trc) +
+ LiveInterval::InstrSlots::USE;
+ }
+ else {
+ MachineInstr *loadInst = &defBlock->back();
+ loadIdx = insertLoadAfter(loadInst, ss, li->reg, trc) +
+ LiveInterval::InstrSlots::USE;
}
-
+ li->removeRange(storeIdx, loadIdx, true);
return spillIntervals;
}
diff --git a/lib/CodeGen/VirtRegRewriter.h b/lib/CodeGen/VirtRegRewriter.h
index bc830f7..f9d7fbb 100644
--- a/lib/CodeGen/VirtRegRewriter.h
+++ b/lib/CodeGen/VirtRegRewriter.h
@@ -32,11 +32,6 @@
#include "VirtRegMap.h"
#include <map>
-// TODO:
-// - Finish renaming Spiller -> Rewriter
-// - SimpleSpiller
-// - LocalSpiller
-
namespace llvm {
/// VirtRegRewriter interface: Implementations of this interface assign
OpenPOWER on IntegriCloud