Commit 2f3cda58 authored by Bill Budge's avatar Bill Budge Committed by Commit Bot

[compiler] Rework calculation to start of return slots

- Changes GetOffsetToReturns to take into account return slot padding
  and argument padding.
- Changes GetStackParameterDelta to use GetOffsetToReturns for the SP
  delta calculation.
- Removes GetFirstUnusedStackSlot.

Change-Id: I13df72e86750c62798bae262f0560cf1d7f981db
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2593306
Commit-Queue: Bill Budge <bbudge@chromium.org>
Reviewed-by: 's avatarAndreas Haas <ahaas@chromium.org>
Reviewed-by: 's avatarGeorg Neis <neis@chromium.org>
Cr-Commit-Position: refs/heads/master@{#72078}
parent 2d2d95c6
......@@ -3076,7 +3076,7 @@ void InstructionSelector::VisitTailCall(Node* node) {
// instruction. This is used by backends that need to pad arguments for stack
// alignment, in order to store an optional slot of padding above the
// arguments.
const int optional_padding_slot = callee->GetFirstUnusedStackSlot();
const int optional_padding_slot = callee->GetOffsetToReturns();
buffer.instruction_args.push_back(g.TempImmediate(optional_padding_slot));
const int first_unused_stack_slot =
......
......@@ -77,21 +77,6 @@ MachineSignature* CallDescriptor::GetMachineSignature(Zone* zone) const {
return zone->New<MachineSignature>(return_count, param_count, types);
}
int CallDescriptor::GetFirstUnusedStackSlot() const {
int slots_above_sp = 0;
for (size_t i = 0; i < InputCount(); ++i) {
LinkageLocation operand = GetInputLocation(i);
if (!operand.IsRegister()) {
int new_candidate =
-operand.GetLocation() + operand.GetSizeInPointers() - 1;
if (new_candidate > slots_above_sp) {
slots_above_sp = new_candidate;
}
}
}
return slots_above_sp;
}
int CallDescriptor::GetStackParameterDelta(
CallDescriptor const* tail_caller) const {
// In the IsTailCallForTierUp case, the callee has
......@@ -100,8 +85,8 @@ int CallDescriptor::GetStackParameterDelta(
// inputs to the TailCall node, since they already exist on the stack.
if (IsTailCallForTierUp()) return 0;
int callee_slots_above_sp = GetFirstUnusedStackSlot();
int tail_caller_slots_above_sp = tail_caller->GetFirstUnusedStackSlot();
int callee_slots_above_sp = GetOffsetToReturns();
int tail_caller_slots_above_sp = tail_caller->GetOffsetToReturns();
int stack_param_delta = callee_slots_above_sp - tail_caller_slots_above_sp;
if (ShouldPadArguments(stack_param_delta)) {
if (callee_slots_above_sp % 2 != 0) {
......@@ -120,9 +105,37 @@ int CallDescriptor::GetStackParameterDelta(
}
int CallDescriptor::GetOffsetToReturns() const {
int offset = static_cast<int>(StackParameterCount());
if (ShouldPadArguments(offset)) offset++;
return offset;
// If there are return stack slots, return the first slot of the last one.
constexpr int kNoReturnSlot = std::numeric_limits<int>::max();
int end_of_returns = kNoReturnSlot;
for (size_t i = 0; i < ReturnCount(); ++i) {
LinkageLocation operand = GetReturnLocation(i);
if (!operand.IsRegister()) {
// Reverse, since returns have negative offsets in the frame.
int reverse_location = -operand.GetLocation() - 1;
DCHECK_GE(reverse_location, 0);
end_of_returns = std::min(end_of_returns, reverse_location);
}
}
if (end_of_returns != kNoReturnSlot) return end_of_returns;
// Otherwise, return the first unused slot before the parameters, with any
// additional padding slot if it exists.
int start_of_args = 0;
for (size_t i = 0; i < InputCount(); ++i) {
LinkageLocation operand = GetInputLocation(i);
if (!operand.IsRegister()) {
// Reverse, since arguments have negative offsets in the frame.
int reverse_location =
-operand.GetLocation() + operand.GetSizeInPointers() - 1;
DCHECK_GE(reverse_location, 0);
start_of_args = std::max(start_of_args, reverse_location);
}
}
if (ShouldPadArguments(start_of_args)) start_of_args++;
DCHECK_EQ(start_of_args == 0, StackParameterCount() == 0);
return start_of_args;
}
int CallDescriptor::GetTaggedParameterSlots() const {
......@@ -138,11 +151,12 @@ int CallDescriptor::GetTaggedParameterSlots() const {
bool CallDescriptor::CanTailCall(const CallDescriptor* callee) const {
if (ReturnCount() != callee->ReturnCount()) return false;
const int stack_param_delta = callee->GetStackParameterDelta(this);
const int stack_returns_delta =
GetOffsetToReturns() - callee->GetOffsetToReturns();
for (size_t i = 0; i < ReturnCount(); ++i) {
if (GetReturnLocation(i).IsCallerFrameSlot() &&
callee->GetReturnLocation(i).IsCallerFrameSlot()) {
if (GetReturnLocation(i).AsCallerFrameSlot() - stack_param_delta !=
if (GetReturnLocation(i).AsCallerFrameSlot() + stack_returns_delta !=
callee->GetReturnLocation(i).AsCallerFrameSlot()) {
return false;
}
......
......@@ -389,12 +389,11 @@ class V8_EXPORT_PRIVATE CallDescriptor final
bool UsesOnlyRegisters() const;
// Returns the first stack slot that is not used by the stack parameters.
int GetFirstUnusedStackSlot() const;
int GetStackParameterDelta(const CallDescriptor* tail_caller) const;
// Returns the number of slots to the first return value slot.
// If there are return stack slots, returns the first slot of the last one.
// Otherwise, return the first unused slot before the parameters. This is the
// slot where returns would go if there were any.
int GetOffsetToReturns() const;
int GetTaggedParameterSlots() const;
......
......@@ -29,16 +29,26 @@ class LinkageTailCall : public TestWithZone {
DCHECK(arraysize(kMachineTypes) >=
locations->return_count() + locations->parameter_count());
USE(kMachineTypes);
size_t stack_arguments = 0;
for (size_t i = 0; i < locations->parameter_count(); ++i) {
if (locations->GetParam(i).IsCallerFrameSlot()) stack_arguments++;
}
size_t stack_returns = 0;
for (size_t i = 0; i < locations->return_count(); ++i) {
if (locations->GetReturn(i).IsCallerFrameSlot()) stack_returns++;
}
return zone()->New<CallDescriptor>(
CallDescriptor::kCallCodeObject, MachineType::AnyTagged(),
LinkageLocation::ForAnyRegister(MachineType::Pointer()),
locations, // location_sig
0, // js_parameter_count
locations, // location_sig
stack_arguments,
Operator::kNoProperties, // properties
0, // callee-saved
0, // callee-saved fp
CallDescriptor::kNoFlags, // flags,
"");
"", StackArgumentOrder::kDefault,
0, // allocatable_registers
stack_returns);
}
LinkageLocation StackLocation(int loc) {
......
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