Improve representation inference for HUnknownOSRValue.

Use corresponding phi from the loop entry as a hint to infer proper representation for HUnkownOSRValue and dependent phis.

R=fschneider@chromium.org

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

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@11055 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
vegorov@chromium.org 2012-03-15 12:21:29 +00:00
parent 100bc51eae
commit 211a867943
4 changed files with 75 additions and 9 deletions

View File

@ -2262,7 +2262,15 @@ Representation HPhi::InferredRepresentation() {
bool int32_occurred = false;
for (int i = 0; i < OperandCount(); ++i) {
HValue* value = OperandAt(i);
if (value->IsUnknownOSRValue()) continue;
if (value->IsUnknownOSRValue()) {
HPhi* hint_value = HUnknownOSRValue::cast(value)->incoming_value();
if (hint_value != NULL) {
Representation hint = hint_value->representation();
if (hint.IsDouble()) double_occurred = true;
if (hint.IsInteger32()) int32_occurred = true;
}
continue;
}
if (value->representation().IsDouble()) double_occurred = true;
if (value->representation().IsInteger32()) int32_occurred = true;
if (value->representation().IsTagged()) {

View File

@ -3423,13 +3423,27 @@ class HCallStub: public HUnaryCall {
class HUnknownOSRValue: public HTemplateInstruction<0> {
public:
HUnknownOSRValue() { set_representation(Representation::Tagged()); }
HUnknownOSRValue()
: incoming_value_(NULL) {
set_representation(Representation::Tagged());
}
virtual Representation RequiredInputRepresentation(int index) {
return Representation::None();
}
void set_incoming_value(HPhi* value) {
incoming_value_ = value;
}
HPhi* incoming_value() {
return incoming_value_;
}
DECLARE_CONCRETE_INSTRUCTION(UnknownOSRValue)
private:
HPhi* incoming_value_;
};

View File

@ -2520,6 +2520,14 @@ HGraph* HGraphBuilder::CreateGraph() {
if (FLAG_eliminate_dead_phis) graph()->EliminateUnreachablePhis();
graph()->CollectPhis();
if (graph()->has_osr_loop_entry()) {
const ZoneList<HPhi*>* phis = graph()->osr_loop_entry()->phis();
for (int j = 0; j < phis->length(); j++) {
HPhi* phi = phis->at(j);
graph()->osr_values()->at(phi->merged_index())->set_incoming_value(phi);
}
}
HInferRepresentation rep(graph());
rep.Analyze();
@ -3092,8 +3100,8 @@ bool HGraphBuilder::HasOsrEntryAt(IterationStatement* statement) {
}
void HGraphBuilder::PreProcessOsrEntry(IterationStatement* statement) {
if (!HasOsrEntryAt(statement)) return;
bool HGraphBuilder::PreProcessOsrEntry(IterationStatement* statement) {
if (!HasOsrEntryAt(statement)) return false;
HBasicBlock* non_osr_entry = graph()->CreateBasicBlock();
HBasicBlock* osr_entry = graph()->CreateBasicBlock();
@ -3108,10 +3116,14 @@ void HGraphBuilder::PreProcessOsrEntry(IterationStatement* statement) {
int osr_entry_id = statement->OsrEntryId();
int first_expression_index = environment()->first_expression_index();
int length = environment()->length();
ZoneList<HUnknownOSRValue*>* osr_values =
new(zone()) ZoneList<HUnknownOSRValue*>(length);
for (int i = 0; i < first_expression_index; ++i) {
HUnknownOSRValue* osr_value = new(zone()) HUnknownOSRValue;
AddInstruction(osr_value);
environment()->Bind(i, osr_value);
osr_values->Add(osr_value);
}
if (first_expression_index != length) {
@ -3120,9 +3132,12 @@ void HGraphBuilder::PreProcessOsrEntry(IterationStatement* statement) {
HUnknownOSRValue* osr_value = new(zone()) HUnknownOSRValue;
AddInstruction(osr_value);
environment()->Push(osr_value);
osr_values->Add(osr_value);
}
}
graph()->set_osr_values(osr_values);
AddSimulate(osr_entry_id);
AddInstruction(new(zone()) HOsrEntry(osr_entry_id));
HContext* context = new(zone()) HContext;
@ -3131,6 +3146,7 @@ void HGraphBuilder::PreProcessOsrEntry(IterationStatement* statement) {
current_block()->Goto(loop_predecessor);
loop_predecessor->SetJoinId(statement->EntryId());
set_current_block(loop_predecessor);
return true;
}
@ -3154,10 +3170,11 @@ void HGraphBuilder::VisitDoWhileStatement(DoWhileStatement* stmt) {
ASSERT(current_block() != NULL);
ASSERT(current_block()->HasPredecessor());
ASSERT(current_block() != NULL);
PreProcessOsrEntry(stmt);
bool osr_entry = PreProcessOsrEntry(stmt);
HBasicBlock* loop_entry = CreateLoopHeaderBlock();
current_block()->Goto(loop_entry);
set_current_block(loop_entry);
if (osr_entry) graph()->set_osr_loop_entry(loop_entry);
BreakAndContinueInfo break_info(stmt);
CHECK_BAILOUT(VisitLoopBody(stmt, loop_entry, &break_info));
@ -3196,10 +3213,12 @@ void HGraphBuilder::VisitWhileStatement(WhileStatement* stmt) {
ASSERT(current_block() != NULL);
ASSERT(current_block()->HasPredecessor());
ASSERT(current_block() != NULL);
PreProcessOsrEntry(stmt);
bool osr_entry = PreProcessOsrEntry(stmt);
HBasicBlock* loop_entry = CreateLoopHeaderBlock();
current_block()->Goto(loop_entry);
set_current_block(loop_entry);
if (osr_entry) graph()->set_osr_loop_entry(loop_entry);
// If the condition is constant true, do not generate a branch.
HBasicBlock* loop_successor = NULL;
@ -3241,10 +3260,11 @@ void HGraphBuilder::VisitForStatement(ForStatement* stmt) {
CHECK_ALIVE(Visit(stmt->init()));
}
ASSERT(current_block() != NULL);
PreProcessOsrEntry(stmt);
bool osr_entry = PreProcessOsrEntry(stmt);
HBasicBlock* loop_entry = CreateLoopHeaderBlock();
current_block()->Goto(loop_entry);
set_current_block(loop_entry);
if (osr_entry) graph()->set_osr_loop_entry(loop_entry);
HBasicBlock* loop_successor = NULL;
if (stmt->cond() != NULL) {
@ -3336,10 +3356,11 @@ void HGraphBuilder::VisitForInStatement(ForInStatement* stmt) {
HForInCacheArray::cast(array)->set_index_cache(
HForInCacheArray::cast(index_cache));
PreProcessOsrEntry(stmt);
bool osr_entry = PreProcessOsrEntry(stmt);
HBasicBlock* loop_entry = CreateLoopHeaderBlock();
current_block()->Goto(loop_entry);
set_current_block(loop_entry);
if (osr_entry) graph()->set_osr_loop_entry(loop_entry);
HValue* index = environment()->ExpressionStackAt(0);
HValue* limit = environment()->ExpressionStackAt(1);

View File

@ -313,6 +313,26 @@ class HGraph: public ZoneObject {
void Verify(bool do_full_verify) const;
#endif
bool has_osr_loop_entry() {
return osr_loop_entry_.is_set();
}
HBasicBlock* osr_loop_entry() {
return osr_loop_entry_.get();
}
void set_osr_loop_entry(HBasicBlock* entry) {
osr_loop_entry_.set(entry);
}
ZoneList<HUnknownOSRValue*>* osr_values() {
return osr_values_.get();
}
void set_osr_values(ZoneList<HUnknownOSRValue*>* values) {
osr_values_.set(values);
}
private:
void Postorder(HBasicBlock* block,
BitVector* visited,
@ -353,6 +373,9 @@ class HGraph: public ZoneObject {
SetOncePointer<HConstant> constant_hole_;
SetOncePointer<HArgumentsObject> arguments_object_;
SetOncePointer<HBasicBlock> osr_loop_entry_;
SetOncePointer<ZoneList<HUnknownOSRValue*> > osr_values_;
DISALLOW_COPY_AND_ASSIGN(HGraph);
};
@ -886,7 +909,7 @@ class HGraphBuilder: public AstVisitor {
void VisitLogicalExpression(BinaryOperation* expr);
void VisitArithmeticExpression(BinaryOperation* expr);
void PreProcessOsrEntry(IterationStatement* statement);
bool PreProcessOsrEntry(IterationStatement* statement);
// True iff. we are compiling for OSR and the statement is the entry.
bool HasOsrEntryAt(IterationStatement* statement);
void VisitLoopBody(IterationStatement* stmt,