Commit deb5a825 by Jim Stichnoth

Subzero: Improve register availability peephole for function return values.

Originally, a call instruction was lowered like this: // %result = call @foo(...) %t1:eax = call foo %result = %t1:eax Because t1 is pre-colored, it is not available as a substitution if the following instruction uses %result as a source operand. To improve this, we copy it through an intermediate temporary: // %result = call @foo(...) %t1:eax = call foo %t2 = %t1:eax %result = %t2 BUG= none R=eholk@chromium.org Review URL: https://codereview.chromium.org/2064073005 .
parent 7f0ab860
...@@ -2688,7 +2688,7 @@ void TargetX86Base<TraitsType>::lowerCall(const InstCall *Instr) { ...@@ -2688,7 +2688,7 @@ void TargetX86Base<TraitsType>::lowerCall(const InstCall *Instr) {
// Mark the call as killing all the caller-save registers. // Mark the call as killing all the caller-save registers.
Context.insert<InstFakeKill>(NewCall); Context.insert<InstFakeKill>(NewCall);
// Handle x86-32 floating point returns. // Handle x86-32 floating point returns.
if (Dest != nullptr && isScalarFloatingType(Dest->getType()) && if (Dest != nullptr && isScalarFloatingType(DestTy) &&
!Traits::X86_PASS_SCALAR_FP_IN_XMM) { !Traits::X86_PASS_SCALAR_FP_IN_XMM) {
// Special treatment for an FP function which returns its result in st(0). // Special treatment for an FP function which returns its result in st(0).
// If Dest ends up being a physical xmm register, the fstp emit code will // If Dest ends up being a physical xmm register, the fstp emit code will
...@@ -2706,14 +2706,19 @@ void TargetX86Base<TraitsType>::lowerCall(const InstCall *Instr) { ...@@ -2706,14 +2706,19 @@ void TargetX86Base<TraitsType>::lowerCall(const InstCall *Instr) {
// Process the return value, if any. // Process the return value, if any.
if (Dest == nullptr) if (Dest == nullptr)
return; return;
// Assign the result of the call to Dest. // Assign the result of the call to Dest. Route it through a temporary so
// that the local register availability peephole can be subsequently used.
Variable *Tmp = nullptr;
if (isVectorType(DestTy)) { if (isVectorType(DestTy)) {
assert(ReturnReg && "Vector type requires a return register"); assert(ReturnReg && "Vector type requires a return register");
_movp(Dest, ReturnReg); Tmp = makeReg(DestTy);
_movp(Tmp, ReturnReg);
_movp(Dest, Tmp);
} else if (isScalarFloatingType(DestTy)) { } else if (isScalarFloatingType(DestTy)) {
if (Traits::X86_PASS_SCALAR_FP_IN_XMM) { if (Traits::X86_PASS_SCALAR_FP_IN_XMM) {
assert(ReturnReg && "FP type requires a return register"); assert(ReturnReg && "FP type requires a return register");
_mov(Dest, ReturnReg); _mov(Tmp, ReturnReg);
_mov(Dest, Tmp);
} }
} else { } else {
assert(isScalarIntegerType(DestTy)); assert(isScalarIntegerType(DestTy));
...@@ -2723,10 +2728,14 @@ void TargetX86Base<TraitsType>::lowerCall(const InstCall *Instr) { ...@@ -2723,10 +2728,14 @@ void TargetX86Base<TraitsType>::lowerCall(const InstCall *Instr) {
auto *Dest64On32 = llvm::cast<Variable64On32>(Dest); auto *Dest64On32 = llvm::cast<Variable64On32>(Dest);
Variable *DestLo = Dest64On32->getLo(); Variable *DestLo = Dest64On32->getLo();
Variable *DestHi = Dest64On32->getHi(); Variable *DestHi = Dest64On32->getHi();
_mov(DestLo, ReturnReg); _mov(Tmp, ReturnReg);
_mov(DestHi, ReturnRegHi); _mov(DestLo, Tmp);
Variable *TmpHi = nullptr;
_mov(TmpHi, ReturnRegHi);
_mov(DestHi, TmpHi);
} else { } else {
_mov(Dest, ReturnReg); _mov(Tmp, ReturnReg);
_mov(Dest, Tmp);
} }
} }
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment