| Index: src/compiler/bytecode-graph-builder.h
|
| diff --git a/src/compiler/bytecode-graph-builder.h b/src/compiler/bytecode-graph-builder.h
|
| index ed90d79cb077ee30c14e20425830c4d2c3e33ee9..812731cdeb91066ddb13755b82cbfd3f6d47e0c0 100644
|
| --- a/src/compiler/bytecode-graph-builder.h
|
| +++ b/src/compiler/bytecode-graph-builder.h
|
| @@ -14,6 +14,8 @@ namespace v8 {
|
| namespace internal {
|
| namespace compiler {
|
|
|
| +class BytecodeBasicBlock;
|
| +
|
| // The BytecodeGraphBuilder produces a high-level IR graph based on
|
| // interpreter bytecodes.
|
| class BytecodeGraphBuilder {
|
| @@ -28,9 +30,11 @@ class BytecodeGraphBuilder {
|
|
|
| private:
|
| class Environment;
|
| + class BlockEnvironmentInfo;
|
|
|
| void CreateGraphBody(bool stack_check);
|
| - void VisitBytecodes();
|
| + void VisitBasicBlocks();
|
| + void VisitBytecodesInBasicBlock(BytecodeBasicBlock* block);
|
|
|
| Node* LoadAccumulator(Node* value);
|
|
|
| @@ -64,6 +68,11 @@ class BytecodeGraphBuilder {
|
| const Environment* environment() const { return environment_; }
|
| Environment* environment() { return environment_; }
|
|
|
| + void set_basic_block(const BytecodeBasicBlock* block) {
|
| + basic_block_ = block;
|
| + }
|
| + const BytecodeBasicBlock* basic_block() const { return basic_block_; }
|
| +
|
| // Node creation helpers
|
| Node* NewNode(const Operator* op, bool incomplete = false) {
|
| return MakeNode(op, 0, static_cast<Node**>(NULL), incomplete);
|
| @@ -89,15 +98,34 @@ class BytecodeGraphBuilder {
|
| return MakeNode(op, arraysize(buffer), buffer, false);
|
| }
|
|
|
| - Node* MakeNode(const Operator* op, int value_input_count, Node** value_inputs,
|
| - bool incomplete);
|
| + // Helpers to create new control nodes.
|
| + Node* NewIfTrue() { return NewNode(common()->IfTrue()); }
|
| + Node* NewIfFalse() { return NewNode(common()->IfFalse()); }
|
| + Node* NewMerge() { return NewNode(common()->Merge(1), true); }
|
| + Node* NewLoop() { return NewNode(common()->Loop(1), true); }
|
| + Node* NewBranch(Node* condition, BranchHint hint = BranchHint::kNone) {
|
| + return NewNode(common()->Branch(hint), condition);
|
| + }
|
|
|
| + // Creates a new Phi node having {count} input values.
|
| + Node* NewPhi(int count, Node* input, Node* control);
|
| + Node* NewEffectPhi(int count, Node* input, Node* control);
|
| +
|
| + // Helpers for merging control, effect or value dependencies.
|
| Node* MergeControl(Node* control, Node* other);
|
| + Node* MergeEffect(Node* effect, Node* other_effect, Node* control);
|
| + Node* MergeValue(Node* value, Node* other_value, Node* control);
|
|
|
| - Node** EnsureInputBufferSize(int size);
|
| + // The main node creation chokepoint. Adds context, frame state, effect,
|
| + // and control dependencies depending on the operator.
|
| + Node* MakeNode(const Operator* op, int value_input_count, Node** value_inputs,
|
| + bool incomplete);
|
|
|
| + // Helper to indicate a node exits the function body.
|
| void UpdateControlDependencyToLeaveFunction(Node* exit);
|
|
|
| + Node** EnsureInputBufferSize(int size);
|
| +
|
| Node* ProcessCallArguments(const Operator* call_op, Node* callee,
|
| interpreter::Register receiver, size_t arity);
|
| Node* ProcessCallNewArguments(const Operator* call_new_op,
|
| @@ -123,6 +151,14 @@ class BytecodeGraphBuilder {
|
| void BuildCastOperator(const Operator* js_op,
|
| const interpreter::BytecodeArrayIterator& iterator);
|
|
|
| + // Control flow plumbing.
|
| + void PrepareForNewBasicBlockVisit();
|
| + void CompleteNewBasicBlockVisit();
|
| + void BuildReturn();
|
| + void BuildJump();
|
| + void BuildConditionalJump(Node* condition);
|
| + void BuildBackEdgeIfRequired(BytecodeBasicBlock* target);
|
| +
|
| // Growth increment for the temporary buffer used to construct input lists to
|
| // new nodes.
|
| static const int kInputBufferSizeIncrement = 64;
|
| @@ -154,6 +190,9 @@ class BytecodeGraphBuilder {
|
| Handle<BytecodeArray> bytecode_array_;
|
| Environment* environment_;
|
|
|
| + const BytecodeBasicBlock* basic_block_;
|
| + ZoneVector<BlockEnvironmentInfo*> block_environment_infos_;
|
| +
|
| // Temporary storage for building node input lists.
|
| int input_buffer_size_;
|
| Node** input_buffer_;
|
| @@ -205,9 +244,15 @@ class BytecodeGraphBuilder::Environment : public ZoneObject {
|
| Node* Context() const { return context_; }
|
| void SetContext(Node* new_context) { context_ = new_context; }
|
|
|
| + Environment* CopyForConditional() const;
|
| + Environment* CopyForLoop();
|
| + void Merge(Environment* other);
|
| +
|
| private:
|
| - int RegisterToValuesIndex(interpreter::Register the_register) const;
|
| + explicit Environment(const Environment* copy);
|
| + void PrepareForLoop();
|
|
|
| + int RegisterToValuesIndex(interpreter::Register the_register) const;
|
| Zone* zone() const { return builder_->local_zone(); }
|
| Graph* graph() const { return builder_->graph(); }
|
| CommonOperatorBuilder* common() const { return builder_->common(); }
|
| @@ -228,6 +273,30 @@ class BytecodeGraphBuilder::Environment : public ZoneObject {
|
| int register_base_;
|
| };
|
|
|
| +// A class to help passage between the environments associated with basic
|
| +// blocks.
|
| +class BytecodeGraphBuilder::BlockEnvironmentInfo final : public ZoneObject {
|
| + public:
|
| + typedef BytecodeGraphBuilder::Environment Environment;
|
| +
|
| + BlockEnvironmentInfo()
|
| + : loop_header_env_(nullptr),
|
| + if_true_env_(nullptr),
|
| + if_false_env_(nullptr) {}
|
| +
|
| + Environment* loop_header_environment() const { return loop_header_env_; }
|
| + Environment* if_true_environment() const { return if_true_env_; }
|
| + Environment* if_false_environment() const { return if_false_env_; }
|
| +
|
| + void set_loop_header_environment(Environment* env) { loop_header_env_ = env; }
|
| + void set_if_true_environment(Environment* env) { if_true_env_ = env; }
|
| + void set_if_false_environment(Environment* env) { if_false_env_ = env; }
|
| +
|
| + private:
|
| + Environment* loop_header_env_;
|
| + Environment* if_true_env_;
|
| + Environment* if_false_env_;
|
| +};
|
|
|
| } // namespace compiler
|
| } // namespace internal
|
|
|