diff options
Diffstat (limited to 'lib/CodeGen')
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 |