Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(22)

Unified Diff: src/IceTargetLoweringX8632.cpp

Issue 1449523002: Eliminate stack adjustment for float-returning functions (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: Created 5 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: src/IceTargetLoweringX8632.cpp
diff --git a/src/IceTargetLoweringX8632.cpp b/src/IceTargetLoweringX8632.cpp
index 52ba7b5aa41e42630c9a5d1f75dd0fbba8f69552..d09bdf41f6e2b6b784261d85786a13489f36a9c5 100644
--- a/src/IceTargetLoweringX8632.cpp
+++ b/src/IceTargetLoweringX8632.cpp
@@ -131,7 +131,7 @@ void TargetX8632::lowerCall(const InstCall *Instr) {
OperandList XmmArgs;
OperandList StackArgs, StackArgLocations;
- uint32_t ParameterAreaSizeBytes = 0;
+ int32_t ParameterAreaSizeBytes = 0;
// Classify each argument operand according to the location where the
// argument is passed.
@@ -158,6 +158,13 @@ void TargetX8632::lowerCall(const InstCall *Instr) {
ParameterAreaSizeBytes += typeWidthInBytesOnStack(Arg->getType());
}
}
+ // Ensure there is enough space for the fstp/movs for floating returns.
+ Variable *Dest = Instr->getDest();
+ if (Dest != nullptr && isScalarFloatingType(Dest->getType())) {
+ ParameterAreaSizeBytes =
+ std::max(static_cast<size_t>(ParameterAreaSizeBytes),
+ typeWidthInBytesOnStack(Dest->getType()));
+ }
// Adjust the parameter area so that the stack is aligned. It is assumed that
// the stack is already aligned at the start of the calling sequence.
@@ -197,7 +204,6 @@ void TargetX8632::lowerCall(const InstCall *Instr) {
}
// Generate the call instruction. Assign its result to a temporary with high
// register allocation weight.
- Variable *Dest = Instr->getDest();
// ReturnReg doubles as ReturnRegLo as necessary.
Variable *ReturnReg = nullptr;
Variable *ReturnRegHi = nullptr;
@@ -255,17 +261,24 @@ void TargetX8632::lowerCall(const InstCall *Instr) {
if (ReturnRegHi)
Context.insert(InstFakeDef::create(Func, ReturnRegHi));
- // Add the appropriate offset to esp. The call instruction takes care of
- // resetting the stack offset during emission.
- if (ParameterAreaSizeBytes) {
- Variable *esp =
- Func->getTarget()->getPhysicalRegister(Traits::RegisterSet::Reg_esp);
- _add(esp, Ctx->getConstantInt32(ParameterAreaSizeBytes));
- }
-
// Insert a register-kill pseudo instruction.
Context.insert(InstFakeKill::create(Func, NewCall));
+ if (Dest != nullptr && isScalarFloatingType(Dest->getType())) {
+ // 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
+ // route st(0) through the space reserved in the function argument area
+ // we allocated.
+ _fstp(Dest);
+ // Create a fake use of Dest in case it actually isn't used, because st(0)
+ // still needs to be popped.
+ Context.insert(InstFakeUse::create(Func, Dest));
+ }
+
+ // Add the appropriate offset to esp.
+ if (ParameterAreaSizeBytes)
+ _adjust_stack(-ParameterAreaSizeBytes);
+
// Generate a FakeUse to keep the call live if necessary.
if (Instr->hasSideEffects() && ReturnReg) {
Inst *FakeUse = InstFakeUse::create(Func, ReturnReg);
@@ -293,14 +306,6 @@ void TargetX8632::lowerCall(const InstCall *Instr) {
_mov(Dest, ReturnReg);
}
}
- } else if (isScalarFloatingType(Dest->getType())) {
- // 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
- // route st(0) through a temporary stack slot.
- _fstp(Dest);
- // Create a fake use of Dest in case it actually isn't used, because st(0)
- // still needs to be popped.
- Context.insert(InstFakeUse::create(Func, Dest));
}
}

Powered by Google App Engine
This is Rietveld 408576698