diff options
author | Chris Lattner <sabre@nondot.org> | 2009-07-09 02:55:47 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2009-07-09 02:55:47 +0000 |
commit | 679cad5653e1a8bd2420872c0aece1373cb7ee6c (patch) | |
tree | 07cb39afbb0062072250d05c7a2f0b59145d2d3f /lib/Target | |
parent | bcd87b754e26e7f42d8fd4bc83d56888f0afd892 (diff) | |
download | external_llvm-679cad5653e1a8bd2420872c0aece1373cb7ee6c.zip external_llvm-679cad5653e1a8bd2420872c0aece1373cb7ee6c.tar.gz external_llvm-679cad5653e1a8bd2420872c0aece1373cb7ee6c.tar.bz2 |
merge two identical functions and simplify things that are GOT specific
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@75091 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Target')
-rw-r--r-- | lib/Target/X86/X86ISelLowering.cpp | 74 |
1 files changed, 33 insertions, 41 deletions
diff --git a/lib/Target/X86/X86ISelLowering.cpp b/lib/Target/X86/X86ISelLowering.cpp index 3889e61..3a8d600 100644 --- a/lib/Target/X86/X86ISelLowering.cpp +++ b/lib/Target/X86/X86ISelLowering.cpp @@ -1319,18 +1319,9 @@ X86TargetLowering::NameDecorationForFORMAL_ARGUMENTS(SDValue Op) { } -/// CallRequiresGOTInRegister - Check whether the call requires the GOT pointer -/// in a register before calling. -static bool CallRequiresGOTPtrInReg(const TargetMachine &TM) { - const X86Subtarget &Subtarget = TM.getSubtarget<X86Subtarget>(); - - return TM.getRelocationModel() == Reloc::PIC_ && - Subtarget.isPICStyleGOT(); -} - -/// CallRequiresFnAddressInReg - Check whether the call requires the function -/// address to be loaded in a register. -static bool CallRequiresFnAddressInReg(const TargetMachine &TM) { +/// isUsingGOT - Return true if the target uses a GOT for PIC, and if we're in +/// PIC mode. +static bool isUsingGOT(const TargetMachine &TM) { const X86Subtarget &Subtarget = TM.getSubtarget<X86Subtarget>(); return TM.getRelocationModel() == Reloc::PIC_ && Subtarget.isPICStyleGOT(); @@ -1802,31 +1793,34 @@ SDValue X86TargetLowering::LowerCALL(SDValue Op, SelectionDAG &DAG) { InFlag = Chain.getValue(1); } - // ELF / PIC requires GOT in the EBX register before function calls via PLT - // GOT pointer. - if (!IsTailCall && CallRequiresGOTPtrInReg(getTargetMachine())) { - Chain = DAG.getCopyToReg(Chain, dl, X86::EBX, - DAG.getNode(X86ISD::GlobalBaseReg, - DebugLoc::getUnknownLoc(), - getPointerTy()), - InFlag); - InFlag = Chain.getValue(1); - } - // If we are tail calling and generating PIC/GOT style code load the address - // of the callee into ecx. The value in ecx is used as target of the tail - // jump. This is done to circumvent the ebx/callee-saved problem for tail - // calls on PIC/GOT architectures. Normally we would just put the address of - // GOT into ebx and then call target@PLT. But for tail calls ebx would be - // restored (since ebx is callee saved) before jumping to the target@PLT. - if (IsTailCall && CallRequiresFnAddressInReg(getTargetMachine())) { - // Note: The actual moving to ecx is done further down. - GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee); - if (G && !G->getGlobal()->hasHiddenVisibility() && - !G->getGlobal()->hasProtectedVisibility()) - Callee = LowerGlobalAddress(Callee, DAG); - else if (isa<ExternalSymbolSDNode>(Callee)) - Callee = LowerExternalSymbol(Callee,DAG); + if (isUsingGOT(getTargetMachine())) { + // ELF / PIC requires GOT in the EBX register before function calls via PLT + // GOT pointer. + if (!IsTailCall) { + Chain = DAG.getCopyToReg(Chain, dl, X86::EBX, + DAG.getNode(X86ISD::GlobalBaseReg, + DebugLoc::getUnknownLoc(), + getPointerTy()), + InFlag); + InFlag = Chain.getValue(1); + } else { + // If we are tail calling and generating PIC/GOT style code load the + // address of the callee into ECX. The value in ecx is used as target of + // the tail jump. This is done to circumvent the ebx/callee-saved problem + // for tail calls on PIC/GOT architectures. Normally we would just put the + // address of GOT into ebx and then call target@PLT. But for tail calls + // ebx would be restored (since ebx is callee saved) before jumping to the + // target@PLT. + + // Note: The actual moving to ECX is done further down. + GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee); + if (G && !G->getGlobal()->hasHiddenVisibility() && + !G->getGlobal()->hasProtectedVisibility()) + Callee = LowerGlobalAddress(Callee, DAG); + else if (isa<ExternalSymbolSDNode>(Callee)) + Callee = LowerExternalSymbol(Callee,DAG); + } } if (Is64Bit && isVarArg) { @@ -1958,9 +1952,7 @@ SDValue X86TargetLowering::LowerCALL(SDValue Op, SelectionDAG &DAG) { RegsToPass[i].second.getValueType())); // Add an implicit use GOT pointer in EBX. - if (!IsTailCall && !Is64Bit && - getTargetMachine().getRelocationModel() == Reloc::PIC_ && - Subtarget->isPICStyleGOT()) + if (!IsTailCall && isUsingGOT(getTargetMachine())) Ops.push_back(DAG.getRegister(X86::EBX, getPointerTy())); // Add an implicit use of AL for x86 vararg functions. @@ -2078,9 +2070,9 @@ bool X86TargetLowering::IsEligibleForTailCallOptimization(CallSDNode *TheCall, unsigned CalleeCC= TheCall->getCallingConv(); if (CalleeCC == CallingConv::Fast && CallerCC == CalleeCC) { SDValue Callee = TheCall->getCallee(); - // On x86/32Bit PIC/GOT tail calls are supported. + // On x86/32Bit PIC/GOT tail calls are supported. if (getTargetMachine().getRelocationModel() != Reloc::PIC_ || - !Subtarget->isPICStyleGOT()|| !Subtarget->is64Bit()) + !Subtarget->isPICStyleGOT() || !Subtarget->is64Bit()) return true; // Can only do local tail calls (in same module, hidden or protected) on |