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:
parent
100bc51eae
commit
211a867943
@ -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()) {
|
||||
|
@ -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_;
|
||||
};
|
||||
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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,
|
||||
|
Loading…
Reference in New Issue
Block a user