PPC/s390: [turbofan] Support variable size argument removal in TF-generated functions
Port 5319b50c85
Original commit message:
This is preparation for using TF to create builtins that handle variable number of
arguments and have to remove these arguments dynamically from the stack upon
return.
The gist of the changes:
- Added a second argument to the Return node which specifies the number of stack
slots to pop upon return in addition to those specified by the Linkage of the
compiled function.
- Removed Tail -> Non-Tail fallback in the instruction selector. Since TF now should
handles all tail-call cases except where the return value type differs, this fallback
was not really useful and in fact caused unexpected behavior with variable
sized argument popping, since it wasn't possible to materialize a Return node
with the right pop count from the TailCall without additional context.
- Modified existing Return generation to pass a constant zero as the additional
pop argument since the variable pop functionality
R=danno@chromium.org, joransiu@ca.ibm.com, jyan@ca.ibm.com, michael_dawson@ca.ibm.com, mbrandy@us.ibm.com
BUG=
LOG=N
Review-Url: https://codereview.chromium.org/2462173002
Cr-Commit-Position: refs/heads/master@{#40682}
This commit is contained in:
parent
9c78194343
commit
2c846a2ac7
@ -1090,7 +1090,7 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
|
||||
break;
|
||||
}
|
||||
case kArchRet:
|
||||
AssembleReturn();
|
||||
AssembleReturn(instr->InputAt(0));
|
||||
DCHECK_EQ(LeaveRC, i.OutputRCBit());
|
||||
break;
|
||||
case kArchStackPointer:
|
||||
@ -2174,8 +2174,7 @@ void CodeGenerator::AssembleConstructFrame() {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void CodeGenerator::AssembleReturn() {
|
||||
void CodeGenerator::AssembleReturn(InstructionOperand* pop) {
|
||||
CallDescriptor* descriptor = linkage()->GetIncomingDescriptor();
|
||||
int pop_count = static_cast<int>(descriptor->StackParameterCount());
|
||||
|
||||
@ -2193,20 +2192,33 @@ void CodeGenerator::AssembleReturn() {
|
||||
if (double_saves != 0) {
|
||||
__ MultiPopDoubles(double_saves);
|
||||
}
|
||||
PPCOperandConverter g(this, nullptr);
|
||||
|
||||
if (descriptor->IsCFunctionCall()) {
|
||||
AssembleDeconstructFrame();
|
||||
} else if (frame_access_state()->has_frame()) {
|
||||
// Canonicalize JSFunction return sites for now.
|
||||
if (return_label_.is_bound()) {
|
||||
__ b(&return_label_);
|
||||
return;
|
||||
// Canonicalize JSFunction return sites for now unless they have an variable
|
||||
// number of stack slot pops
|
||||
if (pop->IsImmediate() && g.ToConstant(pop).ToInt32() == 0) {
|
||||
if (return_label_.is_bound()) {
|
||||
__ b(&return_label_);
|
||||
return;
|
||||
} else {
|
||||
__ bind(&return_label_);
|
||||
AssembleDeconstructFrame();
|
||||
}
|
||||
} else {
|
||||
__ bind(&return_label_);
|
||||
AssembleDeconstructFrame();
|
||||
}
|
||||
}
|
||||
__ Ret(pop_count);
|
||||
if (pop->IsImmediate()) {
|
||||
DCHECK_EQ(Constant::kInt32, g.ToConstant(pop).type());
|
||||
pop_count += g.ToConstant(pop).ToInt32();
|
||||
} else {
|
||||
__ Drop(g.ToRegister(pop));
|
||||
}
|
||||
__ Drop(pop_count);
|
||||
__ Ret();
|
||||
}
|
||||
|
||||
|
||||
|
@ -992,7 +992,7 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
|
||||
break;
|
||||
}
|
||||
case kArchRet:
|
||||
AssembleReturn();
|
||||
AssembleReturn(instr->InputAt(0));
|
||||
break;
|
||||
case kArchStackPointer:
|
||||
__ LoadRR(i.OutputRegister(), sp);
|
||||
@ -2298,7 +2298,7 @@ void CodeGenerator::AssembleConstructFrame() {
|
||||
}
|
||||
}
|
||||
|
||||
void CodeGenerator::AssembleReturn() {
|
||||
void CodeGenerator::AssembleReturn(InstructionOperand* pop) {
|
||||
CallDescriptor* descriptor = linkage()->GetIncomingDescriptor();
|
||||
int pop_count = static_cast<int>(descriptor->StackParameterCount());
|
||||
|
||||
@ -2314,19 +2314,32 @@ void CodeGenerator::AssembleReturn() {
|
||||
__ MultiPopDoubles(double_saves);
|
||||
}
|
||||
|
||||
S390OperandConverter g(this, nullptr);
|
||||
if (descriptor->IsCFunctionCall()) {
|
||||
AssembleDeconstructFrame();
|
||||
} else if (frame_access_state()->has_frame()) {
|
||||
// Canonicalize JSFunction return sites for now.
|
||||
if (return_label_.is_bound()) {
|
||||
__ b(&return_label_);
|
||||
return;
|
||||
// Canonicalize JSFunction return sites for now unless they have an variable
|
||||
// number of stack slot pops
|
||||
if (pop->IsImmediate() && g.ToConstant(pop).ToInt32() == 0) {
|
||||
if (return_label_.is_bound()) {
|
||||
__ b(&return_label_);
|
||||
return;
|
||||
} else {
|
||||
__ bind(&return_label_);
|
||||
AssembleDeconstructFrame();
|
||||
}
|
||||
} else {
|
||||
__ bind(&return_label_);
|
||||
AssembleDeconstructFrame();
|
||||
}
|
||||
}
|
||||
__ Ret(pop_count);
|
||||
if (pop->IsImmediate()) {
|
||||
DCHECK_EQ(Constant::kInt32, g.ToConstant(pop).type());
|
||||
pop_count += g.ToConstant(pop).ToInt32();
|
||||
} else {
|
||||
__ Drop(g.ToRegister(pop));
|
||||
}
|
||||
__ Drop(pop_count);
|
||||
__ Ret();
|
||||
}
|
||||
|
||||
void CodeGenerator::AssembleMove(InstructionOperand* source,
|
||||
|
Loading…
Reference in New Issue
Block a user