HGraph::HGraph(CompilationInfo* info)
- : HSubgraph(this),
- next_block_id_(0),
+ : next_block_id_(0),
+ entry_block_(NULL),
blocks_(8),
values_(16),
phi_list_(NULL) {
start_environment_ = new HEnvironment(NULL, info->scope(), info->closure());
start_environment_->set_ast_id(info->function()->id());
+ entry_block_ = CreateBasicBlock();
+ entry_block_->SetInitialEnvironment(start_environment_);
}
bool HGraph::CollectPhis() {
- const ZoneList<HBasicBlock*>* blocks = graph_->blocks();
- phi_list_ = new ZoneList<HPhi*>(blocks->length());
- for (int i = 0; i < blocks->length(); ++i) {
- for (int j = 0; j < blocks->at(i)->phis()->length(); j++) {
- HPhi* phi = blocks->at(i)->phis()->at(j);
+ int block_count = blocks_.length();
+ phi_list_ = new ZoneList<HPhi*>(block_count);
+ for (int i = 0; i < block_count; ++i) {
+ for (int j = 0; j < blocks_[i]->phis()->length(); ++j) {
+ HPhi* phi = blocks_[i]->phis()->at(j);
phi_list_->Add(phi);
// We don't support phi uses of arguments for now.
if (phi->CheckFlag(HValue::kIsArguments)) return false;
} while (false)
-// 'thing' could be an expression, statement, or list of statements.
-#define ADD_TO_SUBGRAPH(graph, thing) \
- do { \
- AddToSubgraph(graph, thing); \
- if (HasStackOverflow()) return; \
- } while (false)
-
-
-class HGraphBuilder::SubgraphScope BASE_EMBEDDED {
- public:
- SubgraphScope(HGraphBuilder* builder, HSubgraph* new_subgraph)
- : builder_(builder) {
- old_subgraph_ = builder_->current_subgraph_;
- subgraph_ = new_subgraph;
- builder_->current_subgraph_ = subgraph_;
- }
-
- ~SubgraphScope() {
- builder_->current_subgraph_ = old_subgraph_;
- }
-
- HSubgraph* subgraph() const { return subgraph_; }
-
- private:
- HGraphBuilder* builder_;
- HSubgraph* old_subgraph_;
- HSubgraph* subgraph_;
-};
-
-
void HGraphBuilder::Bailout(const char* reason) {
if (FLAG_trace_bailout) {
SmartPointer<char> name(info()->shared_info()->DebugName()->ToCString());
HGraph* HGraphBuilder::CreateGraph() {
- ASSERT(subgraph() == NULL);
graph_ = new HGraph(info());
-
{
HPhase phase("Block building");
- graph()->Initialize(CreateBasicBlock(graph()->start_environment()));
- current_subgraph_ = graph();
+ current_block_ = graph()->entry_block();
Scope* scope = info()->scope();
if (scope->HasIllegalRedeclaration()) {
}
-void HGraphBuilder::AddToSubgraph(HSubgraph* graph, Statement* stmt) {
- SubgraphScope scope(this, graph);
- Visit(stmt);
-}
-
-
-void HGraphBuilder::AddToSubgraph(HSubgraph* graph, Expression* expr) {
- SubgraphScope scope(this, graph);
- VisitForValue(expr);
-}
-
-
-void HGraphBuilder::AddToSubgraph(HSubgraph* graph,
- ZoneList<Statement*>* stmts) {
- SubgraphScope scope(this, graph);
- VisitStatements(stmts);
-}
-
-
HInstruction* HGraphBuilder::AddInstruction(HInstruction* instr) {
ASSERT(current_block() != NULL);
current_block()->AddInstruction(instr);
};
-class HSubgraph: public ZoneObject {
- public:
- explicit HSubgraph(HGraph* graph)
- : graph_(graph),
- entry_block_(NULL),
- exit_block_(NULL) {
- }
-
- HGraph* graph() const { return graph_; }
- HBasicBlock* entry_block() const { return entry_block_; }
- HBasicBlock* exit_block() const { return exit_block_; }
- void set_exit_block(HBasicBlock* block) {
- exit_block_ = block;
- }
-
- void Initialize(HBasicBlock* block) {
- ASSERT(entry_block_ == NULL);
- entry_block_ = block;
- exit_block_ = block;
- }
-
- protected:
- HGraph* graph_; // The graph this is a subgraph of.
- HBasicBlock* entry_block_;
- HBasicBlock* exit_block_;
-};
-
-
-class HGraph: public HSubgraph {
+class HGraph: public ZoneObject {
public:
explicit HGraph(CompilationInfo* info);
const ZoneList<HBasicBlock*>* blocks() const { return &blocks_; }
const ZoneList<HPhi*>* phi_list() const { return phi_list_; }
+ HBasicBlock* entry_block() const { return entry_block_; }
HEnvironment* start_environment() const { return start_environment_; }
void InitializeInferredTypes();
void CheckForBackEdge(HBasicBlock* block, HBasicBlock* successor);
int next_block_id_;
+ HBasicBlock* entry_block_;
HEnvironment* start_environment_;
ZoneList<HBasicBlock*> blocks_;
ZoneList<HValue*> values_;
SetOncePointer<HConstant> constant_false_;
SetOncePointer<HArgumentsObject> arguments_object_;
- friend class HSubgraph;
-
DISALLOW_COPY_AND_ASSIGN(HGraph);
};
ast_context_(NULL),
break_scope_(NULL),
graph_(NULL),
- current_subgraph_(NULL),
+ current_block_(NULL),
inlined_count_(0) {
// This is not initialized in the initializer list because the
// constructor for the initial state relies on function_state_ == NULL
// Simple accessors.
HGraph* graph() const { return graph_; }
- HSubgraph* subgraph() const { return current_subgraph_; }
BreakAndContinueScope* break_scope() const { return break_scope_; }
void set_break_scope(BreakAndContinueScope* head) { break_scope_ = head; }
- HBasicBlock* current_block() const { return subgraph()->exit_block(); }
- void set_current_block(HBasicBlock* block) {
- subgraph()->set_exit_block(block);
- }
+ HBasicBlock* current_block() const { return current_block_; }
+ void set_current_block(HBasicBlock* block) { current_block_ = block; }
HEnvironment* environment() const {
return current_block()->last_environment();
}
HBasicBlock* exit_block,
HBasicBlock* continue_block);
- void AddToSubgraph(HSubgraph* graph, ZoneList<Statement*>* stmts);
- void AddToSubgraph(HSubgraph* graph, Statement* stmt);
- void AddToSubgraph(HSubgraph* graph, Expression* expr);
-
HValue* Top() const { return environment()->Top(); }
void Drop(int n) { environment()->Drop(n); }
void Bind(Variable* var, HValue* value) { environment()->Bind(var, value); }
BreakAndContinueScope* break_scope_;
HGraph* graph_;
- HSubgraph* current_subgraph_;
+ HBasicBlock* current_block_;
int inlined_count_;
Handle<Object> ToHandle(LConstantOperand* op) const;
Operand ToOperand(LOperand* op) const;
-
// Try to generate code for the entire chunk, but it may fail if the
// chunk contains constructs we cannot handle. Returns true if the
// code generation attempt succeeded.