X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FTarget%2FX86%2FX86FastISel.cpp;h=73c2afd7a52fe5e4071456ce0f6123a546eebf55;hb=d1474d09cbe5fdeec8ba0d6c6b52f316f3422532;hp=bd994dea8f414af491e42798d035aca01d162963;hpb=f530c92cd55f35f64904e42e38b3a2bc92b347cb;p=oota-llvm.git diff --git a/lib/Target/X86/X86FastISel.cpp b/lib/Target/X86/X86FastISel.cpp index bd994dea8f4..73c2afd7a52 100644 --- a/lib/Target/X86/X86FastISel.cpp +++ b/lib/Target/X86/X86FastISel.cpp @@ -440,63 +440,93 @@ bool X86FastISel::X86SelectAddress(Value *V, X86AddressMode &AM, bool isCall) { if (GVar->isThreadLocal()) return false; - // Set up the basic address. + // Okay, we've committed to selecting this global. Set up the basic address. AM.GV = GV; if (!isCall && TM.getRelocationModel() == Reloc::PIC_ && - !Subtarget->is64Bit()) + !Subtarget->is64Bit()) { + // FIXME: How do we know Base.Reg is free?? AM.Base.Reg = getInstrInfo()->getGlobalBaseReg(&MF); + } - // Emit an extra load if the ABI requires it. - if (Subtarget->GVRequiresExtraLoad(GV, TM, isCall)) { - // Check to see if we've already materialized this - // value in a register in this block. - DenseMap::iterator I = LocalValueMap.find(V); - if (I != LocalValueMap.end() && I->second != 0) { - AM.Base.Reg = I->second; - AM.GV = 0; - return true; + // If the ABI doesn't require an extra load, return a direct reference to + // the global. + if (!Subtarget->GVRequiresExtraLoad(GV, TM, isCall)) { + 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; + } + + // 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 = AM.GV; + StubAM.GV = GV; - if (TLI.getPointerTy() == MVT::i32) { - Opc = X86::MOV32rm; - RC = X86::GR32RegisterClass; - - if (Subtarget->isPICStyleGOT() && - TM.getRelocationModel() == Reloc::PIC_) - StubAM.GVOpFlags = X86II::MO_GOT; - - } else { + if (TLI.getPointerTy() == MVT::i64) { Opc = X86::MOV64rm; RC = X86::GR64RegisterClass; - if (TM.getRelocationModel() != Reloc::Static) + 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; + } + } } - - unsigned ResultReg = createResultReg(RC); - addFullAddress(BuildMI(MBB, DL, TII.get(Opc), ResultReg), StubAM); - - // Now construct the final address. Note that the Disp, Scale, - // and Index values may already be set here. - AM.Base.Reg = ResultReg; - AM.GV = 0; - + + LoadReg = createResultReg(RC); + addFullAddress(BuildMI(MBB, DL, TII.get(Opc), LoadReg), StubAM); + // Prevent loading GV stub multiple times in same MBB. - LocalValueMap[V] = AM.Base.Reg; - } else if (Subtarget->isPICStyleRIPRel()) { - // Use rip-relative addressing if we can. - AM.Base.Reg = X86::RIP; + 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; } @@ -1212,7 +1242,7 @@ bool X86FastISel::X86SelectCall(Instruction *I) { // Analyze operands of the call, assigning locations to each operand. SmallVector ArgLocs; - CCState CCInfo(CC, false, TM, ArgLocs); + CCState CCInfo(CC, false, TM, ArgLocs, I->getParent()->getContext()); CCInfo.AnalyzeCallOperands(ArgVTs, ArgFlags, CCAssignFnForCall(CC)); // Get a count of how many bytes are to be pushed on the stack. @@ -1292,28 +1322,53 @@ bool X86FastISel::X86SelectCall(Instruction *I) { // ELF / PIC requires GOT in the EBX register before function calls via PLT // GOT pointer. - if (!Subtarget->is64Bit() && - TM.getRelocationModel() == Reloc::PIC_ && - Subtarget->isPICStyleGOT()) { + if (Subtarget->isPICStyleGOT()) { TargetRegisterClass *RC = X86::GR32RegisterClass; unsigned Base = getInstrInfo()->getGlobalBaseReg(&MF); bool Emitted = TII.copyRegToReg(*MBB, MBB->end(), X86::EBX, Base, RC, RC); assert(Emitted && "Failed to emit a copy instruction!"); Emitted=Emitted; Emitted = true; } - + // Issue the call. - unsigned CallOpc = CalleeOp - ? (Subtarget->is64Bit() ? X86::CALL64r : X86::CALL32r) - : (Subtarget->is64Bit() ? X86::CALL64pcrel32 : X86::CALLpcrel32); - MachineInstrBuilder MIB = CalleeOp - ? BuildMI(MBB, DL, TII.get(CallOpc)).addReg(CalleeOp) - : BuildMI(MBB, DL, TII.get(CallOpc)).addGlobalAddress(GV); + MachineInstrBuilder MIB; + if (CalleeOp) { + // Register-indirect call. + unsigned CallOpc = Subtarget->is64Bit() ? X86::CALL64r : X86::CALL32r; + MIB = BuildMI(MBB, DL, TII.get(CallOpc)).addReg(CalleeOp); + + } else { + // Direct call. + assert(GV && "Not a direct call"); + unsigned CallOpc = + Subtarget->is64Bit() ? X86::CALL64pcrel32 : X86::CALLpcrel32; + + // See if we need any target-specific flags on the GV operand. + unsigned char OpFlags = 0; + + // On ELF targets, in both X86-64 and X86-32 mode, direct calls to + // external symbols most go through the PLT in PIC mode. If the symbol + // has hidden or protected visibility, or if it is static or local, then + // we don't need to use the PLT - we can directly call it. + if (Subtarget->isTargetELF() && + TM.getRelocationModel() == Reloc::PIC_ && + GV->hasDefaultVisibility() && !GV->hasLocalLinkage()) { + OpFlags = X86II::MO_PLT; + } else if (Subtarget->isPICStyleStub() && + (GV->isDeclaration() || GV->isWeakForLinker()) && + Subtarget->getDarwinVers() < 9) { + // PC-relative references to external symbols should go through $stub, + // unless we're building with the leopard linker or later, which + // automatically synthesizes these stubs. + OpFlags = X86II::MO_DARWIN_STUB; + } + + + MIB = BuildMI(MBB, DL, TII.get(CallOpc)).addGlobalAddress(GV, 0, OpFlags); + } // Add an implicit use GOT pointer in EBX. - if (!Subtarget->is64Bit() && - TM.getRelocationModel() == Reloc::PIC_ && - Subtarget->isPICStyleGOT()) + if (Subtarget->isPICStyleGOT()) MIB.addReg(X86::EBX); // Add implicit physical register uses to the call. @@ -1327,7 +1382,7 @@ bool X86FastISel::X86SelectCall(Instruction *I) { // Now handle call return value (if any). if (RetVT.getSimpleVT() != MVT::isVoid) { SmallVector RVLocs; - CCState CCInfo(CC, false, TM, RVLocs); + CCState CCInfo(CC, false, TM, RVLocs, I->getParent()->getContext()); CCInfo.AnalyzeCallResult(RetVT, RetCC_X86); // Copy all of the result registers out of their specified physreg. @@ -1507,14 +1562,16 @@ unsigned X86FastISel::TargetMaterializeConstant(Constant *C) { // x86-32 PIC requires a PIC base register for constant pools. unsigned PICBase = 0; unsigned char OpFlag = 0; - if (TM.getRelocationModel() == Reloc::PIC_) { - if (Subtarget->isPICStyleStub()) { - OpFlag = X86II::MO_PIC_BASE_OFFSET; - PICBase = getInstrInfo()->getGlobalBaseReg(&MF); - } else if (Subtarget->isPICStyleGOT()) { - OpFlag = X86II::MO_GOTOFF; - PICBase = getInstrInfo()->getGlobalBaseReg(&MF); - } + if (Subtarget->isPICStyleStub() && + TM.getRelocationModel() == Reloc::PIC_) { // Not dynamic-no-pic + OpFlag = X86II::MO_PIC_BASE_OFFSET; + PICBase = getInstrInfo()->getGlobalBaseReg(&MF); + } else if (Subtarget->isPICStyleGOT()) { + OpFlag = X86II::MO_GOTOFF; + PICBase = getInstrInfo()->getGlobalBaseReg(&MF); + } else if (Subtarget->isPICStyleRIPRel() && + TM.getCodeModel() == CodeModel::Small) { + PICBase = X86::RIP; } // Create the load from the constant pool.