Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(14)

Unified Diff: src/cfg.cc

Issue 165056: Add support for (some) assignment expressions to the CFG builder and... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 11 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/cfg.h ('k') | src/ia32/cfg-ia32.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/cfg.cc
===================================================================
--- src/cfg.cc (revision 2635)
+++ src/cfg.cc (working copy)
@@ -42,7 +42,7 @@
CfgGlobals::CfgGlobals(FunctionLiteral* fun)
: global_fun_(fun),
global_exit_(new ExitNode()),
- effect_(new Effect()),
+ nowhere_(new Nowhere()),
#ifdef DEBUG
node_counter_(0),
temp_counter_(0),
@@ -60,6 +60,12 @@
if (fun->scope()->num_heap_slots() > 0) {
BAILOUT("function has context slots");
}
+ if (fun->scope()->num_stack_slots() > kPointerSize) {
+ BAILOUT("function has too many locals");
+ }
+ if (fun->scope()->num_parameters() > kPointerSize - 1) {
+ BAILOUT("function has too many parameters");
+ }
if (fun->scope()->arguments() != NULL) {
BAILOUT("function uses .arguments");
}
@@ -71,18 +77,18 @@
StatementBuilder builder;
builder.VisitStatements(body);
- Cfg* cfg = builder.cfg();
- if (cfg == NULL) {
+ Cfg* graph = builder.graph();
+ if (graph == NULL) {
BAILOUT("unsupported statement type");
}
- if (cfg->is_empty()) {
+ if (graph->is_empty()) {
BAILOUT("function body produces empty cfg");
}
- if (cfg->has_exit()) {
+ if (graph->has_exit()) {
BAILOUT("control path without explicit return");
}
- cfg->PrependEntryNode();
- return cfg;
+ graph->PrependEntryNode();
+ return graph;
}
#undef BAILOUT
@@ -194,9 +200,19 @@
}
+void MoveInstr::FastAllocate(TempLocation* temp) {
+ ASSERT(temp->where() == TempLocation::NOT_ALLOCATED);
+ if (temp == value()) {
+ temp->set_where(TempLocation::ACCUMULATOR);
+ } else {
+ temp->set_where(TempLocation::STACK);
+ }
+}
+
+
void BinaryOpInstr::FastAllocate(TempLocation* temp) {
- ASSERT(temp->where() == TempLocation::NOWHERE);
- if (temp == val0_ || temp == val1_) {
+ ASSERT(temp->where() == TempLocation::NOT_ALLOCATED);
+ if (temp == value0() || temp == value1()) {
temp->set_where(TempLocation::ACCUMULATOR);
} else {
temp->set_where(TempLocation::STACK);
@@ -205,7 +221,7 @@
void ReturnInstr::FastAllocate(TempLocation* temp) {
- ASSERT(temp->where() == TempLocation::NOWHERE);
+ ASSERT(temp->where() == TempLocation::NOT_ALLOCATED);
if (temp == value_) {
temp->set_where(TempLocation::ACCUMULATOR);
} else {
@@ -226,7 +242,7 @@
// Macros (temporarily) handling unsupported expression types.
#define BAILOUT(reason) \
do { \
- cfg_ = NULL; \
+ graph_ = NULL; \
return; \
} while (false)
@@ -260,11 +276,13 @@
if (slot->type() != Slot::PARAMETER && slot->type() != Slot::LOCAL) {
BAILOUT("unsupported slot type (not a parameter or local)");
}
+ // Ignore the passed destination.
value_ = new SlotLocation(slot->type(), slot->index());
}
void ExpressionBuilder::VisitLiteral(Literal* expr) {
+ // Ignore the passed destination.
value_ = new Constant(expr->handle());
}
@@ -290,7 +308,42 @@
void ExpressionBuilder::VisitAssignment(Assignment* expr) {
- BAILOUT("Assignment");
+ if (expr->op() != Token::ASSIGN && expr->op() != Token::INIT_VAR) {
+ BAILOUT("unsupported compound assignment");
+ }
+ Expression* lhs = expr->target();
+ if (lhs->AsProperty() != NULL) {
+ BAILOUT("unsupported property assignment");
+ }
+ Variable* var = lhs->AsVariableProxy()->AsVariable();
+ if (var == NULL) {
+ BAILOUT("unsupported invalid left-hand side");
+ }
+ if (var->is_global()) {
+ BAILOUT("unsupported global variable");
+ }
+ Slot* slot = var->slot();
+ ASSERT(slot != NULL);
+ if (slot->type() != Slot::PARAMETER && slot->type() != Slot::LOCAL) {
+ BAILOUT("unsupported slot lhs (not a parameter or local)");
+ }
+
+ ExpressionBuilder builder;
+ SlotLocation* loc = new SlotLocation(slot->type(), slot->index());
+ builder.Build(expr->value(), loc);
+ if (builder.graph() == NULL) {
+ BAILOUT("unsupported expression in assignment");
+ }
+ // If the expression did not come back in the slot location, append
+ // a move to the CFG.
+ graph_ = builder.graph();
+ if (builder.value() != loc) {
+ graph()->Append(new MoveInstr(loc, builder.value()));
+ }
+ // Record the assignment.
+ assigned_vars_.AddElement(loc);
+ // Ignore the destination passed to us.
+ value_ = loc;
}
@@ -354,21 +407,35 @@
case Token::DIV:
case Token::MOD: {
ExpressionBuilder left, right;
- left.Build(expr->left());
- if (left.cfg() == NULL) {
+ left.Build(expr->left(), NULL);
+ if (left.graph() == NULL) {
BAILOUT("unsupported left subexpression in binop");
}
- right.Build(expr->right());
- if (right.cfg() == NULL) {
+ right.Build(expr->right(), NULL);
+ if (right.graph() == NULL) {
BAILOUT("unsupported right subexpression in binop");
}
- Location* temp = new TempLocation();
- cfg_ = left.cfg();
- cfg_->Concatenate(right.cfg());
- cfg_->Append(new BinaryOpInstr(temp, op, left.value(), right.value()));
+ if (destination_ == NULL) destination_ = new TempLocation();
- value_ = temp;
+ graph_ = left.graph();
+ // Insert a move to a fresh temporary if the left value is in a
+ // slot that's assigned on the right.
+ Location* temp = NULL;
+ if (left.value()->is_slot() &&
+ right.assigned_vars()->Contains(SlotLocation::cast(left.value()))) {
+ temp = new TempLocation();
+ graph()->Append(new MoveInstr(temp, left.value()));
+ }
+ graph()->Concatenate(right.graph());
+ graph()->Append(new BinaryOpInstr(destination_, op,
+ temp == NULL ? left.value() : temp,
+ right.value()));
+
+ assigned_vars_ = *left.assigned_vars();
+ assigned_vars()->Union(right.assigned_vars());
+
+ value_ = destination_;
return;
}
@@ -393,18 +460,18 @@
// Macros (temporarily) handling unsupported statement types.
#define BAILOUT(reason) \
do { \
- cfg_ = NULL; \
+ graph_ = NULL; \
return; \
} while (false)
#define CHECK_BAILOUT() \
- if (cfg_ == NULL) { return; } else {}
+ if (graph() == NULL) { return; } else {}
void StatementBuilder::VisitStatements(ZoneList<Statement*>* stmts) {
for (int i = 0, len = stmts->length(); i < len; i++) {
Visit(stmts->at(i));
CHECK_BAILOUT();
- if (!cfg_->has_exit()) return;
+ if (!graph()->has_exit()) return;
}
}
@@ -425,19 +492,12 @@
void StatementBuilder::VisitExpressionStatement(ExpressionStatement* stmt) {
ExpressionBuilder builder;
- builder.Build(stmt->expression());
- if (builder.cfg() == NULL) {
+ builder.Build(stmt->expression(), CfgGlobals::current()->nowhere());
+ if (builder.graph() == NULL) {
BAILOUT("unsupported expression in expression statement");
}
- // Here's a temporary hack: we bang on the last instruction of the
- // expression (if any) to set its location to Effect.
- if (!builder.cfg()->is_empty()) {
- InstructionBlock* block = InstructionBlock::cast(builder.cfg()->exit());
- Instruction* instr = block->instructions()->last();
- instr->set_location(CfgGlobals::current()->effect_location());
- }
- cfg_->Append(new PositionInstr(stmt->statement_pos()));
- cfg_->Concatenate(builder.cfg());
+ graph()->Append(new PositionInstr(stmt->statement_pos()));
+ graph()->Concatenate(builder.graph());
}
@@ -463,14 +523,14 @@
void StatementBuilder::VisitReturnStatement(ReturnStatement* stmt) {
ExpressionBuilder builder;
- builder.Build(stmt->expression());
- if (builder.cfg() == NULL) {
+ builder.Build(stmt->expression(), NULL);
+ if (builder.graph() == NULL) {
BAILOUT("unsupported expression in return statement");
}
- cfg_->Append(new PositionInstr(stmt->statement_pos()));
- cfg_->Concatenate(builder.cfg());
- cfg_->AppendReturnInstruction(builder.value());
+ graph()->Append(new PositionInstr(stmt->statement_pos()));
+ graph()->Concatenate(builder.graph());
+ graph()->AppendReturnInstruction(builder.value());
}
@@ -530,8 +590,8 @@
}
-void Effect::Print() {
- PrintF("Effect");
+void Nowhere::Print() {
+ PrintF("Nowhere");
}
@@ -555,13 +615,22 @@
}
+void MoveInstr::Print() {
+ PrintF("Move(");
+ location()->Print();
+ PrintF(", ");
+ value_->Print();
+ PrintF(")\n");
+}
+
+
void BinaryOpInstr::Print() {
PrintF("BinaryOp(");
- loc_->Print();
- PrintF(", %s, ", Token::Name(op_));
- val0_->Print();
+ location()->Print();
+ PrintF(", %s, ", Token::Name(op()));
+ value0()->Print();
PrintF(", ");
- val1_->Print();
+ value1()->Print();
PrintF(")\n");
}
« no previous file with comments | « src/cfg.h ('k') | src/ia32/cfg-ia32.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698