Index: src/compiler/bytecode-graph-builder.h |
diff --git a/src/compiler/bytecode-graph-builder.h b/src/compiler/bytecode-graph-builder.h |
new file mode 100644 |
index 0000000000000000000000000000000000000000..5c206b16ee94036be418a30f21a17d66f56c1f10 |
--- /dev/null |
+++ b/src/compiler/bytecode-graph-builder.h |
@@ -0,0 +1,174 @@ |
+// Copyright 2015 the V8 project authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#ifndef V8_COMPILER_BYTECODE_GRAPH_BUILDER_H_ |
+#define V8_COMPILER_BYTECODE_GRAPH_BUILDER_H_ |
+ |
+#include "src/interpreter/bytecodes.h" |
+ |
+#include "src/compiler.h" |
+#include "src/compiler/js-graph.h" |
+ |
+namespace v8 { |
+namespace internal { |
+namespace compiler { |
+ |
+// The BytecodeGraphBuilder produces a high-level IR graph based on |
+// interpreter bytecodes. |
+class BytecodeGraphBuilder { |
+ public: |
+ BytecodeGraphBuilder(Zone* local_zone, CompilationInfo* info, |
+ JSGraph* jsgraph); |
+ BytecodeGraphBuilder(Zone* local_zone, Handle<BytecodeArray> bytecode_array, |
+ JSGraph* jsgraph); |
+ |
+ // Creates a graph by visiting bytecodes. |
+ bool CreateGraph(bool stack_check = true); |
Michael Starzinger
2015/09/02 12:19:22
The only reason for the {stack_check} flags is for
|
+ bool CreateGraphForTest(bool stack_check = true); |
+ |
+ Graph* graph() const { return jsgraph_->graph(); } |
+ |
+ private: |
+ class Environment; |
+ |
+ void CreateGraphBody(bool stack_check); |
+ void VisitBytecodes(); |
+ |
+ Node* LoadAccumulator(Node* value); |
+ |
+ // Convert values in bytecode_array to convenient to handle forms. |
+ interpreter::Bytecode bytecode_at(int offset) const; |
+ // Get constant from operand at position |offset| in bytecode array. |
+ Handle<Object> constant_at(int offset) const; |
+ // Get smi8 value from operand at position |offset| in bytecode array. |
+ int8_t smi8_at(int offset) const; |
+ // Get register from operand at position |offset| in bytecode array. |
+ int8_t register_at(int offset) const; |
+ |
+ void set_environment(Environment* env) { environment_ = env; } |
+ const Environment* environment() const { return environment_; } |
+ Environment* environment() { return environment_; } |
+ |
+ // Node creation helpers |
+ Node* NewNode(const Operator* op, bool incomplete = false) { |
Michael Starzinger
2015/09/02 12:19:22
The {incomplete} flag is only needed for merge poi
|
+ return MakeNode(op, 0, static_cast<Node**>(NULL), incomplete); |
+ } |
+ |
+ Node* NewNode(const Operator* op, Node* n1) { |
+ Node* buffer[] = {n1}; |
+ return MakeNode(op, arraysize(buffer), buffer, false); |
+ } |
+ |
+ Node* NewNode(const Operator* op, Node* n1, Node* n2) { |
+ Node* buffer[] = {n1, n2}; |
+ return MakeNode(op, arraysize(buffer), buffer, false); |
+ } |
+ |
+ Node* MakeNode(const Operator* op, int value_input_count, Node** value_inputs, |
+ bool incomplete); |
+ |
+ Node* MergeControl(Node* control, Node* other); |
+ |
+ Node** EnsureInputBufferSize(int size); |
+ |
+ void UpdateControlDependencyToLeaveFunction(Node* exit); |
Michael Starzinger
2015/09/02 12:19:22
Again depends on how control flow is modeled. Only
|
+ |
+ void FinishBinaryOperation(Node* node); |
+ |
+ // Growth increment for the temporary buffer used to construct input lists to |
+ // new nodes. |
+ static const int kInputBufferSizeIncrement = 64; |
+ |
+ // Field accessors |
+ CommonOperatorBuilder* common() const { return jsgraph_->common(); } |
+ Zone* graph_zone() const { return graph()->zone(); } |
+ CompilationInfo* info() const { return info_; } |
+ JSGraph* jsgraph() const { return jsgraph_; } |
+ JSOperatorBuilder* javascript() const { return jsgraph_->javascript(); } |
+ Zone* local_zone() const { return local_zone_; } |
+ const Handle<BytecodeArray>& bytecode_array() const { |
+ return bytecode_array_; |
+ } |
+ |
+ LanguageMode language_mode() const { |
+ // TODO(oth): need to propagate language mode through |
+ return LanguageMode::SLOPPY; |
+ } |
+ |
+#define DECLARE_VISIT_BYTECODE(name, ...) void Visit##name(int operand_offset); |
+ BYTECODE_LIST(DECLARE_VISIT_BYTECODE) |
+#undef DECLARE_VISIT_BYTECODE |
+ |
+ Zone* local_zone_; |
+ CompilationInfo* info_; |
+ JSGraph* jsgraph_; |
+ Handle<BytecodeArray> bytecode_array_; |
+ Environment* environment_; |
+ |
+ // Temporary storage for building node input lists. |
+ int input_buffer_size_; |
+ Node** input_buffer_; |
+ |
+ // Control nodes that exit the function body. |
+ ZoneVector<Node*> exit_controls_; |
+ |
+ DISALLOW_COPY_AND_ASSIGN(BytecodeGraphBuilder); |
+}; |
+ |
+ |
+class BytecodeGraphBuilder::Environment : public ZoneObject { |
+ public: |
+ Environment(BytecodeGraphBuilder* builder, int locals_count, |
+ int parameter_count, Node* control_dependency); |
+ |
+ int parameters_count() const { return parameters_count_; } |
+ int locals_count() const { return locals_count_; } |
+ |
+ void BindRegister(int register_index, Node* node); |
+ Node* LookupRegister(int register_index) const; |
+ |
+ void BindAccumulator(Node* node); |
+ Node* LookupAccumulator() const; |
+ |
+ bool IsMarkedAsUnreachable() const; |
+ void MarkAsUnreachable(); |
+ |
+ // Effect dependency tracked by this environment. |
+ Node* GetEffectDependency() { return effect_dependency_; } |
+ void UpdateEffectDependency(Node* dependency) { |
+ effect_dependency_ = dependency; |
+ } |
+ |
+ // Control dependency tracked by this environment. |
+ Node* GetControlDependency() const { return control_dependency_; } |
+ void UpdateControlDependency(Node* dependency) { |
+ control_dependency_ = dependency; |
+ } |
+ |
+ private: |
+ BytecodeGraphBuilder* builder_; |
+ int locals_count_; |
+ int parameters_count_; |
+ Node* accumulator_; |
+ Node* control_dependency_; |
+ Node* effect_dependency_; |
+ NodeVector values_; |
+ int register_base_; |
+ |
+ Zone* zone() const { return builder_->local_zone(); } |
+ Graph* graph() const { return builder_->graph(); } |
+ CommonOperatorBuilder* common() const { return builder_->common(); } |
+ BytecodeGraphBuilder* builder() const { return builder_; } |
+ const NodeVector* values() const { return &values_; } |
+ NodeVector* values() { return &values_; } |
+ Node* accumulator() { return accumulator_; } |
+ |
+ int register_base() const { return register_base_; } |
+}; |
+ |
+} // namespace compiler |
+} // namespace internal |
+} // namespace v8 |
+ |
+#endif // V8_COMPILER_BYTECODE_GRAPH_BUILDER_H_ |