From 87e82b04522befdd0469e1833ea35061a100b8ca Mon Sep 17 00:00:00 2001 From: "fschneider@chromium.org" Date: Mon, 17 Jan 2011 12:22:31 +0000 Subject: [PATCH] Remove the remaining LOperand-members from concrete LIR instructions. This change introduces the third template parameters for LIR instructions to specify the number of temp-operands. This is one step towards removing the instruction-summaries. I also added hydrogen-accessors in more places and refactored the LIR-branch instructions to have common super-classes to avoid code duplication. Added MUST_USE_RESULT to the functions that record uses and definitions so that all LOperands are stored in the LIR instructions (and not only in the summaries). Review URL: http://codereview.chromium.org/6237002 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@6345 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- src/ia32/lithium-codegen-ia32.cc | 242 ++++----- src/ia32/lithium-ia32.cc | 130 +++-- src/ia32/lithium-ia32.h | 1050 ++++++++++++++++++-------------------- 3 files changed, 668 insertions(+), 754 deletions(-) diff --git a/src/ia32/lithium-codegen-ia32.cc b/src/ia32/lithium-codegen-ia32.cc index 84b36f8..a422762 100644 --- a/src/ia32/lithium-codegen-ia32.cc +++ b/src/ia32/lithium-codegen-ia32.cc @@ -706,11 +706,11 @@ void LCodeGen::DoUnknownOSRValue(LUnknownOSRValue* instr) { void LCodeGen::DoModI(LModI* instr) { - LOperand* right = instr->right(); + LOperand* right = instr->InputAt(1); ASSERT(ToRegister(instr->result()).is(edx)); - ASSERT(ToRegister(instr->left()).is(eax)); - ASSERT(!ToRegister(instr->right()).is(eax)); - ASSERT(!ToRegister(instr->right()).is(edx)); + ASSERT(ToRegister(instr->InputAt(0)).is(eax)); + ASSERT(!ToRegister(instr->InputAt(1)).is(eax)); + ASSERT(!ToRegister(instr->InputAt(1)).is(edx)); Register right_reg = ToRegister(right); @@ -746,11 +746,11 @@ void LCodeGen::DoModI(LModI* instr) { void LCodeGen::DoDivI(LDivI* instr) { - LOperand* right = instr->right(); + LOperand* right = instr->InputAt(1); ASSERT(ToRegister(instr->result()).is(eax)); - ASSERT(ToRegister(instr->left()).is(eax)); - ASSERT(!ToRegister(instr->right()).is(eax)); - ASSERT(!ToRegister(instr->right()).is(edx)); + ASSERT(ToRegister(instr->InputAt(0)).is(eax)); + ASSERT(!ToRegister(instr->InputAt(1)).is(eax)); + ASSERT(!ToRegister(instr->InputAt(1)).is(edx)); Register left_reg = eax; @@ -792,11 +792,11 @@ void LCodeGen::DoDivI(LDivI* instr) { void LCodeGen::DoMulI(LMulI* instr) { - Register left = ToRegister(instr->left()); - LOperand* right = instr->right(); + Register left = ToRegister(instr->InputAt(0)); + LOperand* right = instr->InputAt(1); if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { - __ mov(ToRegister(instr->temp()), left); + __ mov(ToRegister(instr->TempAt(0)), left); } if (right->IsConstantOperand()) { @@ -820,7 +820,7 @@ void LCodeGen::DoMulI(LMulI* instr) { } } else { // Test the non-zero operand for negative sign. - __ or_(ToRegister(instr->temp()), ToOperand(right)); + __ or_(ToRegister(instr->TempAt(0)), ToOperand(right)); DeoptimizeIf(sign, instr->environment()); } __ bind(&done); @@ -829,8 +829,8 @@ void LCodeGen::DoMulI(LMulI* instr) { void LCodeGen::DoBitI(LBitI* instr) { - LOperand* left = instr->left(); - LOperand* right = instr->right(); + LOperand* left = instr->InputAt(0); + LOperand* right = instr->InputAt(1); ASSERT(left->Equals(instr->result())); ASSERT(left->IsRegister()); @@ -870,8 +870,8 @@ void LCodeGen::DoBitI(LBitI* instr) { void LCodeGen::DoShiftI(LShiftI* instr) { - LOperand* left = instr->left(); - LOperand* right = instr->right(); + LOperand* left = instr->InputAt(0); + LOperand* right = instr->InputAt(1); ASSERT(left->Equals(instr->result())); ASSERT(left->IsRegister()); if (right->IsRegister()) { @@ -926,8 +926,8 @@ void LCodeGen::DoShiftI(LShiftI* instr) { void LCodeGen::DoSubI(LSubI* instr) { - LOperand* left = instr->left(); - LOperand* right = instr->right(); + LOperand* left = instr->InputAt(0); + LOperand* right = instr->InputAt(1); ASSERT(left->Equals(instr->result())); if (right->IsConstantOperand()) { @@ -982,22 +982,22 @@ void LCodeGen::DoConstantT(LConstantT* instr) { void LCodeGen::DoJSArrayLength(LJSArrayLength* instr) { Register result = ToRegister(instr->result()); - Register array = ToRegister(instr->input()); + Register array = ToRegister(instr->InputAt(0)); __ mov(result, FieldOperand(array, JSArray::kLengthOffset)); } void LCodeGen::DoFixedArrayLength(LFixedArrayLength* instr) { Register result = ToRegister(instr->result()); - Register array = ToRegister(instr->input()); + Register array = ToRegister(instr->InputAt(0)); __ mov(result, FieldOperand(array, FixedArray::kLengthOffset)); } void LCodeGen::DoValueOf(LValueOf* instr) { - Register input = ToRegister(instr->input()); + Register input = ToRegister(instr->InputAt(0)); Register result = ToRegister(instr->result()); - Register map = ToRegister(instr->temporary()); + Register map = ToRegister(instr->TempAt(0)); ASSERT(input.is(result)); NearLabel done; // If the object is a smi return the object. @@ -1014,14 +1014,14 @@ void LCodeGen::DoValueOf(LValueOf* instr) { void LCodeGen::DoBitNotI(LBitNotI* instr) { - LOperand* input = instr->input(); + LOperand* input = instr->InputAt(0); ASSERT(input->Equals(instr->result())); __ not_(ToRegister(input)); } void LCodeGen::DoThrow(LThrow* instr) { - __ push(ToOperand(instr->input())); + __ push(ToOperand(instr->InputAt(0))); CallRuntime(Runtime::kThrow, 1, instr); if (FLAG_debug_code) { @@ -1032,8 +1032,8 @@ void LCodeGen::DoThrow(LThrow* instr) { void LCodeGen::DoAddI(LAddI* instr) { - LOperand* left = instr->left(); - LOperand* right = instr->right(); + LOperand* left = instr->InputAt(0); + LOperand* right = instr->InputAt(1); ASSERT(left->Equals(instr->result())); if (right->IsConstantOperand()) { @@ -1049,8 +1049,8 @@ void LCodeGen::DoAddI(LAddI* instr) { void LCodeGen::DoArithmeticD(LArithmeticD* instr) { - LOperand* left = instr->left(); - LOperand* right = instr->right(); + LOperand* left = instr->InputAt(0); + LOperand* right = instr->InputAt(1); // Modulo uses a fixed result register. ASSERT(instr->op() == Token::MOD || left->Equals(instr->result())); switch (instr->op()) { @@ -1089,8 +1089,8 @@ void LCodeGen::DoArithmeticD(LArithmeticD* instr) { void LCodeGen::DoArithmeticT(LArithmeticT* instr) { - ASSERT(ToRegister(instr->left()).is(edx)); - ASSERT(ToRegister(instr->right()).is(eax)); + ASSERT(ToRegister(instr->InputAt(0)).is(edx)); + ASSERT(ToRegister(instr->InputAt(1)).is(eax)); ASSERT(ToRegister(instr->result()).is(eax)); TypeRecordingBinaryOpStub stub(instr->op(), NO_OVERWRITE); @@ -1131,17 +1131,17 @@ void LCodeGen::DoBranch(LBranch* instr) { Representation r = instr->hydrogen()->representation(); if (r.IsInteger32()) { - Register reg = ToRegister(instr->input()); + Register reg = ToRegister(instr->InputAt(0)); __ test(reg, Operand(reg)); EmitBranch(true_block, false_block, not_zero); } else if (r.IsDouble()) { - XMMRegister reg = ToDoubleRegister(instr->input()); + XMMRegister reg = ToDoubleRegister(instr->InputAt(0)); __ xorpd(xmm0, xmm0); __ ucomisd(reg, xmm0); EmitBranch(true_block, false_block, not_equal); } else { ASSERT(r.IsTagged()); - Register reg = ToRegister(instr->input()); + Register reg = ToRegister(instr->InputAt(0)); if (instr->hydrogen()->type().IsBoolean()) { __ cmp(reg, Factory::true_value()); EmitBranch(true_block, false_block, equal); @@ -1269,8 +1269,8 @@ void LCodeGen::EmitCmpI(LOperand* left, LOperand* right) { void LCodeGen::DoCmpID(LCmpID* instr) { - LOperand* left = instr->left(); - LOperand* right = instr->right(); + LOperand* left = instr->InputAt(0); + LOperand* right = instr->InputAt(1); LOperand* result = instr->result(); NearLabel unordered; @@ -1295,8 +1295,8 @@ void LCodeGen::DoCmpID(LCmpID* instr) { void LCodeGen::DoCmpIDAndBranch(LCmpIDAndBranch* instr) { - LOperand* left = instr->left(); - LOperand* right = instr->right(); + LOperand* left = instr->InputAt(0); + LOperand* right = instr->InputAt(1); int false_block = chunk_->LookupDestination(instr->false_block_id()); int true_block = chunk_->LookupDestination(instr->true_block_id()); @@ -1315,8 +1315,8 @@ void LCodeGen::DoCmpIDAndBranch(LCmpIDAndBranch* instr) { void LCodeGen::DoCmpJSObjectEq(LCmpJSObjectEq* instr) { - Register left = ToRegister(instr->left()); - Register right = ToRegister(instr->right()); + Register left = ToRegister(instr->InputAt(0)); + Register right = ToRegister(instr->InputAt(1)); Register result = ToRegister(instr->result()); __ cmp(left, Operand(right)); @@ -1329,8 +1329,8 @@ void LCodeGen::DoCmpJSObjectEq(LCmpJSObjectEq* instr) { void LCodeGen::DoCmpJSObjectEqAndBranch(LCmpJSObjectEqAndBranch* instr) { - Register left = ToRegister(instr->left()); - Register right = ToRegister(instr->right()); + Register left = ToRegister(instr->InputAt(0)); + Register right = ToRegister(instr->InputAt(1)); int false_block = chunk_->LookupDestination(instr->false_block_id()); int true_block = chunk_->LookupDestination(instr->true_block_id()); @@ -1340,7 +1340,7 @@ void LCodeGen::DoCmpJSObjectEqAndBranch(LCmpJSObjectEqAndBranch* instr) { void LCodeGen::DoIsNull(LIsNull* instr) { - Register reg = ToRegister(instr->input()); + Register reg = ToRegister(instr->InputAt(0)); Register result = ToRegister(instr->result()); // TODO(fsc): If the expression is known to be a smi, then it's @@ -1378,7 +1378,7 @@ void LCodeGen::DoIsNull(LIsNull* instr) { void LCodeGen::DoIsNullAndBranch(LIsNullAndBranch* instr) { - Register reg = ToRegister(instr->input()); + Register reg = ToRegister(instr->InputAt(0)); // TODO(fsc): If the expression is known to be a smi, then it's // definitely not null. Jump to the false block. @@ -1399,7 +1399,7 @@ void LCodeGen::DoIsNullAndBranch(LIsNullAndBranch* instr) { __ j(zero, false_label); // Check for undetectable objects by looking in the bit field in // the map. The object has already been smi checked. - Register scratch = ToRegister(instr->temp()); + Register scratch = ToRegister(instr->TempAt(0)); __ mov(scratch, FieldOperand(reg, HeapObject::kMapOffset)); __ movzx_b(scratch, FieldOperand(scratch, Map::kBitFieldOffset)); __ test(scratch, Immediate(1 << Map::kIsUndetectable)); @@ -1438,9 +1438,9 @@ Condition LCodeGen::EmitIsObject(Register input, void LCodeGen::DoIsObject(LIsObject* instr) { - Register reg = ToRegister(instr->input()); + Register reg = ToRegister(instr->InputAt(0)); Register result = ToRegister(instr->result()); - Register temp = ToRegister(instr->temp()); + Register temp = ToRegister(instr->TempAt(0)); Label is_false, is_true, done; Condition true_cond = EmitIsObject(reg, result, temp, &is_false, &is_true); @@ -1458,9 +1458,9 @@ void LCodeGen::DoIsObject(LIsObject* instr) { void LCodeGen::DoIsObjectAndBranch(LIsObjectAndBranch* instr) { - Register reg = ToRegister(instr->input()); - Register temp = ToRegister(instr->temp()); - Register temp2 = ToRegister(instr->temp2()); + Register reg = ToRegister(instr->InputAt(0)); + Register temp = ToRegister(instr->TempAt(0)); + Register temp2 = ToRegister(instr->TempAt(1)); int true_block = chunk_->LookupDestination(instr->true_block_id()); int false_block = chunk_->LookupDestination(instr->false_block_id()); @@ -1474,7 +1474,7 @@ void LCodeGen::DoIsObjectAndBranch(LIsObjectAndBranch* instr) { void LCodeGen::DoIsSmi(LIsSmi* instr) { - Operand input = ToOperand(instr->input()); + Operand input = ToOperand(instr->InputAt(0)); Register result = ToRegister(instr->result()); ASSERT(instr->hydrogen()->value()->representation().IsTagged()); @@ -1488,7 +1488,7 @@ void LCodeGen::DoIsSmi(LIsSmi* instr) { void LCodeGen::DoIsSmiAndBranch(LIsSmiAndBranch* instr) { - Operand input = ToOperand(instr->input()); + Operand input = ToOperand(instr->InputAt(0)); int true_block = chunk_->LookupDestination(instr->true_block_id()); int false_block = chunk_->LookupDestination(instr->false_block_id()); @@ -1498,9 +1498,9 @@ void LCodeGen::DoIsSmiAndBranch(LIsSmiAndBranch* instr) { } -InstanceType LHasInstanceType::TestType() { - InstanceType from = hydrogen()->from(); - InstanceType to = hydrogen()->to(); +static InstanceType TestType(HHasInstanceType* instr) { + InstanceType from = instr->from(); + InstanceType to = instr->to(); if (from == FIRST_TYPE) return to; ASSERT(from == to || to == LAST_TYPE); return from; @@ -1508,9 +1508,9 @@ InstanceType LHasInstanceType::TestType() { -Condition LHasInstanceType::BranchCondition() { - InstanceType from = hydrogen()->from(); - InstanceType to = hydrogen()->to(); +static Condition BranchCondition(HHasInstanceType* instr) { + InstanceType from = instr->from(); + InstanceType to = instr->to(); if (from == to) return equal; if (to == LAST_TYPE) return above_equal; if (from == FIRST_TYPE) return below_equal; @@ -1520,15 +1520,15 @@ Condition LHasInstanceType::BranchCondition() { void LCodeGen::DoHasInstanceType(LHasInstanceType* instr) { - Register input = ToRegister(instr->input()); + Register input = ToRegister(instr->InputAt(0)); Register result = ToRegister(instr->result()); ASSERT(instr->hydrogen()->value()->representation().IsTagged()); __ test(input, Immediate(kSmiTagMask)); NearLabel done, is_false; __ j(zero, &is_false); - __ CmpObjectType(input, instr->TestType(), result); - __ j(NegateCondition(instr->BranchCondition()), &is_false); + __ CmpObjectType(input, TestType(instr->hydrogen()), result); + __ j(NegateCondition(BranchCondition(instr->hydrogen())), &is_false); __ mov(result, Handle(Heap::true_value())); __ jmp(&done); __ bind(&is_false); @@ -1538,8 +1538,8 @@ void LCodeGen::DoHasInstanceType(LHasInstanceType* instr) { void LCodeGen::DoHasInstanceTypeAndBranch(LHasInstanceTypeAndBranch* instr) { - Register input = ToRegister(instr->input()); - Register temp = ToRegister(instr->temp()); + Register input = ToRegister(instr->InputAt(0)); + Register temp = ToRegister(instr->TempAt(0)); int true_block = chunk_->LookupDestination(instr->true_block_id()); int false_block = chunk_->LookupDestination(instr->false_block_id()); @@ -1549,13 +1549,13 @@ void LCodeGen::DoHasInstanceTypeAndBranch(LHasInstanceTypeAndBranch* instr) { __ test(input, Immediate(kSmiTagMask)); __ j(zero, false_label); - __ CmpObjectType(input, instr->TestType(), temp); - EmitBranch(true_block, false_block, instr->BranchCondition()); + __ CmpObjectType(input, TestType(instr->hydrogen()), temp); + EmitBranch(true_block, false_block, BranchCondition(instr->hydrogen())); } void LCodeGen::DoHasCachedArrayIndex(LHasCachedArrayIndex* instr) { - Register input = ToRegister(instr->input()); + Register input = ToRegister(instr->InputAt(0)); Register result = ToRegister(instr->result()); ASSERT(instr->hydrogen()->value()->representation().IsTagged()); @@ -1571,7 +1571,7 @@ void LCodeGen::DoHasCachedArrayIndex(LHasCachedArrayIndex* instr) { void LCodeGen::DoHasCachedArrayIndexAndBranch( LHasCachedArrayIndexAndBranch* instr) { - Register input = ToRegister(instr->input()); + Register input = ToRegister(instr->InputAt(0)); int true_block = chunk_->LookupDestination(instr->true_block_id()); int false_block = chunk_->LookupDestination(instr->false_block_id()); @@ -1640,10 +1640,10 @@ void LCodeGen::EmitClassOfTest(Label* is_true, void LCodeGen::DoClassOfTest(LClassOfTest* instr) { - Register input = ToRegister(instr->input()); + Register input = ToRegister(instr->InputAt(0)); Register result = ToRegister(instr->result()); ASSERT(input.is(result)); - Register temp = ToRegister(instr->temporary()); + Register temp = ToRegister(instr->TempAt(0)); Handle class_name = instr->hydrogen()->class_name(); NearLabel done; Label is_true, is_false; @@ -1663,9 +1663,9 @@ void LCodeGen::DoClassOfTest(LClassOfTest* instr) { void LCodeGen::DoClassOfTestAndBranch(LClassOfTestAndBranch* instr) { - Register input = ToRegister(instr->input()); - Register temp = ToRegister(instr->temporary()); - Register temp2 = ToRegister(instr->temporary2()); + Register input = ToRegister(instr->InputAt(0)); + Register temp = ToRegister(instr->TempAt(0)); + Register temp2 = ToRegister(instr->TempAt(1)); if (input.is(temp)) { // Swap. Register swapper = temp; @@ -1687,7 +1687,7 @@ void LCodeGen::DoClassOfTestAndBranch(LClassOfTestAndBranch* instr) { void LCodeGen::DoCmpMapAndBranch(LCmpMapAndBranch* instr) { - Register reg = ToRegister(instr->input()); + Register reg = ToRegister(instr->InputAt(0)); int true_block = instr->true_block_id(); int false_block = instr->false_block_id(); @@ -1744,8 +1744,8 @@ void LCodeGen::DoInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr) { deferred = new DeferredInstanceOfKnownGlobal(this, instr); Label done, false_result; - Register object = ToRegister(instr->input()); - Register temp = ToRegister(instr->temp()); + Register object = ToRegister(instr->InputAt(0)); + Register temp = ToRegister(instr->TempAt(0)); // A Smi is not instance of anything. __ test(object, Immediate(kSmiTagMask)); @@ -1755,7 +1755,7 @@ void LCodeGen::DoInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr) { // hole value will be patched to the last map/result pair generated by the // instanceof stub. NearLabel cache_miss; - Register map = ToRegister(instr->temp()); + Register map = ToRegister(instr->TempAt(0)); __ mov(map, FieldOperand(object, HeapObject::kMapOffset)); __ bind(deferred->map_check()); // Label for calculating code patching. __ cmp(map, Factory::the_hole_value()); // Patched to cached map. @@ -1803,7 +1803,7 @@ void LCodeGen::DoDeferredLInstanceOfKnownGlobal(LInstanceOfKnownGlobal* instr, // Get the temp register reserved by the instruction. This needs to be edi as // its slot of the pushing of safepoint registers is used to communicate the // offset to the location of the map check. - Register temp = ToRegister(instr->temp()); + Register temp = ToRegister(instr->TempAt(0)); ASSERT(temp.is(edi)); __ mov(InstanceofStub::right(), Immediate(instr->function())); static const int kAdditionalDelta = 13; @@ -1908,7 +1908,7 @@ void LCodeGen::DoLoadGlobal(LLoadGlobal* instr) { void LCodeGen::DoStoreGlobal(LStoreGlobal* instr) { - Register value = ToRegister(instr->input()); + Register value = ToRegister(instr->InputAt(0)); __ mov(Operand::Cell(instr->hydrogen()->cell()), value); } @@ -1922,7 +1922,7 @@ void LCodeGen::DoLoadContextSlot(LLoadContextSlot* instr) { void LCodeGen::DoLoadNamedField(LLoadNamedField* instr) { - Register object = ToRegister(instr->input()); + Register object = ToRegister(instr->InputAt(0)); Register result = ToRegister(instr->result()); if (instr->hydrogen()->is_in_object()) { __ mov(result, FieldOperand(object, instr->hydrogen()->offset())); @@ -1945,7 +1945,7 @@ void LCodeGen::DoLoadNamedGeneric(LLoadNamedGeneric* instr) { void LCodeGen::DoLoadFunctionPrototype(LLoadFunctionPrototype* instr) { Register function = ToRegister(instr->function()); - Register temp = ToRegister(instr->temporary()); + Register temp = ToRegister(instr->TempAt(0)); Register result = ToRegister(instr->result()); // Check that the function really is a function. @@ -1986,8 +1986,8 @@ void LCodeGen::DoLoadFunctionPrototype(LLoadFunctionPrototype* instr) { void LCodeGen::DoLoadElements(LLoadElements* instr) { - ASSERT(instr->result()->Equals(instr->input())); - Register reg = ToRegister(instr->input()); + ASSERT(instr->result()->Equals(instr->InputAt(0))); + Register reg = ToRegister(instr->InputAt(0)); __ mov(reg, FieldOperand(reg, JSObject::kElementsOffset)); if (FLAG_debug_code) { NearLabel done; @@ -2067,7 +2067,7 @@ void LCodeGen::DoArgumentsElements(LArgumentsElements* instr) { void LCodeGen::DoArgumentsLength(LArgumentsLength* instr) { - Operand elem = ToOperand(instr->input()); + Operand elem = ToOperand(instr->InputAt(0)); Register result = ToRegister(instr->result()); NearLabel done; @@ -2141,7 +2141,7 @@ void LCodeGen::DoApplyArguments(LApplyArguments* instr) { void LCodeGen::DoPushArgument(LPushArgument* instr) { - LOperand* argument = instr->input(); + LOperand* argument = instr->InputAt(0); if (argument->IsConstantOperand()) { __ push(ToImmediate(argument)); } else { @@ -2207,7 +2207,7 @@ void LCodeGen::DoCallConstantFunction(LCallConstantFunction* instr) { void LCodeGen::DoDeferredMathAbsTaggedHeapNumber(LUnaryMathOperation* instr) { - Register input_reg = ToRegister(instr->input()); + Register input_reg = ToRegister(instr->InputAt(0)); __ cmp(FieldOperand(input_reg, HeapObject::kMapOffset), Factory::heap_number_map()); DeoptimizeIf(not_equal, instr->environment()); @@ -2274,17 +2274,17 @@ void LCodeGen::DoMathAbs(LUnaryMathOperation* instr) { LUnaryMathOperation* instr_; }; - ASSERT(instr->input()->Equals(instr->result())); + ASSERT(instr->InputAt(0)->Equals(instr->result())); Representation r = instr->hydrogen()->value()->representation(); if (r.IsDouble()) { XMMRegister scratch = xmm0; - XMMRegister input_reg = ToDoubleRegister(instr->input()); + XMMRegister input_reg = ToDoubleRegister(instr->InputAt(0)); __ pxor(scratch, scratch); __ subsd(scratch, input_reg); __ pand(input_reg, scratch); } else if (r.IsInteger32()) { - Register input_reg = ToRegister(instr->input()); + Register input_reg = ToRegister(instr->InputAt(0)); __ test(input_reg, Operand(input_reg)); Label is_positive; __ j(not_sign, &is_positive); @@ -2296,7 +2296,7 @@ void LCodeGen::DoMathAbs(LUnaryMathOperation* instr) { DeferredMathAbsTaggedHeapNumber* deferred = new DeferredMathAbsTaggedHeapNumber(this, instr); Label not_smi; - Register input_reg = ToRegister(instr->input()); + Register input_reg = ToRegister(instr->InputAt(0)); // Smi check. __ test(input_reg, Immediate(kSmiTagMask)); __ j(not_zero, deferred->entry()); @@ -2317,7 +2317,7 @@ void LCodeGen::DoMathAbs(LUnaryMathOperation* instr) { void LCodeGen::DoMathFloor(LUnaryMathOperation* instr) { XMMRegister xmm_scratch = xmm0; Register output_reg = ToRegister(instr->result()); - XMMRegister input_reg = ToDoubleRegister(instr->input()); + XMMRegister input_reg = ToDoubleRegister(instr->InputAt(0)); __ xorpd(xmm_scratch, xmm_scratch); // Zero the register. __ ucomisd(input_reg, xmm_scratch); @@ -2339,7 +2339,7 @@ void LCodeGen::DoMathFloor(LUnaryMathOperation* instr) { void LCodeGen::DoMathRound(LUnaryMathOperation* instr) { XMMRegister xmm_scratch = xmm0; Register output_reg = ToRegister(instr->result()); - XMMRegister input_reg = ToDoubleRegister(instr->input()); + XMMRegister input_reg = ToDoubleRegister(instr->InputAt(0)); // xmm_scratch = 0.5 ExternalReference one_half = ExternalReference::address_of_one_half(); @@ -2372,7 +2372,7 @@ void LCodeGen::DoMathRound(LUnaryMathOperation* instr) { void LCodeGen::DoMathSqrt(LUnaryMathOperation* instr) { - XMMRegister input_reg = ToDoubleRegister(instr->input()); + XMMRegister input_reg = ToDoubleRegister(instr->InputAt(0)); ASSERT(ToDoubleRegister(instr->result()).is(input_reg)); __ sqrtsd(input_reg, input_reg); } @@ -2380,7 +2380,7 @@ void LCodeGen::DoMathSqrt(LUnaryMathOperation* instr) { void LCodeGen::DoMathPowHalf(LUnaryMathOperation* instr) { XMMRegister xmm_scratch = xmm0; - XMMRegister input_reg = ToDoubleRegister(instr->input()); + XMMRegister input_reg = ToDoubleRegister(instr->InputAt(0)); ASSERT(ToDoubleRegister(instr->result()).is(input_reg)); ExternalReference negative_infinity = ExternalReference::address_of_negative_infinity(); @@ -2392,8 +2392,8 @@ void LCodeGen::DoMathPowHalf(LUnaryMathOperation* instr) { void LCodeGen::DoPower(LPower* instr) { - LOperand* left = instr->left(); - LOperand* right = instr->right(); + LOperand* left = instr->InputAt(0); + LOperand* right = instr->InputAt(1); DoubleRegister result_reg = ToDoubleRegister(instr->result()); Representation exponent_type = instr->hydrogen()->right()->representation(); if (exponent_type.IsDouble()) { @@ -2555,7 +2555,7 @@ void LCodeGen::DoCallKnownGlobal(LCallKnownGlobal* instr) { void LCodeGen::DoCallNew(LCallNew* instr) { - ASSERT(ToRegister(instr->input()).is(edi)); + ASSERT(ToRegister(instr->InputAt(0)).is(edi)); ASSERT(ToRegister(instr->result()).is(eax)); Handle builtin(Builtins::builtin(Builtins::JSConstructCall)); @@ -2582,12 +2582,12 @@ void LCodeGen::DoStoreNamedField(LStoreNamedField* instr) { if (instr->is_in_object()) { __ mov(FieldOperand(object, offset), value); if (instr->needs_write_barrier()) { - Register temp = ToRegister(instr->temp()); + Register temp = ToRegister(instr->TempAt(0)); // Update the write barrier for the object for in-object properties. __ RecordWrite(object, offset, value, temp); } } else { - Register temp = ToRegister(instr->temp()); + Register temp = ToRegister(instr->TempAt(0)); __ mov(temp, FieldOperand(object, JSObject::kPropertiesOffset)); __ mov(FieldOperand(temp, offset), value); if (instr->needs_write_barrier()) { @@ -2651,7 +2651,7 @@ void LCodeGen::DoStoreKeyedGeneric(LStoreKeyedGeneric* instr) { void LCodeGen::DoInteger32ToDouble(LInteger32ToDouble* instr) { - LOperand* input = instr->input(); + LOperand* input = instr->InputAt(0); ASSERT(input->IsRegister() || input->IsStackSlot()); LOperand* output = instr->result(); ASSERT(output->IsDoubleRegister()); @@ -2669,7 +2669,7 @@ void LCodeGen::DoNumberTagI(LNumberTagI* instr) { LNumberTagI* instr_; }; - LOperand* input = instr->input(); + LOperand* input = instr->InputAt(0); ASSERT(input->IsRegister() && input->Equals(instr->result())); Register reg = ToRegister(input); @@ -2682,7 +2682,7 @@ void LCodeGen::DoNumberTagI(LNumberTagI* instr) { void LCodeGen::DoDeferredNumberTagI(LNumberTagI* instr) { Label slow; - Register reg = ToRegister(instr->input()); + Register reg = ToRegister(instr->InputAt(0)); Register tmp = reg.is(eax) ? ecx : eax; // Preserve the value of all registers. @@ -2732,9 +2732,9 @@ void LCodeGen::DoNumberTagD(LNumberTagD* instr) { LNumberTagD* instr_; }; - XMMRegister input_reg = ToDoubleRegister(instr->input()); + XMMRegister input_reg = ToDoubleRegister(instr->InputAt(0)); Register reg = ToRegister(instr->result()); - Register tmp = ToRegister(instr->temp()); + Register tmp = ToRegister(instr->TempAt(0)); DeferredNumberTagD* deferred = new DeferredNumberTagD(this, instr); if (FLAG_inline_new) { @@ -2764,7 +2764,7 @@ void LCodeGen::DoDeferredNumberTagD(LNumberTagD* instr) { void LCodeGen::DoSmiTag(LSmiTag* instr) { - LOperand* input = instr->input(); + LOperand* input = instr->InputAt(0); ASSERT(input->IsRegister() && input->Equals(instr->result())); ASSERT(!instr->hydrogen_value()->CheckFlag(HValue::kCanOverflow)); __ SmiTag(ToRegister(input)); @@ -2772,7 +2772,7 @@ void LCodeGen::DoSmiTag(LSmiTag* instr) { void LCodeGen::DoSmiUntag(LSmiUntag* instr) { - LOperand* input = instr->input(); + LOperand* input = instr->InputAt(0); ASSERT(input->IsRegister() && input->Equals(instr->result())); if (instr->needs_check()) { __ test(ToRegister(input), Immediate(kSmiTagMask)); @@ -2832,7 +2832,7 @@ class DeferredTaggedToI: public LDeferredCode { void LCodeGen::DoDeferredTaggedToI(LTaggedToI* instr) { NearLabel done, heap_number; - Register input_reg = ToRegister(instr->input()); + Register input_reg = ToRegister(instr->InputAt(0)); // Heap number map check. __ cmp(FieldOperand(input_reg, HeapObject::kMapOffset), @@ -2875,7 +2875,7 @@ void LCodeGen::DoDeferredTaggedToI(LTaggedToI* instr) { __ add(Operand(esp), Immediate(kDoubleSize)); } else { NearLabel deopt; - XMMRegister xmm_temp = ToDoubleRegister(instr->temp()); + XMMRegister xmm_temp = ToDoubleRegister(instr->TempAt(0)); __ movdbl(xmm0, FieldOperand(input_reg, HeapNumber::kValueOffset)); __ cvttsd2si(input_reg, Operand(xmm0)); __ cmp(input_reg, 0x80000000u); @@ -2892,7 +2892,7 @@ void LCodeGen::DoDeferredTaggedToI(LTaggedToI* instr) { // Deoptimize if we don't have a heap number. DeoptimizeIf(not_equal, instr->environment()); - XMMRegister xmm_temp = ToDoubleRegister(instr->temp()); + XMMRegister xmm_temp = ToDoubleRegister(instr->TempAt(0)); __ movdbl(xmm0, FieldOperand(input_reg, HeapNumber::kValueOffset)); __ cvttsd2si(input_reg, Operand(xmm0)); __ cvtsi2sd(xmm_temp, Operand(input_reg)); @@ -2912,7 +2912,7 @@ void LCodeGen::DoDeferredTaggedToI(LTaggedToI* instr) { void LCodeGen::DoTaggedToI(LTaggedToI* instr) { - LOperand* input = instr->input(); + LOperand* input = instr->InputAt(0); ASSERT(input->IsRegister()); ASSERT(input->Equals(instr->result())); @@ -2932,7 +2932,7 @@ void LCodeGen::DoTaggedToI(LTaggedToI* instr) { void LCodeGen::DoNumberUntagD(LNumberUntagD* instr) { - LOperand* input = instr->input(); + LOperand* input = instr->InputAt(0); ASSERT(input->IsRegister()); LOperand* result = instr->result(); ASSERT(result->IsDoubleRegister()); @@ -2945,7 +2945,7 @@ void LCodeGen::DoNumberUntagD(LNumberUntagD* instr) { void LCodeGen::DoDoubleToI(LDoubleToI* instr) { - LOperand* input = instr->input(); + LOperand* input = instr->InputAt(0); ASSERT(input->IsDoubleRegister()); LOperand* result = instr->result(); ASSERT(result->IsRegister()); @@ -2983,7 +2983,7 @@ void LCodeGen::DoDoubleToI(LDoubleToI* instr) { __ bind(&done); } else { NearLabel done; - Register temp_reg = ToRegister(instr->temporary()); + Register temp_reg = ToRegister(instr->TempAt(0)); XMMRegister xmm_scratch = xmm0; // If cvttsd2si succeeded, we're done. Otherwise, we attempt @@ -3062,7 +3062,7 @@ void LCodeGen::DoDoubleToI(LDoubleToI* instr) { void LCodeGen::DoCheckSmi(LCheckSmi* instr) { - LOperand* input = instr->input(); + LOperand* input = instr->InputAt(0); ASSERT(input->IsRegister()); __ test(ToRegister(input), Immediate(kSmiTagMask)); DeoptimizeIf(instr->condition(), instr->environment()); @@ -3070,8 +3070,8 @@ void LCodeGen::DoCheckSmi(LCheckSmi* instr) { void LCodeGen::DoCheckInstanceType(LCheckInstanceType* instr) { - Register input = ToRegister(instr->input()); - Register temp = ToRegister(instr->temp()); + Register input = ToRegister(instr->InputAt(0)); + Register temp = ToRegister(instr->TempAt(0)); InstanceType first = instr->hydrogen()->first(); InstanceType last = instr->hydrogen()->last(); @@ -3095,15 +3095,15 @@ void LCodeGen::DoCheckInstanceType(LCheckInstanceType* instr) { void LCodeGen::DoCheckFunction(LCheckFunction* instr) { - ASSERT(instr->input()->IsRegister()); - Register reg = ToRegister(instr->input()); + ASSERT(instr->InputAt(0)->IsRegister()); + Register reg = ToRegister(instr->InputAt(0)); __ cmp(reg, instr->hydrogen()->target()); DeoptimizeIf(not_equal, instr->environment()); } void LCodeGen::DoCheckMap(LCheckMap* instr) { - LOperand* input = instr->input(); + LOperand* input = instr->InputAt(0); ASSERT(input->IsRegister()); Register reg = ToRegister(input); __ cmp(FieldOperand(reg, HeapObject::kMapOffset), @@ -3124,7 +3124,7 @@ void LCodeGen::LoadHeapObject(Register result, Handle object) { void LCodeGen::DoCheckPrototypeMaps(LCheckPrototypeMaps* instr) { - Register reg = ToRegister(instr->temp()); + Register reg = ToRegister(instr->TempAt(0)); Handle holder = instr->holder(); Handle current_prototype = instr->prototype(); @@ -3268,7 +3268,7 @@ void LCodeGen::DoFunctionLiteral(LFunctionLiteral* instr) { void LCodeGen::DoTypeof(LTypeof* instr) { - LOperand* input = instr->input(); + LOperand* input = instr->InputAt(0); if (input->IsConstantOperand()) { __ push(ToImmediate(input)); } else { @@ -3279,7 +3279,7 @@ void LCodeGen::DoTypeof(LTypeof* instr) { void LCodeGen::DoTypeofIs(LTypeofIs* instr) { - Register input = ToRegister(instr->input()); + Register input = ToRegister(instr->InputAt(0)); Register result = ToRegister(instr->result()); Label true_label; Label false_label; @@ -3302,7 +3302,7 @@ void LCodeGen::DoTypeofIs(LTypeofIs* instr) { void LCodeGen::DoTypeofIsAndBranch(LTypeofIsAndBranch* instr) { - Register input = ToRegister(instr->input()); + Register input = ToRegister(instr->InputAt(0)); int true_block = chunk_->LookupDestination(instr->true_block_id()); int false_block = chunk_->LookupDestination(instr->false_block_id()); Label* true_label = chunk_->GetAssemblyLabel(true_block); diff --git a/src/ia32/lithium-ia32.cc b/src/ia32/lithium-ia32.cc index 241d971..c4b1754 100644 --- a/src/ia32/lithium-ia32.cc +++ b/src/ia32/lithium-ia32.cc @@ -90,18 +90,22 @@ void LInstruction::PrintTo(StringStream* stream) { template void LTemplateInstruction::PrintDataTo(StringStream* stream) { - for (int i = 0; i < I; i++) { - stream->Add(i == 0 ? "= " : " "); - inputs_.at(i)->PrintTo(stream); - } + stream->Add("= "); + inputs_.PrintOperandsTo(stream); } template void LTemplateInstruction::PrintOutputOperandTo(StringStream* stream) { - if (this->HasResult()) { - this->result()->PrintTo(stream); - stream->Add(" "); + results_.PrintOperandsTo(stream); +} + + +template +void OperandContainer::PrintOperandsTo(StringStream* stream) { + for (int i = 0; i < N; i++) { + if (i > 0) stream->Add(" "); + elems_[i]->PrintTo(stream); } } @@ -172,22 +176,22 @@ void LGoto::PrintDataTo(StringStream* stream) { void LBranch::PrintDataTo(StringStream* stream) { stream->Add("B%d | B%d on ", true_block_id(), false_block_id()); - input()->PrintTo(stream); + InputAt(0)->PrintTo(stream); } void LCmpIDAndBranch::PrintDataTo(StringStream* stream) { stream->Add("if "); - left()->PrintTo(stream); + InputAt(0)->PrintTo(stream); stream->Add(" %s ", Token::String(op())); - right()->PrintTo(stream); + InputAt(1)->PrintTo(stream); stream->Add(" then B%d else B%d", true_block_id(), false_block_id()); } void LIsNullAndBranch::PrintDataTo(StringStream* stream) { stream->Add("if "); - input()->PrintTo(stream); + InputAt(0)->PrintTo(stream); stream->Add(is_strict() ? " === null" : " == null"); stream->Add(" then B%d else B%d", true_block_id(), false_block_id()); } @@ -195,35 +199,35 @@ void LIsNullAndBranch::PrintDataTo(StringStream* stream) { void LIsObjectAndBranch::PrintDataTo(StringStream* stream) { stream->Add("if is_object("); - input()->PrintTo(stream); + InputAt(0)->PrintTo(stream); stream->Add(") then B%d else B%d", true_block_id(), false_block_id()); } void LIsSmiAndBranch::PrintDataTo(StringStream* stream) { stream->Add("if is_smi("); - input()->PrintTo(stream); + InputAt(0)->PrintTo(stream); stream->Add(") then B%d else B%d", true_block_id(), false_block_id()); } void LHasInstanceTypeAndBranch::PrintDataTo(StringStream* stream) { stream->Add("if has_instance_type("); - input()->PrintTo(stream); + InputAt(0)->PrintTo(stream); stream->Add(") then B%d else B%d", true_block_id(), false_block_id()); } void LHasCachedArrayIndexAndBranch::PrintDataTo(StringStream* stream) { stream->Add("if has_cached_array_index("); - input()->PrintTo(stream); + InputAt(0)->PrintTo(stream); stream->Add(") then B%d else B%d", true_block_id(), false_block_id()); } void LClassOfTestAndBranch::PrintDataTo(StringStream* stream) { stream->Add("if class_of_test("); - input()->PrintTo(stream); + InputAt(0)->PrintTo(stream); stream->Add(", \"%o\") then B%d else B%d", *hydrogen()->class_name(), true_block_id(), @@ -232,14 +236,14 @@ void LClassOfTestAndBranch::PrintDataTo(StringStream* stream) { void LTypeofIs::PrintDataTo(StringStream* stream) { - input()->PrintTo(stream); + InputAt(0)->PrintTo(stream); stream->Add(" == \"%s\"", *hydrogen()->type_literal()->ToCString()); } void LTypeofIsAndBranch::PrintDataTo(StringStream* stream) { stream->Add("if typeof "); - input()->PrintTo(stream); + InputAt(0)->PrintTo(stream); stream->Add(" == \"%s\" then B%d else B%d", *hydrogen()->type_literal()->ToCString(), true_block_id(), false_block_id()); @@ -253,7 +257,7 @@ void LCallConstantFunction::PrintDataTo(StringStream* stream) { void LUnaryMathOperation::PrintDataTo(StringStream* stream) { stream->Add("/%s ", hydrogen()->OpName()); - input()->PrintTo(stream); + InputAt(0)->PrintTo(stream); } @@ -286,14 +290,14 @@ void LCallKnownGlobal::PrintDataTo(StringStream* stream) { void LCallNew::PrintDataTo(StringStream* stream) { stream->Add("= "); - input()->PrintTo(stream); + InputAt(0)->PrintTo(stream); stream->Add(" #%d / ", arity()); } void LClassOfTest::PrintDataTo(StringStream* stream) { stream->Add("= class_of_test("); - input()->PrintTo(stream); + InputAt(0)->PrintTo(stream); stream->Add(", \"%o\")", *hydrogen()->class_name()); } @@ -883,8 +887,17 @@ void LChunkBuilder::VisitInstruction(HInstruction* current) { if (FLAG_stress_environments && !instr->HasEnvironment()) { instr = AssignEnvironment(instr); } - if (current->IsBranch()) { - instr->set_hydrogen_value(HBranch::cast(current)->value()); + if (current->IsBranch() && !instr->IsGoto()) { + // TODO(fschneider): Handle branch instructions uniformly like + // other instructions. This requires us to generate the right + // branch instruction already at the HIR level. + ASSERT(instr->IsControl()); + HBranch* branch = HBranch::cast(current); + instr->set_hydrogen_value(branch->value()); + HBasicBlock* first = branch->FirstSuccessor(); + HBasicBlock* second = branch->SecondSuccessor(); + ASSERT(first != NULL && second != NULL); + instr->SetBranchTargets(first->block_id(), second->block_id()); } else { instr->set_hydrogen_value(current); } @@ -945,12 +958,6 @@ LInstruction* LChunkBuilder::DoGoto(HGoto* instr) { LInstruction* LChunkBuilder::DoBranch(HBranch* instr) { HValue* v = instr->value(); - HBasicBlock* first = instr->FirstSuccessor(); - HBasicBlock* second = instr->SecondSuccessor(); - ASSERT(first != NULL && second != NULL); - int first_id = first->block_id(); - int second_id = second->block_id(); - if (v->EmitAtUses()) { if (v->IsClassOfTest()) { HClassOfTest* compare = HClassOfTest::cast(v); @@ -958,9 +965,7 @@ LInstruction* LChunkBuilder::DoBranch(HBranch* instr) { return new LClassOfTestAndBranch(UseTempRegister(compare->value()), TempRegister(), - TempRegister(), - first_id, - second_id); + TempRegister()); } else if (v->IsCompare()) { HCompare* compare = HCompare::cast(v); Token::Value op = compare->token(); @@ -972,17 +977,13 @@ LInstruction* LChunkBuilder::DoBranch(HBranch* instr) { ASSERT(right->representation().IsInteger32()); return new LCmpIDAndBranch(UseRegisterAtStart(left), - UseOrConstantAtStart(right), - first_id, - second_id); + UseOrConstantAtStart(right)); } else if (r.IsDouble()) { ASSERT(left->representation().IsDouble()); ASSERT(right->representation().IsDouble()); return new LCmpIDAndBranch(UseRegisterAtStart(left), - UseRegisterAtStart(right), - first_id, - second_id); + UseRegisterAtStart(right)); } else { ASSERT(left->representation().IsTagged()); ASSERT(right->representation().IsTagged()); @@ -990,32 +991,26 @@ LInstruction* LChunkBuilder::DoBranch(HBranch* instr) { LOperand* left_operand = UseFixed(left, reversed ? eax : edx); LOperand* right_operand = UseFixed(right, reversed ? edx : eax); LCmpTAndBranch* result = new LCmpTAndBranch(left_operand, - right_operand, - first_id, - second_id); + right_operand); return MarkAsCall(result, instr); } } else if (v->IsIsSmi()) { HIsSmi* compare = HIsSmi::cast(v); ASSERT(compare->value()->representation().IsTagged()); - return new LIsSmiAndBranch(Use(compare->value()), - first_id, - second_id); + return new LIsSmiAndBranch(Use(compare->value())); } else if (v->IsHasInstanceType()) { HHasInstanceType* compare = HHasInstanceType::cast(v); ASSERT(compare->value()->representation().IsTagged()); return new LHasInstanceTypeAndBranch(UseRegisterAtStart(compare->value()), - TempRegister(), - first_id, - second_id); + TempRegister()); } else if (v->IsHasCachedArrayIndex()) { HHasCachedArrayIndex* compare = HHasCachedArrayIndex::cast(v); ASSERT(compare->value()->representation().IsTagged()); return new LHasCachedArrayIndexAndBranch( - UseRegisterAtStart(compare->value()), first_id, second_id); + UseRegisterAtStart(compare->value())); } else if (v->IsIsNull()) { HIsNull* compare = HIsNull::cast(v); ASSERT(compare->value()->representation().IsTagged()); @@ -1023,9 +1018,7 @@ LInstruction* LChunkBuilder::DoBranch(HBranch* instr) { // We only need a temp register for non-strict compare. LOperand* temp = compare->is_strict() ? NULL : TempRegister(); return new LIsNullAndBranch(UseRegisterAtStart(compare->value()), - temp, - first_id, - second_id); + temp); } else if (v->IsIsObject()) { HIsObject* compare = HIsObject::cast(v); ASSERT(compare->value()->representation().IsTagged()); @@ -1034,42 +1027,34 @@ LInstruction* LChunkBuilder::DoBranch(HBranch* instr) { LOperand* temp2 = TempRegister(); return new LIsObjectAndBranch(UseRegisterAtStart(compare->value()), temp1, - temp2, - first_id, - second_id); + temp2); } else if (v->IsCompareJSObjectEq()) { HCompareJSObjectEq* compare = HCompareJSObjectEq::cast(v); return new LCmpJSObjectEqAndBranch(UseRegisterAtStart(compare->left()), - UseRegisterAtStart(compare->right()), - first_id, - second_id); + UseRegisterAtStart(compare->right())); } else if (v->IsInstanceOf()) { HInstanceOf* instance_of = HInstanceOf::cast(v); LInstanceOfAndBranch* result = new LInstanceOfAndBranch( UseFixed(instance_of->left(), InstanceofStub::left()), - UseFixed(instance_of->right(), InstanceofStub::right()), - first_id, - second_id); + UseFixed(instance_of->right(), InstanceofStub::right())); return MarkAsCall(result, instr); } else if (v->IsTypeofIs()) { HTypeofIs* typeof_is = HTypeofIs::cast(v); - return new LTypeofIsAndBranch(UseTempRegister(typeof_is->value()), - first_id, - second_id); + return new LTypeofIsAndBranch(UseTempRegister(typeof_is->value())); } else { if (v->IsConstant()) { if (HConstant::cast(v)->handle()->IsTrue()) { - return new LGoto(first_id); + return new LGoto(instr->FirstSuccessor()->block_id()); } else if (HConstant::cast(v)->handle()->IsFalse()) { - return new LGoto(second_id); + return new LGoto(instr->SecondSuccessor()->block_id()); } } Abort("Undefined compare before branch"); return NULL; } } - return new LBranch(UseRegisterAtStart(v), first_id, second_id); + return new LBranch(UseRegisterAtStart(v)); } @@ -1178,8 +1163,8 @@ LInstruction* LChunkBuilder::DoUnaryMathOperation(HUnaryMathOperation* instr) { LInstruction* LChunkBuilder::DoCallKeyed(HCallKeyed* instr) { ASSERT(instr->key()->representation().IsTagged()); argument_count_ -= instr->argument_count(); - UseFixed(instr->key(), ecx); - return MarkAsCall(DefineFixed(new LCallKeyed, eax), instr); + LOperand* temp = UseFixed(instr->key(), ecx); + return MarkAsCall(DefineFixed(new LCallKeyed(temp), eax), instr); } @@ -1266,10 +1251,11 @@ LInstruction* LChunkBuilder::DoDiv(HDiv* instr) { } else if (instr->representation().IsInteger32()) { // The temporary operand is necessary to ensure that right is not allocated // into edx. - FixedTemp(edx); + LOperand* temp = FixedTemp(edx); LOperand* value = UseFixed(instr->left(), eax); LOperand* divisor = UseRegister(instr->right()); - return AssignEnvironment(DefineFixed(new LDivI(value, divisor), eax)); + LDivI* result = new LDivI(value, divisor, temp); + return AssignEnvironment(DefineFixed(result, eax)); } else { ASSERT(instr->representation().IsTagged()); return DoArithmeticT(Token::DIV, instr); @@ -1283,10 +1269,10 @@ LInstruction* LChunkBuilder::DoMod(HMod* instr) { ASSERT(instr->right()->representation().IsInteger32()); // The temporary operand is necessary to ensure that right is not allocated // into edx. - FixedTemp(edx); + LOperand* temp = FixedTemp(edx); LOperand* value = UseFixed(instr->left(), eax); LOperand* divisor = UseRegister(instr->right()); - LModI* mod = new LModI(value, divisor); + LModI* mod = new LModI(value, divisor, temp); LInstruction* result = DefineFixed(mod, edx); return (instr->CheckFlag(HValue::kBailoutOnMinusZero) || instr->CheckFlag(HValue::kCanBeDivByZero)) diff --git a/src/ia32/lithium-ia32.h b/src/ia32/lithium-ia32.h index 07f0a8d..a47e8f1 100644 --- a/src/ia32/lithium-ia32.h +++ b/src/ia32/lithium-ia32.h @@ -43,10 +43,22 @@ class LCodeGen; // Type hierarchy: // // LInstruction -// LAccessArgumentsAt -// LArgumentsElements -// LArgumentsLength -// LBinaryOperation +// LTemplateInstruction +// LControlInstruction +// LBranch +// LClassOfTestAndBranch +// LCmpJSObjectEqAndBranch +// LCmpIDAndBranch +// LHasCachedArrayIndexAndBranch +// LHasInstanceTypeAndBranch +// LInstanceOfAndBranch +// LIsNullAndBranch +// LIsObjectAndBranch +// LIsSmiAndBranch +// LTypeofIsAndBranch +// LAccessArgumentsAt +// LArgumentsElements +// LArgumentsLength // LAddI // LApplyArguments // LArithmeticD @@ -54,13 +66,10 @@ class LCodeGen; // LBitI // LBoundsCheck // LCmpID -// LCmpIDAndBranch // LCmpJSObjectEq -// LCmpJSObjectEqAndBranch // LCmpT // LDivI // LInstanceOf -// LInstanceOfAndBranch // LInstanceOfKnownGlobal // LLoadKeyedFastElement // LLoadKeyedGeneric @@ -69,67 +78,59 @@ class LCodeGen; // LPower // LShiftI // LSubI -// LCallConstantFunction -// LCallFunction -// LCallGlobal -// LCallKeyed -// LCallKnownGlobal -// LCallNamed -// LCallRuntime -// LCallStub -// LCheckPrototypeMaps -// LConstant -// LConstantD -// LConstantI -// LConstantT -// LDeoptimize -// LFunctionLiteral -// LGap -// LLabel -// LGlobalObject -// LGlobalReceiver -// LGoto -// LLazyBailout -// LLoadContextSlot -// LLoadGlobal -// LMaterializedLiteral +// LCallConstantFunction +// LCallFunction +// LCallGlobal +// LCallKeyed +// LCallKnownGlobal +// LCallNamed +// LCallRuntime +// LCallStub +// LConstant +// LConstantD +// LConstantI +// LConstantT +// LDeoptimize +// LFunctionLiteral +// LGap +// LLabel +// LGlobalObject +// LGlobalReceiver +// LGoto +// LLazyBailout +// LLoadGlobal +// LCheckPrototypeMaps +// LLoadContextSlot // LArrayLiteral // LObjectLiteral // LRegExpLiteral -// LOsrEntry -// LParameter -// LRegExpConstructResult -// LStackCheck -// LStoreKeyed -// LStoreKeyedFastElement -// LStoreKeyedGeneric -// LStoreNamed -// LStoreNamedField -// LStoreNamedGeneric -// LUnaryOperation +// LOsrEntry +// LParameter +// LRegExpConstructResult +// LStackCheck +// LStoreKeyed +// LStoreKeyedFastElement +// LStoreKeyedGeneric +// LStoreNamed +// LStoreNamedField +// LStoreNamedGeneric // LBitNotI -// LBranch // LCallNew // LCheckFunction +// LCheckPrototypeMaps // LCheckInstanceType // LCheckMap // LCheckSmi // LClassOfTest -// LClassOfTestAndBranch // LDeleteProperty // LDoubleToI // LFixedArrayLength // LHasCachedArrayIndex -// LHasCachedArrayIndexAndBranch // LHasInstanceType -// LHasInstanceTypeAndBranch // LInteger32ToDouble // LIsNull -// LIsNullAndBranch // LIsObject -// LIsObjectAndBranch // LIsSmi -// LIsSmiAndBranch // LJSArrayLength // LLoadNamedField // LLoadNamedGeneric @@ -144,19 +145,16 @@ class LCodeGen; // LThrow // LTypeof // LTypeofIs -// LTypeofIsAndBranch // LUnaryMathOperation // LValueOf -// LUnknownOSRValue +// LUnknownOSRValue #define LITHIUM_ALL_INSTRUCTION_LIST(V) \ - V(BinaryOperation) \ + V(ControlInstruction) \ V(Constant) \ V(Call) \ - V(MaterializedLiteral) \ V(StoreKeyed) \ V(StoreNamed) \ - V(UnaryOperation) \ LITHIUM_CONCRETE_INSTRUCTION_LIST(V) @@ -302,7 +300,9 @@ class LInstruction: public ZoneObject { #define DECLARE_DO(type) virtual bool Is##type() const { return false; } LITHIUM_ALL_INSTRUCTION_LIST(DECLARE_DO) #undef DECLARE_DO + virtual bool IsControl() const { return false; } + virtual void SetBranchTargets(int true_block_id, int false_block_id) { } void set_environment(LEnvironment* env) { environment_.set(env); } LEnvironment* environment() const { return environment_.get(); } @@ -341,9 +341,13 @@ class OperandContainer { OperandContainer() { for (int i = 0; i < N; i++) elems_[i] = NULL; } - int length() const { return N; } - T at(int i) const { return elems_[i]; } - void set_at(int i, T value) { elems_[i] = value; } + int length() { return N; } + T& operator[](int i) { + ASSERT(i < length()); + return elems_[i]; + } + void PrintOperandsTo(StringStream* stream); + private: T elems_[N]; }; @@ -352,38 +356,31 @@ class OperandContainer { template class OperandContainer { public: - int length() const { return 0; } - T at(int i) const { - UNREACHABLE(); - return NULL; - } - void set_at(int i, T value) { - UNREACHABLE(); - } + int length() { return 0; } + void PrintOperandsTo(StringStream* stream) { } }; -template +template class LTemplateInstruction: public LInstruction { public: // Allow 0 or 1 output operands. STATIC_ASSERT(R == 0 || R == 1); virtual bool HasResult() const { return R != 0; } - void set_result(LOperand* operand) { outputs_.set_at(0, operand); } - LOperand* result() const { return outputs_.at(0); } + void set_result(LOperand* operand) { results_[0] = operand; } + LOperand* result() { return results_[0]; } - int InputCount() const { return inputs_.length(); } - LOperand* InputAt(int i) const { return inputs_.at(i); } - void SetInputAt(int i, LOperand* operand) { inputs_.set_at(i, operand); } + int InputCount() { return I; } + LOperand* InputAt(int i) { return inputs_[i]; } - int TempCount() const { return temps_.length(); } - LOperand* TempAt(int i) const { return temps_.at(i); } + int TempCount() { return T; } + LOperand* TempAt(int i) { return temps_[i]; } virtual void PrintDataTo(StringStream* stream); virtual void PrintOutputOperandTo(StringStream* stream); - private: - OperandContainer outputs_; + protected: + OperandContainer results_; OperandContainer inputs_; OperandContainer temps_; }; @@ -515,31 +512,22 @@ class LUnknownOSRValue: public LTemplateInstruction<1, 0, 0> { }; -template -class LUnaryOperation: public LTemplateInstruction { +template +class LControlInstruction: public LTemplateInstruction<0, I, T> { public: - explicit LUnaryOperation(LOperand* input) { - this->SetInputAt(0, input); - } - - LOperand* input() const { return this->InputAt(0); } - - DECLARE_INSTRUCTION(UnaryOperation) -}; - + DECLARE_INSTRUCTION(ControlInstruction) + virtual bool IsControl() const { return true; } -template -class LBinaryOperation: public LTemplateInstruction { - public: - LBinaryOperation(LOperand* left, LOperand* right) { - this->SetInputAt(0, left); - this->SetInputAt(1, right); + int true_block_id() const { return true_block_id_; } + int false_block_id() const { return false_block_id_; } + void SetBranchTargets(int true_block_id, int false_block_id) { + true_block_id_ = true_block_id; + false_block_id_ = false_block_id; } - DECLARE_INSTRUCTION(BinaryOperation) - - LOperand* left() const { return this->InputAt(0); } - LOperand* right() const { return this->InputAt(1); } + private: + int true_block_id_; + int false_block_id_; }; @@ -549,43 +537,44 @@ class LApplyArguments: public LTemplateInstruction<1, 4, 0> { LOperand* receiver, LOperand* length, LOperand* elements) { - this->SetInputAt(0, function); - this->SetInputAt(1, receiver); - this->SetInputAt(2, length); - this->SetInputAt(3, elements); + inputs_[0] = function; + inputs_[1] = receiver; + inputs_[2] = length; + inputs_[3] = elements; } DECLARE_CONCRETE_INSTRUCTION(ApplyArguments, "apply-arguments") - LOperand* function() const { return InputAt(0); } - LOperand* receiver() const { return InputAt(1); } - LOperand* length() const { return InputAt(2); } - LOperand* elements() const { return InputAt(3); } + LOperand* function() { return inputs_[0]; } + LOperand* receiver() { return inputs_[1]; } + LOperand* length() { return inputs_[2]; } + LOperand* elements() { return inputs_[3]; } }; class LAccessArgumentsAt: public LTemplateInstruction<1, 3, 0> { public: LAccessArgumentsAt(LOperand* arguments, LOperand* length, LOperand* index) { - this->SetInputAt(0, arguments); - this->SetInputAt(1, length); - this->SetInputAt(2, index); + inputs_[0] = arguments; + inputs_[1] = length; + inputs_[2] = index; } DECLARE_CONCRETE_INSTRUCTION(AccessArgumentsAt, "access-arguments-at") - LOperand* arguments() const { return this->InputAt(0); } - LOperand* length() const { return this->InputAt(1); } - LOperand* index() const { return this->InputAt(2); } + LOperand* arguments() { return inputs_[0]; } + LOperand* length() { return inputs_[1]; } + LOperand* index() { return inputs_[2]; } virtual void PrintDataTo(StringStream* stream); }; -class LArgumentsLength: public LUnaryOperation<1> { +class LArgumentsLength: public LTemplateInstruction<1, 1> { public: - explicit LArgumentsLength(LOperand* elements) - : LUnaryOperation<1>(elements) {} + explicit LArgumentsLength(LOperand* elements) { + inputs_[0] = elements; + } DECLARE_CONCRETE_INSTRUCTION(ArgumentsLength, "arguments-length") }; @@ -599,82 +588,86 @@ class LArgumentsElements: public LTemplateInstruction<1, 0, 0> { }; -class LModI: public LBinaryOperation<1> { +class LModI: public LTemplateInstruction<1, 2, 1> { public: - LModI(LOperand* left, LOperand* right) : LBinaryOperation<1>(left, right) { } + LModI(LOperand* left, LOperand* right, LOperand* temp) { + inputs_[0] = left; + inputs_[1] = right; + temps_[0] = temp; + } DECLARE_CONCRETE_INSTRUCTION(ModI, "mod-i") DECLARE_HYDROGEN_ACCESSOR(Mod) }; -class LDivI: public LBinaryOperation<1> { +class LDivI: public LTemplateInstruction<1, 2, 1> { public: - LDivI(LOperand* left, LOperand* right) - : LBinaryOperation<1>(left, right) { } + LDivI(LOperand* left, LOperand* right, LOperand* temp) { + inputs_[0] = left; + inputs_[1] = right; + temps_[0] = temp; + } DECLARE_CONCRETE_INSTRUCTION(DivI, "div-i") DECLARE_HYDROGEN_ACCESSOR(Div) }; -class LMulI: public LBinaryOperation<1> { +class LMulI: public LTemplateInstruction<1, 2, 1> { public: - LMulI(LOperand* left, LOperand* right, LOperand* temp) - : LBinaryOperation<1>(left, right), temp_(temp) { } + LMulI(LOperand* left, LOperand* right, LOperand* temp) { + inputs_[0] = left; + inputs_[1] = right; + temps_[0] = temp; + } DECLARE_CONCRETE_INSTRUCTION(MulI, "mul-i") DECLARE_HYDROGEN_ACCESSOR(Mul) - - LOperand* temp() const { return temp_; } - - private: - LOperand* temp_; }; -class LCmpID: public LBinaryOperation<1> { +class LCmpID: public LTemplateInstruction<1, 2> { public: - LCmpID(LOperand* left, LOperand* right) - : LBinaryOperation<1>(left, right) { } + LCmpID(LOperand* left, LOperand* right) { + inputs_[0] = left; + inputs_[1] = right; + } + + DECLARE_CONCRETE_INSTRUCTION(CmpID, "cmp-id") + DECLARE_HYDROGEN_ACCESSOR(Compare) Token::Value op() const { return hydrogen()->token(); } bool is_double() const { return hydrogen()->GetInputRepresentation().IsDouble(); } - - DECLARE_CONCRETE_INSTRUCTION(CmpID, "cmp-id") - DECLARE_HYDROGEN_ACCESSOR(Compare) }; -class LCmpIDAndBranch: public LCmpID { +class LCmpIDAndBranch: public LControlInstruction<2> { public: - LCmpIDAndBranch(LOperand* left, - LOperand* right, - int true_block_id, - int false_block_id) - : LCmpID(left, right), - true_block_id_(true_block_id), - false_block_id_(false_block_id) { } + LCmpIDAndBranch(LOperand* left, LOperand* right) { + inputs_[0] = left; + inputs_[1] = right; + } DECLARE_CONCRETE_INSTRUCTION(CmpIDAndBranch, "cmp-id-and-branch") - virtual void PrintDataTo(StringStream* stream); - virtual bool IsControl() const { return true; } + DECLARE_HYDROGEN_ACCESSOR(Compare) - int true_block_id() const { return true_block_id_; } - int false_block_id() const { return false_block_id_; } + Token::Value op() const { return hydrogen()->token(); } + bool is_double() const { + return hydrogen()->GetInputRepresentation().IsDouble(); + } - private: - int true_block_id_; - int false_block_id_; + virtual void PrintDataTo(StringStream* stream); }; -class LUnaryMathOperation: public LUnaryOperation<1> { +class LUnaryMathOperation: public LTemplateInstruction<1, 1> { public: - explicit LUnaryMathOperation(LOperand* value) - : LUnaryOperation<1>(value) { } + explicit LUnaryMathOperation(LOperand* value) { + inputs_[0] = value; + } DECLARE_CONCRETE_INSTRUCTION(UnaryMathOperation, "unary-math-operation") DECLARE_HYDROGEN_ACCESSOR(UnaryMathOperation) @@ -684,40 +677,34 @@ class LUnaryMathOperation: public LUnaryOperation<1> { }; -class LCmpJSObjectEq: public LBinaryOperation<1> { +class LCmpJSObjectEq: public LTemplateInstruction<1, 2> { public: - LCmpJSObjectEq(LOperand* left, LOperand* right) - : LBinaryOperation<1>(left, right) {} + LCmpJSObjectEq(LOperand* left, LOperand* right) { + inputs_[0] = left; + inputs_[1] = right; + } DECLARE_CONCRETE_INSTRUCTION(CmpJSObjectEq, "cmp-jsobject-eq") }; -class LCmpJSObjectEqAndBranch: public LCmpJSObjectEq { +class LCmpJSObjectEqAndBranch: public LControlInstruction<2> { public: - LCmpJSObjectEqAndBranch(LOperand* left, - LOperand* right, - int true_block_id, - int false_block_id) - : LCmpJSObjectEq(left, right), - true_block_id_(true_block_id), - false_block_id_(false_block_id) { } + LCmpJSObjectEqAndBranch(LOperand* left, LOperand* right) { + inputs_[0] = left; + inputs_[1] = right; + } DECLARE_CONCRETE_INSTRUCTION(CmpJSObjectEqAndBranch, "cmp-jsobject-eq-and-branch") - - int true_block_id() const { return true_block_id_; } - int false_block_id() const { return false_block_id_; } - - private: - int true_block_id_; - int false_block_id_; }; -class LIsNull: public LUnaryOperation<1> { +class LIsNull: public LTemplateInstruction<1, 1> { public: - explicit LIsNull(LOperand* value) : LUnaryOperation<1>(value) { } + explicit LIsNull(LOperand* value) { + inputs_[0] = value; + } DECLARE_CONCRETE_INSTRUCTION(IsNull, "is-null") DECLARE_HYDROGEN_ACCESSOR(IsNull) @@ -726,227 +713,155 @@ class LIsNull: public LUnaryOperation<1> { }; -class LIsNullAndBranch: public LIsNull { +class LIsNullAndBranch: public LControlInstruction<1, 1> { public: - LIsNullAndBranch(LOperand* value, - LOperand* temp, - int true_block_id, - int false_block_id) - : LIsNull(value), - temp_(temp), - true_block_id_(true_block_id), - false_block_id_(false_block_id) { } + LIsNullAndBranch(LOperand* value, LOperand* temp) { + inputs_[0] = value; + temps_[0] = temp; + } DECLARE_CONCRETE_INSTRUCTION(IsNullAndBranch, "is-null-and-branch") - virtual void PrintDataTo(StringStream* stream); - virtual bool IsControl() const { return true; } - - int true_block_id() const { return true_block_id_; } - int false_block_id() const { return false_block_id_; } + DECLARE_HYDROGEN_ACCESSOR(IsNull) - LOperand* temp() const { return temp_; } + bool is_strict() const { return hydrogen()->is_strict(); } - private: - LOperand* temp_; - int true_block_id_; - int false_block_id_; + virtual void PrintDataTo(StringStream* stream); }; -class LIsObject: public LUnaryOperation<1> { +class LIsObject: public LTemplateInstruction<1, 1, 1> { public: - LIsObject(LOperand* value, LOperand* temp) - : LUnaryOperation<1>(value), temp_(temp) {} + LIsObject(LOperand* value, LOperand* temp) { + inputs_[0] = value; + temps_[0] = temp; + } DECLARE_CONCRETE_INSTRUCTION(IsObject, "is-object") - - LOperand* temp() const { return temp_; } - - private: - LOperand* temp_; }; -class LIsObjectAndBranch: public LIsObject { +class LIsObjectAndBranch: public LControlInstruction<1, 2> { public: - LIsObjectAndBranch(LOperand* value, - LOperand* temp, - LOperand* temp2, - int true_block_id, - int false_block_id) - : LIsObject(value, temp), - temp2_(temp2), - true_block_id_(true_block_id), - false_block_id_(false_block_id) { } + LIsObjectAndBranch(LOperand* value, LOperand* temp, LOperand* temp2) { + inputs_[0] = value; + temps_[0] = temp; + temps_[1] = temp2; + } DECLARE_CONCRETE_INSTRUCTION(IsObjectAndBranch, "is-object-and-branch") - virtual void PrintDataTo(StringStream* stream); - virtual bool IsControl() const { return true; } - - int true_block_id() const { return true_block_id_; } - int false_block_id() const { return false_block_id_; } - LOperand* temp2() const { return temp2_; } - - private: - LOperand* temp2_; - int true_block_id_; - int false_block_id_; + virtual void PrintDataTo(StringStream* stream); }; -class LIsSmi: public LUnaryOperation<1> { +class LIsSmi: public LTemplateInstruction<1, 1> { public: - explicit LIsSmi(LOperand* value) : LUnaryOperation<1>(value) {} + explicit LIsSmi(LOperand* value) { + inputs_[0] = value; + } DECLARE_CONCRETE_INSTRUCTION(IsSmi, "is-smi") DECLARE_HYDROGEN_ACCESSOR(IsSmi) }; -class LIsSmiAndBranch: public LIsSmi { +class LIsSmiAndBranch: public LControlInstruction<1> { public: - LIsSmiAndBranch(LOperand* value, - int true_block_id, - int false_block_id) - : LIsSmi(value), - true_block_id_(true_block_id), - false_block_id_(false_block_id) { } + explicit LIsSmiAndBranch(LOperand* value) { + inputs_[0] = value; + } DECLARE_CONCRETE_INSTRUCTION(IsSmiAndBranch, "is-smi-and-branch") - virtual void PrintDataTo(StringStream* stream); - virtual bool IsControl() const { return true; } - - int true_block_id() const { return true_block_id_; } - int false_block_id() const { return false_block_id_; } - private: - int true_block_id_; - int false_block_id_; + virtual void PrintDataTo(StringStream* stream); }; -class LHasInstanceType: public LUnaryOperation<1> { +class LHasInstanceType: public LTemplateInstruction<1, 1> { public: - explicit LHasInstanceType(LOperand* value) - : LUnaryOperation<1>(value) { } + explicit LHasInstanceType(LOperand* value) { + inputs_[0] = value; + } DECLARE_CONCRETE_INSTRUCTION(HasInstanceType, "has-instance-type") DECLARE_HYDROGEN_ACCESSOR(HasInstanceType) - - InstanceType TestType(); // The type to test against when generating code. - Condition BranchCondition(); // The branch condition for 'true'. }; -class LHasInstanceTypeAndBranch: public LHasInstanceType { +class LHasInstanceTypeAndBranch: public LControlInstruction<1, 1> { public: - LHasInstanceTypeAndBranch(LOperand* value, - LOperand* temporary, - int true_block_id, - int false_block_id) - : LHasInstanceType(value), - temp_(temporary), - true_block_id_(true_block_id), - false_block_id_(false_block_id) { } + LHasInstanceTypeAndBranch(LOperand* value, LOperand* temp) { + inputs_[0] = value; + temps_[0] = temp; + } DECLARE_CONCRETE_INSTRUCTION(HasInstanceTypeAndBranch, "has-instance-type-and-branch") - virtual void PrintDataTo(StringStream* stream); - virtual bool IsControl() const { return true; } - - int true_block_id() const { return true_block_id_; } - int false_block_id() const { return false_block_id_; } - - LOperand* temp() { return temp_; } + DECLARE_HYDROGEN_ACCESSOR(HasInstanceType) - private: - LOperand* temp_; - int true_block_id_; - int false_block_id_; + virtual void PrintDataTo(StringStream* stream); }; -class LHasCachedArrayIndex: public LUnaryOperation<1> { +class LHasCachedArrayIndex: public LTemplateInstruction<1, 1> { public: - explicit LHasCachedArrayIndex(LOperand* value) : LUnaryOperation<1>(value) {} + explicit LHasCachedArrayIndex(LOperand* value) { + inputs_[0] = value; + } DECLARE_CONCRETE_INSTRUCTION(HasCachedArrayIndex, "has-cached-array-index") DECLARE_HYDROGEN_ACCESSOR(HasCachedArrayIndex) }; -class LHasCachedArrayIndexAndBranch: public LHasCachedArrayIndex { +class LHasCachedArrayIndexAndBranch: public LControlInstruction<1> { public: - LHasCachedArrayIndexAndBranch(LOperand* value, - int true_block_id, - int false_block_id) - : LHasCachedArrayIndex(value), - true_block_id_(true_block_id), - false_block_id_(false_block_id) { } + explicit LHasCachedArrayIndexAndBranch(LOperand* value) { + inputs_[0] = value; + } DECLARE_CONCRETE_INSTRUCTION(HasCachedArrayIndexAndBranch, "has-cached-array-index-and-branch") virtual void PrintDataTo(StringStream* stream); - virtual bool IsControl() const { return true; } - - int true_block_id() const { return true_block_id_; } - int false_block_id() const { return false_block_id_; } - - private: - int true_block_id_; - int false_block_id_; }; -class LClassOfTest: public LUnaryOperation<1> { +class LClassOfTest: public LTemplateInstruction<1, 1, 1> { public: - LClassOfTest(LOperand* value, LOperand* temp) - : LUnaryOperation<1>(value), temporary_(temp) {} + LClassOfTest(LOperand* value, LOperand* temp) { + inputs_[0] = value; + temps_[0] = temp; + } DECLARE_CONCRETE_INSTRUCTION(ClassOfTest, "class-of-test") DECLARE_HYDROGEN_ACCESSOR(ClassOfTest) virtual void PrintDataTo(StringStream* stream); - - LOperand* temporary() { return temporary_; } - - private: - LOperand* temporary_; }; -class LClassOfTestAndBranch: public LClassOfTest { +class LClassOfTestAndBranch: public LControlInstruction<1, 2> { public: - LClassOfTestAndBranch(LOperand* value, - LOperand* temporary, - LOperand* temporary2, - int true_block_id, - int false_block_id) - : LClassOfTest(value, temporary), - temporary2_(temporary2), - true_block_id_(true_block_id), - false_block_id_(false_block_id) { } + LClassOfTestAndBranch(LOperand* value, LOperand* temp, LOperand* temp2) { + inputs_[0] = value; + temps_[0] = temp; + temps_[1] = temp2; + } DECLARE_CONCRETE_INSTRUCTION(ClassOfTestAndBranch, "class-of-test-and-branch") - virtual void PrintDataTo(StringStream* stream); - virtual bool IsControl() const { return true; } - - int true_block_id() const { return true_block_id_; } - int false_block_id() const { return false_block_id_; } - LOperand* temporary2() { return temporary2_; } + DECLARE_HYDROGEN_ACCESSOR(ClassOfTest) - private: - LOperand* temporary2_; - int true_block_id_; - int false_block_id_; + virtual void PrintDataTo(StringStream* stream); }; -class LCmpT: public LBinaryOperation<1> { +class LCmpT: public LTemplateInstruction<1, 2> { public: - LCmpT(LOperand* left, LOperand* right) : LBinaryOperation<1>(left, right) {} + LCmpT(LOperand* left, LOperand* right) { + inputs_[0] = left; + inputs_[1] = right; + } DECLARE_CONCRETE_INSTRUCTION(CmpT, "cmp-t") DECLARE_HYDROGEN_ACCESSOR(Compare) @@ -955,90 +870,78 @@ class LCmpT: public LBinaryOperation<1> { }; -class LCmpTAndBranch: public LCmpT { +class LCmpTAndBranch: public LControlInstruction<2> { public: - LCmpTAndBranch(LOperand* left, - LOperand* right, - int true_block_id, - int false_block_id) - : LCmpT(left, right), - true_block_id_(true_block_id), - false_block_id_(false_block_id) { } + LCmpTAndBranch(LOperand* left, LOperand* right) { + inputs_[0] = left; + inputs_[1] = right; + } DECLARE_CONCRETE_INSTRUCTION(CmpTAndBranch, "cmp-t-and-branch") + DECLARE_HYDROGEN_ACCESSOR(Compare) - int true_block_id() const { return true_block_id_; } - int false_block_id() const { return false_block_id_; } - - private: - int true_block_id_; - int false_block_id_; + Token::Value op() const { return hydrogen()->token(); } }; -class LInstanceOf: public LBinaryOperation<1> { +class LInstanceOf: public LTemplateInstruction<1, 2> { public: - LInstanceOf(LOperand* left, LOperand* right) - : LBinaryOperation<1>(left, right) { } + LInstanceOf(LOperand* left, LOperand* right) { + inputs_[0] = left; + inputs_[1] = right; + } DECLARE_CONCRETE_INSTRUCTION(InstanceOf, "instance-of") }; -class LInstanceOfAndBranch: public LInstanceOf { +class LInstanceOfAndBranch: public LControlInstruction<2> { public: - LInstanceOfAndBranch(LOperand* left, - LOperand* right, - int true_block_id, - int false_block_id) - : LInstanceOf(left, right), - true_block_id_(true_block_id), - false_block_id_(false_block_id) { } + LInstanceOfAndBranch(LOperand* left, LOperand* right) { + inputs_[0] = left; + inputs_[1] = right; + } DECLARE_CONCRETE_INSTRUCTION(InstanceOfAndBranch, "instance-of-and-branch") - - int true_block_id() const { return true_block_id_; } - int false_block_id() const { return false_block_id_; } - - private: - int true_block_id_; - int false_block_id_; }; -class LInstanceOfKnownGlobal: public LUnaryOperation<1> { +class LInstanceOfKnownGlobal: public LTemplateInstruction<1, 1, 1> { public: - LInstanceOfKnownGlobal(LOperand* left, LOperand* temp) - : LUnaryOperation<1>(left), temp_(temp) { } + LInstanceOfKnownGlobal(LOperand* value, LOperand* temp) { + inputs_[0] = value; + temps_[0] = temp; + } DECLARE_CONCRETE_INSTRUCTION(InstanceOfKnownGlobal, "instance-of-known-global") DECLARE_HYDROGEN_ACCESSOR(InstanceOfKnownGlobal) Handle function() const { return hydrogen()->function(); } - LOperand* temp() const { return temp_; } - - private: - LOperand* temp_; }; -class LBoundsCheck: public LBinaryOperation<0> { +class LBoundsCheck: public LTemplateInstruction<0, 2, 0> { public: - LBoundsCheck(LOperand* index, LOperand* length) - : LBinaryOperation<0>(index, length) { } + LBoundsCheck(LOperand* index, LOperand* length) { + inputs_[0] = index; + inputs_[1] = length; + } - LOperand* index() const { return left(); } - LOperand* length() const { return right(); } + LOperand* index() { return inputs_[0]; } + LOperand* length() { return inputs_[1]; } DECLARE_CONCRETE_INSTRUCTION(BoundsCheck, "bounds-check") }; -class LBitI: public LBinaryOperation<1> { +class LBitI: public LTemplateInstruction<1, 2> { public: LBitI(Token::Value op, LOperand* left, LOperand* right) - : LBinaryOperation<1>(left, right), op_(op) { } + : op_(op) { + inputs_[0] = left; + inputs_[1] = right; + } Token::Value op() const { return op_; } @@ -1049,10 +952,13 @@ class LBitI: public LBinaryOperation<1> { }; -class LShiftI: public LBinaryOperation<1> { +class LShiftI: public LTemplateInstruction<1, 2> { public: LShiftI(Token::Value op, LOperand* left, LOperand* right, bool can_deopt) - : LBinaryOperation<1>(left, right), op_(op), can_deopt_(can_deopt) { } + : op_(op), can_deopt_(can_deopt) { + inputs_[0] = left; + inputs_[1] = right; + } Token::Value op() const { return op_; } @@ -1066,10 +972,12 @@ class LShiftI: public LBinaryOperation<1> { }; -class LSubI: public LBinaryOperation<1> { +class LSubI: public LTemplateInstruction<1, 2> { public: - LSubI(LOperand* left, LOperand* right) - : LBinaryOperation<1>(left, right) { } + LSubI(LOperand* left, LOperand* right) { + inputs_[0] = left; + inputs_[1] = right; + } DECLARE_CONCRETE_INSTRUCTION(SubI, "sub-i") DECLARE_HYDROGEN_ACCESSOR(Sub) @@ -1117,31 +1025,24 @@ class LConstantT: public LConstant { }; -class LBranch: public LUnaryOperation<0> { +class LBranch: public LControlInstruction<1> { public: - LBranch(LOperand* input, int true_block_id, int false_block_id) - : LUnaryOperation<0>(input), - true_block_id_(true_block_id), - false_block_id_(false_block_id) { } + explicit LBranch(LOperand* value) { + inputs_[0] = value; + } DECLARE_CONCRETE_INSTRUCTION(Branch, "branch") DECLARE_HYDROGEN_ACCESSOR(Value) virtual void PrintDataTo(StringStream* stream); - virtual bool IsControl() const { return true; } - - int true_block_id() const { return true_block_id_; } - int false_block_id() const { return false_block_id_; } - - private: - int true_block_id_; - int false_block_id_; }; -class LCmpMapAndBranch: public LUnaryOperation<0> { +class LCmpMapAndBranch: public LTemplateInstruction<0, 1> { public: - explicit LCmpMapAndBranch(LOperand* value) : LUnaryOperation<0>(value) { } + explicit LCmpMapAndBranch(LOperand* value) { + inputs_[0] = value; + } DECLARE_CONCRETE_INSTRUCTION(CmpMapAndBranch, "cmp-map-and-branch") DECLARE_HYDROGEN_ACCESSOR(CompareMapAndBranch) @@ -1158,79 +1059,91 @@ class LCmpMapAndBranch: public LUnaryOperation<0> { }; -class LJSArrayLength: public LUnaryOperation<1> { +class LJSArrayLength: public LTemplateInstruction<1, 1> { public: - explicit LJSArrayLength(LOperand* input) : LUnaryOperation<1>(input) { } + explicit LJSArrayLength(LOperand* value) { + inputs_[0] = value; + } DECLARE_CONCRETE_INSTRUCTION(JSArrayLength, "js-array-length") DECLARE_HYDROGEN_ACCESSOR(JSArrayLength) }; -class LFixedArrayLength: public LUnaryOperation<1> { +class LFixedArrayLength: public LTemplateInstruction<1, 1> { public: - explicit LFixedArrayLength(LOperand* input) : LUnaryOperation<1>(input) { } + explicit LFixedArrayLength(LOperand* value) { + inputs_[0] = value; + } DECLARE_CONCRETE_INSTRUCTION(FixedArrayLength, "fixed-array-length") DECLARE_HYDROGEN_ACCESSOR(FixedArrayLength) }; -class LValueOf: public LUnaryOperation<1> { +class LValueOf: public LTemplateInstruction<1, 1, 1> { public: - LValueOf(LOperand* input, LOperand* temporary) - : LUnaryOperation<1>(input), temporary_(temporary) { } - - LOperand* temporary() const { return temporary_; } + LValueOf(LOperand* value, LOperand* temp) { + inputs_[0] = value; + temps_[0] = temp; + } DECLARE_CONCRETE_INSTRUCTION(ValueOf, "value-of") DECLARE_HYDROGEN_ACCESSOR(ValueOf) - - private: - LOperand* temporary_; }; -class LThrow: public LUnaryOperation<0> { +class LThrow: public LTemplateInstruction<0, 1> { public: - explicit LThrow(LOperand* value) : LUnaryOperation<0>(value) { } + explicit LThrow(LOperand* value) { + inputs_[0] = value; + } DECLARE_CONCRETE_INSTRUCTION(Throw, "throw") }; -class LBitNotI: public LUnaryOperation<1> { +class LBitNotI: public LTemplateInstruction<1, 1> { public: - explicit LBitNotI(LOperand* input) : LUnaryOperation<1>(input) { } + explicit LBitNotI(LOperand* value) { + inputs_[0] = value; + } DECLARE_CONCRETE_INSTRUCTION(BitNotI, "bit-not-i") }; -class LAddI: public LBinaryOperation<1> { +class LAddI: public LTemplateInstruction<1, 2> { public: - LAddI(LOperand* left, LOperand* right) - : LBinaryOperation<1>(left, right) { } + LAddI(LOperand* left, LOperand* right) { + inputs_[0] = left; + inputs_[1] = right; + } DECLARE_CONCRETE_INSTRUCTION(AddI, "add-i") DECLARE_HYDROGEN_ACCESSOR(Add) }; -class LPower: public LBinaryOperation<1> { +class LPower: public LTemplateInstruction<1, 2> { public: - LPower(LOperand* left, LOperand* right) - : LBinaryOperation<1>(left, right) { } + LPower(LOperand* left, LOperand* right) { + inputs_[0] = left; + inputs_[1] = right; + } DECLARE_CONCRETE_INSTRUCTION(Power, "power") DECLARE_HYDROGEN_ACCESSOR(Power) }; -class LArithmeticD: public LBinaryOperation<1> { +class LArithmeticD: public LTemplateInstruction<1, 2> { public: LArithmeticD(Token::Value op, LOperand* left, LOperand* right) - : LBinaryOperation<1>(left, right), op_(op) { } + : op_(op) { + inputs_[0] = left; + inputs_[1] = right; + } Token::Value op() const { return op_; } @@ -1242,10 +1155,13 @@ class LArithmeticD: public LBinaryOperation<1> { }; -class LArithmeticT: public LBinaryOperation<1> { +class LArithmeticT: public LTemplateInstruction<1, 2> { public: LArithmeticT(Token::Value op, LOperand* left, LOperand* right) - : LBinaryOperation<1>(left, right), op_(op) { } + : op_(op) { + inputs_[0] = left; + inputs_[1] = right; + } virtual void CompileToNative(LCodeGen* generator); virtual const char* Mnemonic() const; @@ -1257,81 +1173,91 @@ class LArithmeticT: public LBinaryOperation<1> { }; -class LReturn: public LUnaryOperation<0> { +class LReturn: public LTemplateInstruction<0, 1> { public: - explicit LReturn(LOperand* use) : LUnaryOperation<0>(use) { } + explicit LReturn(LOperand* value) { + inputs_[0] = value; + } DECLARE_CONCRETE_INSTRUCTION(Return, "return") }; -class LLoadNamedField: public LUnaryOperation<1> { +class LLoadNamedField: public LTemplateInstruction<1, 1> { public: - explicit LLoadNamedField(LOperand* object) : LUnaryOperation<1>(object) { } + explicit LLoadNamedField(LOperand* object) { + inputs_[0] = object; + } DECLARE_CONCRETE_INSTRUCTION(LoadNamedField, "load-named-field") DECLARE_HYDROGEN_ACCESSOR(LoadNamedField) }; -class LLoadNamedGeneric: public LUnaryOperation<1> { +class LLoadNamedGeneric: public LTemplateInstruction<1, 1> { public: - explicit LLoadNamedGeneric(LOperand* object) : LUnaryOperation<1>(object) { } + explicit LLoadNamedGeneric(LOperand* object) { + inputs_[0] = object; + } DECLARE_CONCRETE_INSTRUCTION(LoadNamedGeneric, "load-named-generic") DECLARE_HYDROGEN_ACCESSOR(LoadNamedGeneric) - LOperand* object() const { return input(); } + LOperand* object() { return inputs_[0]; } Handle name() const { return hydrogen()->name(); } }; -class LLoadFunctionPrototype: public LUnaryOperation<1> { +class LLoadFunctionPrototype: public LTemplateInstruction<1, 1, 1> { public: - LLoadFunctionPrototype(LOperand* function, LOperand* temporary) - : LUnaryOperation<1>(function), temporary_(temporary) { } + LLoadFunctionPrototype(LOperand* function, LOperand* temp) { + inputs_[0] = function; + temps_[0] = temp; + } DECLARE_CONCRETE_INSTRUCTION(LoadFunctionPrototype, "load-function-prototype") DECLARE_HYDROGEN_ACCESSOR(LoadFunctionPrototype) - LOperand* function() const { return input(); } - LOperand* temporary() const { return temporary_; } - - private: - LOperand* temporary_; + LOperand* function() { return inputs_[0]; } }; -class LLoadElements: public LUnaryOperation<1> { +class LLoadElements: public LTemplateInstruction<1, 1> { public: - explicit LLoadElements(LOperand* obj) : LUnaryOperation<1>(obj) { } + explicit LLoadElements(LOperand* object) { + inputs_[0] = object; + } DECLARE_CONCRETE_INSTRUCTION(LoadElements, "load-elements") }; -class LLoadKeyedFastElement: public LBinaryOperation<1> { +class LLoadKeyedFastElement: public LTemplateInstruction<1, 2> { public: - LLoadKeyedFastElement(LOperand* elements, LOperand* key) - : LBinaryOperation<1>(elements, key) { } + LLoadKeyedFastElement(LOperand* elements, LOperand* key) { + inputs_[0] = elements; + inputs_[1] = key; + } DECLARE_CONCRETE_INSTRUCTION(LoadKeyedFastElement, "load-keyed-fast-element") DECLARE_HYDROGEN_ACCESSOR(LoadKeyedFastElement) - LOperand* elements() const { return left(); } - LOperand* key() const { return right(); } + LOperand* elements() { return inputs_[0]; } + LOperand* key() { return inputs_[1]; } }; -class LLoadKeyedGeneric: public LBinaryOperation<1> { +class LLoadKeyedGeneric: public LTemplateInstruction<1, 2> { public: - LLoadKeyedGeneric(LOperand* obj, LOperand* key) - : LBinaryOperation<1>(obj, key) { } + LLoadKeyedGeneric(LOperand* obj, LOperand* key) { + inputs_[0] = obj; + inputs_[1] = key; + } DECLARE_CONCRETE_INSTRUCTION(LoadKeyedGeneric, "load-keyed-generic") - LOperand* object() const { return left(); } - LOperand* key() const { return right(); } + LOperand* object() { return inputs_[0]; } + LOperand* key() { return inputs_[1]; } }; @@ -1342,9 +1268,11 @@ class LLoadGlobal: public LTemplateInstruction<1, 0, 0> { }; -class LStoreGlobal: public LUnaryOperation<0> { +class LStoreGlobal: public LTemplateInstruction<0, 1> { public: - explicit LStoreGlobal(LOperand* value) : LUnaryOperation<0>(value) {} + explicit LStoreGlobal(LOperand* value) { + inputs_[0] = value; + } DECLARE_CONCRETE_INSTRUCTION(StoreGlobal, "store-global") DECLARE_HYDROGEN_ACCESSOR(StoreGlobal) @@ -1356,18 +1284,18 @@ class LLoadContextSlot: public LTemplateInstruction<1, 0, 0> { DECLARE_CONCRETE_INSTRUCTION(LoadContextSlot, "load-context-slot") DECLARE_HYDROGEN_ACCESSOR(LoadContextSlot) - int context_chain_length() const { - return hydrogen()->context_chain_length(); - } - int slot_index() const { return hydrogen()->slot_index(); } + int context_chain_length() { return hydrogen()->context_chain_length(); } + int slot_index() { return hydrogen()->slot_index(); } virtual void PrintDataTo(StringStream* stream); }; -class LPushArgument: public LUnaryOperation<0> { +class LPushArgument: public LTemplateInstruction<0, 1> { public: - explicit LPushArgument(LOperand* argument) : LUnaryOperation<0>(argument) {} + explicit LPushArgument(LOperand* value) { + inputs_[0] = value; + } DECLARE_CONCRETE_INSTRUCTION(PushArgument, "push-argument") }; @@ -1397,8 +1325,12 @@ class LCallConstantFunction: public LTemplateInstruction<1, 0, 0> { }; -class LCallKeyed: public LTemplateInstruction<1, 0, 0> { +class LCallKeyed: public LTemplateInstruction<1, 0, 1> { public: + explicit LCallKeyed(LOperand* temp) { + temps_[0] = temp; + } + DECLARE_CONCRETE_INSTRUCTION(CallKeyed, "call-keyed") DECLARE_HYDROGEN_ACCESSOR(CallKeyed) @@ -1453,9 +1385,11 @@ class LCallKnownGlobal: public LTemplateInstruction<1, 0, 0> { }; -class LCallNew: public LUnaryOperation<1> { +class LCallNew: public LTemplateInstruction<1, 1> { public: - explicit LCallNew(LOperand* constructor) : LUnaryOperation<1>(constructor) { } + explicit LCallNew(LOperand* constructor) { + inputs_[0] = constructor; + } DECLARE_CONCRETE_INSTRUCTION(CallNew, "call-new") DECLARE_HYDROGEN_ACCESSOR(CallNew) @@ -1476,90 +1410,93 @@ class LCallRuntime: public LTemplateInstruction<1, 0, 0> { }; -class LInteger32ToDouble: public LUnaryOperation<1> { +class LInteger32ToDouble: public LTemplateInstruction<1, 1> { public: - explicit LInteger32ToDouble(LOperand* use) : LUnaryOperation<1>(use) { } + explicit LInteger32ToDouble(LOperand* value) { + inputs_[0] = value; + } DECLARE_CONCRETE_INSTRUCTION(Integer32ToDouble, "int32-to-double") }; -class LNumberTagI: public LUnaryOperation<1> { +class LNumberTagI: public LTemplateInstruction<1, 1> { public: - explicit LNumberTagI(LOperand* use) : LUnaryOperation<1>(use) { } + explicit LNumberTagI(LOperand* value) { + inputs_[0] = value; + } DECLARE_CONCRETE_INSTRUCTION(NumberTagI, "number-tag-i") }; -class LNumberTagD: public LUnaryOperation<1> { +class LNumberTagD: public LTemplateInstruction<1, 1, 1> { public: - explicit LNumberTagD(LOperand* value, LOperand* temp) - : LUnaryOperation<1>(value), temp_(temp) { } + explicit LNumberTagD(LOperand* value, LOperand* temp) { + inputs_[0] = value; + temps_[0] = temp; + } DECLARE_CONCRETE_INSTRUCTION(NumberTagD, "number-tag-d") - - LOperand* temp() const { return temp_; } - - private: - LOperand* temp_; }; // Sometimes truncating conversion from a tagged value to an int32. -class LDoubleToI: public LUnaryOperation<1> { +class LDoubleToI: public LTemplateInstruction<1, 1, 1> { public: - LDoubleToI(LOperand* value, LOperand* temporary) - : LUnaryOperation<1>(value), temporary_(temporary) { } + LDoubleToI(LOperand* value, LOperand* temp) { + inputs_[0] = value; + temps_[0] = temp; + } DECLARE_CONCRETE_INSTRUCTION(DoubleToI, "double-to-i") DECLARE_HYDROGEN_ACCESSOR(Change) bool truncating() { return hydrogen()->CanTruncateToInt32(); } - LOperand* temporary() const { return temporary_; } - - private: - LOperand* temporary_; }; // Truncating conversion from a tagged value to an int32. -class LTaggedToI: public LUnaryOperation<1> { +class LTaggedToI: public LTemplateInstruction<1, 1, 1> { public: - LTaggedToI(LOperand* value, LOperand* temp) - : LUnaryOperation<1>(value), temp_(temp) { } + LTaggedToI(LOperand* value, LOperand* temp) { + inputs_[0] = value; + temps_[0] = temp; + } DECLARE_CONCRETE_INSTRUCTION(TaggedToI, "tagged-to-i") DECLARE_HYDROGEN_ACCESSOR(Change) bool truncating() { return hydrogen()->CanTruncateToInt32(); } - LOperand* temp() const { return temp_; } - - private: - LOperand* temp_; }; -class LSmiTag: public LUnaryOperation<1> { +class LSmiTag: public LTemplateInstruction<1, 1> { public: - explicit LSmiTag(LOperand* use) : LUnaryOperation<1>(use) { } + explicit LSmiTag(LOperand* value) { + inputs_[0] = value; + } DECLARE_CONCRETE_INSTRUCTION(SmiTag, "smi-tag") }; -class LNumberUntagD: public LUnaryOperation<1> { +class LNumberUntagD: public LTemplateInstruction<1, 1> { public: - explicit LNumberUntagD(LOperand* value) : LUnaryOperation<1>(value) { } + explicit LNumberUntagD(LOperand* value) { + inputs_[0] = value; + } DECLARE_CONCRETE_INSTRUCTION(NumberUntagD, "double-untag") }; -class LSmiUntag: public LUnaryOperation<1> { +class LSmiUntag: public LTemplateInstruction<1, 1> { public: - LSmiUntag(LOperand* use, bool needs_check) - : LUnaryOperation<1>(use), needs_check_(needs_check) { } + LSmiUntag(LOperand* value, bool needs_check) + : needs_check_(needs_check) { + inputs_[0] = value; + } DECLARE_CONCRETE_INSTRUCTION(SmiUntag, "smi-untag") @@ -1570,11 +1507,11 @@ class LSmiUntag: public LUnaryOperation<1> { }; -class LStoreNamed: public LTemplateInstruction<0, 2, 0> { +class LStoreNamed: public LTemplateInstruction<0, 2, 1> { public: LStoreNamed(LOperand* obj, LOperand* val) { - this->SetInputAt(0, obj); - this->SetInputAt(1, val); + inputs_[0] = obj; + inputs_[1] = val; } DECLARE_INSTRUCTION(StoreNamed) @@ -1582,8 +1519,8 @@ class LStoreNamed: public LTemplateInstruction<0, 2, 0> { virtual void PrintDataTo(StringStream* stream); - LOperand* object() const { return this->InputAt(0); } - LOperand* value() const { return this->InputAt(1); } + LOperand* object() { return inputs_[0]; } + LOperand* value() { return inputs_[1]; } Handle name() const { return hydrogen()->name(); } }; @@ -1591,7 +1528,9 @@ class LStoreNamed: public LTemplateInstruction<0, 2, 0> { class LStoreNamedField: public LStoreNamed { public: LStoreNamedField(LOperand* obj, LOperand* val, LOperand* temp) - : LStoreNamed(obj, val), temp_(temp) { } + : LStoreNamed(obj, val) { + temps_[0] = temp; + } DECLARE_CONCRETE_INSTRUCTION(StoreNamedField, "store-named-field") DECLARE_HYDROGEN_ACCESSOR(StoreNamedField) @@ -1600,11 +1539,6 @@ class LStoreNamedField: public LStoreNamed { int offset() { return hydrogen()->offset(); } bool needs_write_barrier() { return hydrogen()->NeedsWriteBarrier(); } Handle transition() const { return hydrogen()->transition(); } - - LOperand* temp() { return temp_; } - - private: - LOperand* temp_; }; @@ -1621,18 +1555,18 @@ class LStoreNamedGeneric: public LStoreNamed { class LStoreKeyed: public LTemplateInstruction<0, 3, 0> { public: LStoreKeyed(LOperand* obj, LOperand* key, LOperand* val) { - this->SetInputAt(0, obj); - this->SetInputAt(1, key); - this->SetInputAt(2, val); + inputs_[0] = obj; + inputs_[1] = key; + inputs_[2] = val; } DECLARE_INSTRUCTION(StoreKeyed) virtual void PrintDataTo(StringStream* stream); - LOperand* object() const { return this->InputAt(0); } - LOperand* key() const { return this->InputAt(1); } - LOperand* value() const { return this->InputAt(2); } + LOperand* object() { return inputs_[0]; } + LOperand* key() { return inputs_[1]; } + LOperand* value() { return inputs_[2]; } }; @@ -1656,60 +1590,60 @@ class LStoreKeyedGeneric: public LStoreKeyed { }; -class LCheckFunction: public LUnaryOperation<0> { +class LCheckFunction: public LTemplateInstruction<0, 1> { public: - explicit LCheckFunction(LOperand* use) : LUnaryOperation<0>(use) { } + explicit LCheckFunction(LOperand* value) { + inputs_[0] = value; + } DECLARE_CONCRETE_INSTRUCTION(CheckFunction, "check-function") DECLARE_HYDROGEN_ACCESSOR(CheckFunction) }; -class LCheckInstanceType: public LUnaryOperation<0> { +class LCheckInstanceType: public LTemplateInstruction<0, 1, 1> { public: - LCheckInstanceType(LOperand* use, LOperand* temp) - : LUnaryOperation<0>(use), temp_(temp) { } + LCheckInstanceType(LOperand* value, LOperand* temp) { + inputs_[0] = value; + temps_[0] = temp; + } DECLARE_CONCRETE_INSTRUCTION(CheckInstanceType, "check-instance-type") DECLARE_HYDROGEN_ACCESSOR(CheckInstanceType) - - LOperand* temp() const { return temp_; } - - private: - LOperand* temp_; }; -class LCheckMap: public LUnaryOperation<0> { +class LCheckMap: public LTemplateInstruction<0, 1> { public: - explicit LCheckMap(LOperand* use) : LUnaryOperation<0>(use) { } + explicit LCheckMap(LOperand* value) { + inputs_[0] = value; + } DECLARE_CONCRETE_INSTRUCTION(CheckMap, "check-map") DECLARE_HYDROGEN_ACCESSOR(CheckMap) }; -class LCheckPrototypeMaps: public LTemplateInstruction<0, 0, 0> { +class LCheckPrototypeMaps: public LTemplateInstruction<0, 0, 1> { public: - explicit LCheckPrototypeMaps(LOperand* temp) : temp_(temp) { } + explicit LCheckPrototypeMaps(LOperand* temp) { + temps_[0] = temp; + } DECLARE_CONCRETE_INSTRUCTION(CheckPrototypeMaps, "check-prototype-maps") DECLARE_HYDROGEN_ACCESSOR(CheckPrototypeMaps) Handle prototype() const { return hydrogen()->prototype(); } Handle holder() const { return hydrogen()->holder(); } - - LOperand* temp() const { return temp_; } - - private: - LOperand* temp_; }; -class LCheckSmi: public LUnaryOperation<0> { +class LCheckSmi: public LTemplateInstruction<0, 1> { public: - LCheckSmi(LOperand* use, Condition condition) - : LUnaryOperation<0>(use), condition_(condition) { } + LCheckSmi(LOperand* value, Condition condition) + : condition_(condition) { + inputs_[0] = value; + } Condition condition() const { return condition_; } @@ -1723,27 +1657,21 @@ class LCheckSmi: public LUnaryOperation<0> { }; -class LMaterializedLiteral: public LTemplateInstruction<1, 0, 0> { - public: - DECLARE_INSTRUCTION(MaterializedLiteral) -}; - - -class LArrayLiteral: public LMaterializedLiteral { +class LArrayLiteral: public LTemplateInstruction<1, 0, 0> { public: DECLARE_CONCRETE_INSTRUCTION(ArrayLiteral, "array-literal") DECLARE_HYDROGEN_ACCESSOR(ArrayLiteral) }; -class LObjectLiteral: public LMaterializedLiteral { +class LObjectLiteral: public LTemplateInstruction<1, 0, 0> { public: DECLARE_CONCRETE_INSTRUCTION(ObjectLiteral, "object-literal") DECLARE_HYDROGEN_ACCESSOR(ObjectLiteral) }; -class LRegExpLiteral: public LMaterializedLiteral { +class LRegExpLiteral: public LTemplateInstruction<1, 0, 0> { public: DECLARE_CONCRETE_INSTRUCTION(RegExpLiteral, "regexp-literal") DECLARE_HYDROGEN_ACCESSOR(RegExpLiteral) @@ -1759,58 +1687,57 @@ class LFunctionLiteral: public LTemplateInstruction<1, 0, 0> { }; -class LTypeof: public LUnaryOperation<1> { +class LTypeof: public LTemplateInstruction<1, 1> { public: - explicit LTypeof(LOperand* input) : LUnaryOperation<1>(input) { } + explicit LTypeof(LOperand* value) { + inputs_[0] = value; + } DECLARE_CONCRETE_INSTRUCTION(Typeof, "typeof") }; -class LTypeofIs: public LUnaryOperation<1> { +class LTypeofIs: public LTemplateInstruction<1, 1> { public: - explicit LTypeofIs(LOperand* input) : LUnaryOperation<1>(input) { } - virtual void PrintDataTo(StringStream* stream); + explicit LTypeofIs(LOperand* value) { + inputs_[0] = value; + } DECLARE_CONCRETE_INSTRUCTION(TypeofIs, "typeof-is") DECLARE_HYDROGEN_ACCESSOR(TypeofIs) Handle type_literal() { return hydrogen()->type_literal(); } + + virtual void PrintDataTo(StringStream* stream); }; -class LTypeofIsAndBranch: public LTypeofIs { +class LTypeofIsAndBranch: public LControlInstruction<1> { public: - LTypeofIsAndBranch(LOperand* value, - int true_block_id, - int false_block_id) - : LTypeofIs(value), - true_block_id_(true_block_id), - false_block_id_(false_block_id) { } + explicit LTypeofIsAndBranch(LOperand* value) { + inputs_[0] = value; + } DECLARE_CONCRETE_INSTRUCTION(TypeofIsAndBranch, "typeof-is-and-branch") + DECLARE_HYDROGEN_ACCESSOR(TypeofIs) - virtual void PrintDataTo(StringStream* stream); - virtual bool IsControl() const { return true; } - - int true_block_id() const { return true_block_id_; } - int false_block_id() const { return false_block_id_; } + Handle type_literal() { return hydrogen()->type_literal(); } - private: - int true_block_id_; - int false_block_id_; + virtual void PrintDataTo(StringStream* stream); }; -class LDeleteProperty: public LBinaryOperation<1> { +class LDeleteProperty: public LTemplateInstruction<1, 2> { public: - LDeleteProperty(LOperand* obj, LOperand* key) - : LBinaryOperation<1>(obj, key) { } + LDeleteProperty(LOperand* obj, LOperand* key) { + inputs_[0] = obj; + inputs_[1] = key; + } DECLARE_CONCRETE_INSTRUCTION(DeleteProperty, "delete-property") - LOperand* object() const { return left(); } - LOperand* key() const { return right(); } + LOperand* object() { return inputs_[0]; } + LOperand* key() { return inputs_[1]; } }; @@ -1954,9 +1881,10 @@ class LChunkBuilder BASE_EMBEDDED { LUnallocated* ToUnallocated(XMMRegister reg); // Methods for setting up define-use relationships. - LOperand* Use(HValue* value, LUnallocated* operand); - LOperand* UseFixed(HValue* value, Register fixed_register); - LOperand* UseFixedDouble(HValue* value, XMMRegister fixed_register); + MUST_USE_RESULT LOperand* Use(HValue* value, LUnallocated* operand); + MUST_USE_RESULT LOperand* UseFixed(HValue* value, Register fixed_register); + MUST_USE_RESULT LOperand* UseFixedDouble(HValue* value, + XMMRegister fixed_register); // A value that is guaranteed to be allocated to a register. // Operand created by UseRegister is guaranteed to be live until the end of @@ -1966,17 +1894,22 @@ class LChunkBuilder BASE_EMBEDDED { // instruction start. Register allocator is free to assign the same register // to some other operand used inside instruction (i.e. temporary or // output). - LOperand* UseRegister(HValue* value); - LOperand* UseRegisterAtStart(HValue* value); + MUST_USE_RESULT LOperand* UseRegister(HValue* value); + MUST_USE_RESULT LOperand* UseRegisterAtStart(HValue* value); // A value in a register that may be trashed. - LOperand* UseTempRegister(HValue* value); - LOperand* Use(HValue* value); - LOperand* UseAtStart(HValue* value); - LOperand* UseOrConstant(HValue* value); - LOperand* UseOrConstantAtStart(HValue* value); - LOperand* UseRegisterOrConstant(HValue* value); - LOperand* UseRegisterOrConstantAtStart(HValue* value); + MUST_USE_RESULT LOperand* UseTempRegister(HValue* value); + MUST_USE_RESULT LOperand* Use(HValue* value); + MUST_USE_RESULT LOperand* UseAtStart(HValue* value); + MUST_USE_RESULT LOperand* UseOrConstant(HValue* value); + MUST_USE_RESULT LOperand* UseOrConstantAtStart(HValue* value); + MUST_USE_RESULT LOperand* UseRegisterOrConstant(HValue* value); + MUST_USE_RESULT LOperand* UseRegisterOrConstantAtStart(HValue* value); + + // Temporary operand that must be in a register. + MUST_USE_RESULT LUnallocated* TempRegister(); + MUST_USE_RESULT LOperand* FixedTemp(Register reg); + MUST_USE_RESULT LOperand* FixedTemp(XMMRegister reg); // Methods for setting up define-use relationships. // Return the same instruction that they are passed. @@ -2018,11 +1951,6 @@ class LChunkBuilder BASE_EMBEDDED { LEnvironment* CreateEnvironment(HEnvironment* hydrogen_env); - // Temporary operand that must be in a register. - LUnallocated* TempRegister(); - LOperand* FixedTemp(Register reg); - LOperand* FixedTemp(XMMRegister reg); - void VisitInstruction(HInstruction* current); void DoBasicBlock(HBasicBlock* block, HBasicBlock* next_block); -- 2.7.4