}
if (FLAG_use_flow_graph) {
- FlowGraphBuilder builder;
+ int variable_count =
+ function->num_parameters() + function->scope()->num_stack_slots();
+ FlowGraphBuilder builder(variable_count);
builder.Build(function);
if (!builder.HasStackOverflow()) {
- int variable_count =
- function->num_parameters() + function->scope()->num_stack_slots();
- if (variable_count > 0 && builder.definitions()->length() > 0) {
+ if (variable_count > 0) {
ReachingDefinitions rd(builder.postorder(),
- builder.definitions(),
+ builder.body_definitions(),
variable_count);
rd.Compute();
}
}
if (FLAG_use_flow_graph) {
- FlowGraphBuilder builder;
+ int variable_count =
+ literal->num_parameters() + literal->scope()->num_stack_slots();
+ FlowGraphBuilder builder(variable_count);
builder.Build(literal);
if (!builder.HasStackOverflow()) {
- int variable_count =
- literal->num_parameters() + literal->scope()->num_stack_slots();
- if (variable_count > 0 && builder.definitions()->length() > 0) {
+ if (variable_count > 0) {
ReachingDefinitions rd(builder.postorder(),
- builder.definitions(),
+ builder.body_definitions(),
variable_count);
rd.Compute();
}
if (expr->is_compound()) Visit(expr->target());
Visit(expr->value());
if (var->IsStackAllocated()) {
- expr->set_num(definitions_.length());
- definitions_.Add(expr);
+ // The first definition in the body is numbered n, where n is the
+ // number of parameters and stack-allocated locals.
+ expr->set_num(body_definitions_.length() + variable_count_);
+ body_definitions_.Add(expr);
}
} else if (prop != NULL) {
Visit(expr->expression());
Variable* var = expr->expression()->AsVariableProxy()->AsVariable();
if (var != NULL && var->IsStackAllocated()) {
- expr->set_num(definitions_.length());
- definitions_.Add(expr);
+ // The first definition in the body is numbered n, where n is the number
+ // of parameters and stack-allocated locals.
+ expr->set_num(body_definitions_.length() + variable_count_);
+ body_definitions_.Add(expr);
}
if (HasStackOverflow()) return;
int variable_count = variables->length();
rd_.Initialize(definition_count);
+ // The RD_in set for the entry node has a definition for each parameter
+ // and local.
+ if (predecessor_ == NULL) {
+ for (int i = 0; i < variable_count; i++) rd_.rd_in()->Add(i);
+ }
for (int i = 0; i < instruction_count; i++) {
Expression* expr = instructions_[i]->AsExpression();
void ReachingDefinitions::Compute() {
- ASSERT(!definitions_->is_empty());
-
- int variable_count = variables_.length();
- int definition_count = definitions_->length();
+ // The definitions in the body plus an implicit definition for each
+ // variable at function entry.
+ int definition_count = body_definitions_->length() + variable_count_;
int node_count = postorder_->length();
- // Step 1: For each variable, identify the set of all its definitions in
- // the body.
- for (int i = 0; i < definition_count; i++) {
- Variable* var = definitions_->at(i)->AssignedVar();
- variables_[IndexFor(var, variable_count)]->Add(i);
+ // Step 1: For each stack-allocated variable, identify the set of all its
+ // definitions.
+ List<BitVector*> variables;
+ for (int i = 0; i < variable_count_; i++) {
+ // Add the initial definition for each variable.
+ BitVector* initial = new BitVector(definition_count);
+ initial->Add(i);
+ variables.Add(initial);
}
-
- if (FLAG_print_graph_text) {
- for (int i = 0; i < variable_count; i++) {
- BitVector* def_set = variables_[i];
- if (!def_set->IsEmpty()) {
- // At least one definition.
- bool first = true;
- for (int j = 0; j < definition_count; j++) {
- if (def_set->Contains(j)) {
- if (first) {
- Variable* var = definitions_->at(j)->AssignedVar();
- ASSERT(var != NULL);
- PrintF("Def[%s] = {%d", *var->name()->ToCString(), j);
- first = false;
- } else {
- PrintF(",%d", j);
- }
- }
- }
- PrintF("}\n");
- }
- }
+ for (int i = 0, len = body_definitions_->length(); i < len; i++) {
+ // Account for each definition in the body as a definition of the
+ // defined variable.
+ Variable* var = body_definitions_->at(i)->AssignedVar();
+ variables[IndexFor(var, variable_count_)]->Add(i + variable_count_);
}
// Step 2: Compute KILL and GEN for each block node, initialize RD_in for
WorkList<Node> worklist(node_count);
for (int i = node_count - 1; i >= 0; i--) {
postorder_->at(i)->InitializeReachingDefinitions(definition_count,
- &variables_,
+ &variables,
&worklist,
mark);
}
// Step 4: Based on RD_in for block nodes, propagate reaching definitions
// to all variable uses in the block.
for (int i = 0; i < node_count; i++) {
- postorder_->at(i)->PropagateReachingDefinitions(&variables_);
+ postorder_->at(i)->PropagateReachingDefinitions(&variables);
}
}
// traversal orders as a byproduct.
class FlowGraphBuilder: public AstVisitor {
public:
- FlowGraphBuilder()
+ explicit FlowGraphBuilder(int variable_count)
: graph_(FlowGraph::Empty()),
global_exit_(NULL),
preorder_(4),
postorder_(4),
- definitions_(4) {}
+ variable_count_(variable_count),
+ body_definitions_(4) {
+ }
void Build(FunctionLiteral* lit);
FlowGraph* graph() { return &graph_; }
ZoneList<Node*>* postorder() { return &postorder_; }
- ZoneList<Expression*>* definitions() { return &definitions_; }
+ ZoneList<Expression*>* body_definitions() { return &body_definitions_; }
private:
ExitNode* global_exit() { return global_exit_; }
ZoneList<Node*> preorder_;
ZoneList<Node*> postorder_;
- // The flow graph builder collects a list of definitions (assignments and
- // count operations) to stack-allocated variables to use for reaching
- // definitions analysis. AST node numbers in the AST are used to refer
- // into this list.
- ZoneList<Expression*> definitions_;
+ // The flow graph builder collects a list of explicit definitions
+ // (assignments and count operations) to stack-allocated variables to use
+ // for reaching definitions analysis. It does not count the implicit
+ // definition at function entry. AST node numbers in the AST are used to
+ // refer into this list.
+ int variable_count_;
+ ZoneList<Expression*> body_definitions_;
DISALLOW_COPY_AND_ASSIGN(FlowGraphBuilder);
};
class ReachingDefinitions BASE_EMBEDDED {
public:
ReachingDefinitions(ZoneList<Node*>* postorder,
- ZoneList<Expression*>* definitions,
+ ZoneList<Expression*>* body_definitions,
int variable_count)
: postorder_(postorder),
- definitions_(definitions),
- variables_(variable_count) {
- int definition_count = definitions->length();
- for (int i = 0; i < variable_count; i++) {
- variables_.Add(new BitVector(definition_count));
- }
+ body_definitions_(body_definitions),
+ variable_count_(variable_count) {
}
static int IndexFor(Variable* var, int variable_count);
ZoneList<Node*>* postorder_;
// A list of all the definitions in the body.
- ZoneList<Expression*>* definitions_;
+ ZoneList<Expression*>* body_definitions_;
- // For each variable, the set of all its definitions.
- List<BitVector*> variables_;
+ int variable_count_;
DISALLOW_COPY_AND_ASSIGN(ReachingDefinitions);
};