[turbofan] Pass type information of arguments to EmitPrepareArguments.
On ia32 the code which pushes parameters on the stack depends on the types of the parameters which are to be pushed. I provide this type information now by not only passing parameter nodes to EmitPrepareArguments, but also the index in the call descriptor which belongs to the parameter nodes. This type information will also be necessary if we want to use the PokePair instruction on arm64 again. R=bradnelson@chromium.org, bmeurer@chromium.org Review URL: https://codereview.chromium.org/1534593004 Cr-Commit-Position: refs/heads/master@{#32982}
This commit is contained in:
parent
bf8c5160dc
commit
c0c8c756de
@ -1158,9 +1158,9 @@ void InstructionSelector::VisitFloat64RoundTiesEven(Node* node) {
|
||||
}
|
||||
|
||||
|
||||
void InstructionSelector::EmitPrepareArguments(NodeVector* arguments,
|
||||
const CallDescriptor* descriptor,
|
||||
Node* node) {
|
||||
void InstructionSelector::EmitPrepareArguments(
|
||||
ZoneVector<PushParameter>* arguments, const CallDescriptor* descriptor,
|
||||
Node* node) {
|
||||
ArmOperandGenerator g(this);
|
||||
|
||||
// Prepare for C function call.
|
||||
@ -1171,18 +1171,19 @@ void InstructionSelector::EmitPrepareArguments(NodeVector* arguments,
|
||||
|
||||
// Poke any stack arguments.
|
||||
for (size_t n = 0; n < arguments->size(); ++n) {
|
||||
if (Node* input = (*arguments)[n]) {
|
||||
PushParameter input = (*arguments)[n];
|
||||
if (input.node()) {
|
||||
int slot = static_cast<int>(n);
|
||||
Emit(kArmPoke | MiscField::encode(slot), g.NoOutput(),
|
||||
g.UseRegister(input));
|
||||
g.UseRegister(input.node()));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Push any stack arguments.
|
||||
for (Node* input : base::Reversed(*arguments)) {
|
||||
for (PushParameter input : base::Reversed(*arguments)) {
|
||||
// Skip any alignment holes in pushed nodes.
|
||||
if (input == nullptr) continue;
|
||||
Emit(kArmPush, g.NoOutput(), g.UseRegister(input));
|
||||
if (input.node() == nullptr) continue;
|
||||
Emit(kArmPush, g.NoOutput(), g.UseRegister(input.node()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1574,9 +1574,9 @@ void InstructionSelector::VisitFloat64RoundTiesEven(Node* node) {
|
||||
}
|
||||
|
||||
|
||||
void InstructionSelector::EmitPrepareArguments(NodeVector* arguments,
|
||||
const CallDescriptor* descriptor,
|
||||
Node* node) {
|
||||
void InstructionSelector::EmitPrepareArguments(
|
||||
ZoneVector<PushParameter>* arguments, const CallDescriptor* descriptor,
|
||||
Node* node) {
|
||||
Arm64OperandGenerator g(this);
|
||||
|
||||
// Push the arguments to the stack.
|
||||
@ -1602,7 +1602,7 @@ void InstructionSelector::EmitPrepareArguments(NodeVector* arguments,
|
||||
// Move arguments to the stack.
|
||||
int slot = aligned_push_count - 1;
|
||||
while (slot >= 0) {
|
||||
Emit(kArm64Poke, g.NoOutput(), g.UseRegister((*arguments)[slot]),
|
||||
Emit(kArm64Poke, g.NoOutput(), g.UseRegister((*arguments)[slot].node()),
|
||||
g.TempImmediate(slot));
|
||||
slot--;
|
||||
// TODO(ahaas): Poke arguments in pairs if two subsequent arguments have the
|
||||
|
@ -1000,6 +1000,40 @@ void CodeGenerator::AssembleArchInstruction(Instruction* instr) {
|
||||
}
|
||||
break;
|
||||
}
|
||||
case kIA32PushFloat32:
|
||||
if (instr->InputAt(0)->IsDoubleRegister()) {
|
||||
__ sub(esp, Immediate(kDoubleSize));
|
||||
__ movss(Operand(esp, 0), i.InputDoubleRegister(0));
|
||||
frame_access_state()->IncreaseSPDelta(kDoubleSize / kPointerSize);
|
||||
} else if (HasImmediateInput(instr, 0)) {
|
||||
__ Move(kScratchDoubleReg, i.InputDouble(0));
|
||||
__ sub(esp, Immediate(kDoubleSize));
|
||||
__ movss(Operand(esp, 0), kScratchDoubleReg);
|
||||
frame_access_state()->IncreaseSPDelta(kDoubleSize / kPointerSize);
|
||||
} else {
|
||||
__ movsd(kScratchDoubleReg, i.InputOperand(0));
|
||||
__ sub(esp, Immediate(kDoubleSize));
|
||||
__ movss(Operand(esp, 0), kScratchDoubleReg);
|
||||
frame_access_state()->IncreaseSPDelta(kDoubleSize / kPointerSize);
|
||||
}
|
||||
break;
|
||||
case kIA32PushFloat64:
|
||||
if (instr->InputAt(0)->IsDoubleRegister()) {
|
||||
__ sub(esp, Immediate(kDoubleSize));
|
||||
__ movsd(Operand(esp, 0), i.InputDoubleRegister(0));
|
||||
frame_access_state()->IncreaseSPDelta(kDoubleSize / kPointerSize);
|
||||
} else if (HasImmediateInput(instr, 0)) {
|
||||
__ Move(kScratchDoubleReg, i.InputDouble(0));
|
||||
__ sub(esp, Immediate(kDoubleSize));
|
||||
__ movsd(Operand(esp, 0), kScratchDoubleReg);
|
||||
frame_access_state()->IncreaseSPDelta(kDoubleSize / kPointerSize);
|
||||
} else {
|
||||
__ movsd(kScratchDoubleReg, i.InputOperand(0));
|
||||
__ sub(esp, Immediate(kDoubleSize));
|
||||
__ movsd(Operand(esp, 0), kScratchDoubleReg);
|
||||
frame_access_state()->IncreaseSPDelta(kDoubleSize / kPointerSize);
|
||||
}
|
||||
break;
|
||||
case kIA32Push:
|
||||
if (instr->InputAt(0)->IsDoubleRegister()) {
|
||||
__ sub(esp, Immediate(kDoubleSize));
|
||||
|
@ -96,6 +96,8 @@ namespace compiler {
|
||||
V(IA32BitcastIF) \
|
||||
V(IA32Lea) \
|
||||
V(IA32Push) \
|
||||
V(IA32PushFloat32) \
|
||||
V(IA32PushFloat64) \
|
||||
V(IA32Poke) \
|
||||
V(IA32StackCheck)
|
||||
|
||||
|
@ -108,6 +108,8 @@ int InstructionScheduler::GetTargetInstructionFlags(
|
||||
return kIsLoadOperation;
|
||||
|
||||
case kIA32Push:
|
||||
case kIA32PushFloat32:
|
||||
case kIA32PushFloat64:
|
||||
case kIA32Poke:
|
||||
return kHasSideEffect;
|
||||
|
||||
|
@ -896,9 +896,9 @@ void InstructionSelector::VisitFloat64RoundTiesEven(Node* node) {
|
||||
}
|
||||
|
||||
|
||||
void InstructionSelector::EmitPrepareArguments(NodeVector* arguments,
|
||||
const CallDescriptor* descriptor,
|
||||
Node* node) {
|
||||
void InstructionSelector::EmitPrepareArguments(
|
||||
ZoneVector<PushParameter>* arguments, const CallDescriptor* descriptor,
|
||||
Node* node) {
|
||||
IA32OperandGenerator g(this);
|
||||
|
||||
// Prepare for C function call.
|
||||
@ -911,29 +911,34 @@ void InstructionSelector::EmitPrepareArguments(NodeVector* arguments,
|
||||
|
||||
// Poke any stack arguments.
|
||||
for (size_t n = 0; n < arguments->size(); ++n) {
|
||||
if (Node* input = (*arguments)[n]) {
|
||||
PushParameter input = (*arguments)[n];
|
||||
if (input.node()) {
|
||||
int const slot = static_cast<int>(n);
|
||||
InstructionOperand value = g.CanBeImmediate(node)
|
||||
? g.UseImmediate(input)
|
||||
: g.UseRegister(input);
|
||||
? g.UseImmediate(input.node())
|
||||
: g.UseRegister(input.node());
|
||||
Emit(kIA32Poke | MiscField::encode(slot), g.NoOutput(), value);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Push any stack arguments.
|
||||
for (Node* input : base::Reversed(*arguments)) {
|
||||
for (PushParameter input : base::Reversed(*arguments)) {
|
||||
// Skip any alignment holes in pushed nodes.
|
||||
if (input == nullptr) continue;
|
||||
// TODO(titzer): IA32Push cannot handle stack->stack double moves
|
||||
// because there is no way to encode fixed double slots.
|
||||
if (input.node() == nullptr) continue;
|
||||
InstructionOperand value =
|
||||
g.CanBeImmediate(input)
|
||||
? g.UseImmediate(input)
|
||||
g.CanBeImmediate(input.node())
|
||||
? g.UseImmediate(input.node())
|
||||
: IsSupported(ATOM) ||
|
||||
sequence()->IsFloat(GetVirtualRegister(input))
|
||||
? g.UseRegister(input)
|
||||
: g.Use(input);
|
||||
Emit(kIA32Push, g.NoOutput(), value);
|
||||
sequence()->IsFloat(GetVirtualRegister(input.node()))
|
||||
? g.UseRegister(input.node())
|
||||
: g.Use(input.node());
|
||||
if (input.type() == MachineType::Float32()) {
|
||||
Emit(kIA32PushFloat32, g.NoOutput(), value);
|
||||
} else if (input.type() == MachineType::Float64()) {
|
||||
Emit(kIA32PushFloat64, g.NoOutput(), value);
|
||||
} else {
|
||||
Emit(kIA32Push, g.NoOutput(), value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -397,7 +397,7 @@ struct CallBuffer {
|
||||
NodeVector output_nodes;
|
||||
InstructionOperandVector outputs;
|
||||
InstructionOperandVector instruction_args;
|
||||
NodeVector pushed_nodes;
|
||||
ZoneVector<PushParameter> pushed_nodes;
|
||||
|
||||
size_t input_count() const { return descriptor->InputCount(); }
|
||||
|
||||
@ -539,10 +539,10 @@ void InstructionSelector::InitializeCallBuffer(Node* call, CallBuffer* buffer,
|
||||
if (UnallocatedOperand::cast(op).HasFixedSlotPolicy() && !call_tail) {
|
||||
int stack_index = -UnallocatedOperand::cast(op).fixed_slot_index() - 1;
|
||||
if (static_cast<size_t>(stack_index) >= buffer->pushed_nodes.size()) {
|
||||
buffer->pushed_nodes.resize(stack_index + 1, NULL);
|
||||
buffer->pushed_nodes.resize(stack_index + 1);
|
||||
}
|
||||
DCHECK(!buffer->pushed_nodes[stack_index]);
|
||||
buffer->pushed_nodes[stack_index] = *iter;
|
||||
PushParameter parameter(*iter, buffer->descriptor->GetInputType(index));
|
||||
buffer->pushed_nodes[stack_index] = parameter;
|
||||
pushed_count++;
|
||||
} else {
|
||||
buffer->instruction_args.push_back(op);
|
||||
|
@ -28,6 +28,20 @@ struct SwitchInfo;
|
||||
|
||||
typedef ZoneVector<InstructionOperand> InstructionOperandVector;
|
||||
|
||||
// This struct connects nodes of parameters which are going to be pushed on the
|
||||
// call stack with their parameter index in the call descriptor of the callee.
|
||||
class PushParameter {
|
||||
public:
|
||||
PushParameter() : node_(nullptr), type_(MachineType::None()) {}
|
||||
PushParameter(Node* node, MachineType type) : node_(node), type_(type) {}
|
||||
|
||||
Node* node() const { return node_; }
|
||||
MachineType type() const { return type_; }
|
||||
|
||||
private:
|
||||
Node* node_;
|
||||
MachineType type_;
|
||||
};
|
||||
|
||||
// Instruction selection generates an InstructionSequence for a given Schedule.
|
||||
class InstructionSelector final {
|
||||
@ -233,7 +247,7 @@ class InstructionSelector final {
|
||||
void VisitReturn(Node* ret);
|
||||
void VisitThrow(Node* value);
|
||||
|
||||
void EmitPrepareArguments(NodeVector* arguments,
|
||||
void EmitPrepareArguments(ZoneVector<compiler::PushParameter>* arguments,
|
||||
const CallDescriptor* descriptor, Node* node);
|
||||
|
||||
// ===========================================================================
|
||||
|
@ -805,9 +805,9 @@ void InstructionSelector::VisitFloat64RoundTiesEven(Node* node) {
|
||||
}
|
||||
|
||||
|
||||
void InstructionSelector::EmitPrepareArguments(NodeVector* arguments,
|
||||
const CallDescriptor* descriptor,
|
||||
Node* node) {
|
||||
void InstructionSelector::EmitPrepareArguments(
|
||||
ZoneVector<PushParameter>* arguments, const CallDescriptor* descriptor,
|
||||
Node* node) {
|
||||
MipsOperandGenerator g(this);
|
||||
|
||||
// Prepare for C function call.
|
||||
@ -818,8 +818,8 @@ void InstructionSelector::EmitPrepareArguments(NodeVector* arguments,
|
||||
|
||||
// Poke any stack arguments.
|
||||
int slot = kCArgSlotCount;
|
||||
for (Node* input : (*arguments)) {
|
||||
Emit(kMipsStoreToStackSlot, g.NoOutput(), g.UseRegister(input),
|
||||
for (PushParameter input : (*arguments)) {
|
||||
Emit(kMipsStoreToStackSlot, g.NoOutput(), g.UseRegister(input.node()),
|
||||
g.TempImmediate(slot << kPointerSizeLog2));
|
||||
++slot;
|
||||
}
|
||||
@ -831,8 +831,9 @@ void InstructionSelector::EmitPrepareArguments(NodeVector* arguments,
|
||||
g.TempImmediate(push_count << kPointerSizeLog2));
|
||||
}
|
||||
for (size_t n = 0; n < arguments->size(); ++n) {
|
||||
if (Node* input = (*arguments)[n]) {
|
||||
Emit(kMipsStoreToStackSlot, g.NoOutput(), g.UseRegister(input),
|
||||
PushParameter input = (*arguments)[n];
|
||||
if (input.node()) {
|
||||
Emit(kMipsStoreToStackSlot, g.NoOutput(), g.UseRegister(input.node()),
|
||||
g.TempImmediate(n << kPointerSizeLog2));
|
||||
}
|
||||
}
|
||||
|
@ -1241,9 +1241,9 @@ void InstructionSelector::VisitFloat64RoundTiesEven(Node* node) {
|
||||
}
|
||||
|
||||
|
||||
void InstructionSelector::EmitPrepareArguments(NodeVector* arguments,
|
||||
const CallDescriptor* descriptor,
|
||||
Node* node) {
|
||||
void InstructionSelector::EmitPrepareArguments(
|
||||
ZoneVector<PushParameter>* arguments, const CallDescriptor* descriptor,
|
||||
Node* node) {
|
||||
Mips64OperandGenerator g(this);
|
||||
|
||||
// Prepare for C function call.
|
||||
@ -1254,8 +1254,8 @@ void InstructionSelector::EmitPrepareArguments(NodeVector* arguments,
|
||||
|
||||
// Poke any stack arguments.
|
||||
int slot = kCArgSlotCount;
|
||||
for (Node* input : (*arguments)) {
|
||||
Emit(kMips64StoreToStackSlot, g.NoOutput(), g.UseRegister(input),
|
||||
for (PushParameter input : (*arguments)) {
|
||||
Emit(kMips64StoreToStackSlot, g.NoOutput(), g.UseRegister(input.node()),
|
||||
g.TempImmediate(slot << kPointerSizeLog2));
|
||||
++slot;
|
||||
}
|
||||
@ -1266,8 +1266,9 @@ void InstructionSelector::EmitPrepareArguments(NodeVector* arguments,
|
||||
g.TempImmediate(push_count << kPointerSizeLog2));
|
||||
}
|
||||
for (size_t n = 0; n < arguments->size(); ++n) {
|
||||
if (Node* input = (*arguments)[n]) {
|
||||
Emit(kMips64StoreToStackSlot, g.NoOutput(), g.UseRegister(input),
|
||||
PushParameter input = (*arguments)[n];
|
||||
if (input.node()) {
|
||||
Emit(kMips64StoreToStackSlot, g.NoOutput(), g.UseRegister(input.node()),
|
||||
g.TempImmediate(static_cast<int>(n << kPointerSizeLog2)));
|
||||
}
|
||||
}
|
||||
|
@ -1611,9 +1611,9 @@ void InstructionSelector::VisitFloat64LessThanOrEqual(Node* node) {
|
||||
}
|
||||
|
||||
|
||||
void InstructionSelector::EmitPrepareArguments(NodeVector* arguments,
|
||||
const CallDescriptor* descriptor,
|
||||
Node* node) {
|
||||
void InstructionSelector::EmitPrepareArguments(
|
||||
ZoneVector<PushParameter>* arguments, const CallDescriptor* descriptor,
|
||||
Node* node) {
|
||||
PPCOperandGenerator g(this);
|
||||
|
||||
// Prepare for C function call.
|
||||
@ -1624,8 +1624,8 @@ void InstructionSelector::EmitPrepareArguments(NodeVector* arguments,
|
||||
|
||||
// Poke any stack arguments.
|
||||
int slot = kStackFrameExtraParamSlot;
|
||||
for (Node* node : (*arguments)) {
|
||||
Emit(kPPC_StoreToStackSlot, g.NoOutput(), g.UseRegister(node),
|
||||
for (PushParameter input : (*arguments)) {
|
||||
Emit(kPPC_StoreToStackSlot, g.NoOutput(), g.UseRegister(input.node()),
|
||||
g.TempImmediate(slot));
|
||||
++slot;
|
||||
}
|
||||
@ -1633,15 +1633,15 @@ void InstructionSelector::EmitPrepareArguments(NodeVector* arguments,
|
||||
// Push any stack arguments.
|
||||
int num_slots = static_cast<int>(descriptor->StackParameterCount());
|
||||
int slot = 0;
|
||||
for (Node* input : (*arguments)) {
|
||||
for (PushParameter input : (*arguments)) {
|
||||
if (slot == 0) {
|
||||
DCHECK(input);
|
||||
Emit(kPPC_PushFrame, g.NoOutput(), g.UseRegister(input),
|
||||
DCHECK(input.node());
|
||||
Emit(kPPC_PushFrame, g.NoOutput(), g.UseRegister(input.node()),
|
||||
g.TempImmediate(num_slots));
|
||||
} else {
|
||||
// Skip any alignment holes in pushed nodes.
|
||||
if (input) {
|
||||
Emit(kPPC_StoreToStackSlot, g.NoOutput(), g.UseRegister(input),
|
||||
if (input.node()) {
|
||||
Emit(kPPC_StoreToStackSlot, g.NoOutput(), g.UseRegister(input.node()),
|
||||
g.TempImmediate(slot));
|
||||
}
|
||||
}
|
||||
|
@ -1233,9 +1233,9 @@ void InstructionSelector::VisitFloat64RoundTiesEven(Node* node) {
|
||||
}
|
||||
|
||||
|
||||
void InstructionSelector::EmitPrepareArguments(NodeVector* arguments,
|
||||
const CallDescriptor* descriptor,
|
||||
Node* node) {
|
||||
void InstructionSelector::EmitPrepareArguments(
|
||||
ZoneVector<PushParameter>* arguments, const CallDescriptor* descriptor,
|
||||
Node* node) {
|
||||
X64OperandGenerator g(this);
|
||||
|
||||
// Prepare for C function call.
|
||||
@ -1246,26 +1246,27 @@ void InstructionSelector::EmitPrepareArguments(NodeVector* arguments,
|
||||
|
||||
// Poke any stack arguments.
|
||||
for (size_t n = 0; n < arguments->size(); ++n) {
|
||||
if (Node* input = (*arguments)[n]) {
|
||||
PushParameter input = (*arguments)[n];
|
||||
if (input.node()) {
|
||||
int slot = static_cast<int>(n);
|
||||
InstructionOperand value = g.CanBeImmediate(input)
|
||||
? g.UseImmediate(input)
|
||||
: g.UseRegister(input);
|
||||
InstructionOperand value = g.CanBeImmediate(input.node())
|
||||
? g.UseImmediate(input.node())
|
||||
: g.UseRegister(input.node());
|
||||
Emit(kX64Poke | MiscField::encode(slot), g.NoOutput(), value);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Push any stack arguments.
|
||||
for (Node* input : base::Reversed(*arguments)) {
|
||||
for (PushParameter input : base::Reversed(*arguments)) {
|
||||
// TODO(titzer): X64Push cannot handle stack->stack double moves
|
||||
// because there is no way to encode fixed double slots.
|
||||
InstructionOperand value =
|
||||
g.CanBeImmediate(input)
|
||||
? g.UseImmediate(input)
|
||||
g.CanBeImmediate(input.node())
|
||||
? g.UseImmediate(input.node())
|
||||
: IsSupported(ATOM) ||
|
||||
sequence()->IsFloat(GetVirtualRegister(input))
|
||||
? g.UseRegister(input)
|
||||
: g.Use(input);
|
||||
sequence()->IsFloat(GetVirtualRegister(input.node()))
|
||||
? g.UseRegister(input.node())
|
||||
: g.Use(input.node());
|
||||
Emit(kX64Push, g.NoOutput(), value);
|
||||
}
|
||||
}
|
||||
|
@ -903,9 +903,9 @@ void InstructionSelector::VisitFloat64RoundTiesEven(Node* node) {
|
||||
}
|
||||
|
||||
|
||||
void InstructionSelector::EmitPrepareArguments(NodeVector* arguments,
|
||||
const CallDescriptor* descriptor,
|
||||
Node* node) {
|
||||
void InstructionSelector::EmitPrepareArguments(
|
||||
ZoneVector<PushParameter>* arguments, const CallDescriptor* descriptor,
|
||||
Node* node) {
|
||||
X87OperandGenerator g(this);
|
||||
|
||||
// Prepare for C function call.
|
||||
@ -918,26 +918,27 @@ void InstructionSelector::EmitPrepareArguments(NodeVector* arguments,
|
||||
|
||||
// Poke any stack arguments.
|
||||
for (size_t n = 0; n < arguments->size(); ++n) {
|
||||
if (Node* input = (*arguments)[n]) {
|
||||
PushParameter input = (*arguments)[n];
|
||||
if (input.node()) {
|
||||
int const slot = static_cast<int>(n);
|
||||
InstructionOperand value = g.CanBeImmediate(input)
|
||||
? g.UseImmediate(input)
|
||||
: g.UseRegister(input);
|
||||
InstructionOperand value = g.CanBeImmediate(input.node())
|
||||
? g.UseImmediate(input.node())
|
||||
: g.UseRegister(input.node());
|
||||
Emit(kX87Poke | MiscField::encode(slot), g.NoOutput(), value);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Push any stack arguments.
|
||||
for (Node* input : base::Reversed(*arguments)) {
|
||||
for (PushParameter input : base::Reversed(*arguments)) {
|
||||
// TODO(titzer): handle pushing double parameters.
|
||||
if (input == nullptr) continue;
|
||||
if (input.node() == nullptr) continue;
|
||||
InstructionOperand value =
|
||||
g.CanBeImmediate(input)
|
||||
? g.UseImmediate(input)
|
||||
g.CanBeImmediate(input.node())
|
||||
? g.UseImmediate(input.node())
|
||||
: IsSupported(ATOM) ||
|
||||
sequence()->IsFloat(GetVirtualRegister(input))
|
||||
? g.UseRegister(input)
|
||||
: g.Use(input);
|
||||
sequence()->IsFloat(GetVirtualRegister(input.node()))
|
||||
? g.UseRegister(input.node())
|
||||
: g.Use(input.node());
|
||||
Emit(kX87Push, g.NoOutput(), value);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user