From 4116900d8fbac6eeaa1177eb489bc581efc7844f Mon Sep 17 00:00:00 2001 From: dcarney Date: Wed, 4 Feb 2015 04:38:47 -0800 Subject: [PATCH] [turbofan] Don't allocate UnallocatedOperands in Zone memory during instruction selection R=bmeurer@chromium.org Review URL: https://codereview.chromium.org/889843003 Cr-Commit-Position: refs/heads/master@{#26424} --- src/compiler/arm/instruction-selector-arm.cc | 119 ++++++++------- src/compiler/arm64/instruction-selector-arm64.cc | 42 +++--- src/compiler/ia32/instruction-selector-ia32.cc | 62 ++++---- src/compiler/instruction-selector-impl.h | 161 ++++++++++----------- src/compiler/instruction-selector.cc | 108 +++++++------- src/compiler/instruction-selector.h | 63 ++++---- src/compiler/instruction.cc | 25 ++-- src/compiler/instruction.h | 52 ++++--- src/compiler/mips/instruction-selector-mips.cc | 80 +++++----- src/compiler/mips64/instruction-selector-mips64.cc | 84 +++++------ src/compiler/x64/instruction-selector-x64.cc | 53 +++---- test/cctest/compiler/test-instruction.cc | 52 +++---- test/cctest/compiler/test-jump-threading.cc | 8 +- .../compiler/instruction-sequence-unittest.cc | 71 +++++---- .../compiler/instruction-sequence-unittest.h | 40 ++--- 15 files changed, 513 insertions(+), 507 deletions(-) diff --git a/src/compiler/arm/instruction-selector-arm.cc b/src/compiler/arm/instruction-selector-arm.cc index 7219ca3..9122359 100644 --- a/src/compiler/arm/instruction-selector-arm.cc +++ b/src/compiler/arm/instruction-selector-arm.cc @@ -99,8 +99,8 @@ template bool TryMatchShift(InstructionSelector* selector, InstructionCode* opcode_return, Node* node, - InstructionOperand** value_return, - InstructionOperand** shift_return) { + InstructionOperand* value_return, + InstructionOperand* shift_return) { ArmOperandGenerator g(selector); if (node->opcode() == kOpcode) { Int32BinopMatcher m(node); @@ -119,8 +119,8 @@ bool TryMatchShift(InstructionSelector* selector, bool TryMatchROR(InstructionSelector* selector, InstructionCode* opcode_return, - Node* node, InstructionOperand** value_return, - InstructionOperand** shift_return) { + Node* node, InstructionOperand* value_return, + InstructionOperand* shift_return) { return TryMatchShift(selector, opcode_return, node, value_return, shift_return); @@ -128,8 +128,8 @@ bool TryMatchROR(InstructionSelector* selector, InstructionCode* opcode_return, bool TryMatchASR(InstructionSelector* selector, InstructionCode* opcode_return, - Node* node, InstructionOperand** value_return, - InstructionOperand** shift_return) { + Node* node, InstructionOperand* value_return, + InstructionOperand* shift_return) { return TryMatchShift(selector, opcode_return, node, value_return, shift_return); @@ -137,8 +137,8 @@ bool TryMatchASR(InstructionSelector* selector, InstructionCode* opcode_return, bool TryMatchLSL(InstructionSelector* selector, InstructionCode* opcode_return, - Node* node, InstructionOperand** value_return, - InstructionOperand** shift_return) { + Node* node, InstructionOperand* value_return, + InstructionOperand* shift_return) { return TryMatchShift(selector, opcode_return, node, value_return, shift_return); @@ -146,8 +146,8 @@ bool TryMatchLSL(InstructionSelector* selector, InstructionCode* opcode_return, bool TryMatchLSR(InstructionSelector* selector, InstructionCode* opcode_return, - Node* node, InstructionOperand** value_return, - InstructionOperand** shift_return) { + Node* node, InstructionOperand* value_return, + InstructionOperand* shift_return) { return TryMatchShift(selector, opcode_return, node, value_return, shift_return); @@ -156,8 +156,8 @@ bool TryMatchLSR(InstructionSelector* selector, InstructionCode* opcode_return, bool TryMatchShift(InstructionSelector* selector, InstructionCode* opcode_return, Node* node, - InstructionOperand** value_return, - InstructionOperand** shift_return) { + InstructionOperand* value_return, + InstructionOperand* shift_return) { return ( TryMatchASR(selector, opcode_return, node, value_return, shift_return) || TryMatchLSL(selector, opcode_return, node, value_return, shift_return) || @@ -169,7 +169,7 @@ bool TryMatchShift(InstructionSelector* selector, bool TryMatchImmediateOrShift(InstructionSelector* selector, InstructionCode* opcode_return, Node* node, size_t* input_count_return, - InstructionOperand** inputs) { + InstructionOperand* inputs) { ArmOperandGenerator g(selector); if (g.CanBeImmediate(node, *opcode_return)) { *opcode_return |= AddressingModeField::encode(kMode_Operand2_I); @@ -190,9 +190,9 @@ void VisitBinop(InstructionSelector* selector, Node* node, FlagsContinuation* cont) { ArmOperandGenerator g(selector); Int32BinopMatcher m(node); - InstructionOperand* inputs[5]; + InstructionOperand inputs[5]; size_t input_count = 0; - InstructionOperand* outputs[2]; + InstructionOperand outputs[2]; size_t output_count = 0; if (m.left().node() == m.right().node()) { @@ -203,7 +203,7 @@ void VisitBinop(InstructionSelector* selector, Node* node, // mov r0, r1, asr #16 // adds r0, r0, r1, asr #16 // bvs label - InstructionOperand* const input = g.UseRegister(m.left().node()); + InstructionOperand const input = g.UseRegister(m.left().node()); opcode |= AddressingModeField::encode(kMode_Operand2_R); inputs[input_count++] = input; inputs[input_count++] = input; @@ -309,10 +309,9 @@ void InstructionSelector::VisitStore(Node* node) { // TODO(dcarney): refactor RecordWrite function to take temp registers // and pass them here instead of using fixed regs // TODO(dcarney): handle immediate indices. - InstructionOperand* temps[] = {g.TempRegister(r5), g.TempRegister(r6)}; - Emit(kArmStoreWriteBarrier, NULL, g.UseFixed(base, r4), - g.UseFixed(index, r5), g.UseFixed(value, r6), arraysize(temps), - temps); + InstructionOperand temps[] = {g.TempRegister(r5), g.TempRegister(r6)}; + Emit(kArmStoreWriteBarrier, g.NoOutput(), g.UseFixed(base, r4), + g.UseFixed(index, r5), g.UseFixed(value, r6), arraysize(temps), temps); return; } DCHECK_EQ(kNoWriteBarrier, store_rep.write_barrier_kind()); @@ -342,10 +341,10 @@ void InstructionSelector::VisitStore(Node* node) { } if (g.CanBeImmediate(index, opcode)) { - Emit(opcode | AddressingModeField::encode(kMode_Offset_RI), NULL, + Emit(opcode | AddressingModeField::encode(kMode_Offset_RI), g.NoOutput(), g.UseRegister(base), g.UseImmediate(index), g.UseRegister(value)); } else { - Emit(opcode | AddressingModeField::encode(kMode_Offset_RR), NULL, + Emit(opcode | AddressingModeField::encode(kMode_Offset_RR), g.NoOutput(), g.UseRegister(base), g.UseRegister(index), g.UseRegister(value)); } } @@ -379,10 +378,10 @@ void InstructionSelector::VisitCheckedLoad(Node* node) { UNREACHABLE(); return; } - InstructionOperand* offset_operand = g.UseRegister(offset); - InstructionOperand* length_operand = g.CanBeImmediate(length, kArmCmp) - ? g.UseImmediate(length) - : g.UseRegister(length); + InstructionOperand offset_operand = g.UseRegister(offset); + InstructionOperand length_operand = g.CanBeImmediate(length, kArmCmp) + ? g.UseImmediate(length) + : g.UseRegister(length); Emit(opcode | AddressingModeField::encode(kMode_Offset_RR), g.DefineAsRegister(node), offset_operand, length_operand, g.UseRegister(buffer), offset_operand); @@ -417,11 +416,11 @@ void InstructionSelector::VisitCheckedStore(Node* node) { UNREACHABLE(); return; } - InstructionOperand* offset_operand = g.UseRegister(offset); - InstructionOperand* length_operand = g.CanBeImmediate(length, kArmCmp) - ? g.UseImmediate(length) - : g.UseRegister(length); - Emit(opcode | AddressingModeField::encode(kMode_Offset_RR), nullptr, + InstructionOperand offset_operand = g.UseRegister(offset); + InstructionOperand length_operand = g.CanBeImmediate(length, kArmCmp) + ? g.UseImmediate(length) + : g.UseRegister(length); + Emit(opcode | AddressingModeField::encode(kMode_Offset_RR), g.NoOutput(), offset_operand, length_operand, g.UseRegister(value), g.UseRegister(buffer), offset_operand); } @@ -433,8 +432,8 @@ void EmitBic(InstructionSelector* selector, Node* node, Node* left, Node* right) { ArmOperandGenerator g(selector); InstructionCode opcode = kArmBic; - InstructionOperand* value_operand; - InstructionOperand* shift_operand; + InstructionOperand value_operand; + InstructionOperand shift_operand; if (TryMatchShift(selector, &opcode, right, &value_operand, &shift_operand)) { selector->Emit(opcode, g.DefineAsRegister(node), g.UseRegister(left), value_operand, shift_operand); @@ -535,8 +534,8 @@ void InstructionSelector::VisitWord32Xor(Node* node) { Int32BinopMatcher m(node); if (m.right().Is(-1)) { InstructionCode opcode = kArmMvn; - InstructionOperand* value_operand; - InstructionOperand* shift_operand; + InstructionOperand value_operand; + InstructionOperand shift_operand; if (TryMatchShift(this, &opcode, m.left().node(), &value_operand, &shift_operand)) { Emit(opcode, g.DefineAsRegister(node), value_operand, shift_operand); @@ -557,9 +556,9 @@ void VisitShift(InstructionSelector* selector, Node* node, TryMatchShift try_match_shift, FlagsContinuation* cont) { ArmOperandGenerator g(selector); InstructionCode opcode = kArmMov; - InstructionOperand* inputs[4]; + InstructionOperand inputs[4]; size_t input_count = 2; - InstructionOperand* outputs[2]; + InstructionOperand outputs[2]; size_t output_count = 0; CHECK(try_match_shift(selector, &opcode, node, &inputs[0], &inputs[1])); @@ -809,26 +808,26 @@ void InstructionSelector::VisitInt32MulHigh(Node* node) { void InstructionSelector::VisitUint32MulHigh(Node* node) { ArmOperandGenerator g(this); - InstructionOperand* outputs[] = {g.TempRegister(), g.DefineAsRegister(node)}; - InstructionOperand* inputs[] = {g.UseRegister(node->InputAt(0)), - g.UseRegister(node->InputAt(1))}; + InstructionOperand outputs[] = {g.TempRegister(), g.DefineAsRegister(node)}; + InstructionOperand inputs[] = {g.UseRegister(node->InputAt(0)), + g.UseRegister(node->InputAt(1))}; Emit(kArmUmull, arraysize(outputs), outputs, arraysize(inputs), inputs); } static void EmitDiv(InstructionSelector* selector, ArchOpcode div_opcode, ArchOpcode f64i32_opcode, ArchOpcode i32f64_opcode, - InstructionOperand* result_operand, - InstructionOperand* left_operand, - InstructionOperand* right_operand) { + InstructionOperand result_operand, + InstructionOperand left_operand, + InstructionOperand right_operand) { ArmOperandGenerator g(selector); if (selector->IsSupported(SUDIV)) { selector->Emit(div_opcode, result_operand, left_operand, right_operand); return; } - InstructionOperand* left_double_operand = g.TempDoubleRegister(); - InstructionOperand* right_double_operand = g.TempDoubleRegister(); - InstructionOperand* result_double_operand = g.TempDoubleRegister(); + InstructionOperand left_double_operand = g.TempDoubleRegister(); + InstructionOperand right_double_operand = g.TempDoubleRegister(); + InstructionOperand result_double_operand = g.TempDoubleRegister(); selector->Emit(f64i32_opcode, left_double_operand, left_operand); selector->Emit(f64i32_opcode, right_double_operand, right_operand); selector->Emit(kArmVdivF64, result_double_operand, left_double_operand, @@ -863,10 +862,10 @@ static void VisitMod(InstructionSelector* selector, Node* node, ArchOpcode i32f64_opcode) { ArmOperandGenerator g(selector); Int32BinopMatcher m(node); - InstructionOperand* div_operand = g.TempRegister(); - InstructionOperand* result_operand = g.DefineAsRegister(node); - InstructionOperand* left_operand = g.UseRegister(m.left().node()); - InstructionOperand* right_operand = g.UseRegister(m.right().node()); + InstructionOperand div_operand = g.TempRegister(); + InstructionOperand result_operand = g.DefineAsRegister(node); + InstructionOperand left_operand = g.UseRegister(m.left().node()); + InstructionOperand right_operand = g.UseRegister(m.right().node()); EmitDiv(selector, div_opcode, f64i32_opcode, i32f64_opcode, div_operand, left_operand, right_operand); if (selector->IsSupported(MLS)) { @@ -874,7 +873,7 @@ static void VisitMod(InstructionSelector* selector, Node* node, left_operand); return; } - InstructionOperand* mul_operand = g.TempRegister(); + InstructionOperand mul_operand = g.TempRegister(); selector->Emit(kArmMul, mul_operand, div_operand, right_operand); selector->Emit(kArmSub, result_operand, left_operand, mul_operand); } @@ -1041,7 +1040,7 @@ void InstructionSelector::VisitCall(Node* node) { // Push any stack arguments. for (auto i = buffer.pushed_nodes.rbegin(); i != buffer.pushed_nodes.rend(); ++i) { - Emit(kArmPush, nullptr, g.UseRegister(*i)); + Emit(kArmPush, g.NoOutput(), g.UseRegister(*i)); } // Select the appropriate opcode based on the call type. @@ -1061,7 +1060,7 @@ void InstructionSelector::VisitCall(Node* node) { opcode |= MiscField::encode(descriptor->flags()); // Emit the call instruction. - InstructionOperand** first_output = + InstructionOperand* first_output = buffer.outputs.size() > 0 ? &buffer.outputs.front() : NULL; Instruction* call_instr = Emit(opcode, buffer.outputs.size(), first_output, @@ -1077,10 +1076,10 @@ void VisitFloat64Compare(InstructionSelector* selector, Node* node, FlagsContinuation* cont) { ArmOperandGenerator g(selector); Float64BinopMatcher m(node); - InstructionOperand* rhs = m.right().Is(0.0) ? g.UseImmediate(m.right().node()) - : g.UseRegister(m.right().node()); + InstructionOperand rhs = m.right().Is(0.0) ? g.UseImmediate(m.right().node()) + : g.UseRegister(m.right().node()); if (cont->IsBranch()) { - selector->Emit(cont->Encode(kArmVcmpF64), nullptr, + selector->Emit(cont->Encode(kArmVcmpF64), g.NoOutput(), g.UseRegister(m.left().node()), rhs, g.Label(cont->true_block()), g.Label(cont->false_block()))->MarkAsControl(); @@ -1098,9 +1097,9 @@ void VisitWordCompare(InstructionSelector* selector, Node* node, InstructionCode opcode, FlagsContinuation* cont) { ArmOperandGenerator g(selector); Int32BinopMatcher m(node); - InstructionOperand* inputs[5]; + InstructionOperand inputs[5]; size_t input_count = 0; - InstructionOperand* outputs[1]; + InstructionOperand outputs[1]; size_t output_count = 0; if (TryMatchImmediateOrShift(selector, &opcode, m.right().node(), @@ -1234,9 +1233,9 @@ void VisitWordCompareZero(InstructionSelector* selector, Node* user, ArmOperandGenerator g(selector); InstructionCode const opcode = cont->Encode(kArmTst) | AddressingModeField::encode(kMode_Operand2_R); - InstructionOperand* const value_operand = g.UseRegister(value); + InstructionOperand const value_operand = g.UseRegister(value); if (cont->IsBranch()) { - selector->Emit(opcode, nullptr, value_operand, value_operand, + selector->Emit(opcode, g.NoOutput(), value_operand, value_operand, g.Label(cont->true_block()), g.Label(cont->false_block()))->MarkAsControl(); } else { diff --git a/src/compiler/arm64/instruction-selector-arm64.cc b/src/compiler/arm64/instruction-selector-arm64.cc index 4063f8a..d63b630 100644 --- a/src/compiler/arm64/instruction-selector-arm64.cc +++ b/src/compiler/arm64/instruction-selector-arm64.cc @@ -30,7 +30,7 @@ class Arm64OperandGenerator FINAL : public OperandGenerator { explicit Arm64OperandGenerator(InstructionSelector* selector) : OperandGenerator(selector) {} - InstructionOperand* UseOperand(Node* node, ImmediateMode mode) { + InstructionOperand UseOperand(Node* node, ImmediateMode mode) { if (CanBeImmediate(node, mode)) { return UseImmediate(node); } @@ -174,9 +174,9 @@ static void VisitBinop(InstructionSelector* selector, Node* node, FlagsContinuation* cont) { Arm64OperandGenerator g(selector); Matcher m(node); - InstructionOperand* inputs[4]; + InstructionOperand inputs[4]; size_t input_count = 0; - InstructionOperand* outputs[2]; + InstructionOperand outputs[2]; size_t output_count = 0; bool try_ror_operand = true; @@ -313,8 +313,8 @@ void InstructionSelector::VisitStore(Node* node) { // TODO(dcarney): refactor RecordWrite function to take temp registers // and pass them here instead of using fixed regs // TODO(dcarney): handle immediate indices. - InstructionOperand* temps[] = {g.TempRegister(x11), g.TempRegister(x12)}; - Emit(kArm64StoreWriteBarrier, NULL, g.UseFixed(base, x10), + InstructionOperand temps[] = {g.TempRegister(x11), g.TempRegister(x12)}; + Emit(kArm64StoreWriteBarrier, g.NoOutput(), g.UseFixed(base, x10), g.UseFixed(index, x11), g.UseFixed(value, x12), arraysize(temps), temps); return; @@ -354,10 +354,10 @@ void InstructionSelector::VisitStore(Node* node) { return; } if (g.CanBeImmediate(index, immediate_mode)) { - Emit(opcode | AddressingModeField::encode(kMode_MRI), NULL, + Emit(opcode | AddressingModeField::encode(kMode_MRI), g.NoOutput(), g.UseRegister(base), g.UseImmediate(index), g.UseRegister(value)); } else { - Emit(opcode | AddressingModeField::encode(kMode_MRR), NULL, + Emit(opcode | AddressingModeField::encode(kMode_MRR), g.NoOutput(), g.UseRegister(base), g.UseRegister(index), g.UseRegister(value)); } } @@ -424,7 +424,7 @@ void InstructionSelector::VisitCheckedStore(Node* node) { UNREACHABLE(); return; } - Emit(opcode, nullptr, g.UseRegister(buffer), g.UseRegister(offset), + Emit(opcode, g.NoOutput(), g.UseRegister(buffer), g.UseRegister(offset), g.UseOperand(length, kArithmeticImm), g.UseRegister(value)); } @@ -864,7 +864,7 @@ void InstructionSelector::VisitInt64Mul(Node* node) { void InstructionSelector::VisitInt32MulHigh(Node* node) { // TODO(arm64): Can we do better here? Arm64OperandGenerator g(this); - InstructionOperand* const smull_operand = g.TempRegister(); + InstructionOperand const smull_operand = g.TempRegister(); Emit(kArm64Smull, smull_operand, g.UseRegister(node->InputAt(0)), g.UseRegister(node->InputAt(1))); Emit(kArm64Asr, g.DefineAsRegister(node), smull_operand, g.TempImmediate(32)); @@ -874,7 +874,7 @@ void InstructionSelector::VisitInt32MulHigh(Node* node) { void InstructionSelector::VisitUint32MulHigh(Node* node) { // TODO(arm64): Can we do better here? Arm64OperandGenerator g(this); - InstructionOperand* const smull_operand = g.TempRegister(); + InstructionOperand const smull_operand = g.TempRegister(); Emit(kArm64Umull, smull_operand, g.UseRegister(node->InputAt(0)), g.UseRegister(node->InputAt(1))); Emit(kArm64Lsr, g.DefineAsRegister(node), smull_operand, g.TempImmediate(32)); @@ -1107,7 +1107,7 @@ void InstructionSelector::VisitCall(Node* node) { if (aligned_push_count > 0) { // TODO(dcarney): it would be better to bump the csp here only // and emit paired stores with increment for non c frames. - Emit(kArm64Claim | MiscField::encode(aligned_push_count), NULL); + Emit(kArm64Claim | MiscField::encode(aligned_push_count), g.NoOutput()); } // Move arguments to the stack. { @@ -1115,12 +1115,13 @@ void InstructionSelector::VisitCall(Node* node) { // Emit the uneven pushes. if (pushed_count_uneven) { Node* input = buffer.pushed_nodes[slot]; - Emit(kArm64Poke | MiscField::encode(slot), NULL, g.UseRegister(input)); + Emit(kArm64Poke | MiscField::encode(slot), g.NoOutput(), + g.UseRegister(input)); slot--; } // Now all pushes can be done in pairs. for (; slot >= 0; slot -= 2) { - Emit(kArm64PokePair | MiscField::encode(slot), NULL, + Emit(kArm64PokePair | MiscField::encode(slot), g.NoOutput(), g.UseRegister(buffer.pushed_nodes[slot]), g.UseRegister(buffer.pushed_nodes[slot - 1])); } @@ -1143,7 +1144,7 @@ void InstructionSelector::VisitCall(Node* node) { opcode |= MiscField::encode(descriptor->flags()); // Emit the call instruction. - InstructionOperand** first_output = + InstructionOperand* first_output = buffer.outputs.size() > 0 ? &buffer.outputs.front() : NULL; Instruction* call_instr = Emit(opcode, buffer.outputs.size(), first_output, @@ -1154,12 +1155,13 @@ void InstructionSelector::VisitCall(Node* node) { // Shared routine for multiple compare operations. static void VisitCompare(InstructionSelector* selector, InstructionCode opcode, - InstructionOperand* left, InstructionOperand* right, + InstructionOperand left, InstructionOperand right, FlagsContinuation* cont) { Arm64OperandGenerator g(selector); opcode = cont->Encode(opcode); if (cont->IsBranch()) { - selector->Emit(opcode, NULL, left, right, g.Label(cont->true_block()), + selector->Emit(opcode, g.NoOutput(), left, right, + g.Label(cont->true_block()), g.Label(cont->false_block()))->MarkAsControl(); } else { DCHECK(cont->IsSet()); @@ -1348,7 +1350,7 @@ void InstructionSelector::VisitBranch(Node* branch, BasicBlock* tbranch, // If the mask has only one bit set, we can use tbz/tbnz. DCHECK((cont.condition() == kEqual) || (cont.condition() == kNotEqual)); - Emit(cont.Encode(kArm64TestAndBranch32), NULL, + Emit(cont.Encode(kArm64TestAndBranch32), g.NoOutput(), g.UseRegister(m.left().node()), g.TempImmediate( base::bits::CountTrailingZeros32(m.right().Value())), @@ -1366,7 +1368,7 @@ void InstructionSelector::VisitBranch(Node* branch, BasicBlock* tbranch, // If the mask has only one bit set, we can use tbz/tbnz. DCHECK((cont.condition() == kEqual) || (cont.condition() == kNotEqual)); - Emit(cont.Encode(kArm64TestAndBranch), NULL, + Emit(cont.Encode(kArm64TestAndBranch), g.NoOutput(), g.UseRegister(m.left().node()), g.TempImmediate( base::bits::CountTrailingZeros64(m.right().Value())), @@ -1383,8 +1385,8 @@ void InstructionSelector::VisitBranch(Node* branch, BasicBlock* tbranch, } // Branch could not be combined with a compare, compare against 0 and branch. - Emit(cont.Encode(kArm64CompareAndBranch32), NULL, g.UseRegister(value), - g.Label(cont.true_block()), + Emit(cont.Encode(kArm64CompareAndBranch32), g.NoOutput(), + g.UseRegister(value), g.Label(cont.true_block()), g.Label(cont.false_block()))->MarkAsControl(); } diff --git a/src/compiler/ia32/instruction-selector-ia32.cc b/src/compiler/ia32/instruction-selector-ia32.cc index b81210a..da2a659 100644 --- a/src/compiler/ia32/instruction-selector-ia32.cc +++ b/src/compiler/ia32/instruction-selector-ia32.cc @@ -16,7 +16,7 @@ class IA32OperandGenerator FINAL : public OperandGenerator { explicit IA32OperandGenerator(InstructionSelector* selector) : OperandGenerator(selector) {} - InstructionOperand* UseByteRegister(Node* node) { + InstructionOperand UseByteRegister(Node* node) { // TODO(dcarney): relax constraint. return UseFixed(node, edx); } @@ -41,7 +41,7 @@ class IA32OperandGenerator FINAL : public OperandGenerator { AddressingMode GenerateMemoryOperandInputs(Node* index, int scale, Node* base, Node* displacement_node, - InstructionOperand* inputs[], + InstructionOperand inputs[], size_t* input_count) { AddressingMode mode = kMode_MRI; int32_t displacement = (displacement_node == NULL) @@ -99,7 +99,7 @@ class IA32OperandGenerator FINAL : public OperandGenerator { } AddressingMode GetEffectiveAddressMemoryOperand(Node* node, - InstructionOperand* inputs[], + InstructionOperand inputs[], size_t* input_count) { BaseWithIndexAndDisplacement32Matcher m(node, true); DCHECK(m.matches()); @@ -157,9 +157,9 @@ void InstructionSelector::VisitLoad(Node* node) { } IA32OperandGenerator g(this); - InstructionOperand* outputs[1]; + InstructionOperand outputs[1]; outputs[0] = g.DefineAsRegister(node); - InstructionOperand* inputs[3]; + InstructionOperand inputs[3]; size_t input_count = 0; AddressingMode mode = g.GetEffectiveAddressMemoryOperand(node, inputs, &input_count); @@ -181,8 +181,8 @@ void InstructionSelector::VisitStore(Node* node) { // TODO(dcarney): refactor RecordWrite function to take temp registers // and pass them here instead of using fixed regs // TODO(dcarney): handle immediate indices. - InstructionOperand* temps[] = {g.TempRegister(ecx), g.TempRegister(edx)}; - Emit(kIA32StoreWriteBarrier, NULL, g.UseFixed(base, ebx), + InstructionOperand temps[] = {g.TempRegister(ecx), g.TempRegister(edx)}; + Emit(kIA32StoreWriteBarrier, g.NoOutput(), g.UseFixed(base, ebx), g.UseFixed(index, ecx), g.UseFixed(value, edx), arraysize(temps), temps); return; @@ -213,7 +213,7 @@ void InstructionSelector::VisitStore(Node* node) { return; } - InstructionOperand* val; + InstructionOperand val; if (g.CanBeImmediate(value)) { val = g.UseImmediate(value); } else if (rep == kRepWord8 || rep == kRepBit) { @@ -222,13 +222,13 @@ void InstructionSelector::VisitStore(Node* node) { val = g.UseRegister(value); } - InstructionOperand* inputs[4]; + InstructionOperand inputs[4]; size_t input_count = 0; AddressingMode mode = g.GetEffectiveAddressMemoryOperand(node, inputs, &input_count); InstructionCode code = opcode | AddressingModeField::encode(mode); inputs[input_count++] = val; - Emit(code, 0, static_cast(NULL), input_count, inputs); + Emit(code, 0, static_cast(NULL), input_count, inputs); } @@ -260,8 +260,8 @@ void InstructionSelector::VisitCheckedLoad(Node* node) { UNREACHABLE(); return; } - InstructionOperand* offset_operand = g.UseRegister(offset); - InstructionOperand* length_operand = + InstructionOperand offset_operand = g.UseRegister(offset); + InstructionOperand length_operand = g.CanBeImmediate(length) ? g.UseImmediate(length) : g.UseRegister(length); if (g.CanBeImmediate(buffer)) { Emit(opcode | AddressingModeField::encode(kMode_MRI), @@ -303,20 +303,20 @@ void InstructionSelector::VisitCheckedStore(Node* node) { UNREACHABLE(); return; } - InstructionOperand* value_operand = + InstructionOperand value_operand = g.CanBeImmediate(value) ? g.UseImmediate(value) : ((rep == kRepWord8 || rep == kRepBit) ? g.UseByteRegister(value) : g.UseRegister(value)); - InstructionOperand* offset_operand = g.UseRegister(offset); - InstructionOperand* length_operand = + InstructionOperand offset_operand = g.UseRegister(offset); + InstructionOperand length_operand = g.CanBeImmediate(length) ? g.UseImmediate(length) : g.UseRegister(length); if (g.CanBeImmediate(buffer)) { - Emit(opcode | AddressingModeField::encode(kMode_MRI), nullptr, + Emit(opcode | AddressingModeField::encode(kMode_MRI), g.NoOutput(), offset_operand, length_operand, value_operand, offset_operand, g.UseImmediate(buffer)); } else { - Emit(opcode | AddressingModeField::encode(kMode_MR1), nullptr, + Emit(opcode | AddressingModeField::encode(kMode_MR1), g.NoOutput(), offset_operand, length_operand, value_operand, g.UseRegister(buffer), offset_operand); } @@ -330,9 +330,9 @@ static void VisitBinop(InstructionSelector* selector, Node* node, Int32BinopMatcher m(node); Node* left = m.left().node(); Node* right = m.right().node(); - InstructionOperand* inputs[4]; + InstructionOperand inputs[4]; size_t input_count = 0; - InstructionOperand* outputs[2]; + InstructionOperand outputs[2]; size_t output_count = 0; // TODO(turbofan): match complex addressing modes. @@ -344,7 +344,7 @@ static void VisitBinop(InstructionSelector* selector, Node* node, // mov eax, [ebp-0x10] // add eax, [ebp-0x10] // jo label - InstructionOperand* const input = g.UseRegister(left); + InstructionOperand const input = g.UseRegister(left); inputs[input_count++] = input; inputs[input_count++] = input; } else if (g.CanBeImmediate(right)) { @@ -440,7 +440,7 @@ void VisitMulHigh(InstructionSelector* selector, Node* node, void VisitDiv(InstructionSelector* selector, Node* node, ArchOpcode opcode) { IA32OperandGenerator g(selector); - InstructionOperand* temps[] = {g.TempRegister(edx)}; + InstructionOperand temps[] = {g.TempRegister(edx)}; selector->Emit(opcode, g.DefineAsFixed(node, eax), g.UseFixed(node->InputAt(0), eax), g.UseUnique(node->InputAt(1)), arraysize(temps), temps); @@ -457,7 +457,7 @@ void VisitMod(InstructionSelector* selector, Node* node, ArchOpcode opcode) { void EmitLea(InstructionSelector* selector, Node* result, Node* index, int scale, Node* base, Node* displacement) { IA32OperandGenerator g(selector); - InstructionOperand* inputs[4]; + InstructionOperand inputs[4]; size_t input_count = 0; AddressingMode mode = g.GenerateMemoryOperandInputs( index, scale, base, displacement, inputs, &input_count); @@ -465,7 +465,7 @@ void EmitLea(InstructionSelector* selector, Node* result, Node* index, DCHECK_NE(0, static_cast(input_count)); DCHECK_GE(arraysize(inputs), input_count); - InstructionOperand* outputs[1]; + InstructionOperand outputs[1]; outputs[0] = g.DefineAsRegister(result); InstructionCode opcode = AddressingModeField::encode(mode) | kIA32Lea; @@ -510,7 +510,7 @@ void InstructionSelector::VisitInt32Add(Node* node) { BaseWithIndexAndDisplacement32Matcher m(node); if (m.matches() && (m.displacement() == NULL || g.CanBeImmediate(m.displacement()))) { - InstructionOperand* inputs[4]; + InstructionOperand inputs[4]; size_t input_count = 0; AddressingMode mode = g.GenerateMemoryOperandInputs( m.index(), m.scale(), m.base(), m.displacement(), inputs, &input_count); @@ -518,7 +518,7 @@ void InstructionSelector::VisitInt32Add(Node* node) { DCHECK_NE(0, static_cast(input_count)); DCHECK_GE(arraysize(inputs), input_count); - InstructionOperand* outputs[1]; + InstructionOperand outputs[1]; outputs[0] = g.DefineAsRegister(node); InstructionCode opcode = AddressingModeField::encode(mode) | kIA32Lea; @@ -682,7 +682,7 @@ void InstructionSelector::VisitFloat64Div(Node* node) { void InstructionSelector::VisitFloat64Mod(Node* node) { IA32OperandGenerator g(this); - InstructionOperand* temps[] = {g.TempRegister(eax)}; + InstructionOperand temps[] = {g.TempRegister(eax)}; Emit(kSSEFloat64Mod, g.DefineSameAsFirst(node), g.UseRegister(node->InputAt(0)), g.UseRegister(node->InputAt(1)), 1, temps); @@ -738,11 +738,11 @@ void InstructionSelector::VisitCall(Node* node) { for (auto i = buffer.pushed_nodes.rbegin(); i != buffer.pushed_nodes.rend(); ++i) { // TODO(titzer): handle pushing double parameters. - InstructionOperand* value = + InstructionOperand value = g.CanBeImmediate(*i) ? g.UseImmediate(*i) : IsSupported(ATOM) ? g.UseRegister(*i) : g.Use(*i); - Emit(kIA32Push, nullptr, value); + Emit(kIA32Push, g.NoOutput(), value); } // Select the appropriate opcode based on the call type. @@ -762,7 +762,7 @@ void InstructionSelector::VisitCall(Node* node) { opcode |= MiscField::encode(descriptor->flags()); // Emit the call instruction. - InstructionOperand** first_output = + InstructionOperand* first_output = buffer.outputs.size() > 0 ? &buffer.outputs.front() : NULL; Instruction* call_instr = Emit(opcode, buffer.outputs.size(), first_output, @@ -775,11 +775,11 @@ namespace { // Shared routine for multiple compare operations. void VisitCompare(InstructionSelector* selector, InstructionCode opcode, - InstructionOperand* left, InstructionOperand* right, + InstructionOperand left, InstructionOperand right, FlagsContinuation* cont) { IA32OperandGenerator g(selector); if (cont->IsBranch()) { - selector->Emit(cont->Encode(opcode), NULL, left, right, + selector->Emit(cont->Encode(opcode), g.NoOutput(), left, right, g.Label(cont->true_block()), g.Label(cont->false_block()))->MarkAsControl(); } else { diff --git a/src/compiler/instruction-selector-impl.h b/src/compiler/instruction-selector-impl.h index f8e9857..0eb3fbe 100644 --- a/src/compiler/instruction-selector-impl.h +++ b/src/compiler/instruction-selector-impl.h @@ -21,126 +21,129 @@ class OperandGenerator { explicit OperandGenerator(InstructionSelector* selector) : selector_(selector) {} - InstructionOperand* DefineAsRegister(Node* node) { + InstructionOperand NoOutput() { + return InstructionOperand(); // Generates an invalid operand. + } + + InstructionOperand DefineAsRegister(Node* node) { return Define(node, - new (zone()) UnallocatedOperand( - UnallocatedOperand::MUST_HAVE_REGISTER, GetVReg(node))); + UnallocatedOperand(UnallocatedOperand::MUST_HAVE_REGISTER, + GetVReg(node))); } - InstructionOperand* DefineSameAsFirst(Node* node) { + InstructionOperand DefineSameAsFirst(Node* node) { return Define(node, - new (zone()) UnallocatedOperand( - UnallocatedOperand::SAME_AS_FIRST_INPUT, GetVReg(node))); + UnallocatedOperand(UnallocatedOperand::SAME_AS_FIRST_INPUT, + GetVReg(node))); } - InstructionOperand* DefineAsFixed(Node* node, Register reg) { - return Define(node, new (zone()) UnallocatedOperand( - UnallocatedOperand::FIXED_REGISTER, - Register::ToAllocationIndex(reg), GetVReg(node))); + InstructionOperand DefineAsFixed(Node* node, Register reg) { + return Define(node, UnallocatedOperand(UnallocatedOperand::FIXED_REGISTER, + Register::ToAllocationIndex(reg), + GetVReg(node))); } - InstructionOperand* DefineAsFixed(Node* node, DoubleRegister reg) { + InstructionOperand DefineAsFixed(Node* node, DoubleRegister reg) { return Define(node, - new (zone()) UnallocatedOperand( - UnallocatedOperand::FIXED_DOUBLE_REGISTER, - DoubleRegister::ToAllocationIndex(reg), GetVReg(node))); + UnallocatedOperand(UnallocatedOperand::FIXED_DOUBLE_REGISTER, + DoubleRegister::ToAllocationIndex(reg), + GetVReg(node))); } - InstructionOperand* DefineAsConstant(Node* node) { + InstructionOperand DefineAsConstant(Node* node) { selector()->MarkAsDefined(node); int virtual_register = GetVReg(node); sequence()->AddConstant(virtual_register, ToConstant(node)); - return ConstantOperand::Create(virtual_register, zone()); + return ConstantOperand(virtual_register); } - InstructionOperand* DefineAsLocation(Node* node, LinkageLocation location, - MachineType type) { + InstructionOperand DefineAsLocation(Node* node, LinkageLocation location, + MachineType type) { return Define(node, ToUnallocatedOperand(location, type, GetVReg(node))); } - InstructionOperand* Use(Node* node) { - return Use(node, new (zone()) UnallocatedOperand( - UnallocatedOperand::NONE, - UnallocatedOperand::USED_AT_START, GetVReg(node))); + InstructionOperand Use(Node* node) { + return Use(node, UnallocatedOperand(UnallocatedOperand::NONE, + UnallocatedOperand::USED_AT_START, + GetVReg(node))); } - InstructionOperand* UseRegister(Node* node) { - return Use(node, new (zone()) UnallocatedOperand( - UnallocatedOperand::MUST_HAVE_REGISTER, - UnallocatedOperand::USED_AT_START, GetVReg(node))); + InstructionOperand UseRegister(Node* node) { + return Use(node, UnallocatedOperand(UnallocatedOperand::MUST_HAVE_REGISTER, + UnallocatedOperand::USED_AT_START, + GetVReg(node))); } // Use register or operand for the node. If a register is chosen, it won't // alias any temporary or output registers. - InstructionOperand* UseUnique(Node* node) { - return Use(node, new (zone()) UnallocatedOperand(UnallocatedOperand::NONE, - GetVReg(node))); + InstructionOperand UseUnique(Node* node) { + return Use(node, + UnallocatedOperand(UnallocatedOperand::NONE, GetVReg(node))); } // Use a unique register for the node that does not alias any temporary or // output registers. - InstructionOperand* UseUniqueRegister(Node* node) { - return Use(node, - new (zone()) UnallocatedOperand( - UnallocatedOperand::MUST_HAVE_REGISTER, GetVReg(node))); + InstructionOperand UseUniqueRegister(Node* node) { + return Use(node, UnallocatedOperand(UnallocatedOperand::MUST_HAVE_REGISTER, + GetVReg(node))); } - InstructionOperand* UseFixed(Node* node, Register reg) { - return Use(node, new (zone()) UnallocatedOperand( - UnallocatedOperand::FIXED_REGISTER, - Register::ToAllocationIndex(reg), GetVReg(node))); + InstructionOperand UseFixed(Node* node, Register reg) { + return Use(node, UnallocatedOperand(UnallocatedOperand::FIXED_REGISTER, + Register::ToAllocationIndex(reg), + GetVReg(node))); } - InstructionOperand* UseFixed(Node* node, DoubleRegister reg) { + InstructionOperand UseFixed(Node* node, DoubleRegister reg) { return Use(node, - new (zone()) UnallocatedOperand( - UnallocatedOperand::FIXED_DOUBLE_REGISTER, - DoubleRegister::ToAllocationIndex(reg), GetVReg(node))); + UnallocatedOperand(UnallocatedOperand::FIXED_DOUBLE_REGISTER, + DoubleRegister::ToAllocationIndex(reg), + GetVReg(node))); } - InstructionOperand* UseImmediate(Node* node) { + InstructionOperand UseImmediate(Node* node) { int index = sequence()->AddImmediate(ToConstant(node)); - return ImmediateOperand::Create(index, zone()); + return ImmediateOperand(index); } - InstructionOperand* UseLocation(Node* node, LinkageLocation location, - MachineType type) { + InstructionOperand UseLocation(Node* node, LinkageLocation location, + MachineType type) { return Use(node, ToUnallocatedOperand(location, type, GetVReg(node))); } - InstructionOperand* TempRegister() { - return new (zone()) UnallocatedOperand( - UnallocatedOperand::MUST_HAVE_REGISTER, - UnallocatedOperand::USED_AT_START, sequence()->NextVirtualRegister()); + InstructionOperand TempRegister() { + return UnallocatedOperand(UnallocatedOperand::MUST_HAVE_REGISTER, + UnallocatedOperand::USED_AT_START, + sequence()->NextVirtualRegister()); } - InstructionOperand* TempDoubleRegister() { - UnallocatedOperand* op = new (zone()) UnallocatedOperand( + InstructionOperand TempDoubleRegister() { + UnallocatedOperand op = UnallocatedOperand( UnallocatedOperand::MUST_HAVE_REGISTER, UnallocatedOperand::USED_AT_START, sequence()->NextVirtualRegister()); - sequence()->MarkAsDouble(op->virtual_register()); + sequence()->MarkAsDouble(op.virtual_register()); return op; } - InstructionOperand* TempRegister(Register reg) { - return new (zone()) UnallocatedOperand( - UnallocatedOperand::FIXED_REGISTER, Register::ToAllocationIndex(reg), - UnallocatedOperand::kInvalidVirtualRegister); + InstructionOperand TempRegister(Register reg) { + return UnallocatedOperand(UnallocatedOperand::FIXED_REGISTER, + Register::ToAllocationIndex(reg), + UnallocatedOperand::kInvalidVirtualRegister); } - InstructionOperand* TempImmediate(int32_t imm) { + InstructionOperand TempImmediate(int32_t imm) { int index = sequence()->AddImmediate(Constant(imm)); - return ImmediateOperand::Create(index, zone()); + return ImmediateOperand(index); } - InstructionOperand* TempLocation(LinkageLocation location, MachineType type) { + InstructionOperand TempLocation(LinkageLocation location, MachineType type) { return ToUnallocatedOperand(location, type, sequence()->NextVirtualRegister()); } - InstructionOperand* Label(BasicBlock* block) { + InstructionOperand Label(BasicBlock* block) { int index = sequence()->AddImmediate(Constant(block->GetRpoNumber())); - return ImmediateOperand::Create(index, zone()); + return ImmediateOperand(index); } protected: @@ -173,51 +176,47 @@ class OperandGenerator { return Constant(static_cast(0)); } - UnallocatedOperand* Define(Node* node, UnallocatedOperand* operand) { + UnallocatedOperand Define(Node* node, UnallocatedOperand operand) { DCHECK_NOT_NULL(node); - DCHECK_NOT_NULL(operand); - DCHECK_EQ(operand->virtual_register(), GetVReg(node)); + DCHECK_EQ(operand.virtual_register(), GetVReg(node)); selector()->MarkAsDefined(node); return operand; } - UnallocatedOperand* Use(Node* node, UnallocatedOperand* operand) { + UnallocatedOperand Use(Node* node, UnallocatedOperand operand) { DCHECK_NOT_NULL(node); - DCHECK_NOT_NULL(operand); - DCHECK_EQ(operand->virtual_register(), GetVReg(node)); + DCHECK_EQ(operand.virtual_register(), GetVReg(node)); selector()->MarkAsUsed(node); return operand; } - UnallocatedOperand* ToUnallocatedOperand(LinkageLocation location, - MachineType type, - int virtual_register) { + UnallocatedOperand ToUnallocatedOperand(LinkageLocation location, + MachineType type, + int virtual_register) { if (location.location_ == LinkageLocation::ANY_REGISTER) { // any machine register. - return new (zone()) UnallocatedOperand( - UnallocatedOperand::MUST_HAVE_REGISTER, virtual_register); + return UnallocatedOperand(UnallocatedOperand::MUST_HAVE_REGISTER, + virtual_register); } if (location.location_ < 0) { // a location on the caller frame. - return new (zone()) UnallocatedOperand( - UnallocatedOperand::FIXED_SLOT, location.location_, virtual_register); + return UnallocatedOperand(UnallocatedOperand::FIXED_SLOT, + location.location_, virtual_register); } if (location.location_ > LinkageLocation::ANY_REGISTER) { // a spill location on this (callee) frame. - return new (zone()) UnallocatedOperand( + return UnallocatedOperand( UnallocatedOperand::FIXED_SLOT, location.location_ - LinkageLocation::ANY_REGISTER - 1, virtual_register); } // a fixed register. if (RepresentationOf(type) == kRepFloat64) { - return new (zone()) - UnallocatedOperand(UnallocatedOperand::FIXED_DOUBLE_REGISTER, - location.location_, virtual_register); + return UnallocatedOperand(UnallocatedOperand::FIXED_DOUBLE_REGISTER, + location.location_, virtual_register); } - return new (zone()) - UnallocatedOperand(UnallocatedOperand::FIXED_REGISTER, - location.location_, virtual_register); + return UnallocatedOperand(UnallocatedOperand::FIXED_REGISTER, + location.location_, virtual_register); } InstructionSelector* selector_; diff --git a/src/compiler/instruction-selector.cc b/src/compiler/instruction-selector.cc index 05d1b21..65f1b00 100644 --- a/src/compiler/instruction-selector.cc +++ b/src/compiler/instruction-selector.cc @@ -73,30 +73,30 @@ void InstructionSelector::SelectInstructions() { Instruction* InstructionSelector::Emit(InstructionCode opcode, - InstructionOperand* output, + InstructionOperand output, size_t temp_count, - InstructionOperand** temps) { - size_t output_count = output == NULL ? 0 : 1; + InstructionOperand* temps) { + size_t output_count = output.IsInvalid() ? 0 : 1; return Emit(opcode, output_count, &output, 0, NULL, temp_count, temps); } Instruction* InstructionSelector::Emit(InstructionCode opcode, - InstructionOperand* output, - InstructionOperand* a, size_t temp_count, - InstructionOperand** temps) { - size_t output_count = output == NULL ? 0 : 1; + InstructionOperand output, + InstructionOperand a, size_t temp_count, + InstructionOperand* temps) { + size_t output_count = output.IsInvalid() ? 0 : 1; return Emit(opcode, output_count, &output, 1, &a, temp_count, temps); } Instruction* InstructionSelector::Emit(InstructionCode opcode, - InstructionOperand* output, - InstructionOperand* a, - InstructionOperand* b, size_t temp_count, - InstructionOperand** temps) { - size_t output_count = output == NULL ? 0 : 1; - InstructionOperand* inputs[] = {a, b}; + InstructionOperand output, + InstructionOperand a, + InstructionOperand b, size_t temp_count, + InstructionOperand* temps) { + size_t output_count = output.IsInvalid() ? 0 : 1; + InstructionOperand inputs[] = {a, b}; size_t input_count = arraysize(inputs); return Emit(opcode, output_count, &output, input_count, inputs, temp_count, temps); @@ -104,13 +104,13 @@ Instruction* InstructionSelector::Emit(InstructionCode opcode, Instruction* InstructionSelector::Emit(InstructionCode opcode, - InstructionOperand* output, - InstructionOperand* a, - InstructionOperand* b, - InstructionOperand* c, size_t temp_count, - InstructionOperand** temps) { - size_t output_count = output == NULL ? 0 : 1; - InstructionOperand* inputs[] = {a, b, c}; + InstructionOperand output, + InstructionOperand a, + InstructionOperand b, + InstructionOperand c, size_t temp_count, + InstructionOperand* temps) { + size_t output_count = output.IsInvalid() ? 0 : 1; + InstructionOperand inputs[] = {a, b, c}; size_t input_count = arraysize(inputs); return Emit(opcode, output_count, &output, input_count, inputs, temp_count, temps); @@ -118,11 +118,11 @@ Instruction* InstructionSelector::Emit(InstructionCode opcode, Instruction* InstructionSelector::Emit( - InstructionCode opcode, InstructionOperand* output, InstructionOperand* a, - InstructionOperand* b, InstructionOperand* c, InstructionOperand* d, - size_t temp_count, InstructionOperand** temps) { - size_t output_count = output == NULL ? 0 : 1; - InstructionOperand* inputs[] = {a, b, c, d}; + InstructionCode opcode, InstructionOperand output, InstructionOperand a, + InstructionOperand b, InstructionOperand c, InstructionOperand d, + size_t temp_count, InstructionOperand* temps) { + size_t output_count = output.IsInvalid() ? 0 : 1; + InstructionOperand inputs[] = {a, b, c, d}; size_t input_count = arraysize(inputs); return Emit(opcode, output_count, &output, input_count, inputs, temp_count, temps); @@ -130,11 +130,11 @@ Instruction* InstructionSelector::Emit( Instruction* InstructionSelector::Emit( - InstructionCode opcode, InstructionOperand* output, InstructionOperand* a, - InstructionOperand* b, InstructionOperand* c, InstructionOperand* d, - InstructionOperand* e, size_t temp_count, InstructionOperand** temps) { - size_t output_count = output == NULL ? 0 : 1; - InstructionOperand* inputs[] = {a, b, c, d, e}; + InstructionCode opcode, InstructionOperand output, InstructionOperand a, + InstructionOperand b, InstructionOperand c, InstructionOperand d, + InstructionOperand e, size_t temp_count, InstructionOperand* temps) { + size_t output_count = output.IsInvalid() ? 0 : 1; + InstructionOperand inputs[] = {a, b, c, d, e}; size_t input_count = arraysize(inputs); return Emit(opcode, output_count, &output, input_count, inputs, temp_count, temps); @@ -142,12 +142,12 @@ Instruction* InstructionSelector::Emit( Instruction* InstructionSelector::Emit( - InstructionCode opcode, InstructionOperand* output, InstructionOperand* a, - InstructionOperand* b, InstructionOperand* c, InstructionOperand* d, - InstructionOperand* e, InstructionOperand* f, size_t temp_count, - InstructionOperand** temps) { - size_t output_count = output == NULL ? 0 : 1; - InstructionOperand* inputs[] = {a, b, c, d, e, f}; + InstructionCode opcode, InstructionOperand output, InstructionOperand a, + InstructionOperand b, InstructionOperand c, InstructionOperand d, + InstructionOperand e, InstructionOperand f, size_t temp_count, + InstructionOperand* temps) { + size_t output_count = output.IsInvalid() ? 0 : 1; + InstructionOperand inputs[] = {a, b, c, d, e, f}; size_t input_count = arraysize(inputs); return Emit(opcode, output_count, &output, input_count, inputs, temp_count, temps); @@ -155,9 +155,9 @@ Instruction* InstructionSelector::Emit( Instruction* InstructionSelector::Emit( - InstructionCode opcode, size_t output_count, InstructionOperand** outputs, - size_t input_count, InstructionOperand** inputs, size_t temp_count, - InstructionOperand** temps) { + InstructionCode opcode, size_t output_count, InstructionOperand* outputs, + size_t input_count, InstructionOperand* inputs, size_t temp_count, + InstructionOperand* temps) { Instruction* instr = Instruction::New(instruction_zone(), opcode, output_count, outputs, input_count, inputs, temp_count, temps); @@ -271,15 +271,15 @@ void InstructionSelector::MarkAsReference(Node* node) { void InstructionSelector::MarkAsRepresentation(MachineType rep, - InstructionOperand* op) { - UnallocatedOperand* unalloc = UnallocatedOperand::cast(op); + const InstructionOperand& op) { + UnallocatedOperand unalloc = UnallocatedOperand::cast(op); switch (RepresentationOf(rep)) { case kRepFloat32: case kRepFloat64: - sequence()->MarkAsDouble(unalloc->virtual_register()); + sequence()->MarkAsDouble(unalloc.virtual_register()); break; case kRepTagged: - sequence()->MarkAsReference(unalloc->virtual_register()); + sequence()->MarkAsReference(unalloc.virtual_register()); break; default: break; @@ -363,7 +363,7 @@ void InstructionSelector::InitializeCallBuffer(Node* call, CallBuffer* buffer, buffer->descriptor->GetReturnLocation(static_cast(i)); Node* output = buffer->output_nodes[i]; - InstructionOperand* op = + InstructionOperand op = output == NULL ? g.TempLocation(location, type) : g.DefineAsLocation(output, location, type); MarkAsRepresentation(type, op); @@ -427,11 +427,11 @@ void InstructionSelector::InitializeCallBuffer(Node* call, CallBuffer* buffer, DCHECK(iter != call->inputs().end()); DCHECK((*iter)->op()->opcode() != IrOpcode::kFrameState); if (index == 0) continue; // The first argument (callee) is already done. - InstructionOperand* op = + InstructionOperand op = g.UseLocation(*iter, buffer->descriptor->GetInputLocation(index), buffer->descriptor->GetInputType(index)); - if (UnallocatedOperand::cast(op)->HasFixedSlotPolicy()) { - int stack_index = -UnallocatedOperand::cast(op)->fixed_slot_index() - 1; + if (UnallocatedOperand::cast(op).HasFixedSlotPolicy()) { + int stack_index = -UnallocatedOperand::cast(op).fixed_slot_index() - 1; if (static_cast(stack_index) >= buffer->pushed_nodes.size()) { buffer->pushed_nodes.resize(stack_index + 1, NULL); } @@ -1034,23 +1034,25 @@ void InstructionSelector::VisitConstant(Node* node) { void InstructionSelector::VisitGoto(BasicBlock* target) { // jump to the next block. OperandGenerator g(this); - Emit(kArchJmp, NULL, g.Label(target))->MarkAsControl(); + Emit(kArchJmp, g.NoOutput(), g.Label(target))->MarkAsControl(); } void InstructionSelector::VisitReturn(Node* value) { OperandGenerator g(this); if (value != NULL) { - Emit(kArchRet, NULL, g.UseLocation(value, linkage()->GetReturnLocation(), - linkage()->GetReturnType())); + Emit(kArchRet, g.NoOutput(), + g.UseLocation(value, linkage()->GetReturnLocation(), + linkage()->GetReturnType())); } else { - Emit(kArchRet, NULL); + Emit(kArchRet, g.NoOutput()); } } void InstructionSelector::VisitThrow(Node* value) { - Emit(kArchNop, NULL); // TODO(titzer) + OperandGenerator g(this); + Emit(kArchNop, g.NoOutput()); // TODO(titzer) } @@ -1089,7 +1091,7 @@ FrameStateDescriptor* InstructionSelector::GetFrameStateDescriptor( } -static InstructionOperand* UseOrImmediate(OperandGenerator* g, Node* input) { +static InstructionOperand UseOrImmediate(OperandGenerator* g, Node* input) { switch (input->opcode()) { case IrOpcode::kInt32Constant: case IrOpcode::kNumberConstant: diff --git a/src/compiler/instruction-selector.h b/src/compiler/instruction-selector.h index dc8f1b8..d589f4b 100644 --- a/src/compiler/instruction-selector.h +++ b/src/compiler/instruction-selector.h @@ -23,6 +23,9 @@ class FlagsContinuation; class Linkage; +typedef ZoneVector InstructionOperandVector; + + // Instruction selection generates an InstructionSequence for a given Schedule. class InstructionSelector FINAL { public: @@ -41,36 +44,36 @@ class InstructionSelector FINAL { // ============= Architecture-independent code emission methods. ============= // =========================================================================== - Instruction* Emit(InstructionCode opcode, InstructionOperand* output, - size_t temp_count = 0, InstructionOperand* *temps = NULL); - Instruction* Emit(InstructionCode opcode, InstructionOperand* output, - InstructionOperand* a, size_t temp_count = 0, - InstructionOperand* *temps = NULL); - Instruction* Emit(InstructionCode opcode, InstructionOperand* output, - InstructionOperand* a, InstructionOperand* b, - size_t temp_count = 0, InstructionOperand* *temps = NULL); - Instruction* Emit(InstructionCode opcode, InstructionOperand* output, - InstructionOperand* a, InstructionOperand* b, - InstructionOperand* c, size_t temp_count = 0, - InstructionOperand* *temps = NULL); - Instruction* Emit(InstructionCode opcode, InstructionOperand* output, - InstructionOperand* a, InstructionOperand* b, - InstructionOperand* c, InstructionOperand* d, - size_t temp_count = 0, InstructionOperand* *temps = NULL); - Instruction* Emit(InstructionCode opcode, InstructionOperand* output, - InstructionOperand* a, InstructionOperand* b, - InstructionOperand* c, InstructionOperand* d, - InstructionOperand* e, size_t temp_count = 0, - InstructionOperand* *temps = NULL); - Instruction* Emit(InstructionCode opcode, InstructionOperand* output, - InstructionOperand* a, InstructionOperand* b, - InstructionOperand* c, InstructionOperand* d, - InstructionOperand* e, InstructionOperand* f, - size_t temp_count = 0, InstructionOperand* *temps = NULL); + Instruction* Emit(InstructionCode opcode, InstructionOperand output, + size_t temp_count = 0, InstructionOperand* temps = NULL); + Instruction* Emit(InstructionCode opcode, InstructionOperand output, + InstructionOperand a, size_t temp_count = 0, + InstructionOperand* temps = NULL); + Instruction* Emit(InstructionCode opcode, InstructionOperand output, + InstructionOperand a, InstructionOperand b, + size_t temp_count = 0, InstructionOperand* temps = NULL); + Instruction* Emit(InstructionCode opcode, InstructionOperand output, + InstructionOperand a, InstructionOperand b, + InstructionOperand c, size_t temp_count = 0, + InstructionOperand* temps = NULL); + Instruction* Emit(InstructionCode opcode, InstructionOperand output, + InstructionOperand a, InstructionOperand b, + InstructionOperand c, InstructionOperand d, + size_t temp_count = 0, InstructionOperand* temps = NULL); + Instruction* Emit(InstructionCode opcode, InstructionOperand output, + InstructionOperand a, InstructionOperand b, + InstructionOperand c, InstructionOperand d, + InstructionOperand e, size_t temp_count = 0, + InstructionOperand* temps = NULL); + Instruction* Emit(InstructionCode opcode, InstructionOperand output, + InstructionOperand a, InstructionOperand b, + InstructionOperand c, InstructionOperand d, + InstructionOperand e, InstructionOperand f, + size_t temp_count = 0, InstructionOperand* temps = NULL); Instruction* Emit(InstructionCode opcode, size_t output_count, - InstructionOperand** outputs, size_t input_count, - InstructionOperand** inputs, size_t temp_count = 0, - InstructionOperand* *temps = NULL); + InstructionOperand* outputs, size_t input_count, + InstructionOperand* inputs, size_t temp_count = 0, + InstructionOperand* temps = NULL); Instruction* Emit(Instruction* instr); // =========================================================================== @@ -154,7 +157,7 @@ class InstructionSelector FINAL { // Inform the register allocation of the representation of the unallocated // operand {op}. - void MarkAsRepresentation(MachineType rep, InstructionOperand* op); + void MarkAsRepresentation(MachineType rep, const InstructionOperand& op); // Initialize the call buffer with the InstructionOperands, nodes, etc, // corresponding diff --git a/src/compiler/instruction.cc b/src/compiler/instruction.cc index 6c358fb..9ec2fb9 100644 --- a/src/compiler/instruction.cc +++ b/src/compiler/instruction.cc @@ -119,16 +119,6 @@ bool ParallelMove::IsRedundant() const { } -static void SetOperand(UnallocatedOperand* loc, InstructionOperand* value) { - if (value->IsUnallocated()) { - loc[0] = *UnallocatedOperand::cast(value); - } else { - InstructionOperand* casted = static_cast(loc); - casted[0] = *value; - } -} - - Instruction::Instruction(InstructionCode opcode) : opcode_(opcode), bit_field_(OutputCountField::encode(0) | InputCountField::encode(0) | @@ -138,9 +128,9 @@ Instruction::Instruction(InstructionCode opcode) Instruction::Instruction(InstructionCode opcode, size_t output_count, - InstructionOperand** outputs, size_t input_count, - InstructionOperand** inputs, size_t temp_count, - InstructionOperand** temps) + InstructionOperand* outputs, size_t input_count, + InstructionOperand* inputs, size_t temp_count, + InstructionOperand* temps) : opcode_(opcode), bit_field_(OutputCountField::encode(output_count) | InputCountField::encode(input_count) | @@ -149,13 +139,16 @@ Instruction::Instruction(InstructionCode opcode, size_t output_count, pointer_map_(NULL) { size_t offset = 0; for (size_t i = 0; i < output_count; ++i) { - SetOperand(&operands_[offset++], outputs[i]); + DCHECK(!outputs[i].IsInvalid()); + operands_[offset++] = outputs[i]; } for (size_t i = 0; i < input_count; ++i) { - SetOperand(&operands_[offset++], inputs[i]); + DCHECK(!inputs[i].IsInvalid()); + operands_[offset++] = inputs[i]; } for (size_t i = 0; i < temp_count; ++i) { - SetOperand(&operands_[offset++], temps[i]); + DCHECK(!temps[i].IsInvalid()); + operands_[offset++] = temps[i]; } } diff --git a/src/compiler/instruction.h b/src/compiler/instruction.h index 6614d47..d78a5e8 100644 --- a/src/compiler/instruction.h +++ b/src/compiler/instruction.h @@ -35,7 +35,7 @@ const InstructionCode kSourcePositionInstruction = -2; V(Register, REGISTER, RegisterConfiguration::kMaxGeneralRegisters) \ V(DoubleRegister, DOUBLE_REGISTER, RegisterConfiguration::kMaxDoubleRegisters) -class InstructionOperand : public ZoneObject { +class InstructionOperand { public: static const int kInvalidVirtualRegister = -1; @@ -50,6 +50,10 @@ class InstructionOperand : public ZoneObject { DOUBLE_REGISTER }; + InstructionOperand() : virtual_register_(kInvalidVirtualRegister) { + ConvertTo(INVALID, 0); + } + InstructionOperand(Kind kind, int index) : virtual_register_(kInvalidVirtualRegister) { DCHECK(kind != INVALID); @@ -62,6 +66,7 @@ class InstructionOperand : public ZoneObject { bool Is##name() const { return kind() == type; } INSTRUCTION_OPERAND_LIST(INSTRUCTION_OPERAND_PREDICATE) INSTRUCTION_OPERAND_PREDICATE(Unallocated, UNALLOCATED, 0) + INSTRUCTION_OPERAND_PREDICATE(Invalid, INVALID, 0) #undef INSTRUCTION_OPERAND_PREDICATE bool Equals(const InstructionOperand* other) const { return value_ == other->value_; @@ -79,6 +84,12 @@ class InstructionOperand : public ZoneObject { static void SetUpCaches(); static void TearDownCaches(); + // TODO(dcarney): get rid of these + void* operator new(size_t, void* location) { return location; } + void* operator new(size_t size, Zone* zone) { + return zone->New(static_cast(size)); + } + protected: InstructionOperand(Kind kind, int index, int virtual_register) : virtual_register_(virtual_register) { @@ -91,8 +102,6 @@ class InstructionOperand : public ZoneObject { int32_t virtual_register_; }; -typedef ZoneVector InstructionOperandVector; - struct PrintableInstructionOperand { const RegisterConfiguration* register_configuration_; const InstructionOperand* op_; @@ -131,10 +140,6 @@ class UnallocatedOperand : public InstructionOperand { // TODO(dcarney): remove this. static const int kInvalidVirtualRegister = -1; - // This is only for array initialization. - UnallocatedOperand() - : InstructionOperand(INVALID, 0, kInvalidVirtualRegister) {} - UnallocatedOperand(ExtendedPolicy policy, int virtual_register) : InstructionOperand(UNALLOCATED, 0, virtual_register) { value_ |= BasicPolicyField::encode(EXTENDED_POLICY); @@ -181,6 +186,11 @@ class UnallocatedOperand : public InstructionOperand { return static_cast(op); } + static UnallocatedOperand cast(const InstructionOperand& op) { + DCHECK(op.IsUnallocated()); + return *static_cast(&op); + } + // The encoding used for UnallocatedOperand operands depends on the policy // that is // stored within the operand. The FIXED_SLOT policy uses a compact encoding @@ -341,6 +351,9 @@ std::ostream& operator<<(std::ostream& os, const PrintableMoveOperands& mo); template class SubKindOperand FINAL : public InstructionOperand { public: + explicit SubKindOperand(int index) + : InstructionOperand(kOperandKind, index) {} + static SubKindOperand* Create(int index, Zone* zone) { DCHECK(index >= 0); if (index < kNumCachedOperands) return &cache[index]; @@ -357,6 +370,11 @@ class SubKindOperand FINAL : public InstructionOperand { return reinterpret_cast(op); } + static SubKindOperand cast(const InstructionOperand& op) { + DCHECK(op.kind() == kOperandKind); + return *static_cast(&op); + } + static void SetUpCache(); static void TearDownCache(); @@ -364,8 +382,6 @@ class SubKindOperand FINAL : public InstructionOperand { static SubKindOperand* cache; SubKindOperand() : InstructionOperand(kOperandKind, 0) {} // For the caches. - explicit SubKindOperand(int index) - : InstructionOperand(kOperandKind, index) {} }; @@ -492,9 +508,9 @@ class Instruction : public ZoneObject { } static Instruction* New(Zone* zone, InstructionCode opcode, - size_t output_count, InstructionOperand** outputs, - size_t input_count, InstructionOperand** inputs, - size_t temp_count, InstructionOperand** temps) { + size_t output_count, InstructionOperand* outputs, + size_t input_count, InstructionOperand* inputs, + size_t temp_count, InstructionOperand* temps) { DCHECK(opcode >= 0); DCHECK(output_count == 0 || outputs != NULL); DCHECK(input_count == 0 || inputs != NULL); @@ -502,8 +518,8 @@ class Instruction : public ZoneObject { size_t total_extra_ops = output_count + input_count + temp_count; if (total_extra_ops != 0) total_extra_ops--; int size = static_cast( - RoundUp(sizeof(Instruction), sizeof(UnallocatedOperand)) + - total_extra_ops * sizeof(UnallocatedOperand)); + RoundUp(sizeof(Instruction), sizeof(InstructionOperand)) + + total_extra_ops * sizeof(InstructionOperand)); return new (zone->New(size)) Instruction( opcode, output_count, outputs, input_count, inputs, temp_count, temps); } @@ -559,9 +575,9 @@ class Instruction : public ZoneObject { protected: explicit Instruction(InstructionCode opcode); Instruction(InstructionCode opcode, size_t output_count, - InstructionOperand** outputs, size_t input_count, - InstructionOperand** inputs, size_t temp_count, - InstructionOperand** temps); + InstructionOperand* outputs, size_t input_count, + InstructionOperand* inputs, size_t temp_count, + InstructionOperand* temps); protected: typedef BitField OutputCountField; @@ -573,7 +589,7 @@ class Instruction : public ZoneObject { InstructionCode opcode_; uint32_t bit_field_; PointerMap* pointer_map_; - UnallocatedOperand operands_[1]; + InstructionOperand operands_[1]; }; diff --git a/src/compiler/mips/instruction-selector-mips.cc b/src/compiler/mips/instruction-selector-mips.cc index 6eb29bc..ae6ba3f 100644 --- a/src/compiler/mips/instruction-selector-mips.cc +++ b/src/compiler/mips/instruction-selector-mips.cc @@ -23,7 +23,7 @@ class MipsOperandGenerator FINAL : public OperandGenerator { explicit MipsOperandGenerator(InstructionSelector* selector) : OperandGenerator(selector) {} - InstructionOperand* UseOperand(Node* node, InstructionCode opcode) { + InstructionOperand UseOperand(Node* node, InstructionCode opcode) { if (CanBeImmediate(node, opcode)) { return UseImmediate(node); } @@ -91,9 +91,9 @@ static void VisitBinop(InstructionSelector* selector, Node* node, InstructionCode opcode, FlagsContinuation* cont) { MipsOperandGenerator g(selector); Int32BinopMatcher m(node); - InstructionOperand* inputs[4]; + InstructionOperand inputs[4]; size_t input_count = 0; - InstructionOperand* outputs[2]; + InstructionOperand outputs[2]; size_t output_count = 0; inputs[input_count++] = g.UseRegister(m.left().node()); @@ -162,7 +162,7 @@ void InstructionSelector::VisitLoad(Node* node) { Emit(opcode | AddressingModeField::encode(kMode_MRI), g.DefineAsRegister(node), g.UseRegister(base), g.UseImmediate(index)); } else { - InstructionOperand* addr_reg = g.TempRegister(); + InstructionOperand addr_reg = g.TempRegister(); Emit(kMipsAdd | AddressingModeField::encode(kMode_None), addr_reg, g.UseRegister(index), g.UseRegister(base)); // Emit desired load opcode, using temp addr_reg. @@ -185,8 +185,8 @@ void InstructionSelector::VisitStore(Node* node) { // TODO(dcarney): refactor RecordWrite function to take temp registers // and pass them here instead of using fixed regs // TODO(dcarney): handle immediate indices. - InstructionOperand* temps[] = {g.TempRegister(t1), g.TempRegister(t2)}; - Emit(kMipsStoreWriteBarrier, NULL, g.UseFixed(base, t0), + InstructionOperand temps[] = {g.TempRegister(t1), g.TempRegister(t2)}; + Emit(kMipsStoreWriteBarrier, g.NoOutput(), g.UseFixed(base, t0), g.UseFixed(index, t1), g.UseFixed(value, t2), arraysize(temps), temps); return; } @@ -217,15 +217,15 @@ void InstructionSelector::VisitStore(Node* node) { } if (g.CanBeImmediate(index, opcode)) { - Emit(opcode | AddressingModeField::encode(kMode_MRI), NULL, + Emit(opcode | AddressingModeField::encode(kMode_MRI), g.NoOutput(), g.UseRegister(base), g.UseImmediate(index), g.UseRegister(value)); } else { - InstructionOperand* addr_reg = g.TempRegister(); + InstructionOperand addr_reg = g.TempRegister(); Emit(kMipsAdd | AddressingModeField::encode(kMode_None), addr_reg, g.UseRegister(index), g.UseRegister(base)); // Emit desired store opcode, using temp addr_reg. - Emit(opcode | AddressingModeField::encode(kMode_MRI), NULL, addr_reg, - g.TempImmediate(0), g.UseRegister(value)); + Emit(opcode | AddressingModeField::encode(kMode_MRI), g.NoOutput(), + addr_reg, g.TempImmediate(0), g.UseRegister(value)); } } @@ -290,7 +290,7 @@ void InstructionSelector::VisitInt32Mul(Node* node) { return; } if (base::bits::IsPowerOfTwo32(value - 1)) { - InstructionOperand* temp = g.TempRegister(); + InstructionOperand temp = g.TempRegister(); Emit(kMipsShl | AddressingModeField::encode(kMode_None), temp, g.UseRegister(m.left().node()), g.TempImmediate(WhichPowerOf2(value - 1))); @@ -299,7 +299,7 @@ void InstructionSelector::VisitInt32Mul(Node* node) { return; } if (base::bits::IsPowerOfTwo32(value + 1)) { - InstructionOperand* temp = g.TempRegister(); + InstructionOperand temp = g.TempRegister(); Emit(kMipsShl | AddressingModeField::encode(kMode_None), temp, g.UseRegister(m.left().node()), g.TempImmediate(WhichPowerOf2(value + 1))); @@ -466,12 +466,12 @@ void InstructionSelector::VisitCall(Node* node) { // Possibly align stack here for functions. int push_count = buffer.pushed_nodes.size(); if (push_count > 0) { - Emit(kMipsStackClaim | MiscField::encode(push_count), NULL); + Emit(kMipsStackClaim | MiscField::encode(push_count), g.NoOutput()); } int slot = buffer.pushed_nodes.size() - 1; for (auto i = buffer.pushed_nodes.rbegin(); i != buffer.pushed_nodes.rend(); ++i) { - Emit(kMipsStoreToStackSlot | MiscField::encode(slot), nullptr, + Emit(kMipsStoreToStackSlot | MiscField::encode(slot), g.NoOutput(), g.UseRegister(*i)); slot--; } @@ -493,7 +493,7 @@ void InstructionSelector::VisitCall(Node* node) { opcode |= MiscField::encode(descriptor->flags()); // Emit the call instruction. - InstructionOperand** first_output = + InstructionOperand* first_output = buffer.outputs.size() > 0 ? &buffer.outputs.front() : NULL; Instruction* call_instr = Emit(opcode, buffer.outputs.size(), first_output, @@ -530,15 +530,15 @@ void InstructionSelector::VisitCheckedLoad(Node* node) { UNREACHABLE(); return; } - InstructionOperand* offset_operand = g.CanBeImmediate(offset, opcode) - ? g.UseImmediate(offset) - : g.UseRegister(offset); + InstructionOperand offset_operand = g.CanBeImmediate(offset, opcode) + ? g.UseImmediate(offset) + : g.UseRegister(offset); - InstructionOperand* length_operand = - (!g.CanBeImmediate(offset, opcode)) ? g.CanBeImmediate(length, opcode) - ? g.UseImmediate(length) - : g.UseRegister(length) - : g.UseRegister(length); + InstructionOperand length_operand = (!g.CanBeImmediate(offset, opcode)) + ? g.CanBeImmediate(length, opcode) + ? g.UseImmediate(length) + : g.UseRegister(length) + : g.UseRegister(length); Emit(opcode | AddressingModeField::encode(kMode_MRI), g.DefineAsRegister(node), offset_operand, length_operand, @@ -574,18 +574,19 @@ void InstructionSelector::VisitCheckedStore(Node* node) { UNREACHABLE(); return; } - InstructionOperand* offset_operand = g.CanBeImmediate(offset, opcode) - ? g.UseImmediate(offset) - : g.UseRegister(offset); - - InstructionOperand* length_operand = - (!g.CanBeImmediate(offset, opcode)) ? g.CanBeImmediate(length, opcode) - ? g.UseImmediate(length) - : g.UseRegister(length) - : g.UseRegister(length); - - Emit(opcode | AddressingModeField::encode(kMode_MRI), nullptr, offset_operand, - length_operand, g.UseRegister(value), g.UseRegister(buffer)); + InstructionOperand offset_operand = g.CanBeImmediate(offset, opcode) + ? g.UseImmediate(offset) + : g.UseRegister(offset); + + InstructionOperand length_operand = (!g.CanBeImmediate(offset, opcode)) + ? g.CanBeImmediate(length, opcode) + ? g.UseImmediate(length) + : g.UseRegister(length) + : g.UseRegister(length); + + Emit(opcode | AddressingModeField::encode(kMode_MRI), g.NoOutput(), + offset_operand, length_operand, g.UseRegister(value), + g.UseRegister(buffer)); } @@ -593,12 +594,13 @@ namespace { // Shared routine for multiple compare operations. static void VisitCompare(InstructionSelector* selector, InstructionCode opcode, - InstructionOperand* left, InstructionOperand* right, + InstructionOperand left, InstructionOperand right, FlagsContinuation* cont) { MipsOperandGenerator g(selector); opcode = cont->Encode(opcode); if (cont->IsBranch()) { - selector->Emit(opcode, NULL, left, right, g.Label(cont->true_block()), + selector->Emit(opcode, g.NoOutput(), left, right, + g.Label(cont->true_block()), g.Label(cont->false_block()))->MarkAsControl(); } else { DCHECK(cont->IsSet()); @@ -725,9 +727,9 @@ void VisitWordCompareZero(InstructionSelector* selector, Node* user, // Continuation could not be combined with a compare, emit compare against 0. MipsOperandGenerator g(selector); InstructionCode const opcode = cont->Encode(kMipsCmp); - InstructionOperand* const value_operand = g.UseRegister(value); + InstructionOperand const value_operand = g.UseRegister(value); if (cont->IsBranch()) { - selector->Emit(opcode, nullptr, value_operand, g.TempImmediate(0), + selector->Emit(opcode, g.NoOutput(), value_operand, g.TempImmediate(0), g.Label(cont->true_block()), g.Label(cont->false_block()))->MarkAsControl(); } else { diff --git a/src/compiler/mips64/instruction-selector-mips64.cc b/src/compiler/mips64/instruction-selector-mips64.cc index 027276f..9f97d68 100644 --- a/src/compiler/mips64/instruction-selector-mips64.cc +++ b/src/compiler/mips64/instruction-selector-mips64.cc @@ -23,7 +23,7 @@ class Mips64OperandGenerator FINAL : public OperandGenerator { explicit Mips64OperandGenerator(InstructionSelector* selector) : OperandGenerator(selector) {} - InstructionOperand* UseOperand(Node* node, InstructionCode opcode) { + InstructionOperand UseOperand(Node* node, InstructionCode opcode) { if (CanBeImmediate(node, opcode)) { return UseImmediate(node); } @@ -124,9 +124,9 @@ static void VisitBinop(InstructionSelector* selector, Node* node, InstructionCode opcode, FlagsContinuation* cont) { Mips64OperandGenerator g(selector); Int32BinopMatcher m(node); - InstructionOperand* inputs[4]; + InstructionOperand inputs[4]; size_t input_count = 0; - InstructionOperand* outputs[2]; + InstructionOperand outputs[2]; size_t output_count = 0; inputs[input_count++] = g.UseRegister(m.left().node()); @@ -198,7 +198,7 @@ void InstructionSelector::VisitLoad(Node* node) { Emit(opcode | AddressingModeField::encode(kMode_MRI), g.DefineAsRegister(node), g.UseRegister(base), g.UseImmediate(index)); } else { - InstructionOperand* addr_reg = g.TempRegister(); + InstructionOperand addr_reg = g.TempRegister(); Emit(kMips64Dadd | AddressingModeField::encode(kMode_None), addr_reg, g.UseRegister(index), g.UseRegister(base)); // Emit desired load opcode, using temp addr_reg. @@ -221,8 +221,8 @@ void InstructionSelector::VisitStore(Node* node) { // TODO(dcarney): refactor RecordWrite function to take temp registers // and pass them here instead of using fixed regs // TODO(dcarney): handle immediate indices. - InstructionOperand* temps[] = {g.TempRegister(t1), g.TempRegister(t2)}; - Emit(kMips64StoreWriteBarrier, NULL, g.UseFixed(base, t0), + InstructionOperand temps[] = {g.TempRegister(t1), g.TempRegister(t2)}; + Emit(kMips64StoreWriteBarrier, g.NoOutput(), g.UseFixed(base, t0), g.UseFixed(index, t1), g.UseFixed(value, t2), arraysize(temps), temps); return; } @@ -256,15 +256,15 @@ void InstructionSelector::VisitStore(Node* node) { } if (g.CanBeImmediate(index, opcode)) { - Emit(opcode | AddressingModeField::encode(kMode_MRI), NULL, + Emit(opcode | AddressingModeField::encode(kMode_MRI), g.NoOutput(), g.UseRegister(base), g.UseImmediate(index), g.UseRegister(value)); } else { - InstructionOperand* addr_reg = g.TempRegister(); + InstructionOperand addr_reg = g.TempRegister(); Emit(kMips64Dadd | AddressingModeField::encode(kMode_None), addr_reg, g.UseRegister(index), g.UseRegister(base)); // Emit desired store opcode, using temp addr_reg. - Emit(opcode | AddressingModeField::encode(kMode_MRI), NULL, addr_reg, - g.TempImmediate(0), g.UseRegister(value)); + Emit(opcode | AddressingModeField::encode(kMode_MRI), g.NoOutput(), + addr_reg, g.TempImmediate(0), g.UseRegister(value)); } } @@ -375,7 +375,7 @@ void InstructionSelector::VisitInt32Mul(Node* node) { return; } if (base::bits::IsPowerOfTwo32(value - 1)) { - InstructionOperand* temp = g.TempRegister(); + InstructionOperand temp = g.TempRegister(); Emit(kMips64Shl | AddressingModeField::encode(kMode_None), temp, g.UseRegister(m.left().node()), g.TempImmediate(WhichPowerOf2(value - 1))); @@ -384,7 +384,7 @@ void InstructionSelector::VisitInt32Mul(Node* node) { return; } if (base::bits::IsPowerOfTwo32(value + 1)) { - InstructionOperand* temp = g.TempRegister(); + InstructionOperand temp = g.TempRegister(); Emit(kMips64Shl | AddressingModeField::encode(kMode_None), temp, g.UseRegister(m.left().node()), g.TempImmediate(WhichPowerOf2(value + 1))); @@ -407,7 +407,7 @@ void InstructionSelector::VisitInt32MulHigh(Node* node) { void InstructionSelector::VisitUint32MulHigh(Node* node) { Mips64OperandGenerator g(this); - InstructionOperand* const dmul_operand = g.TempRegister(); + InstructionOperand const dmul_operand = g.TempRegister(); Emit(kMips64MulHighU, dmul_operand, g.UseRegister(node->InputAt(0)), g.UseRegister(node->InputAt(1))); Emit(kMips64Ext, g.DefineAsRegister(node), dmul_operand, g.TempImmediate(0), @@ -428,7 +428,7 @@ void InstructionSelector::VisitInt64Mul(Node* node) { return; } if (base::bits::IsPowerOfTwo32(value - 1)) { - InstructionOperand* temp = g.TempRegister(); + InstructionOperand temp = g.TempRegister(); Emit(kMips64Dshl | AddressingModeField::encode(kMode_None), temp, g.UseRegister(m.left().node()), g.TempImmediate(WhichPowerOf2(value - 1))); @@ -437,7 +437,7 @@ void InstructionSelector::VisitInt64Mul(Node* node) { return; } if (base::bits::IsPowerOfTwo32(value + 1)) { - InstructionOperand* temp = g.TempRegister(); + InstructionOperand temp = g.TempRegister(); Emit(kMips64Dshl | AddressingModeField::encode(kMode_None), temp, g.UseRegister(m.left().node()), g.TempImmediate(WhichPowerOf2(value + 1))); @@ -646,12 +646,12 @@ void InstructionSelector::VisitCall(Node* node) { int push_count = buffer.pushed_nodes.size(); if (push_count > 0) { - Emit(kMips64StackClaim | MiscField::encode(push_count), NULL); + Emit(kMips64StackClaim | MiscField::encode(push_count), g.NoOutput()); } int slot = buffer.pushed_nodes.size() - 1; for (auto i = buffer.pushed_nodes.rbegin(); i != buffer.pushed_nodes.rend(); ++i) { - Emit(kMips64StoreToStackSlot | MiscField::encode(slot), nullptr, + Emit(kMips64StoreToStackSlot | MiscField::encode(slot), g.NoOutput(), g.UseRegister(*i)); slot--; } @@ -709,15 +709,15 @@ void InstructionSelector::VisitCheckedLoad(Node* node) { UNREACHABLE(); return; } - InstructionOperand* offset_operand = g.CanBeImmediate(offset, opcode) - ? g.UseImmediate(offset) - : g.UseRegister(offset); + InstructionOperand offset_operand = g.CanBeImmediate(offset, opcode) + ? g.UseImmediate(offset) + : g.UseRegister(offset); - InstructionOperand* length_operand = - (!g.CanBeImmediate(offset, opcode)) ? g.CanBeImmediate(length, opcode) - ? g.UseImmediate(length) - : g.UseRegister(length) - : g.UseRegister(length); + InstructionOperand length_operand = (!g.CanBeImmediate(offset, opcode)) + ? g.CanBeImmediate(length, opcode) + ? g.UseImmediate(length) + : g.UseRegister(length) + : g.UseRegister(length); Emit(opcode | AddressingModeField::encode(kMode_MRI), g.DefineAsRegister(node), offset_operand, length_operand, @@ -753,18 +753,19 @@ void InstructionSelector::VisitCheckedStore(Node* node) { UNREACHABLE(); return; } - InstructionOperand* offset_operand = g.CanBeImmediate(offset, opcode) - ? g.UseImmediate(offset) - : g.UseRegister(offset); - - InstructionOperand* length_operand = - (!g.CanBeImmediate(offset, opcode)) ? g.CanBeImmediate(length, opcode) - ? g.UseImmediate(length) - : g.UseRegister(length) - : g.UseRegister(length); - - Emit(opcode | AddressingModeField::encode(kMode_MRI), nullptr, offset_operand, - length_operand, g.UseRegister(value), g.UseRegister(buffer)); + InstructionOperand offset_operand = g.CanBeImmediate(offset, opcode) + ? g.UseImmediate(offset) + : g.UseRegister(offset); + + InstructionOperand length_operand = (!g.CanBeImmediate(offset, opcode)) + ? g.CanBeImmediate(length, opcode) + ? g.UseImmediate(length) + : g.UseRegister(length) + : g.UseRegister(length); + + Emit(opcode | AddressingModeField::encode(kMode_MRI), g.NoOutput(), + offset_operand, length_operand, g.UseRegister(value), + g.UseRegister(buffer)); } @@ -772,12 +773,13 @@ namespace { // Shared routine for multiple compare operations. static void VisitCompare(InstructionSelector* selector, InstructionCode opcode, - InstructionOperand* left, InstructionOperand* right, + InstructionOperand left, InstructionOperand right, FlagsContinuation* cont) { Mips64OperandGenerator g(selector); opcode = cont->Encode(opcode); if (cont->IsBranch()) { - selector->Emit(opcode, NULL, left, right, g.Label(cont->true_block()), + selector->Emit(opcode, g.NoOutput(), left, right, + g.Label(cont->true_block()), g.Label(cont->false_block()))->MarkAsControl(); } else { DCHECK(cont->IsSet()); @@ -838,9 +840,9 @@ void EmitWordCompareZero(InstructionSelector* selector, InstructionCode opcode, Node* value, FlagsContinuation* cont) { Mips64OperandGenerator g(selector); opcode = cont->Encode(opcode); - InstructionOperand* const value_operand = g.UseRegister(value); + InstructionOperand const value_operand = g.UseRegister(value); if (cont->IsBranch()) { - selector->Emit(opcode, nullptr, value_operand, g.TempImmediate(0), + selector->Emit(opcode, g.NoOutput(), value_operand, g.TempImmediate(0), g.Label(cont->true_block()), g.Label(cont->false_block()))->MarkAsControl(); } else { diff --git a/src/compiler/x64/instruction-selector-x64.cc b/src/compiler/x64/instruction-selector-x64.cc index f19225f..1722b43 100644 --- a/src/compiler/x64/instruction-selector-x64.cc +++ b/src/compiler/x64/instruction-selector-x64.cc @@ -31,7 +31,7 @@ class X64OperandGenerator FINAL : public OperandGenerator { AddressingMode GenerateMemoryOperandInputs(Node* index, int scale_exponent, Node* base, Node* displacement, - InstructionOperand* inputs[], + InstructionOperand inputs[], size_t* input_count) { AddressingMode mode = kMode_MRI; if (base != NULL) { @@ -80,7 +80,7 @@ class X64OperandGenerator FINAL : public OperandGenerator { } AddressingMode GetEffectiveAddressMemoryOperand(Node* operand, - InstructionOperand* inputs[], + InstructionOperand inputs[], size_t* input_count) { BaseWithIndexAndDisplacement64Matcher m(operand, true); DCHECK(m.matches()); @@ -132,9 +132,9 @@ void InstructionSelector::VisitLoad(Node* node) { return; } - InstructionOperand* outputs[1]; + InstructionOperand outputs[1]; outputs[0] = g.DefineAsRegister(node); - InstructionOperand* inputs[3]; + InstructionOperand inputs[3]; size_t input_count = 0; AddressingMode mode = g.GetEffectiveAddressMemoryOperand(node, inputs, &input_count); @@ -156,8 +156,8 @@ void InstructionSelector::VisitStore(Node* node) { // TODO(dcarney): refactor RecordWrite function to take temp registers // and pass them here instead of using fixed regs // TODO(dcarney): handle immediate indices. - InstructionOperand* temps[] = {g.TempRegister(rcx), g.TempRegister(rdx)}; - Emit(kX64StoreWriteBarrier, NULL, g.UseFixed(base, rbx), + InstructionOperand temps[] = {g.TempRegister(rcx), g.TempRegister(rdx)}; + Emit(kX64StoreWriteBarrier, g.NoOutput(), g.UseFixed(base, rbx), g.UseFixed(index, rcx), g.UseFixed(value, rdx), arraysize(temps), temps); return; @@ -189,15 +189,15 @@ void InstructionSelector::VisitStore(Node* node) { UNREACHABLE(); return; } - InstructionOperand* inputs[4]; + InstructionOperand inputs[4]; size_t input_count = 0; AddressingMode mode = g.GetEffectiveAddressMemoryOperand(node, inputs, &input_count); InstructionCode code = opcode | AddressingModeField::encode(mode); - InstructionOperand* value_operand = + InstructionOperand value_operand = g.CanBeImmediate(value) ? g.UseImmediate(value) : g.UseRegister(value); inputs[input_count++] = value_operand; - Emit(code, 0, static_cast(NULL), input_count, inputs); + Emit(code, 0, static_cast(NULL), input_count, inputs); } @@ -241,7 +241,7 @@ void InstructionSelector::VisitCheckedLoad(Node* node) { return; } } - InstructionOperand* length_operand = + InstructionOperand length_operand = g.CanBeImmediate(length) ? g.UseImmediate(length) : g.UseRegister(length); Emit(opcode, g.DefineAsRegister(node), g.UseRegister(buffer), g.UseRegister(offset), g.TempImmediate(0), length_operand); @@ -276,7 +276,7 @@ void InstructionSelector::VisitCheckedStore(Node* node) { UNREACHABLE(); return; } - InstructionOperand* value_operand = + InstructionOperand value_operand = g.CanBeImmediate(value) ? g.UseImmediate(value) : g.UseRegister(value); if (offset->opcode() == IrOpcode::kInt32Add && CanCover(node, offset)) { Int32Matcher mlength(length); @@ -284,16 +284,16 @@ void InstructionSelector::VisitCheckedStore(Node* node) { if (mlength.HasValue() && moffset.right().HasValue() && moffset.right().Value() >= 0 && mlength.Value() >= moffset.right().Value()) { - Emit(opcode, nullptr, g.UseRegister(buffer), + Emit(opcode, g.NoOutput(), g.UseRegister(buffer), g.UseRegister(moffset.left().node()), g.UseImmediate(moffset.right().node()), g.UseImmediate(length), value_operand); return; } } - InstructionOperand* length_operand = + InstructionOperand length_operand = g.CanBeImmediate(length) ? g.UseImmediate(length) : g.UseRegister(length); - Emit(opcode, nullptr, g.UseRegister(buffer), g.UseRegister(offset), + Emit(opcode, g.NoOutput(), g.UseRegister(buffer), g.UseRegister(offset), g.TempImmediate(0), length_operand, value_operand); } @@ -305,9 +305,9 @@ static void VisitBinop(InstructionSelector* selector, Node* node, Int32BinopMatcher m(node); Node* left = m.left().node(); Node* right = m.right().node(); - InstructionOperand* inputs[4]; + InstructionOperand inputs[4]; size_t input_count = 0; - InstructionOperand* outputs[2]; + InstructionOperand outputs[2]; size_t output_count = 0; // TODO(turbofan): match complex addressing modes. @@ -319,7 +319,7 @@ static void VisitBinop(InstructionSelector* selector, Node* node, // mov rax, [rbp-0x10] // add rax, [rbp-0x10] // jo label - InstructionOperand* const input = g.UseRegister(left); + InstructionOperand const input = g.UseRegister(left); inputs[input_count++] = input; inputs[input_count++] = input; } else if (g.CanBeImmediate(right)) { @@ -456,7 +456,7 @@ void EmitLea(InstructionSelector* selector, InstructionCode opcode, Node* displacement) { X64OperandGenerator g(selector); - InstructionOperand* inputs[4]; + InstructionOperand inputs[4]; size_t input_count = 0; AddressingMode mode = g.GenerateMemoryOperandInputs( index, scale, base, displacement, inputs, &input_count); @@ -464,7 +464,7 @@ void EmitLea(InstructionSelector* selector, InstructionCode opcode, DCHECK_NE(0, static_cast(input_count)); DCHECK_GE(arraysize(inputs), input_count); - InstructionOperand* outputs[1]; + InstructionOperand outputs[1]; outputs[0] = g.DefineAsRegister(result); opcode = AddressingModeField::encode(mode) | opcode; @@ -634,7 +634,7 @@ void VisitMulHigh(InstructionSelector* selector, Node* node, void VisitDiv(InstructionSelector* selector, Node* node, ArchOpcode opcode) { X64OperandGenerator g(selector); - InstructionOperand* temps[] = {g.TempRegister(rdx)}; + InstructionOperand temps[] = {g.TempRegister(rdx)}; selector->Emit( opcode, g.DefineAsFixed(node, rax), g.UseFixed(node->InputAt(0), rax), g.UseUniqueRegister(node->InputAt(1)), arraysize(temps), temps); @@ -870,7 +870,7 @@ void InstructionSelector::VisitFloat64Div(Node* node) { void InstructionSelector::VisitFloat64Mod(Node* node) { X64OperandGenerator g(this); - InstructionOperand* temps[] = {g.TempRegister(rax)}; + InstructionOperand temps[] = {g.TempRegister(rax)}; Emit(kSSEFloat64Mod, g.DefineSameAsFirst(node), g.UseRegister(node->InputAt(0)), g.UseRegister(node->InputAt(1)), 1, temps); @@ -937,11 +937,11 @@ void InstructionSelector::VisitCall(Node* node) { for (auto i = buffer.pushed_nodes.rbegin(); i != buffer.pushed_nodes.rend(); ++i) { // TODO(titzer): handle pushing double parameters. - InstructionOperand* value = + InstructionOperand value = g.CanBeImmediate(*i) ? g.UseImmediate(*i) : IsSupported(ATOM) ? g.UseRegister(*i) : g.Use(*i); - Emit(kX64Push, nullptr, value); + Emit(kX64Push, g.NoOutput(), value); } // Select the appropriate opcode based on the call type. @@ -961,7 +961,7 @@ void InstructionSelector::VisitCall(Node* node) { opcode |= MiscField::encode(descriptor->flags()); // Emit the call instruction. - InstructionOperand** first_output = + InstructionOperand* first_output = buffer.outputs.size() > 0 ? &buffer.outputs.front() : NULL; Instruction* call_instr = Emit(opcode, buffer.outputs.size(), first_output, @@ -972,12 +972,13 @@ void InstructionSelector::VisitCall(Node* node) { // Shared routine for multiple compare operations. static void VisitCompare(InstructionSelector* selector, InstructionCode opcode, - InstructionOperand* left, InstructionOperand* right, + InstructionOperand left, InstructionOperand right, FlagsContinuation* cont) { X64OperandGenerator g(selector); opcode = cont->Encode(opcode); if (cont->IsBranch()) { - selector->Emit(opcode, NULL, left, right, g.Label(cont->true_block()), + selector->Emit(opcode, g.NoOutput(), left, right, + g.Label(cont->true_block()), g.Label(cont->false_block()))->MarkAsControl(); } else { DCHECK(cont->IsSet()); diff --git a/test/cctest/compiler/test-instruction.cc b/test/cctest/compiler/test-instruction.cc index da460d1..0e8056e 100644 --- a/test/cctest/compiler/test-instruction.cc +++ b/test/cctest/compiler/test-instruction.cc @@ -296,35 +296,23 @@ TEST(InstructionOperands) { } int vreg = 15; - InstructionOperand* outputs[] = { - new (&zone) - UnallocatedOperand(UnallocatedOperand::MUST_HAVE_REGISTER, vreg), - new (&zone) - UnallocatedOperand(UnallocatedOperand::MUST_HAVE_REGISTER, vreg), - new (&zone) - UnallocatedOperand(UnallocatedOperand::MUST_HAVE_REGISTER, vreg), - new (&zone) - UnallocatedOperand(UnallocatedOperand::MUST_HAVE_REGISTER, vreg)}; - - InstructionOperand* inputs[] = { - new (&zone) - UnallocatedOperand(UnallocatedOperand::MUST_HAVE_REGISTER, vreg), - new (&zone) - UnallocatedOperand(UnallocatedOperand::MUST_HAVE_REGISTER, vreg), - new (&zone) - UnallocatedOperand(UnallocatedOperand::MUST_HAVE_REGISTER, vreg), - new (&zone) - UnallocatedOperand(UnallocatedOperand::MUST_HAVE_REGISTER, vreg)}; - - InstructionOperand* temps[] = { - new (&zone) - UnallocatedOperand(UnallocatedOperand::MUST_HAVE_REGISTER, vreg), - new (&zone) - UnallocatedOperand(UnallocatedOperand::MUST_HAVE_REGISTER, vreg), - new (&zone) - UnallocatedOperand(UnallocatedOperand::MUST_HAVE_REGISTER, vreg), - new (&zone) - UnallocatedOperand(UnallocatedOperand::MUST_HAVE_REGISTER, vreg)}; + InstructionOperand outputs[] = { + UnallocatedOperand(UnallocatedOperand::MUST_HAVE_REGISTER, vreg), + UnallocatedOperand(UnallocatedOperand::MUST_HAVE_REGISTER, vreg), + UnallocatedOperand(UnallocatedOperand::MUST_HAVE_REGISTER, vreg), + UnallocatedOperand(UnallocatedOperand::MUST_HAVE_REGISTER, vreg)}; + + InstructionOperand inputs[] = { + UnallocatedOperand(UnallocatedOperand::MUST_HAVE_REGISTER, vreg), + UnallocatedOperand(UnallocatedOperand::MUST_HAVE_REGISTER, vreg), + UnallocatedOperand(UnallocatedOperand::MUST_HAVE_REGISTER, vreg), + UnallocatedOperand(UnallocatedOperand::MUST_HAVE_REGISTER, vreg)}; + + InstructionOperand temps[] = { + UnallocatedOperand(UnallocatedOperand::MUST_HAVE_REGISTER, vreg), + UnallocatedOperand(UnallocatedOperand::MUST_HAVE_REGISTER, vreg), + UnallocatedOperand(UnallocatedOperand::MUST_HAVE_REGISTER, vreg), + UnallocatedOperand(UnallocatedOperand::MUST_HAVE_REGISTER, vreg)}; for (size_t i = 0; i < arraysize(outputs); i++) { for (size_t j = 0; j < arraysize(inputs); j++) { @@ -336,15 +324,15 @@ TEST(InstructionOperands) { CHECK(k == m->TempCount()); for (size_t z = 0; z < i; z++) { - CHECK(outputs[z]->Equals(m->OutputAt(z))); + CHECK(outputs[z].Equals(m->OutputAt(z))); } for (size_t z = 0; z < j; z++) { - CHECK(inputs[z]->Equals(m->InputAt(z))); + CHECK(inputs[z].Equals(m->InputAt(z))); } for (size_t z = 0; z < k; z++) { - CHECK(temps[z]->Equals(m->TempAt(z))); + CHECK(temps[z].Equals(m->TempAt(z))); } } } diff --git a/test/cctest/compiler/test-jump-threading.cc b/test/cctest/compiler/test-jump-threading.cc index 894c9c7..549e4ac 100644 --- a/test/cctest/compiler/test-jump-threading.cc +++ b/test/cctest/compiler/test-jump-threading.cc @@ -31,7 +31,7 @@ class TestCode : public HandleAndZoneScope { int Jump(int target) { Start(); - InstructionOperand* ops[] = {UseRpo(target)}; + InstructionOperand ops[] = {UseRpo(target)}; sequence_.AddInstruction(Instruction::New(main_zone(), kArchJmp, 0, NULL, 1, ops, 0, NULL)->MarkAsControl()); int pos = static_cast(sequence_.instructions().size() - 1); @@ -44,7 +44,7 @@ class TestCode : public HandleAndZoneScope { } int Branch(int ttarget, int ftarget) { Start(); - InstructionOperand* ops[] = {UseRpo(ttarget), UseRpo(ftarget)}; + InstructionOperand ops[] = {UseRpo(ttarget), UseRpo(ftarget)}; InstructionCode code = 119 | FlagsModeField::encode(kFlags_branch) | FlagsConditionField::encode(kEqual); sequence_.AddInstruction(Instruction::New(main_zone(), code, 0, NULL, 2, @@ -81,9 +81,9 @@ class TestCode : public HandleAndZoneScope { current_ = NULL; rpo_number_ = RpoNumber::FromInt(rpo_number_.ToInt() + 1); } - InstructionOperand* UseRpo(int num) { + InstructionOperand UseRpo(int num) { int index = sequence_.AddImmediate(Constant(RpoNumber::FromInt(num))); - return ImmediateOperand::Create(index, main_zone()); + return ImmediateOperand(index); } void Start(bool deferred = false) { if (current_ == NULL) { diff --git a/test/unittests/compiler/instruction-sequence-unittest.cc b/test/unittests/compiler/instruction-sequence-unittest.cc index 4228470..dceefaf 100644 --- a/test/unittests/compiler/instruction-sequence-unittest.cc +++ b/test/unittests/compiler/instruction-sequence-unittest.cc @@ -138,7 +138,7 @@ InstructionSequenceTest::TestOperand InstructionSequenceTest::Imm(int32_t imm) { InstructionSequenceTest::VReg InstructionSequenceTest::Define( TestOperand output_op) { VReg vreg = NewReg(); - InstructionOperand* outputs[1]{ConvertOutputOp(vreg, output_op)}; + InstructionOperand outputs[1]{ConvertOutputOp(vreg, output_op)}; Emit(vreg.value_, kArchNop, 1, outputs); return vreg; } @@ -146,7 +146,7 @@ InstructionSequenceTest::VReg InstructionSequenceTest::Define( int InstructionSequenceTest::Return(TestOperand input_op_0) { block_returns_ = true; - InstructionOperand* inputs[1]{ConvertInputOp(input_op_0)}; + InstructionOperand inputs[1]{ConvertInputOp(input_op_0)}; return Emit(NewIndex(), kArchRet, 0, nullptr, 1, inputs); } @@ -176,7 +176,7 @@ InstructionSequenceTest::VReg InstructionSequenceTest::DefineConstant( int32_t imm) { VReg vreg = NewReg(); sequence()->AddConstant(vreg.value_, Constant(imm)); - InstructionOperand* outputs[1]{ConstantOperand::Create(vreg.value_, zone())}; + InstructionOperand outputs[1]{ConstantOperand(vreg.value_)}; Emit(vreg.value_, kArchNop, 1, outputs); return vreg; } @@ -196,7 +196,7 @@ static size_t CountInputs(size_t size, int InstructionSequenceTest::EmitI(size_t input_size, TestOperand* inputs) { - InstructionOperand** mapped_inputs = ConvertInputs(input_size, inputs); + InstructionOperand* mapped_inputs = ConvertInputs(input_size, inputs); return Emit(NewIndex(), kArchNop, 0, nullptr, input_size, mapped_inputs); } @@ -213,8 +213,8 @@ int InstructionSequenceTest::EmitI(TestOperand input_op_0, InstructionSequenceTest::VReg InstructionSequenceTest::EmitOI( TestOperand output_op, size_t input_size, TestOperand* inputs) { VReg output_vreg = NewReg(); - InstructionOperand* outputs[1]{ConvertOutputOp(output_vreg, output_op)}; - InstructionOperand** mapped_inputs = ConvertInputs(input_size, inputs); + InstructionOperand outputs[1]{ConvertOutputOp(output_vreg, output_op)}; + InstructionOperand* mapped_inputs = ConvertInputs(input_size, inputs); Emit(output_vreg.value_, kArchNop, 1, outputs, input_size, mapped_inputs); return output_vreg; } @@ -231,9 +231,9 @@ InstructionSequenceTest::VReg InstructionSequenceTest::EmitOI( InstructionSequenceTest::VReg InstructionSequenceTest::EmitCall( TestOperand output_op, size_t input_size, TestOperand* inputs) { VReg output_vreg = NewReg(); - InstructionOperand* outputs[1]{ConvertOutputOp(output_vreg, output_op)}; - CHECK(UnallocatedOperand::cast(outputs[0])->HasFixedPolicy()); - InstructionOperand** mapped_inputs = ConvertInputs(input_size, inputs); + InstructionOperand outputs[1]{ConvertOutputOp(output_vreg, output_op)}; + CHECK(UnallocatedOperand::cast(outputs[0]).HasFixedPolicy()); + InstructionOperand* mapped_inputs = ConvertInputs(input_size, inputs); Emit(output_vreg.value_, kArchCallCodeObject, 1, outputs, input_size, mapped_inputs, 0, nullptr, true); return output_vreg; @@ -257,8 +257,8 @@ const Instruction* InstructionSequenceTest::GetInstruction( int InstructionSequenceTest::EmitBranch(TestOperand input_op) { - InstructionOperand* inputs[4]{ConvertInputOp(input_op), ConvertInputOp(Imm()), - ConvertInputOp(Imm()), ConvertInputOp(Imm())}; + InstructionOperand inputs[4]{ConvertInputOp(input_op), ConvertInputOp(Imm()), + ConvertInputOp(Imm()), ConvertInputOp(Imm())}; InstructionCode opcode = kArchJmp | FlagsModeField::encode(kFlags_branch) | FlagsConditionField::encode(kEqual); auto instruction = @@ -274,7 +274,7 @@ int InstructionSequenceTest::EmitFallThrough() { int InstructionSequenceTest::EmitJump() { - InstructionOperand* inputs[1]{ConvertInputOp(Imm())}; + InstructionOperand inputs[1]{ConvertInputOp(Imm())}; auto instruction = NewInstruction(kArchJmp, 0, nullptr, 1, inputs)->MarkAsControl(); return AddInstruction(NewIndex(), instruction); @@ -282,44 +282,44 @@ int InstructionSequenceTest::EmitJump() { Instruction* InstructionSequenceTest::NewInstruction( - InstructionCode code, size_t outputs_size, InstructionOperand** outputs, - size_t inputs_size, InstructionOperand** inputs, size_t temps_size, - InstructionOperand** temps) { + InstructionCode code, size_t outputs_size, InstructionOperand* outputs, + size_t inputs_size, InstructionOperand* inputs, size_t temps_size, + InstructionOperand* temps) { CHECK(current_block_); return Instruction::New(zone(), code, outputs_size, outputs, inputs_size, inputs, temps_size, temps); } -InstructionOperand* InstructionSequenceTest::Unallocated( +InstructionOperand InstructionSequenceTest::Unallocated( TestOperand op, UnallocatedOperand::ExtendedPolicy policy) { - return new (zone()) UnallocatedOperand(policy, op.vreg_.value_); + return UnallocatedOperand(policy, op.vreg_.value_); } -InstructionOperand* InstructionSequenceTest::Unallocated( +InstructionOperand InstructionSequenceTest::Unallocated( TestOperand op, UnallocatedOperand::ExtendedPolicy policy, UnallocatedOperand::Lifetime lifetime) { - return new (zone()) UnallocatedOperand(policy, lifetime, op.vreg_.value_); + return UnallocatedOperand(policy, lifetime, op.vreg_.value_); } -InstructionOperand* InstructionSequenceTest::Unallocated( +InstructionOperand InstructionSequenceTest::Unallocated( TestOperand op, UnallocatedOperand::ExtendedPolicy policy, int index) { - return new (zone()) UnallocatedOperand(policy, index, op.vreg_.value_); + return UnallocatedOperand(policy, index, op.vreg_.value_); } -InstructionOperand* InstructionSequenceTest::Unallocated( +InstructionOperand InstructionSequenceTest::Unallocated( TestOperand op, UnallocatedOperand::BasicPolicy policy, int index) { - return new (zone()) UnallocatedOperand(policy, index, op.vreg_.value_); + return UnallocatedOperand(policy, index, op.vreg_.value_); } -InstructionOperand** InstructionSequenceTest::ConvertInputs( +InstructionOperand* InstructionSequenceTest::ConvertInputs( size_t input_size, TestOperand* inputs) { - InstructionOperand** mapped_inputs = - zone()->NewArray(static_cast(input_size)); + InstructionOperand* mapped_inputs = + zone()->NewArray(static_cast(input_size)); for (size_t i = 0; i < input_size; ++i) { mapped_inputs[i] = ConvertInputOp(inputs[i]); } @@ -327,10 +327,10 @@ InstructionOperand** InstructionSequenceTest::ConvertInputs( } -InstructionOperand* InstructionSequenceTest::ConvertInputOp(TestOperand op) { +InstructionOperand InstructionSequenceTest::ConvertInputOp(TestOperand op) { if (op.type_ == kImmediate) { CHECK_EQ(op.vreg_.value_, kNoValue); - return ImmediateOperand::Create(op.value_, zone()); + return ImmediateOperand(op.value_); } CHECK_NE(op.vreg_.value_, kNoValue); switch (op.type_) { @@ -353,12 +353,12 @@ InstructionOperand* InstructionSequenceTest::ConvertInputOp(TestOperand op) { break; } CHECK(false); - return NULL; + return InstructionOperand(); } -InstructionOperand* InstructionSequenceTest::ConvertOutputOp(VReg vreg, - TestOperand op) { +InstructionOperand InstructionSequenceTest::ConvertOutputOp(VReg vreg, + TestOperand op) { CHECK_EQ(op.vreg_.value_, kNoValue); op.vreg_ = vreg; switch (op.type_) { @@ -375,7 +375,7 @@ InstructionOperand* InstructionSequenceTest::ConvertOutputOp(VReg vreg, break; } CHECK(false); - return NULL; + return InstructionOperand(); } @@ -445,11 +445,10 @@ void InstructionSequenceTest::WireBlock(size_t block_offset, int jump_offset) { int InstructionSequenceTest::Emit(int instruction_index, InstructionCode code, size_t outputs_size, - InstructionOperand** outputs, + InstructionOperand* outputs, size_t inputs_size, - InstructionOperand** inputs, - size_t temps_size, InstructionOperand** temps, - bool is_call) { + InstructionOperand* inputs, size_t temps_size, + InstructionOperand* temps, bool is_call) { auto instruction = NewInstruction(code, outputs_size, outputs, inputs_size, inputs, temps_size, temps); if (is_call) instruction->MarkAsCall(); diff --git a/test/unittests/compiler/instruction-sequence-unittest.h b/test/unittests/compiler/instruction-sequence-unittest.h index 9ce1cc3..a5bf482 100644 --- a/test/unittests/compiler/instruction-sequence-unittest.h +++ b/test/unittests/compiler/instruction-sequence-unittest.h @@ -179,32 +179,32 @@ class InstructionSequenceTest : public TestWithIsolateAndZone { int EmitFallThrough(); int EmitJump(); Instruction* NewInstruction(InstructionCode code, size_t outputs_size, - InstructionOperand** outputs, + InstructionOperand* outputs, size_t inputs_size = 0, - InstructionOperand* *inputs = nullptr, + InstructionOperand* inputs = nullptr, size_t temps_size = 0, - InstructionOperand* *temps = nullptr); - InstructionOperand* Unallocated(TestOperand op, - UnallocatedOperand::ExtendedPolicy policy); - InstructionOperand* Unallocated(TestOperand op, - UnallocatedOperand::ExtendedPolicy policy, - UnallocatedOperand::Lifetime lifetime); - InstructionOperand* Unallocated(TestOperand op, - UnallocatedOperand::ExtendedPolicy policy, - int index); - InstructionOperand* Unallocated(TestOperand op, - UnallocatedOperand::BasicPolicy policy, - int index); - InstructionOperand** ConvertInputs(size_t input_size, TestOperand* inputs); - InstructionOperand* ConvertInputOp(TestOperand op); - InstructionOperand* ConvertOutputOp(VReg vreg, TestOperand op); + InstructionOperand* temps = nullptr); + InstructionOperand Unallocated(TestOperand op, + UnallocatedOperand::ExtendedPolicy policy); + InstructionOperand Unallocated(TestOperand op, + UnallocatedOperand::ExtendedPolicy policy, + UnallocatedOperand::Lifetime lifetime); + InstructionOperand Unallocated(TestOperand op, + UnallocatedOperand::ExtendedPolicy policy, + int index); + InstructionOperand Unallocated(TestOperand op, + UnallocatedOperand::BasicPolicy policy, + int index); + InstructionOperand* ConvertInputs(size_t input_size, TestOperand* inputs); + InstructionOperand ConvertInputOp(TestOperand op); + InstructionOperand ConvertOutputOp(VReg vreg, TestOperand op); InstructionBlock* NewBlock(); void WireBlock(size_t block_offset, int jump_offset); int Emit(int instruction_index, InstructionCode code, size_t outputs_size = 0, - InstructionOperand* *outputs = nullptr, size_t inputs_size = 0, - InstructionOperand* *inputs = nullptr, size_t temps_size = 0, - InstructionOperand* *temps = nullptr, bool is_call = false); + InstructionOperand* outputs = nullptr, size_t inputs_size = 0, + InstructionOperand* inputs = nullptr, size_t temps_size = 0, + InstructionOperand* temps = nullptr, bool is_call = false); int AddInstruction(int instruction_index, Instruction* instruction); -- 2.7.4