From 4ee7a92d834da3c3986c746242f320155edaa154 Mon Sep 17 00:00:00 2001 From: "olivf@chromium.org" Date: Thu, 20 Jun 2013 11:50:50 +0000 Subject: [PATCH] Lithium codegen should not pass around block_ids. Rather encapsulate the basic block to assembly label mapping in the LInstruction. BUG= R=jkummerow@chromium.org Review URL: https://codereview.chromium.org/17276002 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@15235 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- src/arm/lithium-arm.h | 41 ++++++++--- src/arm/lithium-codegen-arm.cc | 145 +++++++++++++------------------------- src/arm/lithium-codegen-arm.h | 4 +- src/ia32/lithium-codegen-ia32.cc | 146 +++++++++++++-------------------------- src/ia32/lithium-codegen-ia32.h | 4 +- src/ia32/lithium-ia32.h | 41 ++++++++--- src/x64/lithium-codegen-x64.cc | 143 +++++++++++++------------------------- src/x64/lithium-codegen-x64.h | 4 +- src/x64/lithium-x64.h | 41 ++++++++--- 9 files changed, 241 insertions(+), 328 deletions(-) diff --git a/src/arm/lithium-arm.h b/src/arm/lithium-arm.h index a3aea08..d3695b9 100644 --- a/src/arm/lithium-arm.h +++ b/src/arm/lithium-arm.h @@ -490,17 +490,44 @@ class LUnknownOSRValue: public LTemplateInstruction<1, 0, 0> { template class LControlInstruction: public LTemplateInstruction<0, I, T> { public: + LControlInstruction() : false_label_(NULL), true_label_(NULL) { } + virtual bool IsControl() const { return true; } int SuccessorCount() { return hydrogen()->SuccessorCount(); } HBasicBlock* SuccessorAt(int i) { return hydrogen()->SuccessorAt(i); } - int true_block_id() { return hydrogen()->SuccessorAt(0)->block_id(); } - int false_block_id() { return hydrogen()->SuccessorAt(1)->block_id(); } + + int TrueDestination(LChunk* chunk) { + return chunk->LookupDestination(true_block_id()); + } + int FalseDestination(LChunk* chunk) { + return chunk->LookupDestination(false_block_id()); + } + + Label* TrueLabel(LChunk* chunk) { + if (true_label_ == NULL) { + true_label_ = chunk->GetAssemblyLabel(TrueDestination(chunk)); + } + return true_label_; + } + Label* FalseLabel(LChunk* chunk) { + if (false_label_ == NULL) { + false_label_ = chunk->GetAssemblyLabel(FalseDestination(chunk)); + } + return false_label_; + } + + protected: + int true_block_id() { return SuccessorAt(0)->block_id(); } + int false_block_id() { return SuccessorAt(1)->block_id(); } private: HControlInstruction* hydrogen() { return HControlInstruction::cast(this->hydrogen_value()); } + + Label* false_label_; + Label* true_label_; }; @@ -1237,7 +1264,7 @@ class LBranch: public LControlInstruction<1, 0> { }; -class LCmpMapAndBranch: public LTemplateInstruction<0, 1, 1> { +class LCmpMapAndBranch: public LControlInstruction<1, 1> { public: LCmpMapAndBranch(LOperand* value, LOperand* temp) { inputs_[0] = value; @@ -1250,15 +1277,7 @@ class LCmpMapAndBranch: public LTemplateInstruction<0, 1, 1> { DECLARE_CONCRETE_INSTRUCTION(CmpMapAndBranch, "cmp-map-and-branch") DECLARE_HYDROGEN_ACCESSOR(CompareMap) - virtual bool IsControl() const { return true; } - Handle map() const { return hydrogen()->map(); } - int true_block_id() const { - return hydrogen()->FirstSuccessor()->block_id(); - } - int false_block_id() const { - return hydrogen()->SecondSuccessor()->block_id(); - } }; diff --git a/src/arm/lithium-codegen-arm.cc b/src/arm/lithium-codegen-arm.cc index b5ed662..431bb38 100644 --- a/src/arm/lithium-codegen-arm.cc +++ b/src/arm/lithium-codegen-arm.cc @@ -2159,11 +2159,12 @@ int LCodeGen::GetNextEmittedBlock() const { return -1; } +template +void LCodeGen::EmitBranch(InstrType instr, Condition cc) { + int right_block = instr->FalseDestination(chunk_); + int left_block = instr->TrueDestination(chunk_); -void LCodeGen::EmitBranch(int left_block, int right_block, Condition cc) { int next_block = GetNextEmittedBlock(); - right_block = chunk_->LookupDestination(right_block); - left_block = chunk_->LookupDestination(left_block); if (right_block == left_block) { EmitGoto(left_block); @@ -2184,22 +2185,19 @@ void LCodeGen::DoDebugBreak(LDebugBreak* instr) { void LCodeGen::DoBranch(LBranch* instr) { - int true_block = chunk_->LookupDestination(instr->true_block_id()); - int false_block = chunk_->LookupDestination(instr->false_block_id()); - Representation r = instr->hydrogen()->value()->representation(); if (r.IsInteger32() || r.IsSmi()) { ASSERT(!info()->IsStub()); Register reg = ToRegister(instr->value()); __ cmp(reg, Operand::Zero()); - EmitBranch(true_block, false_block, ne); + EmitBranch(instr, ne); } else if (r.IsDouble()) { ASSERT(!info()->IsStub()); DwVfpRegister reg = ToDoubleRegister(instr->value()); // Test the double value. Zero and NaN are false. __ VFPCompareAndSetFlags(reg, 0.0); __ cmp(r0, r0, vs); // If NaN, set the Z flag. - EmitBranch(true_block, false_block, ne); + EmitBranch(instr, ne); } else { ASSERT(r.IsTagged()); Register reg = ToRegister(instr->value()); @@ -2207,15 +2205,12 @@ void LCodeGen::DoBranch(LBranch* instr) { if (type.IsBoolean()) { ASSERT(!info()->IsStub()); __ CompareRoot(reg, Heap::kTrueValueRootIndex); - EmitBranch(true_block, false_block, eq); + EmitBranch(instr, eq); } else if (type.IsSmi()) { ASSERT(!info()->IsStub()); __ cmp(reg, Operand::Zero()); - EmitBranch(true_block, false_block, ne); + EmitBranch(instr, ne); } else { - Label* true_label = chunk_->GetAssemblyLabel(true_block); - Label* false_label = chunk_->GetAssemblyLabel(false_block); - ToBooleanStub::Types expected = instr->hydrogen()->expected_input_types(); // Avoid deopts in the case where we've never executed this path before. if (expected.IsEmpty()) expected = ToBooleanStub::all_types(); @@ -2223,26 +2218,26 @@ void LCodeGen::DoBranch(LBranch* instr) { if (expected.Contains(ToBooleanStub::UNDEFINED)) { // undefined -> false. __ CompareRoot(reg, Heap::kUndefinedValueRootIndex); - __ b(eq, false_label); + __ b(eq, instr->FalseLabel(chunk_)); } if (expected.Contains(ToBooleanStub::BOOLEAN)) { // Boolean -> its value. __ CompareRoot(reg, Heap::kTrueValueRootIndex); - __ b(eq, true_label); + __ b(eq, instr->TrueLabel(chunk_)); __ CompareRoot(reg, Heap::kFalseValueRootIndex); - __ b(eq, false_label); + __ b(eq, instr->FalseLabel(chunk_)); } if (expected.Contains(ToBooleanStub::NULL_TYPE)) { // 'null' -> false. __ CompareRoot(reg, Heap::kNullValueRootIndex); - __ b(eq, false_label); + __ b(eq, instr->FalseLabel(chunk_)); } if (expected.Contains(ToBooleanStub::SMI)) { // Smis: 0 -> false, all other -> true. __ cmp(reg, Operand::Zero()); - __ b(eq, false_label); - __ JumpIfSmi(reg, true_label); + __ b(eq, instr->FalseLabel(chunk_)); + __ JumpIfSmi(reg, instr->TrueLabel(chunk_)); } else if (expected.NeedsMap()) { // If we need a map later and have a Smi -> deopt. __ SmiTst(reg); @@ -2257,14 +2252,14 @@ void LCodeGen::DoBranch(LBranch* instr) { // Undetectable -> false. __ ldrb(ip, FieldMemOperand(map, Map::kBitFieldOffset)); __ tst(ip, Operand(1 << Map::kIsUndetectable)); - __ b(ne, false_label); + __ b(ne, instr->FalseLabel(chunk_)); } } if (expected.Contains(ToBooleanStub::SPEC_OBJECT)) { // spec object -> true. __ CompareInstanceType(map, ip, FIRST_SPEC_OBJECT_TYPE); - __ b(ge, true_label); + __ b(ge, instr->TrueLabel(chunk_)); } if (expected.Contains(ToBooleanStub::STRING)) { @@ -2274,15 +2269,15 @@ void LCodeGen::DoBranch(LBranch* instr) { __ b(ge, ¬_string); __ ldr(ip, FieldMemOperand(reg, String::kLengthOffset)); __ cmp(ip, Operand::Zero()); - __ b(ne, true_label); - __ b(false_label); + __ b(ne, instr->TrueLabel(chunk_)); + __ b(instr->FalseLabel(chunk_)); __ bind(¬_string); } if (expected.Contains(ToBooleanStub::SYMBOL)) { // Symbol value -> true. __ CompareInstanceType(map, ip, SYMBOL_TYPE); - __ b(eq, true_label); + __ b(eq, instr->TrueLabel(chunk_)); } if (expected.Contains(ToBooleanStub::HEAP_NUMBER)) { @@ -2294,8 +2289,8 @@ void LCodeGen::DoBranch(LBranch* instr) { __ vldr(dbl_scratch, FieldMemOperand(reg, HeapNumber::kValueOffset)); __ VFPCompareAndSetFlags(dbl_scratch, 0.0); __ cmp(r0, r0, vs); // NaN -> false. - __ b(eq, false_label); // +0, -0 -> false. - __ b(true_label); + __ b(eq, instr->FalseLabel(chunk_)); // +0, -0 -> false. + __ b(instr->TrueLabel(chunk_)); __ bind(¬_heap_number); } @@ -2308,7 +2303,7 @@ void LCodeGen::DoBranch(LBranch* instr) { void LCodeGen::EmitGoto(int block) { if (!IsNextEmittedBlock(block)) { - __ jmp(chunk_->GetAssemblyLabel(chunk_->LookupDestination(block))); + __ jmp(chunk_->GetAssemblyLabel(LookupDestination(block))); } } @@ -2349,17 +2344,14 @@ Condition LCodeGen::TokenToCondition(Token::Value op, bool is_unsigned) { void LCodeGen::DoCmpIDAndBranch(LCmpIDAndBranch* instr) { LOperand* left = instr->left(); LOperand* right = instr->right(); - int false_block = chunk_->LookupDestination(instr->false_block_id()); - int true_block = chunk_->LookupDestination(instr->true_block_id()); Condition cond = TokenToCondition(instr->op(), false); if (left->IsConstantOperand() && right->IsConstantOperand()) { // We can statically evaluate the comparison. double left_val = ToDouble(LConstantOperand::cast(left)); double right_val = ToDouble(LConstantOperand::cast(right)); - int next_block = - EvalComparison(instr->op(), left_val, right_val) ? true_block - : false_block; + int next_block = EvalComparison(instr->op(), left_val, right_val) ? + instr->TrueDestination(chunk_) : instr->FalseDestination(chunk_); EmitGoto(next_block); } else { if (instr->is_double()) { @@ -2368,7 +2360,7 @@ void LCodeGen::DoCmpIDAndBranch(LCmpIDAndBranch* instr) { __ VFPCompareAndSetFlags(ToDoubleRegister(left), ToDoubleRegister(right)); // If a NaN is involved, i.e. the result is unordered (V set), // jump to false block label. - __ b(vs, chunk_->GetAssemblyLabel(false_block)); + __ b(vs, instr->FalseLabel(chunk_)); } else { if (right->IsConstantOperand()) { int32_t value = ToInteger32(LConstantOperand::cast(right)); @@ -2390,7 +2382,7 @@ void LCodeGen::DoCmpIDAndBranch(LCmpIDAndBranch* instr) { __ cmp(ToRegister(left), ToRegister(right)); } } - EmitBranch(true_block, false_block, cond); + EmitBranch(instr, cond); } } @@ -2398,21 +2390,17 @@ void LCodeGen::DoCmpIDAndBranch(LCmpIDAndBranch* instr) { void LCodeGen::DoCmpObjectEqAndBranch(LCmpObjectEqAndBranch* instr) { Register left = ToRegister(instr->left()); Register right = ToRegister(instr->right()); - int false_block = chunk_->LookupDestination(instr->false_block_id()); - int true_block = chunk_->LookupDestination(instr->true_block_id()); __ cmp(left, Operand(right)); - EmitBranch(true_block, false_block, eq); + EmitBranch(instr, eq); } void LCodeGen::DoCmpConstantEqAndBranch(LCmpConstantEqAndBranch* instr) { Register left = ToRegister(instr->left()); - int true_block = chunk_->LookupDestination(instr->true_block_id()); - int false_block = chunk_->LookupDestination(instr->false_block_id()); __ cmp(left, Operand(instr->hydrogen()->right())); - EmitBranch(true_block, false_block, eq); + EmitBranch(instr, eq); } @@ -2447,15 +2435,11 @@ void LCodeGen::DoIsObjectAndBranch(LIsObjectAndBranch* instr) { Register reg = ToRegister(instr->value()); Register temp1 = ToRegister(instr->temp()); - 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); - Label* false_label = chunk_->GetAssemblyLabel(false_block); - Condition true_cond = - EmitIsObject(reg, temp1, false_label, true_label); + EmitIsObject(reg, temp1, + instr->FalseLabel(chunk_), instr->TrueLabel(chunk_)); - EmitBranch(true_block, false_block, true_cond); + EmitBranch(instr, true_cond); } @@ -2473,24 +2457,17 @@ void LCodeGen::DoIsStringAndBranch(LIsStringAndBranch* instr) { Register reg = ToRegister(instr->value()); Register temp1 = ToRegister(instr->temp()); - int true_block = chunk_->LookupDestination(instr->true_block_id()); - int false_block = chunk_->LookupDestination(instr->false_block_id()); - Label* false_label = chunk_->GetAssemblyLabel(false_block); - Condition true_cond = - EmitIsString(reg, temp1, false_label); + EmitIsString(reg, temp1, instr->FalseLabel(chunk_)); - EmitBranch(true_block, false_block, true_cond); + EmitBranch(instr, true_cond); } void LCodeGen::DoIsSmiAndBranch(LIsSmiAndBranch* instr) { - int true_block = chunk_->LookupDestination(instr->true_block_id()); - int false_block = chunk_->LookupDestination(instr->false_block_id()); - Register input_reg = EmitLoadRegister(instr->value(), ip); __ SmiTst(input_reg); - EmitBranch(true_block, false_block, eq); + EmitBranch(instr, eq); } @@ -2498,14 +2475,11 @@ void LCodeGen::DoIsUndetectableAndBranch(LIsUndetectableAndBranch* instr) { Register input = ToRegister(instr->value()); Register temp = ToRegister(instr->temp()); - int true_block = chunk_->LookupDestination(instr->true_block_id()); - int false_block = chunk_->LookupDestination(instr->false_block_id()); - - __ JumpIfSmi(input, chunk_->GetAssemblyLabel(false_block)); + __ JumpIfSmi(input, instr->FalseLabel(chunk_)); __ ldr(temp, FieldMemOperand(input, HeapObject::kMapOffset)); __ ldrb(temp, FieldMemOperand(temp, Map::kBitFieldOffset)); __ tst(temp, Operand(1 << Map::kIsUndetectable)); - EmitBranch(true_block, false_block, ne); + EmitBranch(instr, ne); } @@ -2531,8 +2505,6 @@ static Condition ComputeCompareCondition(Token::Value op) { void LCodeGen::DoStringCompareAndBranch(LStringCompareAndBranch* instr) { Token::Value op = instr->op(); - int true_block = chunk_->LookupDestination(instr->true_block_id()); - int false_block = chunk_->LookupDestination(instr->false_block_id()); Handle ic = CompareIC::GetUninitialized(isolate(), op); CallCode(ic, RelocInfo::CODE_TARGET, instr); @@ -2541,7 +2513,7 @@ void LCodeGen::DoStringCompareAndBranch(LStringCompareAndBranch* instr) { Condition condition = ComputeCompareCondition(op); - EmitBranch(true_block, false_block, condition); + EmitBranch(instr, condition); } @@ -2569,15 +2541,10 @@ void LCodeGen::DoHasInstanceTypeAndBranch(LHasInstanceTypeAndBranch* instr) { Register scratch = scratch0(); Register input = ToRegister(instr->value()); - int true_block = chunk_->LookupDestination(instr->true_block_id()); - int false_block = chunk_->LookupDestination(instr->false_block_id()); - - Label* false_label = chunk_->GetAssemblyLabel(false_block); - - __ JumpIfSmi(input, false_label); + __ JumpIfSmi(input, instr->FalseLabel(chunk_)); __ CompareObjectType(input, scratch, scratch, TestType(instr->hydrogen())); - EmitBranch(true_block, false_block, BranchCondition(instr->hydrogen())); + EmitBranch(instr, BranchCondition(instr->hydrogen())); } @@ -2597,13 +2564,10 @@ void LCodeGen::DoHasCachedArrayIndexAndBranch( Register input = ToRegister(instr->value()); Register scratch = scratch0(); - int true_block = chunk_->LookupDestination(instr->true_block_id()); - int false_block = chunk_->LookupDestination(instr->false_block_id()); - __ ldr(scratch, FieldMemOperand(input, String::kHashFieldOffset)); __ tst(scratch, Operand(String::kContainsCachedArrayIndexMask)); - EmitBranch(true_block, false_block, eq); + EmitBranch(instr, eq); } @@ -2680,27 +2644,20 @@ void LCodeGen::DoClassOfTestAndBranch(LClassOfTestAndBranch* instr) { Register temp2 = ToRegister(instr->temp()); Handle class_name = instr->hydrogen()->class_name(); - 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); - Label* false_label = chunk_->GetAssemblyLabel(false_block); - - EmitClassOfTest(true_label, false_label, class_name, input, temp, temp2); + EmitClassOfTest(instr->TrueLabel(chunk_), instr->FalseLabel(chunk_), + class_name, input, temp, temp2); - EmitBranch(true_block, false_block, eq); + EmitBranch(instr, eq); } void LCodeGen::DoCmpMapAndBranch(LCmpMapAndBranch* instr) { Register reg = ToRegister(instr->value()); Register temp = ToRegister(instr->temp()); - int true_block = instr->true_block_id(); - int false_block = instr->false_block_id(); __ ldr(temp, FieldMemOperand(reg, HeapObject::kMapOffset)); __ cmp(temp, Operand(instr->map())); - EmitBranch(true_block, false_block, eq); + EmitBranch(instr, eq); } @@ -5597,17 +5554,13 @@ void LCodeGen::DoTypeof(LTypeof* instr) { void LCodeGen::DoTypeofIsAndBranch(LTypeofIsAndBranch* instr) { Register input = ToRegister(instr->value()); - 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); - Label* false_label = chunk_->GetAssemblyLabel(false_block); - Condition final_branch_condition = EmitTypeofIs(true_label, - false_label, + Condition final_branch_condition = EmitTypeofIs(instr->TrueLabel(chunk_), + instr->FalseLabel(chunk_), input, instr->type_literal()); if (final_branch_condition != kNoCondition) { - EmitBranch(true_block, false_block, final_branch_condition); + EmitBranch(instr, final_branch_condition); } } @@ -5692,11 +5645,9 @@ Condition LCodeGen::EmitTypeofIs(Label* true_label, void LCodeGen::DoIsConstructCallAndBranch(LIsConstructCallAndBranch* instr) { Register temp1 = ToRegister(instr->temp()); - int true_block = chunk_->LookupDestination(instr->true_block_id()); - int false_block = chunk_->LookupDestination(instr->false_block_id()); EmitIsConstructCall(temp1, scratch0()); - EmitBranch(true_block, false_block, eq); + EmitBranch(instr, eq); } diff --git a/src/arm/lithium-codegen-arm.h b/src/arm/lithium-codegen-arm.h index 3bdf6b0..9202dd5 100644 --- a/src/arm/lithium-codegen-arm.h +++ b/src/arm/lithium-codegen-arm.h @@ -79,7 +79,6 @@ class LCodeGen BASE_EMBEDDED { Heap* heap() const { return isolate()->heap(); } Zone* zone() const { return zone_; } - // TODO(svenpanne) Use this consistently. int LookupDestination(int block_id) const { return chunk()->LookupDestination(block_id); } @@ -320,7 +319,8 @@ class LCodeGen BASE_EMBEDDED { static Condition TokenToCondition(Token::Value op, bool is_unsigned); void EmitGoto(int block); - void EmitBranch(int left_block, int right_block, Condition cc); + template + void EmitBranch(InstrType instr, Condition cc); void EmitNumberUntagD(Register input, DwVfpRegister result, bool allow_undefined_as_nan, diff --git a/src/ia32/lithium-codegen-ia32.cc b/src/ia32/lithium-codegen-ia32.cc index 07e355f..28164c7 100644 --- a/src/ia32/lithium-codegen-ia32.cc +++ b/src/ia32/lithium-codegen-ia32.cc @@ -2087,10 +2087,12 @@ int LCodeGen::GetNextEmittedBlock() const { } -void LCodeGen::EmitBranch(int left_block, int right_block, Condition cc) { +template +void LCodeGen::EmitBranch(InstrType instr, Condition cc) { + int right_block = instr->FalseDestination(chunk_); + int left_block = instr->TrueDestination(chunk_); + int next_block = GetNextEmittedBlock(); - right_block = chunk_->LookupDestination(right_block); - left_block = chunk_->LookupDestination(left_block); if (right_block == left_block) { EmitGoto(left_block); @@ -2106,22 +2108,19 @@ void LCodeGen::EmitBranch(int left_block, int right_block, Condition cc) { void LCodeGen::DoBranch(LBranch* instr) { - int true_block = chunk_->LookupDestination(instr->true_block_id()); - int false_block = chunk_->LookupDestination(instr->false_block_id()); - Representation r = instr->hydrogen()->value()->representation(); if (r.IsSmiOrInteger32()) { ASSERT(!info()->IsStub()); Register reg = ToRegister(instr->value()); __ test(reg, Operand(reg)); - EmitBranch(true_block, false_block, not_zero); + EmitBranch(instr, not_zero); } else if (r.IsDouble()) { ASSERT(!info()->IsStub()); CpuFeatureScope scope(masm(), SSE2); XMMRegister reg = ToDoubleRegister(instr->value()); __ xorps(xmm0, xmm0); __ ucomisd(reg, xmm0); - EmitBranch(true_block, false_block, not_equal); + EmitBranch(instr, not_equal); } else { ASSERT(r.IsTagged()); Register reg = ToRegister(instr->value()); @@ -2129,15 +2128,12 @@ void LCodeGen::DoBranch(LBranch* instr) { if (type.IsBoolean()) { ASSERT(!info()->IsStub()); __ cmp(reg, factory()->true_value()); - EmitBranch(true_block, false_block, equal); + EmitBranch(instr, equal); } else if (type.IsSmi()) { ASSERT(!info()->IsStub()); __ test(reg, Operand(reg)); - EmitBranch(true_block, false_block, not_equal); + EmitBranch(instr, not_equal); } else { - Label* true_label = chunk_->GetAssemblyLabel(true_block); - Label* false_label = chunk_->GetAssemblyLabel(false_block); - ToBooleanStub::Types expected = instr->hydrogen()->expected_input_types(); // Avoid deopts in the case where we've never executed this path before. if (expected.IsEmpty()) expected = ToBooleanStub::all_types(); @@ -2145,27 +2141,27 @@ void LCodeGen::DoBranch(LBranch* instr) { if (expected.Contains(ToBooleanStub::UNDEFINED)) { // undefined -> false. __ cmp(reg, factory()->undefined_value()); - __ j(equal, false_label); + __ j(equal, instr->FalseLabel(chunk_)); } if (expected.Contains(ToBooleanStub::BOOLEAN)) { // true -> true. __ cmp(reg, factory()->true_value()); - __ j(equal, true_label); + __ j(equal, instr->TrueLabel(chunk_)); // false -> false. __ cmp(reg, factory()->false_value()); - __ j(equal, false_label); + __ j(equal, instr->FalseLabel(chunk_)); } if (expected.Contains(ToBooleanStub::NULL_TYPE)) { // 'null' -> false. __ cmp(reg, factory()->null_value()); - __ j(equal, false_label); + __ j(equal, instr->FalseLabel(chunk_)); } if (expected.Contains(ToBooleanStub::SMI)) { // Smis: 0 -> false, all other -> true. __ test(reg, Operand(reg)); - __ j(equal, false_label); - __ JumpIfSmi(reg, true_label); + __ j(equal, instr->FalseLabel(chunk_)); + __ JumpIfSmi(reg, instr->TrueLabel(chunk_)); } else if (expected.NeedsMap()) { // If we need a map later and have a Smi -> deopt. __ test(reg, Immediate(kSmiTagMask)); @@ -2182,14 +2178,14 @@ void LCodeGen::DoBranch(LBranch* instr) { // Undetectable -> false. __ test_b(FieldOperand(map, Map::kBitFieldOffset), 1 << Map::kIsUndetectable); - __ j(not_zero, false_label); + __ j(not_zero, instr->FalseLabel(chunk_)); } } if (expected.Contains(ToBooleanStub::SPEC_OBJECT)) { // spec object -> true. __ CmpInstanceType(map, FIRST_SPEC_OBJECT_TYPE); - __ j(above_equal, true_label); + __ j(above_equal, instr->TrueLabel(chunk_)); } if (expected.Contains(ToBooleanStub::STRING)) { @@ -2198,15 +2194,15 @@ void LCodeGen::DoBranch(LBranch* instr) { __ CmpInstanceType(map, FIRST_NONSTRING_TYPE); __ j(above_equal, ¬_string, Label::kNear); __ cmp(FieldOperand(reg, String::kLengthOffset), Immediate(0)); - __ j(not_zero, true_label); - __ jmp(false_label); + __ j(not_zero, instr->TrueLabel(chunk_)); + __ jmp(instr->FalseLabel(chunk_)); __ bind(¬_string); } if (expected.Contains(ToBooleanStub::SYMBOL)) { // Symbol value -> true. __ CmpInstanceType(map, SYMBOL_TYPE); - __ j(equal, true_label); + __ j(equal, instr->TrueLabel(chunk_)); } if (expected.Contains(ToBooleanStub::HEAP_NUMBER)) { @@ -2224,8 +2220,8 @@ void LCodeGen::DoBranch(LBranch* instr) { __ fld_d(FieldOperand(reg, HeapNumber::kValueOffset)); __ FCmp(); } - __ j(zero, false_label); - __ jmp(true_label); + __ j(zero, instr->FalseLabel(chunk_)); + __ jmp(instr->TrueLabel(chunk_)); __ bind(¬_heap_number); } @@ -2238,7 +2234,7 @@ void LCodeGen::DoBranch(LBranch* instr) { void LCodeGen::EmitGoto(int block) { if (!IsNextEmittedBlock(block)) { - __ jmp(chunk_->GetAssemblyLabel(chunk_->LookupDestination(block))); + __ jmp(chunk_->GetAssemblyLabel(LookupDestination(block))); } } @@ -2279,17 +2275,14 @@ Condition LCodeGen::TokenToCondition(Token::Value op, bool is_unsigned) { void LCodeGen::DoCmpIDAndBranch(LCmpIDAndBranch* instr) { LOperand* left = instr->left(); LOperand* right = instr->right(); - int false_block = chunk_->LookupDestination(instr->false_block_id()); - int true_block = chunk_->LookupDestination(instr->true_block_id()); Condition cc = TokenToCondition(instr->op(), instr->is_double()); if (left->IsConstantOperand() && right->IsConstantOperand()) { // We can statically evaluate the comparison. double left_val = ToDouble(LConstantOperand::cast(left)); double right_val = ToDouble(LConstantOperand::cast(right)); - int next_block = - EvalComparison(instr->op(), left_val, right_val) ? true_block - : false_block; + int next_block = EvalComparison(instr->op(), left_val, right_val) ? + instr->TrueDestination(chunk_) : instr->FalseDestination(chunk_); EmitGoto(next_block); } else { if (instr->is_double()) { @@ -2297,7 +2290,7 @@ void LCodeGen::DoCmpIDAndBranch(LCmpIDAndBranch* instr) { // Don't base result on EFLAGS when a NaN is involved. Instead // jump to the false block. __ ucomisd(ToDoubleRegister(left), ToDoubleRegister(right)); - __ j(parity_even, chunk_->GetAssemblyLabel(false_block)); + __ j(parity_even, instr->FalseLabel(chunk_)); } else { if (right->IsConstantOperand()) { int32_t const_value = ToInteger32(LConstantOperand::cast(right)); @@ -2319,15 +2312,13 @@ void LCodeGen::DoCmpIDAndBranch(LCmpIDAndBranch* instr) { __ cmp(ToRegister(left), ToOperand(right)); } } - EmitBranch(true_block, false_block, cc); + EmitBranch(instr, cc); } } void LCodeGen::DoCmpObjectEqAndBranch(LCmpObjectEqAndBranch* instr) { Register left = ToRegister(instr->left()); - int false_block = chunk_->LookupDestination(instr->false_block_id()); - int true_block = chunk_->LookupDestination(instr->true_block_id()); if (instr->right()->IsConstantOperand()) { Handle right = ToHandle(LConstantOperand::cast(instr->right())); @@ -2336,17 +2327,15 @@ void LCodeGen::DoCmpObjectEqAndBranch(LCmpObjectEqAndBranch* instr) { Operand right = ToOperand(instr->right()); __ cmp(left, right); } - EmitBranch(true_block, false_block, equal); + EmitBranch(instr, equal); } void LCodeGen::DoCmpConstantEqAndBranch(LCmpConstantEqAndBranch* instr) { Register left = ToRegister(instr->left()); - int true_block = chunk_->LookupDestination(instr->true_block_id()); - int false_block = chunk_->LookupDestination(instr->false_block_id()); __ cmp(left, instr->hydrogen()->right()); - EmitBranch(true_block, false_block, equal); + EmitBranch(instr, equal); } @@ -2377,14 +2366,10 @@ void LCodeGen::DoIsObjectAndBranch(LIsObjectAndBranch* instr) { Register reg = ToRegister(instr->value()); Register temp = ToRegister(instr->temp()); - 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); - Label* false_label = chunk_->GetAssemblyLabel(false_block); - - Condition true_cond = EmitIsObject(reg, temp, false_label, true_label); + Condition true_cond = EmitIsObject( + reg, temp, instr->FalseLabel(chunk_), instr->TrueLabel(chunk_)); - EmitBranch(true_block, false_block, true_cond); + EmitBranch(instr, true_cond); } @@ -2403,24 +2388,17 @@ void LCodeGen::DoIsStringAndBranch(LIsStringAndBranch* instr) { Register reg = ToRegister(instr->value()); Register temp = ToRegister(instr->temp()); - int true_block = chunk_->LookupDestination(instr->true_block_id()); - int false_block = chunk_->LookupDestination(instr->false_block_id()); - Label* false_label = chunk_->GetAssemblyLabel(false_block); + Condition true_cond = EmitIsString(reg, temp, instr->FalseLabel(chunk_)); - Condition true_cond = EmitIsString(reg, temp, false_label); - - EmitBranch(true_block, false_block, true_cond); + EmitBranch(instr, true_cond); } void LCodeGen::DoIsSmiAndBranch(LIsSmiAndBranch* instr) { Operand input = ToOperand(instr->value()); - int true_block = chunk_->LookupDestination(instr->true_block_id()); - int false_block = chunk_->LookupDestination(instr->false_block_id()); - __ test(input, Immediate(kSmiTagMask)); - EmitBranch(true_block, false_block, zero); + EmitBranch(instr, zero); } @@ -2428,15 +2406,12 @@ void LCodeGen::DoIsUndetectableAndBranch(LIsUndetectableAndBranch* instr) { Register input = ToRegister(instr->value()); Register temp = ToRegister(instr->temp()); - int true_block = chunk_->LookupDestination(instr->true_block_id()); - int false_block = chunk_->LookupDestination(instr->false_block_id()); - STATIC_ASSERT(kSmiTag == 0); - __ JumpIfSmi(input, chunk_->GetAssemblyLabel(false_block)); + __ JumpIfSmi(input, instr->FalseLabel(chunk_)); __ mov(temp, FieldOperand(input, HeapObject::kMapOffset)); __ test_b(FieldOperand(temp, Map::kBitFieldOffset), 1 << Map::kIsUndetectable); - EmitBranch(true_block, false_block, not_zero); + EmitBranch(instr, not_zero); } @@ -2462,8 +2437,6 @@ static Condition ComputeCompareCondition(Token::Value op) { void LCodeGen::DoStringCompareAndBranch(LStringCompareAndBranch* instr) { Token::Value op = instr->op(); - int true_block = chunk_->LookupDestination(instr->true_block_id()); - int false_block = chunk_->LookupDestination(instr->false_block_id()); Handle ic = CompareIC::GetUninitialized(isolate(), op); CallCode(ic, RelocInfo::CODE_TARGET, instr); @@ -2471,7 +2444,7 @@ void LCodeGen::DoStringCompareAndBranch(LStringCompareAndBranch* instr) { Condition condition = ComputeCompareCondition(op); __ test(eax, Operand(eax)); - EmitBranch(true_block, false_block, condition); + EmitBranch(instr, condition); } @@ -2499,15 +2472,10 @@ void LCodeGen::DoHasInstanceTypeAndBranch(LHasInstanceTypeAndBranch* instr) { Register input = ToRegister(instr->value()); Register temp = ToRegister(instr->temp()); - int true_block = chunk_->LookupDestination(instr->true_block_id()); - int false_block = chunk_->LookupDestination(instr->false_block_id()); - - Label* false_label = chunk_->GetAssemblyLabel(false_block); - - __ JumpIfSmi(input, false_label); + __ JumpIfSmi(input, instr->FalseLabel(chunk_)); __ CmpObjectType(input, TestType(instr->hydrogen()), temp); - EmitBranch(true_block, false_block, BranchCondition(instr->hydrogen())); + EmitBranch(instr, BranchCondition(instr->hydrogen())); } @@ -2526,12 +2494,9 @@ void LCodeGen::DoHasCachedArrayIndexAndBranch( LHasCachedArrayIndexAndBranch* instr) { Register input = ToRegister(instr->value()); - int true_block = chunk_->LookupDestination(instr->true_block_id()); - int false_block = chunk_->LookupDestination(instr->false_block_id()); - __ test(FieldOperand(input, String::kHashFieldOffset), Immediate(String::kContainsCachedArrayIndexMask)); - EmitBranch(true_block, false_block, equal); + EmitBranch(instr, equal); } @@ -2607,25 +2572,17 @@ void LCodeGen::DoClassOfTestAndBranch(LClassOfTestAndBranch* instr) { Handle class_name = instr->hydrogen()->class_name(); - int true_block = chunk_->LookupDestination(instr->true_block_id()); - int false_block = chunk_->LookupDestination(instr->false_block_id()); + EmitClassOfTest(instr->TrueLabel(chunk_), instr->FalseLabel(chunk_), + class_name, input, temp, temp2); - Label* true_label = chunk_->GetAssemblyLabel(true_block); - Label* false_label = chunk_->GetAssemblyLabel(false_block); - - EmitClassOfTest(true_label, false_label, class_name, input, temp, temp2); - - EmitBranch(true_block, false_block, equal); + EmitBranch(instr, equal); } void LCodeGen::DoCmpMapAndBranch(LCmpMapAndBranch* instr) { Register reg = ToRegister(instr->value()); - int true_block = instr->true_block_id(); - int false_block = instr->false_block_id(); - __ cmp(FieldOperand(reg, HeapObject::kMapOffset), instr->map()); - EmitBranch(true_block, false_block, equal); + EmitBranch(instr, equal); } @@ -6243,15 +6200,12 @@ void LCodeGen::DoTypeof(LTypeof* instr) { void LCodeGen::DoTypeofIsAndBranch(LTypeofIsAndBranch* instr) { Register input = ToRegister(instr->value()); - 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); - Label* false_label = chunk_->GetAssemblyLabel(false_block); Condition final_branch_condition = - EmitTypeofIs(true_label, false_label, input, instr->type_literal()); + EmitTypeofIs(instr->TrueLabel(chunk_), instr->FalseLabel(chunk_), + input, instr->type_literal()); if (final_branch_condition != no_condition) { - EmitBranch(true_block, false_block, final_branch_condition); + EmitBranch(instr, final_branch_condition); } } @@ -6332,11 +6286,9 @@ Condition LCodeGen::EmitTypeofIs(Label* true_label, void LCodeGen::DoIsConstructCallAndBranch(LIsConstructCallAndBranch* instr) { Register temp = ToRegister(instr->temp()); - int true_block = chunk_->LookupDestination(instr->true_block_id()); - int false_block = chunk_->LookupDestination(instr->false_block_id()); EmitIsConstructCall(temp); - EmitBranch(true_block, false_block, equal); + EmitBranch(instr, equal); } diff --git a/src/ia32/lithium-codegen-ia32.h b/src/ia32/lithium-codegen-ia32.h index 260711b..e684527 100644 --- a/src/ia32/lithium-codegen-ia32.h +++ b/src/ia32/lithium-codegen-ia32.h @@ -83,7 +83,6 @@ class LCodeGen BASE_EMBEDDED { Heap* heap() const { return isolate()->heap(); } Zone* zone() const { return zone_; } - // TODO(svenpanne) Use this consistently. int LookupDestination(int block_id) const { return chunk()->LookupDestination(block_id); } @@ -318,7 +317,8 @@ class LCodeGen BASE_EMBEDDED { static Condition TokenToCondition(Token::Value op, bool is_unsigned); void EmitGoto(int block); - void EmitBranch(int left_block, int right_block, Condition cc); + template + void EmitBranch(InstrType instr, Condition cc); void EmitNumberUntagD( Register input, Register temp, diff --git a/src/ia32/lithium-ia32.h b/src/ia32/lithium-ia32.h index 5529759..b04f3ee 100644 --- a/src/ia32/lithium-ia32.h +++ b/src/ia32/lithium-ia32.h @@ -483,17 +483,44 @@ class LUnknownOSRValue: public LTemplateInstruction<1, 0, 0> { template class LControlInstruction: public LTemplateInstruction<0, I, T> { public: + LControlInstruction() : false_label_(NULL), true_label_(NULL) { } + virtual bool IsControl() const { return true; } int SuccessorCount() { return hydrogen()->SuccessorCount(); } HBasicBlock* SuccessorAt(int i) { return hydrogen()->SuccessorAt(i); } - int true_block_id() { return hydrogen()->SuccessorAt(0)->block_id(); } - int false_block_id() { return hydrogen()->SuccessorAt(1)->block_id(); } + + int TrueDestination(LChunk* chunk) { + return chunk->LookupDestination(true_block_id()); + } + int FalseDestination(LChunk* chunk) { + return chunk->LookupDestination(false_block_id()); + } + + Label* TrueLabel(LChunk* chunk) { + if (true_label_ == NULL) { + true_label_ = chunk->GetAssemblyLabel(TrueDestination(chunk)); + } + return true_label_; + } + Label* FalseLabel(LChunk* chunk) { + if (false_label_ == NULL) { + false_label_ = chunk->GetAssemblyLabel(FalseDestination(chunk)); + } + return false_label_; + } + + protected: + int true_block_id() { return SuccessorAt(0)->block_id(); } + int false_block_id() { return SuccessorAt(1)->block_id(); } private: HControlInstruction* hydrogen() { return HControlInstruction::cast(this->hydrogen_value()); } + + Label* false_label_; + Label* true_label_; }; @@ -1207,7 +1234,7 @@ class LBranch: public LControlInstruction<1, 1> { }; -class LCmpMapAndBranch: public LTemplateInstruction<0, 1, 0> { +class LCmpMapAndBranch: public LControlInstruction<1, 0> { public: explicit LCmpMapAndBranch(LOperand* value) { inputs_[0] = value; @@ -1218,15 +1245,7 @@ class LCmpMapAndBranch: public LTemplateInstruction<0, 1, 0> { DECLARE_CONCRETE_INSTRUCTION(CmpMapAndBranch, "cmp-map-and-branch") DECLARE_HYDROGEN_ACCESSOR(CompareMap) - virtual bool IsControl() const { return true; } - Handle map() const { return hydrogen()->map(); } - int true_block_id() const { - return hydrogen()->FirstSuccessor()->block_id(); - } - int false_block_id() const { - return hydrogen()->SecondSuccessor()->block_id(); - } }; diff --git a/src/x64/lithium-codegen-x64.cc b/src/x64/lithium-codegen-x64.cc index 5960726..1dac13d 100644 --- a/src/x64/lithium-codegen-x64.cc +++ b/src/x64/lithium-codegen-x64.cc @@ -1862,10 +1862,12 @@ int LCodeGen::GetNextEmittedBlock() const { } -void LCodeGen::EmitBranch(int left_block, int right_block, Condition cc) { +template +void LCodeGen::EmitBranch(InstrType instr, Condition cc) { + int right_block = instr->FalseDestination(chunk_); + int left_block = instr->TrueDestination(chunk_); + int next_block = GetNextEmittedBlock(); - right_block = chunk_->LookupDestination(right_block); - left_block = chunk_->LookupDestination(left_block); if (right_block == left_block) { EmitGoto(left_block); @@ -1888,26 +1890,23 @@ void LCodeGen::DoDebugBreak(LDebugBreak* instr) { void LCodeGen::DoBranch(LBranch* instr) { - int true_block = chunk_->LookupDestination(instr->true_block_id()); - int false_block = chunk_->LookupDestination(instr->false_block_id()); - Representation r = instr->hydrogen()->value()->representation(); if (r.IsInteger32()) { ASSERT(!info()->IsStub()); Register reg = ToRegister(instr->value()); __ testl(reg, reg); - EmitBranch(true_block, false_block, not_zero); + EmitBranch(instr, not_zero); } else if (r.IsSmi()) { ASSERT(!info()->IsStub()); Register reg = ToRegister(instr->value()); __ testq(reg, reg); - EmitBranch(true_block, false_block, not_zero); + EmitBranch(instr, not_zero); } else if (r.IsDouble()) { ASSERT(!info()->IsStub()); XMMRegister reg = ToDoubleRegister(instr->value()); __ xorps(xmm0, xmm0); __ ucomisd(reg, xmm0); - EmitBranch(true_block, false_block, not_equal); + EmitBranch(instr, not_equal); } else { ASSERT(r.IsTagged()); Register reg = ToRegister(instr->value()); @@ -1915,15 +1914,12 @@ void LCodeGen::DoBranch(LBranch* instr) { if (type.IsBoolean()) { ASSERT(!info()->IsStub()); __ CompareRoot(reg, Heap::kTrueValueRootIndex); - EmitBranch(true_block, false_block, equal); + EmitBranch(instr, equal); } else if (type.IsSmi()) { ASSERT(!info()->IsStub()); __ SmiCompare(reg, Smi::FromInt(0)); - EmitBranch(true_block, false_block, not_equal); + EmitBranch(instr, not_equal); } else { - Label* true_label = chunk_->GetAssemblyLabel(true_block); - Label* false_label = chunk_->GetAssemblyLabel(false_block); - ToBooleanStub::Types expected = instr->hydrogen()->expected_input_types(); // Avoid deopts in the case where we've never executed this path before. if (expected.IsEmpty()) expected = ToBooleanStub::all_types(); @@ -1931,27 +1927,27 @@ void LCodeGen::DoBranch(LBranch* instr) { if (expected.Contains(ToBooleanStub::UNDEFINED)) { // undefined -> false. __ CompareRoot(reg, Heap::kUndefinedValueRootIndex); - __ j(equal, false_label); + __ j(equal, instr->FalseLabel(chunk_)); } if (expected.Contains(ToBooleanStub::BOOLEAN)) { // true -> true. __ CompareRoot(reg, Heap::kTrueValueRootIndex); - __ j(equal, true_label); + __ j(equal, instr->TrueLabel(chunk_)); // false -> false. __ CompareRoot(reg, Heap::kFalseValueRootIndex); - __ j(equal, false_label); + __ j(equal, instr->FalseLabel(chunk_)); } if (expected.Contains(ToBooleanStub::NULL_TYPE)) { // 'null' -> false. __ CompareRoot(reg, Heap::kNullValueRootIndex); - __ j(equal, false_label); + __ j(equal, instr->FalseLabel(chunk_)); } if (expected.Contains(ToBooleanStub::SMI)) { // Smis: 0 -> false, all other -> true. __ Cmp(reg, Smi::FromInt(0)); - __ j(equal, false_label); - __ JumpIfSmi(reg, true_label); + __ j(equal, instr->FalseLabel(chunk_)); + __ JumpIfSmi(reg, instr->TrueLabel(chunk_)); } else if (expected.NeedsMap()) { // If we need a map later and have a Smi -> deopt. __ testb(reg, Immediate(kSmiTagMask)); @@ -1966,14 +1962,14 @@ void LCodeGen::DoBranch(LBranch* instr) { // Undetectable -> false. __ testb(FieldOperand(map, Map::kBitFieldOffset), Immediate(1 << Map::kIsUndetectable)); - __ j(not_zero, false_label); + __ j(not_zero, instr->FalseLabel(chunk_)); } } if (expected.Contains(ToBooleanStub::SPEC_OBJECT)) { // spec object -> true. __ CmpInstanceType(map, FIRST_SPEC_OBJECT_TYPE); - __ j(above_equal, true_label); + __ j(above_equal, instr->TrueLabel(chunk_)); } if (expected.Contains(ToBooleanStub::STRING)) { @@ -1982,8 +1978,8 @@ void LCodeGen::DoBranch(LBranch* instr) { __ CmpInstanceType(map, FIRST_NONSTRING_TYPE); __ j(above_equal, ¬_string, Label::kNear); __ cmpq(FieldOperand(reg, String::kLengthOffset), Immediate(0)); - __ j(not_zero, true_label); - __ jmp(false_label); + __ j(not_zero, instr->TrueLabel(chunk_)); + __ jmp(instr->FalseLabel(chunk_)); __ bind(¬_string); } @@ -1994,8 +1990,8 @@ void LCodeGen::DoBranch(LBranch* instr) { __ j(not_equal, ¬_heap_number, Label::kNear); __ xorps(xmm0, xmm0); __ ucomisd(xmm0, FieldOperand(reg, HeapNumber::kValueOffset)); - __ j(zero, false_label); - __ jmp(true_label); + __ j(zero, instr->FalseLabel(chunk_)); + __ jmp(instr->TrueLabel(chunk_)); __ bind(¬_heap_number); } @@ -2049,24 +2045,21 @@ inline Condition LCodeGen::TokenToCondition(Token::Value op, bool is_unsigned) { void LCodeGen::DoCmpIDAndBranch(LCmpIDAndBranch* instr) { LOperand* left = instr->left(); LOperand* right = instr->right(); - int false_block = chunk_->LookupDestination(instr->false_block_id()); - int true_block = chunk_->LookupDestination(instr->true_block_id()); Condition cc = TokenToCondition(instr->op(), instr->is_double()); if (left->IsConstantOperand() && right->IsConstantOperand()) { // We can statically evaluate the comparison. double left_val = ToDouble(LConstantOperand::cast(left)); double right_val = ToDouble(LConstantOperand::cast(right)); - int next_block = - EvalComparison(instr->op(), left_val, right_val) ? true_block - : false_block; + int next_block = EvalComparison(instr->op(), left_val, right_val) ? + instr->TrueDestination(chunk_) : instr->FalseDestination(chunk_); EmitGoto(next_block); } else { if (instr->is_double()) { // Don't base result on EFLAGS when a NaN is involved. Instead // jump to the false block. __ ucomisd(ToDoubleRegister(left), ToDoubleRegister(right)); - __ j(parity_even, chunk_->GetAssemblyLabel(false_block)); + __ j(parity_even, instr->FalseLabel(chunk_)); } else { int32_t value; if (right->IsConstantOperand()) { @@ -2105,15 +2098,13 @@ void LCodeGen::DoCmpIDAndBranch(LCmpIDAndBranch* instr) { } } } - EmitBranch(true_block, false_block, cc); + EmitBranch(instr, cc); } } void LCodeGen::DoCmpObjectEqAndBranch(LCmpObjectEqAndBranch* instr) { Register left = ToRegister(instr->left()); - int false_block = chunk_->LookupDestination(instr->false_block_id()); - int true_block = chunk_->LookupDestination(instr->true_block_id()); if (instr->right()->IsConstantOperand()) { Handle right = ToHandle(LConstantOperand::cast(instr->right())); @@ -2122,17 +2113,15 @@ void LCodeGen::DoCmpObjectEqAndBranch(LCmpObjectEqAndBranch* instr) { Register right = ToRegister(instr->right()); __ cmpq(left, right); } - EmitBranch(true_block, false_block, equal); + EmitBranch(instr, equal); } void LCodeGen::DoCmpConstantEqAndBranch(LCmpConstantEqAndBranch* instr) { Register left = ToRegister(instr->left()); - int true_block = chunk_->LookupDestination(instr->true_block_id()); - int false_block = chunk_->LookupDestination(instr->false_block_id()); __ cmpq(left, Immediate(instr->hydrogen()->right())); - EmitBranch(true_block, false_block, equal); + EmitBranch(instr, equal); } @@ -2164,14 +2153,10 @@ Condition LCodeGen::EmitIsObject(Register input, void LCodeGen::DoIsObjectAndBranch(LIsObjectAndBranch* instr) { Register reg = ToRegister(instr->value()); - 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); - Label* false_label = chunk_->GetAssemblyLabel(false_block); + Condition true_cond = EmitIsObject( + reg, instr->FalseLabel(chunk_), instr->TrueLabel(chunk_)); - Condition true_cond = EmitIsObject(reg, false_label, true_label); - - EmitBranch(true_block, false_block, true_cond); + EmitBranch(instr, true_cond); } @@ -2189,20 +2174,13 @@ void LCodeGen::DoIsStringAndBranch(LIsStringAndBranch* instr) { Register reg = ToRegister(instr->value()); Register temp = ToRegister(instr->temp()); - int true_block = chunk_->LookupDestination(instr->true_block_id()); - int false_block = chunk_->LookupDestination(instr->false_block_id()); - Label* false_label = chunk_->GetAssemblyLabel(false_block); - - Condition true_cond = EmitIsString(reg, temp, false_label); + Condition true_cond = EmitIsString(reg, temp, instr->FalseLabel(chunk_)); - EmitBranch(true_block, false_block, true_cond); + EmitBranch(instr, true_cond); } void LCodeGen::DoIsSmiAndBranch(LIsSmiAndBranch* instr) { - int true_block = chunk_->LookupDestination(instr->true_block_id()); - int false_block = chunk_->LookupDestination(instr->false_block_id()); - Condition is_smi; if (instr->value()->IsRegister()) { Register input = ToRegister(instr->value()); @@ -2211,7 +2189,7 @@ void LCodeGen::DoIsSmiAndBranch(LIsSmiAndBranch* instr) { Operand input = ToOperand(instr->value()); is_smi = masm()->CheckSmi(input); } - EmitBranch(true_block, false_block, is_smi); + EmitBranch(instr, is_smi); } @@ -2219,21 +2197,16 @@ void LCodeGen::DoIsUndetectableAndBranch(LIsUndetectableAndBranch* instr) { Register input = ToRegister(instr->value()); Register temp = ToRegister(instr->temp()); - int true_block = chunk_->LookupDestination(instr->true_block_id()); - int false_block = chunk_->LookupDestination(instr->false_block_id()); - - __ JumpIfSmi(input, chunk_->GetAssemblyLabel(false_block)); + __ JumpIfSmi(input, instr->FalseLabel(chunk_)); __ movq(temp, FieldOperand(input, HeapObject::kMapOffset)); __ testb(FieldOperand(temp, Map::kBitFieldOffset), Immediate(1 << Map::kIsUndetectable)); - EmitBranch(true_block, false_block, not_zero); + EmitBranch(instr, not_zero); } void LCodeGen::DoStringCompareAndBranch(LStringCompareAndBranch* instr) { Token::Value op = instr->op(); - int true_block = chunk_->LookupDestination(instr->true_block_id()); - int false_block = chunk_->LookupDestination(instr->false_block_id()); Handle ic = CompareIC::GetUninitialized(isolate(), op); CallCode(ic, RelocInfo::CODE_TARGET, instr); @@ -2241,7 +2214,7 @@ void LCodeGen::DoStringCompareAndBranch(LStringCompareAndBranch* instr) { Condition condition = TokenToCondition(op, false); __ testq(rax, rax); - EmitBranch(true_block, false_block, condition); + EmitBranch(instr, condition); } @@ -2268,15 +2241,10 @@ static Condition BranchCondition(HHasInstanceTypeAndBranch* instr) { void LCodeGen::DoHasInstanceTypeAndBranch(LHasInstanceTypeAndBranch* instr) { Register input = ToRegister(instr->value()); - int true_block = chunk_->LookupDestination(instr->true_block_id()); - int false_block = chunk_->LookupDestination(instr->false_block_id()); - - Label* false_label = chunk_->GetAssemblyLabel(false_block); - - __ JumpIfSmi(input, false_label); + __ JumpIfSmi(input, instr->FalseLabel(chunk_)); __ CmpObjectType(input, TestType(instr->hydrogen()), kScratchRegister); - EmitBranch(true_block, false_block, BranchCondition(instr->hydrogen())); + EmitBranch(instr, BranchCondition(instr->hydrogen())); } @@ -2296,12 +2264,9 @@ void LCodeGen::DoHasCachedArrayIndexAndBranch( LHasCachedArrayIndexAndBranch* instr) { Register input = ToRegister(instr->value()); - int true_block = chunk_->LookupDestination(instr->true_block_id()); - int false_block = chunk_->LookupDestination(instr->false_block_id()); - __ testl(FieldOperand(input, String::kHashFieldOffset), Immediate(String::kContainsCachedArrayIndexMask)); - EmitBranch(true_block, false_block, equal); + EmitBranch(instr, equal); } @@ -2379,25 +2344,18 @@ void LCodeGen::DoClassOfTestAndBranch(LClassOfTestAndBranch* instr) { Register temp2 = ToRegister(instr->temp2()); Handle class_name = instr->hydrogen()->class_name(); - 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); - Label* false_label = chunk_->GetAssemblyLabel(false_block); - - EmitClassOfTest(true_label, false_label, class_name, input, temp, temp2); + EmitClassOfTest(instr->TrueLabel(chunk_), instr->FalseLabel(chunk_), + class_name, input, temp, temp2); - EmitBranch(true_block, false_block, equal); + EmitBranch(instr, equal); } void LCodeGen::DoCmpMapAndBranch(LCmpMapAndBranch* instr) { Register reg = ToRegister(instr->value()); - int true_block = instr->true_block_id(); - int false_block = instr->false_block_id(); __ Cmp(FieldOperand(reg, HeapObject::kMapOffset), instr->map()); - EmitBranch(true_block, false_block, equal); + EmitBranch(instr, equal); } @@ -5347,15 +5305,12 @@ void LCodeGen::EmitPushTaggedOperand(LOperand* operand) { void LCodeGen::DoTypeofIsAndBranch(LTypeofIsAndBranch* instr) { Register input = ToRegister(instr->value()); - 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); - Label* false_label = chunk_->GetAssemblyLabel(false_block); Condition final_branch_condition = - EmitTypeofIs(true_label, false_label, input, instr->type_literal()); + EmitTypeofIs(instr->TrueLabel(chunk_), + instr->FalseLabel(chunk_), input, instr->type_literal()); if (final_branch_condition != no_condition) { - EmitBranch(true_block, false_block, final_branch_condition); + EmitBranch(instr, final_branch_condition); } } @@ -5438,11 +5393,9 @@ Condition LCodeGen::EmitTypeofIs(Label* true_label, void LCodeGen::DoIsConstructCallAndBranch(LIsConstructCallAndBranch* instr) { Register temp = ToRegister(instr->temp()); - int true_block = chunk_->LookupDestination(instr->true_block_id()); - int false_block = chunk_->LookupDestination(instr->false_block_id()); EmitIsConstructCall(temp); - EmitBranch(true_block, false_block, equal); + EmitBranch(instr, equal); } diff --git a/src/x64/lithium-codegen-x64.h b/src/x64/lithium-codegen-x64.h index b0114d0..116f875 100644 --- a/src/x64/lithium-codegen-x64.h +++ b/src/x64/lithium-codegen-x64.h @@ -79,7 +79,6 @@ class LCodeGen BASE_EMBEDDED { Heap* heap() const { return isolate()->heap(); } Zone* zone() const { return zone_; } - // TODO(svenpanne) Use this consistently. int LookupDestination(int block_id) const { return chunk()->LookupDestination(block_id); } @@ -283,7 +282,8 @@ class LCodeGen BASE_EMBEDDED { static Condition TokenToCondition(Token::Value op, bool is_unsigned); void EmitGoto(int block); - void EmitBranch(int left_block, int right_block, Condition cc); + template + void EmitBranch(InstrType instr, Condition cc); void EmitNumberUntagD( Register input, XMMRegister result, diff --git a/src/x64/lithium-x64.h b/src/x64/lithium-x64.h index 94efc29..c1a4817 100644 --- a/src/x64/lithium-x64.h +++ b/src/x64/lithium-x64.h @@ -490,17 +490,44 @@ class LUnknownOSRValue: public LTemplateInstruction<1, 0, 0> { template class LControlInstruction: public LTemplateInstruction<0, I, T> { public: + LControlInstruction() : false_label_(NULL), true_label_(NULL) { } + virtual bool IsControl() const { return true; } int SuccessorCount() { return hydrogen()->SuccessorCount(); } HBasicBlock* SuccessorAt(int i) { return hydrogen()->SuccessorAt(i); } - int true_block_id() { return hydrogen()->SuccessorAt(0)->block_id(); } - int false_block_id() { return hydrogen()->SuccessorAt(1)->block_id(); } + + int TrueDestination(LChunk* chunk) { + return chunk->LookupDestination(true_block_id()); + } + int FalseDestination(LChunk* chunk) { + return chunk->LookupDestination(false_block_id()); + } + + Label* TrueLabel(LChunk* chunk) { + if (true_label_ == NULL) { + true_label_ = chunk->GetAssemblyLabel(TrueDestination(chunk)); + } + return true_label_; + } + Label* FalseLabel(LChunk* chunk) { + if (false_label_ == NULL) { + false_label_ = chunk->GetAssemblyLabel(FalseDestination(chunk)); + } + return false_label_; + } + + protected: + int true_block_id() { return SuccessorAt(0)->block_id(); } + int false_block_id() { return SuccessorAt(1)->block_id(); } private: HControlInstruction* hydrogen() { return HControlInstruction::cast(this->hydrogen_value()); } + + Label* false_label_; + Label* true_label_; }; @@ -1191,7 +1218,7 @@ class LDebugBreak: public LTemplateInstruction<0, 0, 0> { }; -class LCmpMapAndBranch: public LTemplateInstruction<0, 1, 0> { +class LCmpMapAndBranch: public LControlInstruction<1, 0> { public: explicit LCmpMapAndBranch(LOperand* value) { inputs_[0] = value; @@ -1202,15 +1229,7 @@ class LCmpMapAndBranch: public LTemplateInstruction<0, 1, 0> { DECLARE_CONCRETE_INSTRUCTION(CmpMapAndBranch, "cmp-map-and-branch") DECLARE_HYDROGEN_ACCESSOR(CompareMap) - virtual bool IsControl() const { return true; } - Handle map() const { return hydrogen()->map(); } - int true_block_id() const { - return hydrogen()->FirstSuccessor()->block_id(); - } - int false_block_id() const { - return hydrogen()->SecondSuccessor()->block_id(); - } }; -- 2.7.4