From 7277a807f08f6c447bad1b04f251b3674401350f Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Fri, 10 Jul 2009 05:45:15 +0000 Subject: [PATCH] There is only one case where GVRequiresExtraLoad returns true for calls: split its handling out to PCRelGVRequiresExtraLoad, and simplify code based on this. llvm-svn: 75230 --- llvm/lib/Target/X86/X86FastISel.cpp | 90 ++++--------------------- llvm/lib/Target/X86/X86ISelLowering.cpp | 2 +- llvm/lib/Target/X86/X86Subtarget.cpp | 17 ++++- llvm/lib/Target/X86/X86Subtarget.h | 8 ++- 4 files changed, 37 insertions(+), 80 deletions(-) diff --git a/llvm/lib/Target/X86/X86FastISel.cpp b/llvm/lib/Target/X86/X86FastISel.cpp index edc464c39b70..bbf773871b0c 100644 --- a/llvm/lib/Target/X86/X86FastISel.cpp +++ b/llvm/lib/Target/X86/X86FastISel.cpp @@ -589,89 +589,27 @@ bool X86FastISel::X86SelectCallAddress(Value *V, X86AddressMode &AM) { // Can't handle TLS yet. if (GlobalVariable *GVar = dyn_cast(GV)) - if (GVar->isThreadLocal()) + if (GVar->isThreadLocal() || GVar->hasDLLImportLinkage()) return false; // Okay, we've committed to selecting this global. Set up the basic address. AM.GV = GV; - // If the ABI doesn't require an extra load, return a direct reference to - // the global. - if (!Subtarget->GVRequiresExtraLoad(GV, TM, true)) { - if (Subtarget->isPICStyleRIPRel()) { - // Use rip-relative addressing if we can. Above we verified that the - // base and index registers are unused. - assert(AM.Base.Reg == 0 && AM.IndexReg == 0); - AM.Base.Reg = X86::RIP; - } else if (Subtarget->isPICStyleStub() && - TM.getRelocationModel() == Reloc::PIC_) { - AM.GVOpFlags = X86II::MO_PIC_BASE_OFFSET; - } else if (Subtarget->isPICStyleGOT()) { - AM.GVOpFlags = X86II::MO_GOTOFF; - } - - return true; + // No ABI requires an extra load for anything other than DLLImport, which + // we rejected above. Return a direct reference to the global. + assert(!Subtarget->PCRelGVRequiresExtraLoad(GV, TM)); + if (Subtarget->isPICStyleRIPRel()) { + // Use rip-relative addressing if we can. Above we verified that the + // base and index registers are unused. + assert(AM.Base.Reg == 0 && AM.IndexReg == 0); + AM.Base.Reg = X86::RIP; + } else if (Subtarget->isPICStyleStub() && + TM.getRelocationModel() == Reloc::PIC_) { + AM.GVOpFlags = X86II::MO_PIC_BASE_OFFSET; + } else if (Subtarget->isPICStyleGOT()) { + AM.GVOpFlags = X86II::MO_GOTOFF; } - // Check to see if we've already materialized this stub loaded value into a - // register in this block. If so, just reuse it. - DenseMap::iterator I = LocalValueMap.find(V); - unsigned LoadReg; - if (I != LocalValueMap.end() && I->second != 0) { - LoadReg = I->second; - } else { - // Issue load from stub. - unsigned Opc = 0; - const TargetRegisterClass *RC = NULL; - X86AddressMode StubAM; - StubAM.Base.Reg = AM.Base.Reg; - StubAM.GV = GV; - - if (TLI.getPointerTy() == MVT::i64) { - Opc = X86::MOV64rm; - RC = X86::GR64RegisterClass; - - if (Subtarget->isPICStyleRIPRel()) { - StubAM.GVOpFlags = X86II::MO_GOTPCREL; - StubAM.Base.Reg = X86::RIP; - } - - } else { - Opc = X86::MOV32rm; - RC = X86::GR32RegisterClass; - - if (Subtarget->isPICStyleGOT()) - StubAM.GVOpFlags = X86II::MO_GOT; - else if (Subtarget->isPICStyleStub()) { - // In darwin, we have multiple different stub types, and we have both - // PIC and -mdynamic-no-pic. Determine whether we have a stub - // reference and/or whether the reference is relative to the PIC base - // or not. - bool IsPIC = TM.getRelocationModel() == Reloc::PIC_; - - if (!GV->hasHiddenVisibility()) { - // Non-hidden $non_lazy_ptr reference. - StubAM.GVOpFlags = IsPIC ? X86II::MO_DARWIN_NONLAZY_PIC_BASE : - X86II::MO_DARWIN_NONLAZY; - } else { - // Hidden $non_lazy_ptr reference. - StubAM.GVOpFlags = IsPIC ? X86II::MO_DARWIN_HIDDEN_NONLAZY_PIC_BASE: - X86II::MO_DARWIN_HIDDEN_NONLAZY; - } - } - } - - LoadReg = createResultReg(RC); - addFullAddress(BuildMI(MBB, DL, TII.get(Opc), LoadReg), StubAM); - - // Prevent loading GV stub multiple times in same MBB. - LocalValueMap[V] = LoadReg; - } - - // Now construct the final address. Note that the Disp, Scale, - // and Index values may already be set here. - AM.Base.Reg = LoadReg; - AM.GV = 0; return true; } diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp index 8084cd58e9e9..5e615484028c 100644 --- a/llvm/lib/Target/X86/X86ISelLowering.cpp +++ b/llvm/lib/Target/X86/X86ISelLowering.cpp @@ -1902,7 +1902,7 @@ SDValue X86TargetLowering::LowerCALL(SDValue Op, SelectionDAG &DAG) { // We should use extra load for direct calls to dllimported functions in // non-JIT mode. GlobalValue *GV = G->getGlobal(); - if (!Subtarget->GVRequiresExtraLoad(GV, getTargetMachine(), true)) { + if (!Subtarget->PCRelGVRequiresExtraLoad(GV, getTargetMachine())) { unsigned char OpFlags = 0; // On ELF targets, in both X86-64 and X86-32 mode, direct calls to diff --git a/llvm/lib/Target/X86/X86Subtarget.cpp b/llvm/lib/Target/X86/X86Subtarget.cpp index 7d1f972b4e7f..6eb0235e15da 100644 --- a/llvm/lib/Target/X86/X86Subtarget.cpp +++ b/llvm/lib/Target/X86/X86Subtarget.cpp @@ -38,8 +38,8 @@ AsmWriterFlavor("x86-asm-syntax", cl::init(X86Subtarget::Unset), /// symbols are indirect, loading the value at address GV rather then the /// value of GV itself. This means that the GlobalAddress must be in the base /// or index register of the address, not the GV offset field. -bool X86Subtarget::GVRequiresExtraLoad(const GlobalValue* GV, - const TargetMachine& TM, +bool X86Subtarget::GVRequiresExtraLoad(const GlobalValue *GV, + const TargetMachine &TM, bool isDirectCall) const { // Windows targets only require an extra load for DLLImport linkage values, // and they need these regardless of whether we're in PIC mode or not. @@ -72,6 +72,19 @@ bool X86Subtarget::GVRequiresExtraLoad(const GlobalValue* GV, return false; } +/// PCRelGVRequiresExtraLoad - True if accessing the GV from a PC-relative +/// operand like a call target requires an extra load. +bool X86Subtarget::PCRelGVRequiresExtraLoad(const GlobalValue *GV, + const TargetMachine &TM) const { + // Windows targets only require an extra load for DLLImport linkage values, + // and they need these regardless of whether we're in PIC mode or not. + if (isTargetCygMing() || isTargetWindows()) + return GV->hasDLLImportLinkage(); + + return false; +} + + /// True if accessing the GV requires a register. This is a superset of the /// cases where GVRequiresExtraLoad is true. Some variations of PIC require /// a register, but not an extra load. diff --git a/llvm/lib/Target/X86/X86Subtarget.h b/llvm/lib/Target/X86/X86Subtarget.h index db3b5d5eaf9b..b2e518ed39f7 100644 --- a/llvm/lib/Target/X86/X86Subtarget.h +++ b/llvm/lib/Target/X86/X86Subtarget.h @@ -204,10 +204,16 @@ public: bool GVRequiresExtraLoad(const GlobalValue* GV, const TargetMachine &TM, bool isDirectCall) const; + /// PCRelGVRequiresExtraLoad - True if accessing the GV from a PC-relative + /// operand like a call target requires an extra load. + bool PCRelGVRequiresExtraLoad(const GlobalValue *GV, + const TargetMachine &TM) const; + + /// True if accessing the GV requires a register. This is a superset of the /// cases where GVRequiresExtraLoad is true. Some variations of PIC require /// a register, but not an extra load. - bool GVRequiresRegister(const GlobalValue* GV, const TargetMachine &TM) const; + bool GVRequiresRegister(const GlobalValue *GV, const TargetMachine &TM) const; /// IsLegalToCallImmediateAddr - Return true if the subtarget allows calls /// to immediate address.