Commit cae7667c authored by Junliang Yan's avatar Junliang Yan Committed by Commit Bot

PPC/s390: Reland [turbofan] Implement on-stack returns (Intel)

Port bd732f7d

Original Commit Message:

    The original CL introduced a test which uses a random number generator.
    I disable the test for now, which is okay because this CL adds to a
    work-in-progress feature anyways, and I will fix the problem in another
    CL.

    Original description:
    Add the ability to return (multiple) return values on the stack:

    - Extend stack frames with a new buffer region for return slots.
      This region is located at the end of a caller's frame such that
      its slots can be indexed as caller frame slots in a callee
      (located beyond its parameters) and assigned return values.
    - Adjust stack frame constructon and deconstruction accordingly.
    - Extend linkage computation to support register plus stack returns.
    - Reserve return slots in caller frame when respective calls occur.
    - Introduce and generate architecture instructions ('peek') for
      reading back results from return slots in the caller.
    - Aggressive tests.
    - Some minor clean-up.

    So far, only ia32 and x64 are implemented.

R=ahaas@chromium.org, joransiu@ca.ibm.com, jbarboza@ca.ibm.com
BUG=
LOG=N

Change-Id: I8d63286aa5af5f52cc2eeaf2adeee13d0ff19e7d
Reviewed-on: https://chromium-review.googlesource.com/823084
Commit-Queue: Junliang Yan <jyan@ca.ibm.com>
Reviewed-by: 's avatarJoran Siu <joransiu@ca.ibm.com>
Reviewed-by: 's avatarAndreas Haas <ahaas@chromium.org>
Cr-Commit-Position: refs/heads/master@{#50091}
parent 2c3fae96
...@@ -1942,7 +1942,7 @@ void InstructionSelector::EmitPrepareArguments( ...@@ -1942,7 +1942,7 @@ void InstructionSelector::EmitPrepareArguments(
// Poke any stack arguments. // Poke any stack arguments.
int slot = kStackFrameExtraParamSlot; int slot = kStackFrameExtraParamSlot;
for (PushParameter input : (*arguments)) { for (PushParameter input : (*arguments)) {
Emit(kPPC_StoreToStackSlot, g.NoOutput(), g.UseRegister(input.node()), Emit(kPPC_StoreToStackSlot, g.NoOutput(), g.UseRegister(input.node),
g.TempImmediate(slot)); g.TempImmediate(slot));
++slot; ++slot;
} }
...@@ -1950,8 +1950,8 @@ void InstructionSelector::EmitPrepareArguments( ...@@ -1950,8 +1950,8 @@ void InstructionSelector::EmitPrepareArguments(
// Push any stack arguments. // Push any stack arguments.
for (PushParameter input : base::Reversed(*arguments)) { for (PushParameter input : base::Reversed(*arguments)) {
// Skip any alignment holes in pushed nodes. // Skip any alignment holes in pushed nodes.
if (input.node() == nullptr) continue; if (input.node == nullptr) continue;
Emit(kPPC_Push, g.NoOutput(), g.UseRegister(input.node())); Emit(kPPC_Push, g.NoOutput(), g.UseRegister(input.node));
} }
} }
} }
...@@ -2271,6 +2271,26 @@ void InstructionSelector::VisitS128Not(Node* node) { UNIMPLEMENTED(); } ...@@ -2271,6 +2271,26 @@ void InstructionSelector::VisitS128Not(Node* node) { UNIMPLEMENTED(); }
void InstructionSelector::VisitS128Zero(Node* node) { UNIMPLEMENTED(); } void InstructionSelector::VisitS128Zero(Node* node) { UNIMPLEMENTED(); }
void InstructionSelector::VisitF32x4Eq(Node* node) { UNIMPLEMENTED(); }
void InstructionSelector::VisitF32x4Ne(Node* node) { UNIMPLEMENTED(); }
void InstructionSelector::VisitF32x4Lt(Node* node) { UNIMPLEMENTED(); }
void InstructionSelector::VisitF32x4Le(Node* node) { UNIMPLEMENTED(); }
void InstructionSelector::VisitF32x4Splat(Node* node) { UNIMPLEMENTED(); }
void InstructionSelector::VisitF32x4ExtractLane(Node* node) { UNIMPLEMENTED(); }
void InstructionSelector::VisitF32x4ReplaceLane(Node* node) { UNIMPLEMENTED(); }
void InstructionSelector::EmitPrepareResults(ZoneVector<PushParameter>* results,
const CallDescriptor* descriptor,
Node* node) {
// TODO(John): Port.
}
// static // static
MachineOperatorBuilder::Flags MachineOperatorBuilder::Flags
InstructionSelector::SupportedMachineOperatorFlags() { InstructionSelector::SupportedMachineOperatorFlags() {
......
...@@ -2309,7 +2309,7 @@ void InstructionSelector::EmitPrepareArguments( ...@@ -2309,7 +2309,7 @@ void InstructionSelector::EmitPrepareArguments(
// Poke any stack arguments. // Poke any stack arguments.
int slot = kStackFrameExtraParamSlot; int slot = kStackFrameExtraParamSlot;
for (PushParameter input : (*arguments)) { for (PushParameter input : (*arguments)) {
Emit(kS390_StoreToStackSlot, g.NoOutput(), g.UseRegister(input.node()), Emit(kS390_StoreToStackSlot, g.NoOutput(), g.UseRegister(input.node),
g.TempImmediate(slot)); g.TempImmediate(slot));
++slot; ++slot;
} }
...@@ -2319,19 +2319,20 @@ void InstructionSelector::EmitPrepareArguments( ...@@ -2319,19 +2319,20 @@ void InstructionSelector::EmitPrepareArguments(
int slot = 0; int slot = 0;
for (PushParameter input : *arguments) { for (PushParameter input : *arguments) {
if (input.node() == nullptr) continue; if (input.node == nullptr) continue;
num_slots += num_slots += input.location.GetType().representation() ==
input.type().representation() == MachineRepresentation::kFloat64 MachineRepresentation::kFloat64
? kDoubleSize / kPointerSize ? kDoubleSize / kPointerSize
: 1; : 1;
} }
Emit(kS390_StackClaim, g.NoOutput(), g.TempImmediate(num_slots)); Emit(kS390_StackClaim, g.NoOutput(), g.TempImmediate(num_slots));
for (PushParameter input : *arguments) { for (PushParameter input : *arguments) {
// Skip any alignment holes in pushed nodes. // Skip any alignment holes in pushed nodes.
if (input.node()) { if (input.node) {
Emit(kS390_StoreToStackSlot, g.NoOutput(), g.UseRegister(input.node()), Emit(kS390_StoreToStackSlot, g.NoOutput(), g.UseRegister(input.node),
g.TempImmediate(slot)); g.TempImmediate(slot));
slot += input.type().representation() == MachineRepresentation::kFloat64 slot += input.location.GetType().representation() ==
MachineRepresentation::kFloat64
? (kDoubleSize / kPointerSize) ? (kDoubleSize / kPointerSize)
: 1; : 1;
} }
...@@ -2601,6 +2602,26 @@ void InstructionSelector::VisitS128Not(Node* node) { UNIMPLEMENTED(); } ...@@ -2601,6 +2602,26 @@ void InstructionSelector::VisitS128Not(Node* node) { UNIMPLEMENTED(); }
void InstructionSelector::VisitS128Zero(Node* node) { UNIMPLEMENTED(); } void InstructionSelector::VisitS128Zero(Node* node) { UNIMPLEMENTED(); }
void InstructionSelector::VisitF32x4Eq(Node* node) { UNIMPLEMENTED(); }
void InstructionSelector::VisitF32x4Ne(Node* node) { UNIMPLEMENTED(); }
void InstructionSelector::VisitF32x4Lt(Node* node) { UNIMPLEMENTED(); }
void InstructionSelector::VisitF32x4Le(Node* node) { UNIMPLEMENTED(); }
void InstructionSelector::VisitF32x4Splat(Node* node) { UNIMPLEMENTED(); }
void InstructionSelector::VisitF32x4ExtractLane(Node* node) { UNIMPLEMENTED(); }
void InstructionSelector::VisitF32x4ReplaceLane(Node* node) { UNIMPLEMENTED(); }
void InstructionSelector::EmitPrepareResults(ZoneVector<PushParameter>* results,
const CallDescriptor* descriptor,
Node* node) {
// TODO(John): Port.
}
// static // static
MachineOperatorBuilder::Flags MachineOperatorBuilder::Flags
InstructionSelector::SupportedMachineOperatorFlags() { InstructionSelector::SupportedMachineOperatorFlags() {
......
...@@ -165,8 +165,8 @@ ...@@ -165,8 +165,8 @@
}], # 'arch == arm64 and mode == debug and simulator_run' }], # 'arch == arm64 and mode == debug and simulator_run'
############################################################################## ##############################################################################
# TODO(ahaas): Port multiple return values to ARM and MIPS # TODO(ahaas): Port multiple return values to ARM, MIPS, S390 and PPC
['arch == arm or arch == arm64 or arch == mips or arch == mips64 or arch == mipsel or arch == mips64el', { ['arch == arm or arch == arm64 or arch == mips or arch == mips64 or arch == mipsel or arch == mips64el or arch == s390 or arch == s390x or arch == ppc or arch == ppc64', {
'test-multiple-return/*': [SKIP], 'test-multiple-return/*': [SKIP],
}], }],
['system == windows and arch == x64', { ['system == windows and arch == x64', {
......
...@@ -199,8 +199,8 @@ ...@@ -199,8 +199,8 @@
}], # novfp3 == True }], # novfp3 == True
############################################################################## ##############################################################################
# TODO(ahaas): Port multiple return values to ARM and MIPS # TODO(ahaas): Port multiple return values to ARM, MIPS, S390 and PPC
['arch == arm or arch == arm64 or arch == mips or arch == mips64 or arch == mipsel or arch == mips64el', { ['arch == arm or arch == arm64 or arch == mips or arch == mips64 or arch == mipsel or arch == mips64el or arch == s390 or arch == s390x or arch == ppc or arch == ppc64', {
'wasm/multi-value': [SKIP], 'wasm/multi-value': [SKIP],
}], }],
......
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