Commit d04ba1b2 authored by vegorov@chromium.org's avatar vegorov@chromium.org

Improve representation inference

- Extend HValue interface to allow splitting observed input representation (comming from type feedback) from required input representation (dictated by instruction itself). Currently all instructions except for bitwise binary operations have this representations match. For bitwise binary operations hydrogen builder unconditionaly forces Integer32 representation for those operations that have Double type feedback. Thus causing representation inference to incorrectly count such uses as Integer32 instead of Double. This change also prepares for more fine grained type feedback for inputs of binary operations.

- For phies that are not convertable to Integer32 discard direct and indirect use count of Integer32 type to avoid propagation of these uses to connected phies.

R=jkummerow@chromium.org
BUG=v8:2096

Review URL: https://chromiumcodereview.appspot.com/10540049

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@11737 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 128f426e
...@@ -1298,14 +1298,33 @@ void HPhi::InitRealUses(int phi_id) { ...@@ -1298,14 +1298,33 @@ void HPhi::InitRealUses(int phi_id) {
for (HUseIterator it(uses()); !it.Done(); it.Advance()) { for (HUseIterator it(uses()); !it.Done(); it.Advance()) {
HValue* value = it.value(); HValue* value = it.value();
if (!value->IsPhi()) { if (!value->IsPhi()) {
Representation rep = value->RequiredInputRepresentation(it.index()); Representation rep = value->ObservedInputRepresentation(it.index());
non_phi_uses_[rep.kind()] += value->LoopWeight(); non_phi_uses_[rep.kind()] += value->LoopWeight();
if (FLAG_trace_representation) {
PrintF("%d %s is used by %d %s as %s\n",
this->id(),
this->Mnemonic(),
value->id(),
value->Mnemonic(),
rep.Mnemonic());
}
} }
} }
} }
void HPhi::AddNonPhiUsesFrom(HPhi* other) { void HPhi::AddNonPhiUsesFrom(HPhi* other) {
if (FLAG_trace_representation) {
PrintF("adding to %d %s uses of %d %s: i%d d%d t%d\n",
this->id(),
this->Mnemonic(),
other->id(),
other->Mnemonic(),
other->non_phi_uses_[Representation::kInteger32],
other->non_phi_uses_[Representation::kDouble],
other->non_phi_uses_[Representation::kTagged]);
}
for (int i = 0; i < Representation::kNumRepresentations; i++) { for (int i = 0; i < Representation::kNumRepresentations; i++) {
indirect_uses_[i] += other->non_phi_uses_[i]; indirect_uses_[i] += other->non_phi_uses_[i];
} }
...@@ -1319,6 +1338,12 @@ void HPhi::AddIndirectUsesTo(int* dest) { ...@@ -1319,6 +1338,12 @@ void HPhi::AddIndirectUsesTo(int* dest) {
} }
void HPhi::ResetInteger32Uses() {
non_phi_uses_[Representation::kInteger32] = 0;
indirect_uses_[Representation::kInteger32] = 0;
}
void HSimulate::PrintDataTo(StringStream* stream) { void HSimulate::PrintDataTo(StringStream* stream) {
stream->Add("id=%d", ast_id()); stream->Add("id=%d", ast_id());
if (pop_count_ > 0) stream->Add(" pop %d", pop_count_); if (pop_count_ > 0) stream->Add(" pop %d", pop_count_);
......
...@@ -720,6 +720,11 @@ class HValue: public ZoneObject { ...@@ -720,6 +720,11 @@ class HValue: public ZoneObject {
return representation(); return representation();
} }
// Type feedback access.
virtual Representation ObservedInputRepresentation(int index) {
return RequiredInputRepresentation(index);
}
// This gives the instruction an opportunity to replace itself with an // This gives the instruction an opportunity to replace itself with an
// instruction that does the same in some better way. To replace an // instruction that does the same in some better way. To replace an
// instruction with a new one, first add the new instruction to the graph, // instruction with a new one, first add the new instruction to the graph,
...@@ -2402,11 +2407,15 @@ class HPhi: public HValue { ...@@ -2402,11 +2407,15 @@ class HPhi: public HValue {
bool AllOperandsConvertibleToInteger() { bool AllOperandsConvertibleToInteger() {
for (int i = 0; i < OperandCount(); ++i) { for (int i = 0; i < OperandCount(); ++i) {
if (!OperandAt(i)->IsConvertibleToInteger()) return false; if (!OperandAt(i)->IsConvertibleToInteger()) {
return false;
}
} }
return true; return true;
} }
void ResetInteger32Uses();
protected: protected:
virtual void DeleteFromGraph(); virtual void DeleteFromGraph();
virtual void InternalSetOperandAt(int index, HValue* value) { virtual void InternalSetOperandAt(int index, HValue* value) {
...@@ -2556,6 +2565,7 @@ class HBinaryOperation: public HTemplateInstruction<3> { ...@@ -2556,6 +2565,7 @@ class HBinaryOperation: public HTemplateInstruction<3> {
if (IsCommutative() && left()->IsConstant()) return right(); if (IsCommutative() && left()->IsConstant()) return right();
return left(); return left();
} }
HValue* MostConstantOperand() { HValue* MostConstantOperand() {
if (IsCommutative() && left()->IsConstant()) return left(); if (IsCommutative() && left()->IsConstant()) return left();
return right(); return right();
...@@ -2721,6 +2731,9 @@ class HBitwiseBinaryOperation: public HBinaryOperation { ...@@ -2721,6 +2731,9 @@ class HBitwiseBinaryOperation: public HBinaryOperation {
set_representation(Representation::Tagged()); set_representation(Representation::Tagged());
SetFlag(kFlexibleRepresentation); SetFlag(kFlexibleRepresentation);
SetAllSideEffects(); SetAllSideEffects();
observed_input_representation_[0] = Representation::Tagged();
observed_input_representation_[1] = Representation::None();
observed_input_representation_[2] = Representation::None();
} }
virtual Representation RequiredInputRepresentation(int index) { virtual Representation RequiredInputRepresentation(int index) {
...@@ -2740,7 +2753,19 @@ class HBitwiseBinaryOperation: public HBinaryOperation { ...@@ -2740,7 +2753,19 @@ class HBitwiseBinaryOperation: public HBinaryOperation {
virtual HType CalculateInferredType(); virtual HType CalculateInferredType();
virtual Representation ObservedInputRepresentation(int index) {
return observed_input_representation_[index];
}
void InitializeObservedInputRepresentation(Representation r) {
observed_input_representation_[1] = r;
observed_input_representation_[2] = r;
}
DECLARE_ABSTRACT_INSTRUCTION(BitwiseBinaryOperation) DECLARE_ABSTRACT_INSTRUCTION(BitwiseBinaryOperation)
private:
Representation observed_input_representation_[3];
}; };
......
...@@ -2140,8 +2140,16 @@ Representation HInferRepresentation::TryChange(HValue* value) { ...@@ -2140,8 +2140,16 @@ Representation HInferRepresentation::TryChange(HValue* value) {
for (HUseIterator it(value->uses()); !it.Done(); it.Advance()) { for (HUseIterator it(value->uses()); !it.Done(); it.Advance()) {
HValue* use = it.value(); HValue* use = it.value();
Representation rep = use->RequiredInputRepresentation(it.index()); Representation rep = use->ObservedInputRepresentation(it.index());
if (rep.IsNone()) continue; if (rep.IsNone()) continue;
if (FLAG_trace_representation) {
PrintF("%d %s is used by %d %s as %s\n",
value->id(),
value->Mnemonic(),
use->id(),
use->Mnemonic(),
rep.Mnemonic());
}
if (use->IsPhi()) HPhi::cast(use)->AddIndirectUsesTo(&use_count[0]); if (use->IsPhi()) HPhi::cast(use)->AddIndirectUsesTo(&use_count[0]);
use_count[rep.kind()] += use->LoopWeight(); use_count[rep.kind()] += use->LoopWeight();
} }
...@@ -2205,21 +2213,34 @@ void HInferRepresentation::Analyze() { ...@@ -2205,21 +2213,34 @@ void HInferRepresentation::Analyze() {
} }
} }
// (3) Use the phi reachability information from step 2 to // (3a) Use the phi reachability information from step 2 to
// (a) sum up the non-phi use counts of all connected phis. // push information about values which can't be converted to integer
// (b) push information about values which can't be converted to integer // without deoptimization through the phi use-def chains, avoiding
// without deoptimization through the phi use-def chains, avoiding // unnecessary deoptimizations later.
// unnecessary deoptimizations later.
for (int i = 0; i < phi_count; ++i) { for (int i = 0; i < phi_count; ++i) {
HPhi* phi = phi_list->at(i); HPhi* phi = phi_list->at(i);
bool cti = phi->AllOperandsConvertibleToInteger(); bool cti = phi->AllOperandsConvertibleToInteger();
if (cti) continue;
for (BitVector::Iterator it(connected_phis.at(i));
!it.Done();
it.Advance()) {
HPhi* phi = phi_list->at(it.Current());
phi->set_is_convertible_to_integer(false);
phi->ResetInteger32Uses();
}
}
// (3b) Use the phi reachability information from step 2 to
// sum up the non-phi use counts of all connected phis.
for (int i = 0; i < phi_count; ++i) {
HPhi* phi = phi_list->at(i);
for (BitVector::Iterator it(connected_phis.at(i)); for (BitVector::Iterator it(connected_phis.at(i));
!it.Done(); !it.Done();
it.Advance()) { it.Advance()) {
int index = it.Current(); int index = it.Current();
HPhi* it_use = phi_list->at(it.Current()); HPhi* it_use = phi_list->at(index);
if (index != i) phi->AddNonPhiUsesFrom(it_use); // Don't count twice! if (index != i) phi->AddNonPhiUsesFrom(it_use); // Don't count twice.
if (!cti) it_use->set_is_convertible_to_integer(false);
} }
} }
...@@ -7503,8 +7524,10 @@ HInstruction* HGraphBuilder::BuildBinaryOperation(BinaryOperation* expr, ...@@ -7503,8 +7524,10 @@ HInstruction* HGraphBuilder::BuildBinaryOperation(BinaryOperation* expr,
} }
Representation rep = ToRepresentation(info); Representation rep = ToRepresentation(info);
// We only generate either int32 or generic tagged bitwise operations. // We only generate either int32 or generic tagged bitwise operations.
if (instr->IsBitwiseBinaryOperation() && rep.IsDouble()) { if (instr->IsBitwiseBinaryOperation()) {
rep = Representation::Integer32(); HBitwiseBinaryOperation::cast(instr)->
InitializeObservedInputRepresentation(rep);
if (rep.IsDouble()) rep = Representation::Integer32();
} }
TraceRepresentation(expr->op(), info, instr, rep); TraceRepresentation(expr->op(), info, instr, rep);
instr->AssumeRepresentation(rep); instr->AssumeRepresentation(rep);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment