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:
parent
345cc98a25
commit
bd50e6d38f
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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 {
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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];
|
||||
|
@ -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();
|
||||
|
@ -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()) {
|
||||
|
@ -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);
|
||||
|
@ -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());
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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());
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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 {
|
||||
|
@ -15827,6 +15827,7 @@ Type* PropertyCell::type() {
|
||||
|
||||
|
||||
void PropertyCell::set_type(Type* type, WriteBarrierMode ignored) {
|
||||
ASSERT(IsPropertyCell());
|
||||
set_type_raw(type, ignored);
|
||||
}
|
||||
|
||||
|
@ -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());
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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 {
|
||||
|
@ -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.
|
||||
|
Loading…
Reference in New Issue
Block a user