| Index: src/compiler/bytecode-graph-builder.h
|
| diff --git a/src/compiler/bytecode-graph-builder.h b/src/compiler/bytecode-graph-builder.h
|
| index ce1c5dafb673325b1e7c39bd3c8f05976195210d..bbc504d7931826c080cc12fd31090d88f3be1cb8 100644
|
| --- a/src/compiler/bytecode-graph-builder.h
|
| +++ b/src/compiler/bytecode-graph-builder.h
|
| @@ -6,6 +6,7 @@
|
| #define V8_COMPILER_BYTECODE_GRAPH_BUILDER_H_
|
|
|
| #include "src/compiler.h"
|
| +#include "src/compiler/bytecode-branch-analysis.h"
|
| #include "src/compiler/js-graph.h"
|
| #include "src/interpreter/bytecode-array-iterator.h"
|
| #include "src/interpreter/bytecodes.h"
|
| @@ -89,15 +90,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,
|
| @@ -130,6 +150,21 @@ class BytecodeGraphBuilder {
|
| void BuildCastOperator(const Operator* js_op,
|
| const interpreter::BytecodeArrayIterator& iterator);
|
|
|
| + // Control flow plumbing.
|
| + void BuildJump(int source_offset, int target_offset);
|
| + void BuildJump();
|
| + void BuildConditionalJump(Node* condition);
|
| +
|
| + // Helpers for building conditions for conditional jumps.
|
| + Node* BuildCondition(Node* comperand);
|
| + Node* BuildToBooleanCondition(Node* comperand);
|
| +
|
| + // Constructing merge and loop headers.
|
| + void MergeEnvironmentsOfBackwardBranches(int source_offset,
|
| + int target_offset);
|
| + void MergeEnvironmentsOfForwardBranches(int source_offset);
|
| + void BuildLoopHeaderForBackwardBranches(int source_offset);
|
| +
|
| // Growth increment for the temporary buffer used to construct input lists to
|
| // new nodes.
|
| static const int kInputBufferSizeIncrement = 64;
|
| @@ -150,6 +185,23 @@ class BytecodeGraphBuilder {
|
| return info()->language_mode();
|
| }
|
|
|
| + const interpreter::BytecodeArrayIterator* bytecode_iterator() const {
|
| + return bytecode_iterator_;
|
| + }
|
| +
|
| + void set_bytecode_iterator(
|
| + const interpreter::BytecodeArrayIterator* bytecode_iterator) {
|
| + bytecode_iterator_ = bytecode_iterator;
|
| + }
|
| +
|
| + const BytecodeBranchAnalysis* branch_analysis() const {
|
| + return branch_analysis_;
|
| + }
|
| +
|
| + void set_branch_analysis(const BytecodeBranchAnalysis* branch_analysis) {
|
| + branch_analysis_ = branch_analysis;
|
| + }
|
| +
|
| #define DECLARE_VISIT_BYTECODE(name, ...) \
|
| void Visit##name(const interpreter::BytecodeArrayIterator& iterator);
|
| BYTECODE_LIST(DECLARE_VISIT_BYTECODE)
|
| @@ -159,8 +211,18 @@ class BytecodeGraphBuilder {
|
| CompilationInfo* info_;
|
| JSGraph* jsgraph_;
|
| Handle<BytecodeArray> bytecode_array_;
|
| + const interpreter::BytecodeArrayIterator* bytecode_iterator_;
|
| + const BytecodeBranchAnalysis* branch_analysis_;
|
| Environment* environment_;
|
|
|
| + // Merge environments are snapshots of the environment at a particular
|
| + // bytecode offset to be merged into a later environment.
|
| + ZoneMap<int, Environment*> merge_environments_;
|
| +
|
| + // Loop header environments are environments created for bytecodes
|
| + // where it is known there are back branches, ie a loop header.
|
| + ZoneMap<int, Environment*> loop_header_environments_;
|
| +
|
| // Temporary storage for building node input lists.
|
| int input_buffer_size_;
|
| Node** input_buffer_;
|
| @@ -212,9 +274,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(); }
|
| @@ -235,7 +303,6 @@ class BytecodeGraphBuilder::Environment : public ZoneObject {
|
| int register_base_;
|
| };
|
|
|
| -
|
| } // namespace compiler
|
| } // namespace internal
|
| } // namespace v8
|
|
|