diff options
| author | Chris Lattner <sabre@nondot.org> | 2005-12-04 06:03:50 +0000 |
|---|---|---|
| committer | Chris Lattner <sabre@nondot.org> | 2005-12-04 06:03:50 +0000 |
| commit | 7e79292fef3e0cfeb85d8d8cb587997d69589f39 (patch) | |
| tree | 67f698c0cbf23bafed30208928dad1b87d79b7a9 /llvm/lib/Target/X86/X86ISelPattern.cpp | |
| parent | 394350dcca47c5a25dcceb29098195fad0ca2d92 (diff) | |
| download | bcm5719-llvm-7e79292fef3e0cfeb85d8d8cb587997d69589f39.tar.gz bcm5719-llvm-7e79292fef3e0cfeb85d8d8cb587997d69589f39.zip | |
Fix PR672 another way which should be more robust
llvm-svn: 24585
Diffstat (limited to 'llvm/lib/Target/X86/X86ISelPattern.cpp')
| -rw-r--r-- | llvm/lib/Target/X86/X86ISelPattern.cpp | 30 |
1 files changed, 14 insertions, 16 deletions
diff --git a/llvm/lib/Target/X86/X86ISelPattern.cpp b/llvm/lib/Target/X86/X86ISelPattern.cpp index 28f799ee4a8..6132c942d62 100644 --- a/llvm/lib/Target/X86/X86ISelPattern.cpp +++ b/llvm/lib/Target/X86/X86ISelPattern.cpp @@ -3014,7 +3014,10 @@ void ISel::EmitFastCCToFastCCTailCall(SDNode *TailCallNode) { bool isDirect = isa<GlobalAddressSDNode>(Callee) || isa<ExternalSymbolSDNode>(Callee); unsigned CalleeReg = 0; - if (!isDirect) CalleeReg = SelectExpr(Callee); + if (!isDirect) { + // If this is not a direct tail call, evaluate the callee's address. + CalleeReg = SelectExpr(Callee); + } unsigned RegOp1 = 0; unsigned RegOp2 = 0; @@ -3059,6 +3062,15 @@ void ISel::EmitFastCCToFastCCTailCall(SDNode *TailCallNode) { break; } } + + // If this is not a direct tail call, put the callee's address into ECX. + // The address has to be evaluated into a non-callee save register that is + // not used for arguments. This means either ECX, as EAX and EDX may be + // used for argument passing. We do this here to make sure that the + // expressions for arguments and callee are all evaluated before the copies + // into physical registers. + if (!isDirect) + BuildMI(BB, X86::MOV32rr, 1, X86::ECX).addReg(CalleeReg); // Adjust ESP. if (ESPOffset) @@ -3067,21 +3079,7 @@ void ISel::EmitFastCCToFastCCTailCall(SDNode *TailCallNode) { // TODO: handle jmp [mem] if (!isDirect) { - // We do not want the register allocator to allocate CalleeReg to a callee - // saved register, as these will be restored before the JMP. To prevent - // this, emit explicit clobbers of callee saved regs here. A better way to - // solve this would be to specify that the register constraints of TAILJMPr - // only allow registers that are not callee saved, but we currently can't - // express that. This forces all four of these regs to be saved and - // reloaded for all functions with an indirect tail call. - // TODO: Improve this! - BuildMI(BB, X86::IMPLICIT_DEF, 4) - .addReg(X86::ESI, MachineOperand::Def) - .addReg(X86::EDI, MachineOperand::Def) - .addReg(X86::EBX, MachineOperand::Def) - .addReg(X86::EBP, MachineOperand::Def); - - BuildMI(BB, X86::TAILJMPr, 1).addReg(CalleeReg); + BuildMI(BB, X86::TAILJMPr, 1).addReg(X86::ECX); } else if (GlobalAddressSDNode *GASD = dyn_cast<GlobalAddressSDNode>(Callee)){ BuildMI(BB, X86::TAILJMPd, 1).addGlobalAddress(GASD->getGlobal(), true); } else { |

