Refactoring and cleanup of control instructions

R=mstarzinger@chromium.org

Review URL: https://codereview.chromium.org/18331004

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@15513 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
danno@chromium.org 2013-07-05 10:40:14 +00:00
parent 345cc98a25
commit bd50e6d38f
19 changed files with 132 additions and 155 deletions

View File

@ -182,7 +182,7 @@ void LBranch::PrintDataTo(StringStream* stream) {
}
void LCmpIDAndBranch::PrintDataTo(StringStream* stream) {
void LCompareNumericAndBranch::PrintDataTo(StringStream* stream) {
stream->Add("if ");
left()->PrintTo(stream);
stream->Add(" %s ", Token::String(op()));
@ -1685,8 +1685,8 @@ LInstruction* LChunkBuilder::DoCompareGeneric(HCompareGeneric* instr) {
}
LInstruction* LChunkBuilder::DoCompareIDAndBranch(
HCompareIDAndBranch* instr) {
LInstruction* LChunkBuilder::DoCompareNumericAndBranch(
HCompareNumericAndBranch* instr) {
Representation r = instr->representation();
if (r.IsSmiOrInteger32()) {
ASSERT(instr->left()->representation().IsSmiOrInteger32());
@ -1694,14 +1694,14 @@ LInstruction* LChunkBuilder::DoCompareIDAndBranch(
instr->right()->representation()));
LOperand* left = UseRegisterOrConstantAtStart(instr->left());
LOperand* right = UseRegisterOrConstantAtStart(instr->right());
return new(zone()) LCmpIDAndBranch(left, right);
return new(zone()) LCompareNumericAndBranch(left, right);
} else {
ASSERT(r.IsDouble());
ASSERT(instr->left()->representation().IsDouble());
ASSERT(instr->right()->representation().IsDouble());
LOperand* left = UseRegisterAtStart(instr->left());
LOperand* right = UseRegisterAtStart(instr->right());
return new(zone()) LCmpIDAndBranch(left, right);
return new(zone()) LCompareNumericAndBranch(left, right);
}
}

View File

@ -81,7 +81,7 @@ class LCodeGen;
V(ClampTToUint8) \
V(ClassOfTestAndBranch) \
V(CmpConstantEqAndBranch) \
V(CmpIDAndBranch) \
V(CompareNumericAndBranch) \
V(CmpObjectEqAndBranch) \
V(CmpMapAndBranch) \
V(CmpT) \
@ -720,9 +720,9 @@ class LDebugBreak: public LTemplateInstruction<0, 0, 0> {
};
class LCmpIDAndBranch: public LControlInstruction<2, 0> {
class LCompareNumericAndBranch: public LControlInstruction<2, 0> {
public:
LCmpIDAndBranch(LOperand* left, LOperand* right) {
LCompareNumericAndBranch(LOperand* left, LOperand* right) {
inputs_[0] = left;
inputs_[1] = right;
}
@ -730,8 +730,9 @@ class LCmpIDAndBranch: public LControlInstruction<2, 0> {
LOperand* left() { return inputs_[0]; }
LOperand* right() { return inputs_[1]; }
DECLARE_CONCRETE_INSTRUCTION(CmpIDAndBranch, "cmp-id-and-branch")
DECLARE_HYDROGEN_ACCESSOR(CompareIDAndBranch)
DECLARE_CONCRETE_INSTRUCTION(CompareNumericAndBranch,
"compare-numeric-and-branch")
DECLARE_HYDROGEN_ACCESSOR(CompareNumericAndBranch)
Token::Value op() const { return hydrogen()->token(); }
bool is_double() const {

View File

@ -2348,7 +2348,7 @@ Condition LCodeGen::TokenToCondition(Token::Value op, bool is_unsigned) {
}
void LCodeGen::DoCmpIDAndBranch(LCmpIDAndBranch* instr) {
void LCodeGen::DoCompareNumericAndBranch(LCompareNumericAndBranch* instr) {
LOperand* left = instr->left();
LOperand* right = instr->right();
Condition cond = TokenToCondition(instr->op(), false);

View File

@ -329,7 +329,7 @@ HValue* CodeStubGraphBuilder<FastCloneShallowArrayStub>::BuildCodeStub() {
HValue* elements = AddLoadElements(boilerplate);
IfBuilder if_fixed_cow(this);
if_fixed_cow.IfCompareMap(elements, factory->fixed_cow_array_map());
if_fixed_cow.If<HCompareMap>(elements, factory->fixed_cow_array_map());
if_fixed_cow.Then();
environment()->Push(BuildCloneShallowArray(context(),
boilerplate,
@ -339,7 +339,7 @@ HValue* CodeStubGraphBuilder<FastCloneShallowArrayStub>::BuildCodeStub() {
if_fixed_cow.Else();
IfBuilder if_fixed(this);
if_fixed.IfCompareMap(elements, factory->fixed_array_map());
if_fixed.If<HCompareMap>(elements, factory->fixed_array_map());
if_fixed.Then();
environment()->Push(BuildCloneShallowArray(context(),
boilerplate,
@ -392,7 +392,8 @@ HValue* CodeStubGraphBuilder<FastCloneShallowObjectStub>::BuildCodeStub() {
AddInstruction(new(zone) HInstanceSize(boilerplate));
HValue* size_in_words =
AddInstruction(new(zone) HConstant(size >> kPointerSizeLog2));
checker.IfCompare(boilerplate_size, size_in_words, Token::EQ);
checker.If<HCompareNumericAndBranch>(boilerplate_size,
size_in_words, Token::EQ);
checker.Then();
HValue* size_in_bytes = AddInstruction(new(zone) HConstant(size));
@ -501,7 +502,9 @@ HValue* CodeStubGraphBuilder<TransitionElementsKindStub>::BuildCodeStub() {
IfBuilder if_builder(this);
if_builder.IfCompare(array_length, graph()->GetConstant0(), Token::EQ);
if_builder.If<HCompareNumericAndBranch>(array_length,
graph()->GetConstant0(),
Token::EQ);
if_builder.Then();
// Nothing to do, just change the map.
@ -606,7 +609,8 @@ HValue* CodeStubGraphBuilderBase::BuildArraySingleArgumentConstructor(
HBoundsCheck* checked_arg = Add<HBoundsCheck>(argument, max_alloc_length);
IfBuilder if_builder(this);
if_builder.IfCompare(checked_arg, constant_zero, Token::EQ);
if_builder.If<HCompareNumericAndBranch>(checked_arg, constant_zero,
Token::EQ);
if_builder.Then();
Push(initial_capacity_node); // capacity
Push(constant_zero); // length
@ -838,10 +842,11 @@ HValue* CodeStubGraphBuilder<StoreGlobalStub>::BuildCodeInitializedStub() {
set_current_block(NULL);
} else {
HValue* cell = Add<HConstant>(placeholder_cell, Representation::Tagged());
// Check that the map of the global has not changed.
AddInstruction(HCheckMaps::New(receiver,
Handle<Map>(isolate()->heap()->meta_map()),
zone()));
// Check that the map of the global has not changed: use a placeholder map
// that will be replaced later with the global object's map.
Handle<Map> placeholder_map = isolate()->factory()->meta_map();
AddInstruction(HCheckMaps::New(receiver, placeholder_map, zone()));
// Load the payload of the global parameter cell. A hole indicates that the
// property has been deleted and that the store must be handled by the

View File

@ -2558,7 +2558,7 @@ void HStringCompareAndBranch::PrintDataTo(StringStream* stream) {
}
void HCompareIDAndBranch::AddInformativeDefinitions() {
void HCompareNumericAndBranch::AddInformativeDefinitions() {
NumericRelation r = NumericRelation::FromToken(token());
if (r.IsNone()) return;
@ -2568,7 +2568,7 @@ void HCompareIDAndBranch::AddInformativeDefinitions() {
}
void HCompareIDAndBranch::PrintDataTo(StringStream* stream) {
void HCompareNumericAndBranch::PrintDataTo(StringStream* stream) {
stream->Add(Token::Name(token()));
stream->Add(" ");
left()->PrintNameTo(stream);
@ -2591,7 +2591,7 @@ void HGoto::PrintDataTo(StringStream* stream) {
}
void HCompareIDAndBranch::InferRepresentation(
void HCompareNumericAndBranch::InferRepresentation(
HInferRepresentationPhase* h_infer) {
Representation left_rep = left()->representation();
Representation right_rep = right()->representation();
@ -2613,9 +2613,9 @@ void HCompareIDAndBranch::InferRepresentation(
// and !=) have special handling of undefined, e.g. undefined == undefined
// is 'true'. Relational comparisons have a different semantic, first
// calling ToPrimitive() on their arguments. The standard Crankshaft
// tagged-to-double conversion to ensure the HCompareIDAndBranch's inputs
// are doubles caused 'undefined' to be converted to NaN. That's compatible
// out-of-the box with ordered relational comparisons (<, >, <=,
// tagged-to-double conversion to ensure the HCompareNumericAndBranch's
// inputs are doubles caused 'undefined' to be converted to NaN. That's
// compatible out-of-the box with ordered relational comparisons (<, >, <=,
// >=). However, for equality comparisons (and for 'in' and 'instanceof'),
// it is not consistent with the spec. For example, it would cause undefined
// == undefined (should be true) to be evaluated as NaN == NaN

View File

@ -96,7 +96,7 @@ class LChunkBuilder;
V(CheckPrototypeMaps) \
V(ClampToUint8) \
V(ClassOfTestAndBranch) \
V(CompareIDAndBranch) \
V(CompareNumericAndBranch) \
V(CompareGeneric) \
V(CompareObjectEqAndBranch) \
V(CompareMap) \
@ -1606,21 +1606,11 @@ class HUnaryControlInstruction: public HTemplateControlInstruction<2, 1> {
class HBranch: public HUnaryControlInstruction {
public:
HBranch(HValue* value,
HBasicBlock* true_target,
HBasicBlock* false_target,
ToBooleanStub::Types expected_input_types = ToBooleanStub::Types())
ToBooleanStub::Types expected_input_types = ToBooleanStub::Types(),
HBasicBlock* true_target = NULL,
HBasicBlock* false_target = NULL)
: HUnaryControlInstruction(value, true_target, false_target),
expected_input_types_(expected_input_types) {
ASSERT(true_target != NULL && false_target != NULL);
SetFlag(kAllowUndefinedAsNaN);
}
explicit HBranch(HValue* value)
: HUnaryControlInstruction(value, NULL, NULL) {
SetFlag(kAllowUndefinedAsNaN);
}
HBranch(HValue* value, ToBooleanStub::Types expected_input_types)
: HUnaryControlInstruction(value, NULL, NULL),
expected_input_types_(expected_input_types) {
SetFlag(kAllowUndefinedAsNaN);
}
@ -1644,12 +1634,10 @@ class HCompareMap: public HUnaryControlInstruction {
public:
HCompareMap(HValue* value,
Handle<Map> map,
HBasicBlock* true_target,
HBasicBlock* false_target)
HBasicBlock* true_target = NULL,
HBasicBlock* false_target = NULL)
: HUnaryControlInstruction(value, true_target, false_target),
map_(map) {
ASSERT(true_target != NULL);
ASSERT(false_target != NULL);
map_(map) {
ASSERT(!map.is_null());
}
@ -3960,9 +3948,9 @@ class HCompareGeneric: public HBinaryOperation {
};
class HCompareIDAndBranch: public HTemplateControlInstruction<2, 2> {
class HCompareNumericAndBranch: public HTemplateControlInstruction<2, 2> {
public:
HCompareIDAndBranch(HValue* left, HValue* right, Token::Value token)
HCompareNumericAndBranch(HValue* left, HValue* right, Token::Value token)
: token_(token) {
SetFlag(kFlexibleRepresentation);
ASSERT(Token::IsCompareOp(token));
@ -3992,7 +3980,7 @@ class HCompareIDAndBranch: public HTemplateControlInstruction<2, 2> {
virtual void AddInformativeDefinitions();
DECLARE_CONCRETE_INSTRUCTION(CompareIDAndBranch)
DECLARE_CONCRETE_INSTRUCTION(CompareNumericAndBranch)
private:
Representation observed_input_representation_[2];

View File

@ -63,7 +63,8 @@ HBasicBlock* HOsrBuilder::BuildPossibleOsrLoopEntry(
HBasicBlock* non_osr_entry = graph->CreateBasicBlock();
osr_entry_ = graph->CreateBasicBlock();
HValue* true_value = graph->GetConstantTrue();
HBranch* test = new(zone) HBranch(true_value, non_osr_entry, osr_entry_);
HBranch* test = new(zone) HBranch(true_value, ToBooleanStub::Types(),
non_osr_entry, osr_entry_);
builder_->current_block()->Finish(test);
HBasicBlock* loop_predecessor = graph->CreateBasicBlock();

View File

@ -49,8 +49,9 @@ void HRangeAnalysisPhase::Analyze(HBasicBlock* block) {
// Infer range based on control flow.
if (block->predecessors()->length() == 1) {
HBasicBlock* pred = block->predecessors()->first();
if (pred->end()->IsCompareIDAndBranch()) {
InferControlFlowRange(HCompareIDAndBranch::cast(pred->end()), block);
if (pred->end()->IsCompareNumericAndBranch()) {
InferControlFlowRange(HCompareNumericAndBranch::cast(pred->end()),
block);
}
}
@ -74,7 +75,7 @@ void HRangeAnalysisPhase::Analyze(HBasicBlock* block) {
}
void HRangeAnalysisPhase::InferControlFlowRange(HCompareIDAndBranch* test,
void HRangeAnalysisPhase::InferControlFlowRange(HCompareNumericAndBranch* test,
HBasicBlock* dest) {
ASSERT((test->FirstSuccessor() == dest) == (test->SecondSuccessor() != dest));
if (test->representation().IsSmiOrInteger32()) {

View File

@ -46,7 +46,8 @@ class HRangeAnalysisPhase : public HPhase {
private:
void TraceRange(const char* msg, ...);
void Analyze(HBasicBlock* block);
void InferControlFlowRange(HCompareIDAndBranch* test, HBasicBlock* dest);
void InferControlFlowRange(HCompareNumericAndBranch* test,
HBasicBlock* dest);
void UpdateControlFlowRange(Token::Value op, HValue* value, HValue* other);
void InferRange(HValue* value);
void RollBackTo(int index);

View File

@ -725,26 +725,6 @@ HGraphBuilder::IfBuilder::IfBuilder(
}
HInstruction* HGraphBuilder::IfBuilder::IfCompare(
HValue* left,
HValue* right,
Token::Value token) {
HCompareIDAndBranch* compare =
new(zone()) HCompareIDAndBranch(left, right, token);
AddCompare(compare);
return compare;
}
HInstruction* HGraphBuilder::IfBuilder::IfCompareMap(HValue* left,
Handle<Map> map) {
HCompareMap* compare =
new(zone()) HCompareMap(left, map, first_true_block_, first_false_block_);
AddCompare(compare);
return compare;
}
void HGraphBuilder::IfBuilder::AddCompare(HControlInstruction* compare) {
if (split_edge_merge_block_ != NULL) {
HEnvironment* env = first_false_block_->last_environment();
@ -825,8 +805,8 @@ void HGraphBuilder::IfBuilder::Then() {
ToBooleanStub::Types boolean_type = ToBooleanStub::Types();
boolean_type.Add(ToBooleanStub::BOOLEAN);
HBranch* branch =
new(zone()) HBranch(constant_false, first_true_block_,
first_false_block_, boolean_type);
new(zone()) HBranch(constant_false, boolean_type, first_true_block_,
first_false_block_);
builder_->current_block()->Finish(branch);
}
builder_->set_current_block(first_true_block_);
@ -930,8 +910,8 @@ HValue* HGraphBuilder::LoopBuilder::BeginBody(
body_env->Pop();
builder_->set_current_block(header_block_);
HCompareIDAndBranch* compare =
new(zone()) HCompareIDAndBranch(phi_, terminating, token);
HCompareNumericAndBranch* compare =
new(zone()) HCompareNumericAndBranch(phi_, terminating, token);
compare->SetSuccessorAt(0, body_block_);
compare->SetSuccessorAt(1, exit_block_);
builder_->current_block()->Finish(compare);
@ -1156,14 +1136,15 @@ HValue* HGraphBuilder::BuildCheckForCapacityGrow(HValue* object,
Zone* zone = this->zone();
IfBuilder length_checker(this);
length_checker.IfCompare(length, key, Token::EQ);
length_checker.If<HCompareNumericAndBranch>(length, key, Token::EQ);
length_checker.Then();
HValue* current_capacity = AddLoadFixedArrayLength(elements);
IfBuilder capacity_checker(this);
capacity_checker.IfCompare(length, current_capacity, Token::EQ);
capacity_checker.If<HCompareNumericAndBranch>(length, current_capacity,
Token::EQ);
capacity_checker.Then();
HValue* context = environment()->LookupContext();
@ -1207,12 +1188,11 @@ HValue* HGraphBuilder::BuildCopyElementsOnWrite(HValue* object,
HValue* elements,
ElementsKind kind,
HValue* length) {
Heap* heap = isolate()->heap();
Factory* factory = isolate()->factory();
IfBuilder cow_checker(this);
cow_checker.IfCompareMap(elements,
Handle<Map>(heap->fixed_cow_array_map()));
cow_checker.If<HCompareMap>(elements, factory->fixed_cow_array_map());
cow_checker.Then();
HValue* capacity = AddLoadFixedArrayLength(elements);
@ -1281,10 +1261,10 @@ HInstruction* HGraphBuilder::BuildUncheckedMonomorphicElementAccess(
HLoadExternalArrayPointer* external_elements =
Add<HLoadExternalArrayPointer>(elements);
IfBuilder length_checker(this);
length_checker.IfCompare(key, length, Token::LT);
length_checker.If<HCompareNumericAndBranch>(key, length, Token::LT);
length_checker.Then();
IfBuilder negative_checker(this);
HValue* bounds_check = negative_checker.IfCompare(
HValue* bounds_check = negative_checker.If<HCompareNumericAndBranch>(
key, graph()->GetConstant0(), Token::GTE);
negative_checker.Then();
HInstruction* result = BuildExternalArrayElementAccess(
@ -2980,12 +2960,11 @@ void HGraph::RecursivelyMarkPhiDeoptimizeOnUndefined(HPhi* phi) {
void HGraph::MarkDeoptimizeOnUndefined() {
HPhase phase("H_MarkDeoptimizeOnUndefined", this);
// Compute DeoptimizeOnUndefined flag for phis.
// Any phi that can reach a use with DeoptimizeOnUndefined set must
// have DeoptimizeOnUndefined set. Currently only HCompareIDAndBranch, with
// double input representation, has this flag set.
// The flag is used by HChange tagged->double, which must deoptimize
// if one of its uses has this flag set.
// Compute DeoptimizeOnUndefined flag for phis. Any phi that can reach a use
// with DeoptimizeOnUndefined set must have DeoptimizeOnUndefined set.
// Currently only HCompareNumericAndBranch, with double input representation,
// has this flag set. The flag is used by HChange tagged->double, which must
// deoptimize if one of its uses has this flag set.
for (int i = 0; i < phi_list()->length(); i++) {
HPhi* phi = phi_list()->at(i);
for (HUseIterator it(phi->uses()); !it.Done(); it.Advance()) {
@ -3286,7 +3265,7 @@ void TestContext::BuildBranch(HValue* value) {
HBasicBlock* empty_true = builder->graph()->CreateBasicBlock();
HBasicBlock* empty_false = builder->graph()->CreateBasicBlock();
ToBooleanStub::Types expected(condition()->to_boolean_types());
HBranch* test = new(zone()) HBranch(value, empty_true, empty_false, expected);
HBranch* test = new(zone()) HBranch(value, expected, empty_true, empty_false);
builder->current_block()->Finish(test);
empty_true->Goto(if_true(), builder->function_state());
@ -4488,10 +4467,10 @@ void HOptimizedGraphBuilder::VisitSwitchStatement(SwitchStatement* stmt) {
AddSoftDeoptimize();
}
HCompareIDAndBranch* compare_ =
new(zone()) HCompareIDAndBranch(tag_value,
label_value,
Token::EQ_STRICT);
HCompareNumericAndBranch* compare_ =
new(zone()) HCompareNumericAndBranch(tag_value,
label_value,
Token::EQ_STRICT);
compare_->set_observed_input_representation(
Representation::Smi(), Representation::Smi());
compare = compare_;
@ -4775,8 +4754,8 @@ void HOptimizedGraphBuilder::VisitForInStatement(ForInStatement* stmt) {
HValue* limit = environment()->ExpressionStackAt(1);
// Check that we still have more keys.
HCompareIDAndBranch* compare_index =
new(zone()) HCompareIDAndBranch(index, limit, Token::LT);
HCompareNumericAndBranch* compare_index =
new(zone()) HCompareNumericAndBranch(index, limit, Token::LT);
compare_index->set_observed_input_representation(
Representation::Smi(), Representation::Smi());
@ -5835,7 +5814,7 @@ void HOptimizedGraphBuilder::HandlePolymorphicStoreNamedField(
HBasicBlock* if_true = graph()->CreateBasicBlock();
HBasicBlock* if_false = graph()->CreateBasicBlock();
HCompareMap* compare =
new(zone()) HCompareMap(object, map, if_true, if_false);
new(zone()) HCompareMap(object, map, if_true, if_false);
current_block()->Finish(compare);
set_current_block(if_true);
@ -5940,7 +5919,7 @@ void HOptimizedGraphBuilder::HandleGlobalVariableAssignment(
IfBuilder builder(this);
HValue* constant = Add<HConstant>(cell->type()->AsConstant());
if (cell->type()->AsConstant()->IsNumber()) {
builder.IfCompare(value, constant, Token::EQ);
builder.If<HCompareNumericAndBranch>(value, constant, Token::EQ);
} else {
builder.If<HCompareObjectEqAndBranch>(value, constant);
}
@ -8913,8 +8892,8 @@ void HOptimizedGraphBuilder::VisitLogicalExpression(BinaryOperation* expr) {
HBasicBlock* eval_right = graph()->CreateBasicBlock();
ToBooleanStub::Types expected(expr->left()->to_boolean_types());
HBranch* test = is_logical_and
? new(zone()) HBranch(left_value, eval_right, empty_block, expected)
: new(zone()) HBranch(left_value, empty_block, eval_right, expected);
? new(zone()) HBranch(left_value, expected, eval_right, empty_block)
: new(zone()) HBranch(left_value, expected, empty_block, eval_right);
current_block()->Finish(test);
set_current_block(eval_right);
@ -9207,8 +9186,8 @@ void HOptimizedGraphBuilder::VisitCompareOperation(CompareOperation* expr) {
// returns Smi when the IC measures Smi.
if (left_type->Is(Type::Smi())) left_rep = Representation::Smi();
if (right_type->Is(Type::Smi())) right_rep = Representation::Smi();
HCompareIDAndBranch* result =
new(zone()) HCompareIDAndBranch(left, right, op);
HCompareNumericAndBranch* result =
new(zone()) HCompareNumericAndBranch(left, right, op);
result->set_observed_input_representation(left_rep, right_rep);
result->set_position(expr->position());
return ast_context()->ReturnControl(result, expr->id());

View File

@ -1151,13 +1151,6 @@ class HGraphBuilder {
if (!finished_) End();
}
HInstruction* IfCompare(
HValue* left,
HValue* right,
Token::Value token);
HInstruction* IfCompareMap(HValue* left, Handle<Map> map);
template<class Condition>
HInstruction* If(HValue *p) {
HControlInstruction* compare = new(zone()) Condition(p);
@ -1172,6 +1165,13 @@ class HGraphBuilder {
return compare;
}
template<class Condition, class P2, class P3>
HInstruction* If(HValue* p1, P2 p2, P3 p3) {
HControlInstruction* compare = new(zone()) Condition(p1, p2, p3);
AddCompare(compare);
return compare;
}
template<class Condition, class P2>
HInstruction* IfNot(HValue* p1, P2 p2) {
HControlInstruction* compare = new(zone()) Condition(p1, p2);
@ -1183,17 +1183,15 @@ class HGraphBuilder {
return compare;
}
HInstruction* OrIfCompare(
HValue* p1,
HValue* p2,
Token::Value token) {
Or();
return IfCompare(p1, p2, token);
}
HInstruction* OrIfCompareMap(HValue* left, Handle<Map> map) {
Or();
return IfCompareMap(left, map);
template<class Condition, class P2, class P3>
HInstruction* IfNot(HValue* p1, P2 p2, P3 p3) {
HControlInstruction* compare = new(zone()) Condition(p1, p2, p3);
AddCompare(compare);
HBasicBlock* block0 = compare->SuccessorAt(0);
HBasicBlock* block1 = compare->SuccessorAt(1);
compare->SetSuccessorAt(0, block1);
compare->SetSuccessorAt(1, block0);
return compare;
}
template<class Condition>
@ -1208,17 +1206,10 @@ class HGraphBuilder {
return If<Condition>(p1, p2);
}
HInstruction* AndIfCompare(
HValue* p1,
HValue* p2,
Token::Value token) {
And();
return IfCompare(p1, p2, token);
}
HInstruction* AndIfCompareMap(HValue* left, Handle<Map> map) {
And();
return IfCompareMap(left, map);
template<class Condition, class P2, class P3>
HInstruction* OrIf(HValue* p1, P2 p2, P3 p3) {
Or();
return If<Condition>(p1, p2, p3);
}
template<class Condition>
@ -1233,6 +1224,12 @@ class HGraphBuilder {
return If<Condition>(p1, p2);
}
template<class Condition, class P2, class P3>
HInstruction* AndIf(HValue* p1, P2 p2, P3 p3) {
And();
return If<Condition>(p1, p2, p3);
}
void Or();
void And();

View File

@ -2285,7 +2285,7 @@ Condition LCodeGen::TokenToCondition(Token::Value op, bool is_unsigned) {
}
void LCodeGen::DoCmpIDAndBranch(LCmpIDAndBranch* instr) {
void LCodeGen::DoCompareNumericAndBranch(LCompareNumericAndBranch* instr) {
LOperand* left = instr->left();
LOperand* right = instr->right();
Condition cc = TokenToCondition(instr->op(), instr->is_double());

View File

@ -201,7 +201,7 @@ void LBranch::PrintDataTo(StringStream* stream) {
}
void LCmpIDAndBranch::PrintDataTo(StringStream* stream) {
void LCompareNumericAndBranch::PrintDataTo(StringStream* stream) {
stream->Add("if ");
left()->PrintTo(stream);
stream->Add(" %s ", Token::String(op()));
@ -1705,8 +1705,8 @@ LInstruction* LChunkBuilder::DoCompareGeneric(HCompareGeneric* instr) {
}
LInstruction* LChunkBuilder::DoCompareIDAndBranch(
HCompareIDAndBranch* instr) {
LInstruction* LChunkBuilder::DoCompareNumericAndBranch(
HCompareNumericAndBranch* instr) {
Representation r = instr->representation();
if (r.IsSmiOrInteger32()) {
ASSERT(instr->left()->representation().IsSmiOrInteger32());
@ -1714,7 +1714,7 @@ LInstruction* LChunkBuilder::DoCompareIDAndBranch(
instr->right()->representation()));
LOperand* left = UseRegisterOrConstantAtStart(instr->left());
LOperand* right = UseOrConstantAtStart(instr->right());
return new(zone()) LCmpIDAndBranch(left, right);
return new(zone()) LCompareNumericAndBranch(left, right);
} else {
ASSERT(r.IsDouble());
ASSERT(instr->left()->representation().IsDouble());
@ -1728,7 +1728,7 @@ LInstruction* LChunkBuilder::DoCompareIDAndBranch(
left = UseRegisterAtStart(instr->left());
right = UseRegisterAtStart(instr->right());
}
return new(zone()) LCmpIDAndBranch(left, right);
return new(zone()) LCompareNumericAndBranch(left, right);
}
}

View File

@ -75,7 +75,7 @@ class LCodeGen;
V(ClampTToUint8) \
V(ClampTToUint8NoSSE2) \
V(ClassOfTestAndBranch) \
V(CmpIDAndBranch) \
V(CompareNumericAndBranch) \
V(CmpObjectEqAndBranch) \
V(CmpMapAndBranch) \
V(CmpT) \
@ -690,9 +690,9 @@ class LMulI: public LTemplateInstruction<1, 2, 1> {
};
class LCmpIDAndBranch: public LControlInstruction<2, 0> {
class LCompareNumericAndBranch: public LControlInstruction<2, 0> {
public:
LCmpIDAndBranch(LOperand* left, LOperand* right) {
LCompareNumericAndBranch(LOperand* left, LOperand* right) {
inputs_[0] = left;
inputs_[1] = right;
}
@ -700,8 +700,9 @@ class LCmpIDAndBranch: public LControlInstruction<2, 0> {
LOperand* left() { return inputs_[0]; }
LOperand* right() { return inputs_[1]; }
DECLARE_CONCRETE_INSTRUCTION(CmpIDAndBranch, "cmp-id-and-branch")
DECLARE_HYDROGEN_ACCESSOR(CompareIDAndBranch)
DECLARE_CONCRETE_INSTRUCTION(CompareNumericAndBranch,
"compare-numeric-and-branch")
DECLARE_HYDROGEN_ACCESSOR(CompareNumericAndBranch)
Token::Value op() const { return hydrogen()->token(); }
bool is_double() const {

View File

@ -15827,6 +15827,7 @@ Type* PropertyCell::type() {
void PropertyCell::set_type(Type* type, WriteBarrierMode ignored) {
ASSERT(IsPropertyCell());
set_type_raw(type, ignored);
}

View File

@ -2046,7 +2046,7 @@ inline Condition LCodeGen::TokenToCondition(Token::Value op, bool is_unsigned) {
}
void LCodeGen::DoCmpIDAndBranch(LCmpIDAndBranch* instr) {
void LCodeGen::DoCompareNumericAndBranch(LCompareNumericAndBranch* instr) {
LOperand* left = instr->left();
LOperand* right = instr->right();
Condition cc = TokenToCondition(instr->op(), instr->is_double());

View File

@ -185,7 +185,7 @@ void LBranch::PrintDataTo(StringStream* stream) {
}
void LCmpIDAndBranch::PrintDataTo(StringStream* stream) {
void LCompareNumericAndBranch::PrintDataTo(StringStream* stream) {
stream->Add("if ");
left()->PrintTo(stream);
stream->Add(" %s ", Token::String(op()));
@ -1599,8 +1599,8 @@ LInstruction* LChunkBuilder::DoCompareGeneric(HCompareGeneric* instr) {
}
LInstruction* LChunkBuilder::DoCompareIDAndBranch(
HCompareIDAndBranch* instr) {
LInstruction* LChunkBuilder::DoCompareNumericAndBranch(
HCompareNumericAndBranch* instr) {
Representation r = instr->representation();
if (r.IsSmiOrInteger32()) {
ASSERT(instr->left()->representation().IsSmiOrInteger32());
@ -1608,7 +1608,7 @@ LInstruction* LChunkBuilder::DoCompareIDAndBranch(
instr->right()->representation()));
LOperand* left = UseRegisterOrConstantAtStart(instr->left());
LOperand* right = UseOrConstantAtStart(instr->right());
return new(zone()) LCmpIDAndBranch(left, right);
return new(zone()) LCompareNumericAndBranch(left, right);
} else {
ASSERT(r.IsDouble());
ASSERT(instr->left()->representation().IsDouble());
@ -1622,7 +1622,7 @@ LInstruction* LChunkBuilder::DoCompareIDAndBranch(
left = UseRegisterAtStart(instr->left());
right = UseRegisterAtStart(instr->right());
}
return new(zone()) LCmpIDAndBranch(left, right);
return new(zone()) LCompareNumericAndBranch(left, right);
}
}

View File

@ -81,7 +81,7 @@ class LCodeGen;
V(ClampTToUint8) \
V(ClassOfTestAndBranch) \
V(CmpConstantEqAndBranch) \
V(CmpIDAndBranch) \
V(CompareNumericAndBranch) \
V(CmpObjectEqAndBranch) \
V(CmpMapAndBranch) \
V(CmpT) \
@ -673,9 +673,9 @@ class LMulI: public LTemplateInstruction<1, 2, 0> {
};
class LCmpIDAndBranch: public LControlInstruction<2, 0> {
class LCompareNumericAndBranch: public LControlInstruction<2, 0> {
public:
LCmpIDAndBranch(LOperand* left, LOperand* right) {
LCompareNumericAndBranch(LOperand* left, LOperand* right) {
inputs_[0] = left;
inputs_[1] = right;
}
@ -683,8 +683,9 @@ class LCmpIDAndBranch: public LControlInstruction<2, 0> {
LOperand* left() { return inputs_[0]; }
LOperand* right() { return inputs_[1]; }
DECLARE_CONCRETE_INSTRUCTION(CmpIDAndBranch, "cmp-id-and-branch")
DECLARE_HYDROGEN_ACCESSOR(CompareIDAndBranch)
DECLARE_CONCRETE_INSTRUCTION(CompareNumericAndBranch,
"compare-numeric-and-branch")
DECLARE_HYDROGEN_ACCESSOR(CompareNumericAndBranch)
Token::Value op() const { return hydrogen()->token(); }
bool is_double() const {

View File

@ -31,7 +31,8 @@ var large_int = 0x40000000;
function foo(x, expected) {
assertEquals(expected, x); // This succeeds.
x += 0; // Force int32 representation so that CompareIDAndBranch is used.
x += 0; // Force int32 representation so that
// CompareNumericAndBranch is used.
if (3 != x) {
x += 0; // Poor man's "iDef".
// Fails due to Smi-tagging without overflow check.