X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FTarget%2FX86%2FX86TargetMachine.cpp;h=c3b236aae2e0496f848f3ec21470328fcf8c7636;hb=beb6898df8f96ccea4ae147587479b507bb3e491;hp=53c46c3595ed5ed96fafbb027e36dfd450691636;hpb=1555a23335400143f2b54a66aedc4b5cbbb79f8d;p=oota-llvm.git diff --git a/lib/Target/X86/X86TargetMachine.cpp b/lib/Target/X86/X86TargetMachine.cpp index 53c46c3595e..c3b236aae2e 100644 --- a/lib/Target/X86/X86TargetMachine.cpp +++ b/lib/Target/X86/X86TargetMachine.cpp @@ -11,174 +11,178 @@ // //===----------------------------------------------------------------------===// -#include "X86TargetAsmInfo.h" +#include "X86MCAsmInfo.h" #include "X86TargetMachine.h" #include "X86.h" -#include "llvm/Module.h" #include "llvm/PassManager.h" #include "llvm/CodeGen/MachineFunction.h" #include "llvm/CodeGen/Passes.h" -#include "llvm/Support/raw_ostream.h" +#include "llvm/MC/MCCodeEmitter.h" +#include "llvm/MC/MCStreamer.h" +#include "llvm/Support/FormattedStream.h" #include "llvm/Target/TargetOptions.h" -#include "llvm/Target/TargetMachineRegistry.h" +#include "llvm/Target/TargetRegistry.h" using namespace llvm; -/// X86TargetMachineModule - Note that this is used on hosts that cannot link -/// in a library unless there are references into the library. In particular, -/// it seems that it is not possible to get things to work on Win32 without -/// this. Though it is unused, do not remove it. -extern "C" int X86TargetMachineModule; -int X86TargetMachineModule = 0; - -// Register the target. -static RegisterTarget -X("x86", "32-bit X86: Pentium-Pro and above"); -static RegisterTarget -Y("x86-64", "64-bit X86: EM64T and AMD64"); - -// Force static initialization when called from llvm/InitializeAllTargets.h -namespace llvm { - void InitializeX86Target() { } -} - -// No assembler printer by default -X86TargetMachine::AsmPrinterCtorFn X86TargetMachine::AsmPrinterCtor = 0; - -const TargetAsmInfo *X86TargetMachine::createTargetAsmInfo() const { - if (Subtarget.isFlavorIntel()) - return new X86WinTargetAsmInfo(*this); - else - switch (Subtarget.TargetType) { - case X86Subtarget::isDarwin: - return new X86DarwinTargetAsmInfo(*this); - case X86Subtarget::isELF: - return new X86ELFTargetAsmInfo(*this); - case X86Subtarget::isMingw: - case X86Subtarget::isCygwin: - return new X86COFFTargetAsmInfo(*this); - case X86Subtarget::isWindows: - return new X86WinTargetAsmInfo(*this); - default: - return new X86GenericTargetAsmInfo(*this); - } -} - -unsigned X86_32TargetMachine::getJITMatchQuality() { -#if defined(i386) || defined(__i386__) || defined(__x86__) || defined(_M_IX86) - return 10; -#endif - return 0; +static MCAsmInfo *createMCAsmInfo(const Target &T, StringRef TT) { + Triple TheTriple(TT); + switch (TheTriple.getOS()) { + case Triple::Darwin: + return new X86MCAsmInfoDarwin(TheTriple); + case Triple::MinGW32: + case Triple::MinGW64: + case Triple::Cygwin: + case Triple::Win32: + return new X86MCAsmInfoCOFF(TheTriple); + default: + return new X86ELFMCAsmInfo(TheTriple); + } } -unsigned X86_64TargetMachine::getJITMatchQuality() { -#if defined(__x86_64__) || defined(_M_AMD64) - return 10; -#endif - return 0; +static MCStreamer *createMCStreamer(const Target &T, const std::string &TT, + MCContext &Ctx, TargetAsmBackend &TAB, + raw_ostream &_OS, + MCCodeEmitter *_Emitter, + bool RelaxAll) { + Triple TheTriple(TT); + switch (TheTriple.getOS()) { + case Triple::Darwin: + return createMachOStreamer(Ctx, TAB, _OS, _Emitter, RelaxAll); + case Triple::MinGW32: + case Triple::MinGW64: + case Triple::Cygwin: + case Triple::Win32: + return createWinCOFFStreamer(Ctx, TAB, *_Emitter, _OS, RelaxAll); + default: + return createELFStreamer(Ctx, TAB, _OS, _Emitter, RelaxAll); + } } -unsigned X86_32TargetMachine::getModuleMatchQuality(const Module &M) { - // We strongly match "i[3-9]86-*". - std::string TT = M.getTargetTriple(); - if (TT.size() >= 5 && TT[0] == 'i' && TT[2] == '8' && TT[3] == '6' && - TT[4] == '-' && TT[1] - '3' < 6) - return 20; - // If the target triple is something non-X86, we don't match. - if (!TT.empty()) return 0; - - if (M.getEndianness() == Module::LittleEndian && - M.getPointerSize() == Module::Pointer32) - return 10; // Weak match - else if (M.getEndianness() != Module::AnyEndianness || - M.getPointerSize() != Module::AnyPointerSize) - return 0; // Match for some other target - - return getJITMatchQuality()/2; +extern "C" void LLVMInitializeX86Target() { + // Register the target. + RegisterTargetMachine X(TheX86_32Target); + RegisterTargetMachine Y(TheX86_64Target); + + // Register the target asm info. + RegisterAsmInfoFn A(TheX86_32Target, createMCAsmInfo); + RegisterAsmInfoFn B(TheX86_64Target, createMCAsmInfo); + + // Register the code emitter. + TargetRegistry::RegisterCodeEmitter(TheX86_32Target, + createX86_32MCCodeEmitter); + TargetRegistry::RegisterCodeEmitter(TheX86_64Target, + createX86_64MCCodeEmitter); + + // Register the asm backend. + TargetRegistry::RegisterAsmBackend(TheX86_32Target, + createX86_32AsmBackend); + TargetRegistry::RegisterAsmBackend(TheX86_64Target, + createX86_64AsmBackend); + + // Register the object streamer. + TargetRegistry::RegisterObjectStreamer(TheX86_32Target, + createMCStreamer); + TargetRegistry::RegisterObjectStreamer(TheX86_64Target, + createMCStreamer); } -unsigned X86_64TargetMachine::getModuleMatchQuality(const Module &M) { - // We strongly match "x86_64-*". - std::string TT = M.getTargetTriple(); - if (TT.size() >= 7 && TT[0] == 'x' && TT[1] == '8' && TT[2] == '6' && - TT[3] == '_' && TT[4] == '6' && TT[5] == '4' && TT[6] == '-') - return 20; - - // We strongly match "amd64-*". - if (TT.size() >= 6 && TT[0] == 'a' && TT[1] == 'm' && TT[2] == 'd' && - TT[3] == '6' && TT[4] == '4' && TT[5] == '-') - return 20; - - // If the target triple is something non-X86-64, we don't match. - if (!TT.empty()) return 0; - - if (M.getEndianness() == Module::LittleEndian && - M.getPointerSize() == Module::Pointer64) - return 10; // Weak match - else if (M.getEndianness() != Module::AnyEndianness || - M.getPointerSize() != Module::AnyPointerSize) - return 0; // Match for some other target - return getJITMatchQuality()/2; +X86_32TargetMachine::X86_32TargetMachine(const Target &T, const std::string &TT, + const std::string &FS) + : X86TargetMachine(T, TT, FS, false), + DataLayout(getSubtargetImpl()->isTargetDarwin() ? + "e-p:32:32-f64:32:64-i64:32:64-f80:128:128-n8:16:32" : + (getSubtargetImpl()->isTargetCygMing() || + getSubtargetImpl()->isTargetWindows()) ? + "e-p:32:32-f64:64:64-i64:64:64-f80:32:32-n8:16:32" : + "e-p:32:32-f64:32:64-i64:32:64-f80:32:32-n8:16:32"), + InstrInfo(*this), + TSInfo(*this), + TLInfo(*this), + JITInfo(*this) { } -X86_32TargetMachine::X86_32TargetMachine(const Module &M, const std::string &FS) - : X86TargetMachine(M, FS, false) { -} - -X86_64TargetMachine::X86_64TargetMachine(const Module &M, const std::string &FS) - : X86TargetMachine(M, FS, true) { +X86_64TargetMachine::X86_64TargetMachine(const Target &T, const std::string &TT, + const std::string &FS) + : X86TargetMachine(T, TT, FS, true), + DataLayout("e-p:64:64-s:64-f64:64:64-i64:64:64-f80:128:128-n8:16:32:64"), + InstrInfo(*this), + TSInfo(*this), + TLInfo(*this), + JITInfo(*this) { } -/// X86TargetMachine ctor - Create an ILP32 architecture model +/// X86TargetMachine ctor - Create an X86 target. /// -X86TargetMachine::X86TargetMachine(const Module &M, const std::string &FS, - bool is64Bit) - : Subtarget(M, FS, is64Bit), - DataLayout(Subtarget.getDataLayout()), - FrameInfo(TargetFrameInfo::StackGrowsDown, - Subtarget.getStackAlignment(), Subtarget.is64Bit() ? -8 : -4), - InstrInfo(*this), JITInfo(*this), TLInfo(*this), ELFWriterInfo(*this) { +X86TargetMachine::X86TargetMachine(const Target &T, const std::string &TT, + const std::string &FS, bool is64Bit) + : LLVMTargetMachine(T, TT), + Subtarget(TT, FS, is64Bit), + FrameInfo(*this, Subtarget), + ELFWriterInfo(is64Bit, true) { DefRelocModel = getRelocationModel(); - // FIXME: Correctly select PIC model for Win64 stuff + + // If no relocation model was picked, default as appropriate for the target. if (getRelocationModel() == Reloc::Default) { - if (Subtarget.isTargetDarwin() || - (Subtarget.isTargetCygMing() && !Subtarget.isTargetWin64())) - setRelocationModel(Reloc::DynamicNoPIC); + // Darwin defaults to PIC in 64 bit mode and dynamic-no-pic in 32 bit mode. + // Win64 requires rip-rel addressing, thus we force it to PIC. Otherwise we + // use static relocation model by default. + if (Subtarget.isTargetDarwin()) { + if (Subtarget.is64Bit()) + setRelocationModel(Reloc::PIC_); + else + setRelocationModel(Reloc::DynamicNoPIC); + } else if (Subtarget.isTargetWin64()) + setRelocationModel(Reloc::PIC_); else setRelocationModel(Reloc::Static); } - // ELF doesn't have a distinct dynamic-no-PIC model. Dynamic-no-PIC - // is defined as a model for code which may be used in static or - // dynamic executables but not necessarily a shared library. On ELF - // implement this by using the Static model. - if (Subtarget.isTargetELF() && - getRelocationModel() == Reloc::DynamicNoPIC) - setRelocationModel(Reloc::Static); + assert(getRelocationModel() != Reloc::Default && + "Relocation mode not picked"); - if (Subtarget.is64Bit()) { - // No DynamicNoPIC support under X86-64. - if (getRelocationModel() == Reloc::DynamicNoPIC) + // ELF and X86-64 don't have a distinct DynamicNoPIC model. DynamicNoPIC + // is defined as a model for code which may be used in static or dynamic + // executables but not necessarily a shared library. On X86-32 we just + // compile in -static mode, in x86-64 we use PIC. + if (getRelocationModel() == Reloc::DynamicNoPIC) { + if (is64Bit) setRelocationModel(Reloc::PIC_); - // Default X86-64 code model is small. - if (getCodeModel() == CodeModel::Default) - setCodeModel(CodeModel::Small); + else if (!Subtarget.isTargetDarwin()) + setRelocationModel(Reloc::Static); } - if (Subtarget.isTargetCygMing()) - Subtarget.setPICStyle(PICStyles::WinPIC); - else if (Subtarget.isTargetDarwin()) { - if (Subtarget.is64Bit()) - Subtarget.setPICStyle(PICStyles::RIPRel); - else - Subtarget.setPICStyle(PICStyles::Stub); + // If we are on Darwin, disallow static relocation model in X86-64 mode, since + // the Mach-O file format doesn't support it. + if (getRelocationModel() == Reloc::Static && + Subtarget.isTargetDarwin() && + is64Bit) + setRelocationModel(Reloc::PIC_); + + // Determine the PICStyle based on the target selected. + if (getRelocationModel() == Reloc::Static) { + // Unless we're in PIC or DynamicNoPIC mode, set the PIC style to None. + Subtarget.setPICStyle(PICStyles::None); + } else if (Subtarget.is64Bit()) { + // PIC in 64 bit mode is always rip-rel. + Subtarget.setPICStyle(PICStyles::RIPRel); + } else if (Subtarget.isTargetCygMing()) { + Subtarget.setPICStyle(PICStyles::None); + } else if (Subtarget.isTargetDarwin()) { + if (getRelocationModel() == Reloc::PIC_) + Subtarget.setPICStyle(PICStyles::StubPIC); + else { + assert(getRelocationModel() == Reloc::DynamicNoPIC); + Subtarget.setPICStyle(PICStyles::StubDynamicNoPIC); + } } else if (Subtarget.isTargetELF()) { - if (Subtarget.is64Bit()) - Subtarget.setPICStyle(PICStyles::RIPRel); - else - Subtarget.setPICStyle(PICStyles::GOT); + Subtarget.setPICStyle(PICStyles::GOT); } + + // Finally, if we have "none" as our PIC style, force to static mode. + if (Subtarget.getPICStyle() == PICStyles::None) + setRelocationModel(Reloc::Static); } //===----------------------------------------------------------------------===// @@ -190,21 +194,16 @@ bool X86TargetMachine::addInstSelector(PassManagerBase &PM, // Install an instruction selector. PM.add(createX86ISelDag(*this, OptLevel)); - // If we're using Fast-ISel, clean up the mess. - if (EnableFastISel) - PM.add(createDeadMachineInstructionElimPass()); - - // Install a pass to insert x87 FP_REG_KILL instructions, as needed. - PM.add(createX87FPRegKillInserterPass()); + // For 32-bit, prepend instructions to set the "global base reg" for PIC. + if (!Subtarget.is64Bit()) + PM.add(createGlobalBaseRegPass()); return false; } bool X86TargetMachine::addPreRegAlloc(PassManagerBase &PM, CodeGenOpt::Level OptLevel) { - // Calculate and set max stack object alignment early, so we can decide - // whether we will need stack realignment (and thus FP). - PM.add(createX86MaxStackAlignmentCalculatorPass()); + PM.add(createX86MaxStackAlignmentHeuristicPass()); return false; // -print-machineinstr shouldn't print after this. } @@ -214,116 +213,48 @@ bool X86TargetMachine::addPostRegAlloc(PassManagerBase &PM, return true; // -print-machineinstr should print after this. } -bool X86TargetMachine::addAssemblyEmitter(PassManagerBase &PM, - CodeGenOpt::Level OptLevel, - bool Verbose, - raw_ostream &Out) { - // FIXME: Move this somewhere else! - // On Darwin, override 64-bit static relocation to pic_ since the - // assembler doesn't support it. - if (DefRelocModel == Reloc::Static && - Subtarget.isTargetDarwin() && Subtarget.is64Bit()) - setRelocationModel(Reloc::PIC_); - - assert(AsmPrinterCtor && "AsmPrinter was not linked in"); - if (AsmPrinterCtor) - PM.add(AsmPrinterCtor(Out, *this, OptLevel, Verbose)); - return false; -} - -bool X86TargetMachine::addCodeEmitter(PassManagerBase &PM, - CodeGenOpt::Level OptLevel, - bool DumpAsm, - MachineCodeEmitter &MCE) { - // FIXME: Move this to TargetJITInfo! - // On Darwin, do not override 64-bit setting made in X86TargetMachine(). - if (DefRelocModel == Reloc::Default && - (!Subtarget.isTargetDarwin() || !Subtarget.is64Bit())) - setRelocationModel(Reloc::Static); - - // 64-bit JIT places everything in the same buffer except external functions. - // On Darwin, use small code model but hack the call instruction for - // externals. Elsewhere, do not assume globals are in the lower 4G. - if (Subtarget.is64Bit()) { - if (Subtarget.isTargetDarwin()) - setCodeModel(CodeModel::Small); - else - setCodeModel(CodeModel::Large); - } - - PM.add(createX86CodeEmitterPass(*this, MCE)); - if (DumpAsm) { - assert(AsmPrinterCtor && "AsmPrinter was not linked in"); - if (AsmPrinterCtor) - PM.add(AsmPrinterCtor(errs(), *this, OptLevel, true)); +bool X86TargetMachine::addPreEmitPass(PassManagerBase &PM, + CodeGenOpt::Level OptLevel) { + if (OptLevel != CodeGenOpt::None && Subtarget.hasSSE2()) { + PM.add(createSSEDomainFixPass()); + return true; } - return false; } bool X86TargetMachine::addCodeEmitter(PassManagerBase &PM, CodeGenOpt::Level OptLevel, - bool DumpAsm, JITCodeEmitter &JCE) { // FIXME: Move this to TargetJITInfo! // On Darwin, do not override 64-bit setting made in X86TargetMachine(). if (DefRelocModel == Reloc::Default && - (!Subtarget.isTargetDarwin() || !Subtarget.is64Bit())) + (!Subtarget.isTargetDarwin() || !Subtarget.is64Bit())) { setRelocationModel(Reloc::Static); - - // 64-bit JIT places everything in the same buffer except external functions. - // On Darwin, use small code model but hack the call instruction for - // externals. Elsewhere, do not assume globals are in the lower 4G. - if (Subtarget.is64Bit()) { - if (Subtarget.isTargetDarwin()) - setCodeModel(CodeModel::Small); - else - setCodeModel(CodeModel::Large); + Subtarget.setPICStyle(PICStyles::None); } + PM.add(createX86JITCodeEmitterPass(*this, JCE)); - if (DumpAsm) { - assert(AsmPrinterCtor && "AsmPrinter was not linked in"); - if (AsmPrinterCtor) - PM.add(AsmPrinterCtor(errs(), *this, OptLevel, true)); - } return false; } -bool X86TargetMachine::addSimpleCodeEmitter(PassManagerBase &PM, - CodeGenOpt::Level OptLevel, - bool DumpAsm, - MachineCodeEmitter &MCE) { - PM.add(createX86CodeEmitterPass(*this, MCE)); - if (DumpAsm) { - assert(AsmPrinterCtor && "AsmPrinter was not linked in"); - if (AsmPrinterCtor) - PM.add(AsmPrinterCtor(errs(), *this, OptLevel, true)); - } +void X86TargetMachine::setCodeModelForStatic() { - return false; + if (getCodeModel() != CodeModel::Default) return; + + // For static codegen, if we're not already set, use Small codegen. + setCodeModel(CodeModel::Small); } -bool X86TargetMachine::addSimpleCodeEmitter(PassManagerBase &PM, - CodeGenOpt::Level OptLevel, - bool DumpAsm, - JITCodeEmitter &JCE) { - PM.add(createX86JITCodeEmitterPass(*this, JCE)); - if (DumpAsm) { - assert(AsmPrinterCtor && "AsmPrinter was not linked in"); - if (AsmPrinterCtor) - PM.add(AsmPrinterCtor(errs(), *this, OptLevel, true)); - } - return false; -} +void X86TargetMachine::setCodeModelForJIT() { -/// symbolicAddressesAreRIPRel - Return true if symbolic addresses are -/// RIP-relative on this machine, taking into consideration the relocation -/// model and subtarget. RIP-relative addresses cannot have a separate -/// base or index register. -bool X86TargetMachine::symbolicAddressesAreRIPRel() const { - return getRelocationModel() != Reloc::Static && - Subtarget.isPICStyleRIPRel(); + if (getCodeModel() != CodeModel::Default) return; + + // 64-bit JIT places everything in the same buffer except external functions. + if (Subtarget.is64Bit()) + setCodeModel(CodeModel::Large); + else + setCodeModel(CodeModel::Small); }