Chromium Code Reviews| 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..1b80e8b866f6d2a02328a93e2d1feac3835dd8ab |
| --- /dev/null |
| +++ b/src/compiler/bytecode-graph-builder.h |
| @@ -0,0 +1,180 @@ |
| +// 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); |
| + |
| + // Creates a graph by visiting bytecodes. |
| + bool CreateGraph(bool stack_check = true); |
| + |
| + Graph* graph() const { return jsgraph_->graph(); } |
| + |
| + private: |
| + class Environment; |
| + |
| + void CreateGraphBody(bool stack_check); |
| + void VisitBytecodes(); |
| + |
| + Node* LoadAccumulator(Node* value); |
| + |
| + Node* GetFunctionContext(); |
| + |
| + // Convert values in bytecode_array to convenient to handle forms. |
|
rmcilroy
2015/09/03 12:41:57
nit - I would just replace this with a comment des
oth
2015/09/04 11:06:36
Done.
|
| + interpreter::Bytecode bytecode_at(int offset) const; |
| + // Get constant from operand at position |offset| in bytecode array. |
|
rmcilroy
2015/09/03 12:41:58
nit - could you make the comment clearer that this
oth
2015/09/04 11:06:36
Done.
|
| + 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. |
| + interpreter::Register register_at(int offset) const; |
|
rmcilroy
2015/09/03 12:41:58
Optional suggestion (fine with doing this in a lat
oth
2015/09/04 11:06:36
Done with BytecodeArrayIterator.
|
| + |
| + 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) { |
| + 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); |
| + |
| + void FinishBinaryOperation(Node* node); |
|
rmcilroy
2015/09/03 12:41:57
How about we replace this with "Node* BuildBinaryO
oth
2015/09/04 11:06:36
Done.
|
| + |
| + // 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_; |
| + |
| + // Nodes representing values in the activation record. |
| + SetOncePointer<Node> function_context_; |
| + |
| + // 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, Node* context); |
| + |
| + int parameters_count() const { return parameters_count_; } |
| + int locals_count() const { return locals_count_; } |
| + |
| + void BindRegister(interpreter::Register the_register, Node* node); |
| + Node* LookupRegister(interpreter::Register the_register) 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; |
| + } |
| + |
| + Node* Context() const { return context_; } |
| + |
| + private: |
| + BytecodeGraphBuilder* builder_; |
| + int locals_count_; |
| + int parameters_count_; |
| + Node* accumulator_; |
| + Node* context_; |
| + 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_; } |
| + |
| + int RegisterToValuesIndex(interpreter::Register the_register) const; |
| +}; |
| + |
| +} // namespace compiler |
| +} // namespace internal |
| +} // namespace v8 |
| + |
| +#endif // V8_COMPILER_BYTECODE_GRAPH_BUILDER_H_ |