1b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Copyright 2014 the V8 project authors. All rights reserved. 2b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Use of this source code is governed by a BSD-style license that can be 3b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// found in the LICENSE file. 4b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 5b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifndef V8_COMPILER_AST_GRAPH_BUILDER_H_ 6b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define V8_COMPILER_AST_GRAPH_BUILDER_H_ 7b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 8014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/ast/ast.h" 9c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch#include "src/compiler/compiler-source-position-table.h" 10b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/compiler/js-graph.h" 11014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/compiler/liveness-analyzer.h" 12014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/compiler/state-values-utils.h" 13b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 14b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochnamespace v8 { 15b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochnamespace internal { 16014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 17014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// Forward declarations. 18014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass BitVector; 19bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdochclass CompilationInfo; 20014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 21b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochnamespace compiler { 22b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 23014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// Forward declarations. 24b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass ControlBuilder; 25b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass Graph; 26958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernierclass LoopAssignmentAnalysis; 27958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernierclass LoopBuilder; 28014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass Node; 29014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 30b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 31b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// The AstGraphBuilder produces a high-level IR graph, based on an 32b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// underlying AST. The produced graph can either be compiled into a 33b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// stand-alone function or be wired into another graph for the purposes 34b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// of function inlining. 35f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// This AstVistor is not final, and provides the AstVisitor methods as virtual 36f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// methods so they can be specialized by subclasses. 37f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochclass AstGraphBuilder : public AstVisitor<AstGraphBuilder> { 38b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public: 39958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier AstGraphBuilder(Zone* local_zone, CompilationInfo* info, JSGraph* jsgraph, 40f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch float invocation_frequency, 4162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch LoopAssignmentAnalysis* loop_assignment = nullptr); 42f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch virtual ~AstGraphBuilder() {} 43b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 44b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Creates a graph by visiting the entire AST. 45014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bool CreateGraph(bool stack_check = true); 46014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 47014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Helpers to create new control nodes. 48014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* NewIfTrue() { return NewNode(common()->IfTrue()); } 49014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* NewIfFalse() { return NewNode(common()->IfFalse()); } 50014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* NewMerge() { return NewNode(common()->Merge(1), true); } 51014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* NewLoop() { return NewNode(common()->Loop(1), true); } 52014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* NewBranch(Node* condition, BranchHint hint = BranchHint::kNone) { 53014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return NewNode(common()->Branch(hint), condition); 54014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 55b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 56b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch protected: 57f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch#define DECLARE_VISIT(type) virtual void Visit##type(type* node); 58014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Visiting functions for AST nodes make this an AstVisitor. 59014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch AST_NODE_LIST(DECLARE_VISIT) 60014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#undef DECLARE_VISIT 61014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 62014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Visiting function for declarations list is overridden. 63c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch void VisitDeclarations(Declaration::List* declarations); 64014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 65014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch private: 66b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch class AstContext; 67b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch class AstEffectContext; 68b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch class AstValueContext; 69b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch class AstTestContext; 70b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch class ContextScope; 71014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch class ControlScope; 72014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch class ControlScopeForBreakable; 73014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch class ControlScopeForIteration; 74b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch class Environment; 75014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch friend class ControlBuilder; 76b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 77014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Isolate* isolate_; 78014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Zone* local_zone_; 79014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CompilationInfo* info_; 80014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch JSGraph* jsgraph_; 81f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch float const invocation_frequency_; 82014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Environment* environment_; 83014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch AstContext* ast_context_; 84b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 85014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // List of global declarations for functions and variables. 86014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ZoneVector<Handle<Object>> globals_; 87014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 88014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Stack of control scopes currently entered by the visitor. 89014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ControlScope* execution_control_; 90014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 91014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Stack of context objects pushed onto the chain by the visitor. 92014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ContextScope* execution_context_; 93014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 94014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Nodes representing values in the activation record. 95014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch SetOncePointer<Node> function_closure_; 96014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch SetOncePointer<Node> function_context_; 97014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 98014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Temporary storage for building node input lists. 99014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int input_buffer_size_; 100014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node** input_buffer_; 101014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 102014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Optimization to cache loaded feedback vector. 103014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch SetOncePointer<Node> feedback_vector_; 104014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 10513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch // Optimization to cache empty frame state. 10613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch SetOncePointer<Node> empty_frame_state_; 10713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 108014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Control nodes that exit the function body. 109014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ZoneVector<Node*> exit_controls_; 110014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 111014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Result of loop assignment analysis performed before graph creation. 112014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch LoopAssignmentAnalysis* loop_assignment_analysis_; 113014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 114014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Cache for StateValues nodes for frame states. 115014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch StateValuesCache state_values_cache_; 116014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 117014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Analyzer of local variable liveness. 118014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch LivenessAnalyzer liveness_analyzer_; 119014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 120014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Function info for frame state construction. 121014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch const FrameStateFunctionInfo* const frame_state_function_info_; 122014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 123014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Growth increment for the temporary buffer used to construct input lists to 124014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // new nodes. 125014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static const int kInputBufferSizeIncrement = 64; 126014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 127014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Zone* local_zone() const { return local_zone_; } 128014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Environment* environment() const { return environment_; } 129b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AstContext* ast_context() const { return ast_context_; } 130014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ControlScope* execution_control() const { return execution_control_; } 131b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ContextScope* execution_context() const { return execution_context_; } 132014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CommonOperatorBuilder* common() const { return jsgraph_->common(); } 133014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CompilationInfo* info() const { return info_; } 134014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Isolate* isolate() const { return isolate_; } 135014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch LanguageMode language_mode() const; 136014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch JSGraph* jsgraph() { return jsgraph_; } 137014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Graph* graph() { return jsgraph_->graph(); } 138014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Zone* graph_zone() { return graph()->zone(); } 139014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch JSOperatorBuilder* javascript() { return jsgraph_->javascript(); } 140014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ZoneVector<Handle<Object>>* globals() { return &globals_; } 141014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Scope* current_scope() const; 142014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* current_context() const; 143014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch LivenessAnalyzer* liveness_analyzer() { return &liveness_analyzer_; } 144014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch const FrameStateFunctionInfo* frame_state_function_info() const { 145014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return frame_state_function_info_; 146014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 147b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 148014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void set_environment(Environment* env) { environment_ = env; } 149b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void set_ast_context(AstContext* ctx) { ast_context_ = ctx; } 150014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void set_execution_control(ControlScope* ctrl) { execution_control_ = ctrl; } 151b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void set_execution_context(ContextScope* ctx) { execution_context_ = ctx; } 152b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 153014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Create the main graph body by visiting the AST. 154014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void CreateGraphBody(bool stack_check); 155b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 156014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Get or create the node that represents the incoming function closure. 157014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* GetFunctionClosureForContext(); 158b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Node* GetFunctionClosure(); 159014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 160014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Get or create the node that represents the incoming function context. 161b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Node* GetFunctionContext(); 162b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 16313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch // Get or create the node that represents the empty frame state. 16413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch Node* GetEmptyFrameState(); 16513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 166014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Node creation helpers. 167014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* NewNode(const Operator* op, bool incomplete = false) { 168014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return MakeNode(op, 0, static_cast<Node**>(nullptr), incomplete); 169014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 170014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 171014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* NewNode(const Operator* op, Node* n1) { 172014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return MakeNode(op, 1, &n1, false); 173014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 174014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 175014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* NewNode(const Operator* op, Node* n1, Node* n2) { 176014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* buffer[] = {n1, n2}; 177014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return MakeNode(op, arraysize(buffer), buffer, false); 178014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 179014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 180014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* NewNode(const Operator* op, Node* n1, Node* n2, Node* n3) { 181014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* buffer[] = {n1, n2, n3}; 182014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return MakeNode(op, arraysize(buffer), buffer, false); 183014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 184014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 185014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* NewNode(const Operator* op, Node* n1, Node* n2, Node* n3, Node* n4) { 186014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* buffer[] = {n1, n2, n3, n4}; 187014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return MakeNode(op, arraysize(buffer), buffer, false); 188014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 189014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 190014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* NewNode(const Operator* op, Node* n1, Node* n2, Node* n3, Node* n4, 191014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* n5) { 192014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* buffer[] = {n1, n2, n3, n4, n5}; 193014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return MakeNode(op, arraysize(buffer), buffer, false); 194014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 195014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 196014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* NewNode(const Operator* op, Node* n1, Node* n2, Node* n3, Node* n4, 197014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* n5, Node* n6) { 198014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* nodes[] = {n1, n2, n3, n4, n5, n6}; 199014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return MakeNode(op, arraysize(nodes), nodes, false); 200014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 201014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 202014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* NewNode(const Operator* op, int value_input_count, Node** value_inputs, 203014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bool incomplete = false) { 204014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return MakeNode(op, value_input_count, value_inputs, incomplete); 205014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 206014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 207014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Creates a new Phi node having {count} input values. 208014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* NewPhi(int count, Node* input, Node* control); 209014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* NewEffectPhi(int count, Node* input, Node* control); 210014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 211014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Helpers for merging control, effect or value dependencies. 212014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* MergeControl(Node* control, Node* other); 213014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* MergeEffect(Node* value, Node* other, Node* control); 214014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* MergeValue(Node* value, Node* other, Node* control); 215014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 216014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // The main node creation chokepoint. Adds context, frame state, effect, 217014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // and control dependencies depending on the operator. 218014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* MakeNode(const Operator* op, int value_input_count, Node** value_inputs, 219014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bool incomplete); 220014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 221014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Helper to indicate a node exits the function body. 222014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void UpdateControlDependencyToLeaveFunction(Node* exit); 223014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 22413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch // Prepare information for lazy deoptimization. This information is attached 22513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch // to the given node and the output value produced by the node is combined. 22613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch // Conceptually this frame state is "after" a given operation. 227014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void PrepareFrameState(Node* node, BailoutId ast_id, 228014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch OutputFrameStateCombine framestate_combine = 229014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch OutputFrameStateCombine::Ignore()); 230014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 23113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch // Prepare information for eager deoptimization. This information is carried 23213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch // by dedicated {Checkpoint} nodes that are wired into the effect chain. 23313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch // Conceptually this frame state is "before" a given operation. 23413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch void PrepareEagerCheckpoint(BailoutId ast_id); 23513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 236014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch BitVector* GetVariablesAssignedInLoop(IterationStatement* stmt); 237014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 238014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Check if the given statement is an OSR entry. 239014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // If so, record the stack height into the compilation and return {true}. 240014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bool CheckOsrEntry(IterationStatement* stmt); 241014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 242014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Computes local variable liveness and replaces dead variables in 243014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // frame states with the undefined values. 244014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void ClearNonLiveSlotsInFrameStates(); 245014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 246014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node** EnsureInputBufferSize(int size); 247014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 248014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Named and keyed loads require a VectorSlotPair for successful lowering. 24962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch VectorSlotPair CreateVectorSlotPair(FeedbackSlot slot) const; 250014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 25162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch // Computes the frequency for JSCall and JSConstruct nodes. 25262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch float ComputeCallFrequency(FeedbackSlot slot) const; 253f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 254014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // =========================================================================== 255b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // The following build methods all generate graph fragments and return one 256b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // resulting node. The operand stack height remains the same, variables and 257b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // other dependencies tracked by the environment might be mutated though. 258958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 259014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Builders to create local function, script and block contexts. 260014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* BuildLocalActivationContext(Node* context); 261014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* BuildLocalFunctionContext(Scope* scope); 262014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* BuildLocalScriptContext(Scope* scope); 263014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* BuildLocalBlockContext(Scope* scope); 264b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 265b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Builder to create an arguments object if it is used. 266b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Node* BuildArgumentsObject(Variable* arguments); 267b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 268b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Builders for variable load and assignment. 269014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* BuildVariableAssignment(Variable* variable, Node* value, 270014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Token::Value op, const VectorSlotPair& slot, 271958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier BailoutId bailout_id, 272014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch OutputFrameStateCombine framestate_combine = 273958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier OutputFrameStateCombine::Ignore()); 274014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* BuildVariableDelete(Variable* variable, BailoutId bailout_id, 275014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch OutputFrameStateCombine framestate_combine); 276014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* BuildVariableLoad(Variable* variable, BailoutId bailout_id, 277958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier const VectorSlotPair& feedback, 278014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch OutputFrameStateCombine framestate_combine, 279014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch TypeofMode typeof_mode = NOT_INSIDE_TYPEOF); 280014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 281014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Builders for property loads and stores. 282014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* BuildKeyedLoad(Node* receiver, Node* key, 283014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch const VectorSlotPair& feedback); 284014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* BuildNamedLoad(Node* receiver, Handle<Name> name, 285014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch const VectorSlotPair& feedback); 286014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* BuildKeyedStore(Node* receiver, Node* key, Node* value, 287014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch const VectorSlotPair& feedback); 288014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* BuildNamedStore(Node* receiver, Handle<Name> name, Node* value, 289014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch const VectorSlotPair& feedback); 29062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch Node* BuildNamedStoreOwn(Node* receiver, Handle<Name> name, Node* value, 29162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch const VectorSlotPair& feedback); 292014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 293014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Builders for global variable loads and stores. 294014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* BuildGlobalLoad(Handle<Name> name, const VectorSlotPair& feedback, 295014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch TypeofMode typeof_mode); 296014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* BuildGlobalStore(Handle<Name> name, Node* value, 297014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch const VectorSlotPair& feedback); 298b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 299b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Builders for accessing the function context. 300b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Node* BuildLoadGlobalObject(); 301014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* BuildLoadNativeContextField(int index); 302b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 303b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Builders for automatic type conversion. 304014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* BuildToBoolean(Node* input, TypeFeedbackId feedback_id); 305014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* BuildToObject(Node* input, BailoutId bailout_id); 306014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 307014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Builder for adding the [[HomeObject]] to a value if the value came from a 308014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // function literal and needs a home object. Do nothing otherwise. 309014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* BuildSetHomeObject(Node* value, Node* home_object, 310f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch LiteralProperty* property, int slot_number = 0); 311b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 312b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Builders for error reporting at runtime. 313014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* BuildThrowError(Node* exception, BailoutId bailout_id); 314958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Node* BuildThrowReferenceError(Variable* var, BailoutId bailout_id); 315958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Node* BuildThrowConstAssignError(BailoutId bailout_id); 316b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 317b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Builders for dynamic hole-checks at runtime. 318014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* BuildHoleCheckThenThrow(Node* value, Variable* var, Node* not_hole, 319014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch BailoutId bailout_id); 320014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* BuildHoleCheckElseThrow(Node* value, Variable* var, Node* for_hole, 321014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch BailoutId bailout_id); 322b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 323014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Builders for non-local control flow. 324014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* BuildReturn(Node* return_value); 325014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* BuildThrow(Node* exception_value); 326b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 327014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Builders for binary operations. 328014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* BuildBinaryOp(Node* left, Node* right, Token::Value op, 329014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch TypeFeedbackId feedback_id); 330958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 331b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Process arguments to a call by popping {arity} elements off the operand 332b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // stack and build a call node using the given call operator. 333b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Node* ProcessArguments(const Operator* op, int arity); 334b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 335014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // =========================================================================== 336014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // The following build methods have the same contract as the above ones, but 337014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // they can also return {nullptr} to indicate that no fragment was built. Note 338014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // that these are optimizations, disabling any of them should still produce 339014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // correct graphs. 340014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 341014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Optimization for variable load from global object. 342014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* TryLoadGlobalConstant(Handle<Name> name); 343014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 344014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Optimizations for automatic type conversion. 345014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* TryFastToBoolean(Node* input); 346014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 347014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // =========================================================================== 348014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // The following visitation methods all recursively visit a subtree of the 349014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // underlying AST and extent the graph. The operand stack is mutated in a way 350014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // consistent with other compilers: 351014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // - Expressions pop operands and push result, depending on {AstContext}. 352014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // - Statements keep the operand stack balanced. 353014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 354b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Visit statements. 355b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void VisitIfNotNull(Statement* stmt); 356b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 357b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Visit expressions. 358958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void Visit(Expression* expr); 359b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void VisitForTest(Expression* expr); 360b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void VisitForEffect(Expression* expr); 361b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void VisitForValue(Expression* expr); 362b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void VisitForValueOrNull(Expression* expr); 363014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void VisitForValueOrTheHole(Expression* expr); 364b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void VisitForValues(ZoneList<Expression*>* exprs); 365b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 366b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Common for all IterationStatement bodies. 367f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch void VisitIterationBody(IterationStatement* stmt, LoopBuilder* loop, 368f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch BailoutId stack_check_id); 369014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 370014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Dispatched from VisitCall. 371014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void VisitCallSuper(Call* expr); 372b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 373b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Dispatched from VisitCallRuntime. 374b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void VisitCallJSRuntime(CallRuntime* expr); 375b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 376b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Dispatched from VisitUnaryOperation. 377b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void VisitDelete(UnaryOperation* expr); 378b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void VisitVoid(UnaryOperation* expr); 379b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void VisitTypeof(UnaryOperation* expr); 380b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void VisitNot(UnaryOperation* expr); 381b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3823b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // Dispatched from VisitTypeof, VisitLiteralCompareTypeof. 3833b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch void VisitTypeofExpression(Expression* expr); 3843b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 385b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Dispatched from VisitBinaryOperation. 386b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void VisitComma(BinaryOperation* expr); 387b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void VisitLogicalExpression(BinaryOperation* expr); 388b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void VisitArithmeticExpression(BinaryOperation* expr); 389b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 3903b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch // Dispatched from VisitCompareOperation. 3913b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch void VisitLiteralCompareNil(CompareOperation* expr, Expression* sub_expr, 3923b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Node* nil_value); 3933b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch void VisitLiteralCompareTypeof(CompareOperation* expr, Expression* sub_expr, 3943b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch Handle<String> check); 3953b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch 396014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Dispatched from VisitObjectLiteral. 397014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void VisitObjectLiteralAccessor(Node* home_object, 398014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch ObjectLiteralProperty* property); 399b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 400b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DEFINE_AST_VISITOR_SUBCLASS_MEMBERS(); 401b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DISALLOW_COPY_AND_ASSIGN(AstGraphBuilder); 402b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}; 403b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 404b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 405b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// The abstract execution environment for generated code consists of 406b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// parameter variables, local variables and the operand stack. The 407b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// environment will perform proper SSA-renaming of all tracked nodes 408b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// at split and merge points in the control flow. Internally all the 409b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// values are stored in one list using the following layout: 410b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// 411b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// [parameters (+receiver)] [locals] [operand stack] 412b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// 413014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass AstGraphBuilder::Environment : public ZoneObject { 414b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public: 415f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Environment(AstGraphBuilder* builder, DeclarationScope* scope, 416f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch Node* control_dependency); 417b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 418b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int parameters_count() const { return parameters_count_; } 419b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int locals_count() const { return locals_count_; } 420014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int context_chain_length() { return static_cast<int>(contexts_.size()); } 421b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int stack_height() { 422b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return static_cast<int>(values()->size()) - parameters_count_ - 423b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch locals_count_; 424b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 425b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 426014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Operations on parameter or local variables. 427014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void Bind(Variable* variable, Node* node); 428014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* Lookup(Variable* variable); 429014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void MarkAllLocalsLive(); 430014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 431014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Raw operations on parameter variables. 432014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void RawParameterBind(int index, Node* node); 433014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* RawParameterLookup(int index); 434014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 435014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Operations on the context chain. 436014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* Context() const { return contexts_.back(); } 437014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void PushContext(Node* context) { contexts()->push_back(context); } 438014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void PopContext() { contexts()->pop_back(); } 439014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void TrimContextChain(int trim_to_length) { 440014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch contexts()->resize(trim_to_length); 441b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 442b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 443b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Operations on the operand stack. 444b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void Push(Node* node) { 445b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch values()->push_back(node); 446b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 447b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Node* Top() { 448b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(stack_height() > 0); 449b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return values()->back(); 450b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 451b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Node* Pop() { 452b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(stack_height() > 0); 453b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Node* back = values()->back(); 454b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch values()->pop_back(); 455b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return back; 456b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 457b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 458b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Direct mutations of the operand stack. 459b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void Poke(int depth, Node* node) { 460b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(depth >= 0 && depth < stack_height()); 461b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int index = static_cast<int>(values()->size()) - depth - 1; 462b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch values()->at(index) = node; 463b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 464b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Node* Peek(int depth) { 465b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(depth >= 0 && depth < stack_height()); 466b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int index = static_cast<int>(values()->size()) - depth - 1; 467b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return values()->at(index); 468b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 469b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch void Drop(int depth) { 470b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(depth >= 0 && depth <= stack_height()); 471b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch values()->erase(values()->end() - depth, values()->end()); 472b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 473014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void TrimStack(int trim_to_height) { 474014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int depth = stack_height() - trim_to_height; 475014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(depth >= 0 && depth <= stack_height()); 476014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch values()->erase(values()->end() - depth, values()->end()); 477014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 478b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 479b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Preserve a checkpoint of the environment for the IR graph. Any 480b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // further mutation of the environment will not affect checkpoints. 481014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* Checkpoint(BailoutId ast_id, OutputFrameStateCombine combine = 482109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch OutputFrameStateCombine::Ignore(), 483109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch bool node_has_exception = false); 484b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 485f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // Inserts a loop exit control node and renames the environment. 486f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch // This is useful for loop peeling to insert phis at loop exits. 487f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch void PrepareForLoopExit(Node* loop, BitVector* assigned_variables); 488f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch 489014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Control dependency tracked by this environment. 490014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* GetControlDependency() { return control_dependency_; } 491014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void UpdateControlDependency(Node* dependency) { 492014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch control_dependency_ = dependency; 493b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 494b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 495014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Effect dependency tracked by this environment. 496014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* GetEffectDependency() { return effect_dependency_; } 497014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void UpdateEffectDependency(Node* dependency) { 498014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch effect_dependency_ = dependency; 499b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 500b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 501014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Mark this environment as being unreachable. 502014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void MarkAsUnreachable() { 503014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch UpdateControlDependency(builder()->jsgraph()->Dead()); 504014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch liveness_block_ = nullptr; 505b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 506014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bool IsMarkedAsUnreachable() { 507014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return GetControlDependency()->opcode() == IrOpcode::kDead; 508b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 509b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 510014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Merge another environment into this one. 511014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void Merge(Environment* other); 512b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 513014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Copies this environment at a control-flow split point. 514014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Environment* CopyForConditional(); 515b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 516014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Copies this environment to a potentially unreachable control-flow point. 517014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Environment* CopyAsUnreachable(); 518b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 519014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Copies this environment at a loop header control-flow point. 520014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Environment* CopyForLoop(BitVector* assigned, bool is_osr = false); 521b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 522f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch // Copies this environment for Osr entry. This only produces environment 523f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch // of the right shape, the caller is responsible for filling in the right 524f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch // values and dependencies. 525f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch Environment* CopyForOsrEntry(); 526f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch 527b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch private: 528014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch AstGraphBuilder* builder_; 529014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int parameters_count_; 530014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch int locals_count_; 531014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch LivenessAnalyzerBlock* liveness_block_; 532014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch NodeVector values_; 533014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch NodeVector contexts_; 534014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* control_dependency_; 535014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* effect_dependency_; 536014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* parameters_node_; 537014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* locals_node_; 538014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* stack_node_; 539b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 540014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch explicit Environment(Environment* copy, 541014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch LivenessAnalyzerBlock* liveness_block); 542014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Environment* CopyAndShareLiveness(); 543014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch void UpdateStateValues(Node** state_values, int offset, int count); 544014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Zone* zone() const { return builder_->local_zone(); } 545014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Graph* graph() const { return builder_->graph(); } 546014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch AstGraphBuilder* builder() const { return builder_; } 547014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch CommonOperatorBuilder* common() { return builder_->common(); } 548014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch NodeVector* values() { return &values_; } 549014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch NodeVector* contexts() { return &contexts_; } 550014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch LivenessAnalyzerBlock* liveness_block() { return liveness_block_; } 551014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bool IsLivenessAnalysisEnabled(); 552014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch bool IsLivenessBlockConsistent(); 553014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 554014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Prepare environment to be used as loop header. 555f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch void PrepareForLoop(BitVector* assigned); 556f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch void PrepareForOsrEntry(); 557014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}; 558958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 559c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdochclass AstGraphBuilderWithPositions final : public AstGraphBuilder { 560c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch public: 561c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch AstGraphBuilderWithPositions(Zone* local_zone, CompilationInfo* info, 562c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch JSGraph* jsgraph, float invocation_frequency, 563c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch LoopAssignmentAnalysis* loop_assignment, 564c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch SourcePositionTable* source_positions, 565c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch int inlining_id = SourcePosition::kNotInlined); 566c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch 567c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch bool CreateGraph(bool stack_check = true) { 568c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch SourcePositionTable::Scope pos_scope(source_positions_, start_position_); 569c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch return AstGraphBuilder::CreateGraph(stack_check); 570c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch } 571c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch 572c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch#define DEF_VISIT(type) \ 573c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch void Visit##type(type* node) override { \ 574c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch SourcePositionTable::Scope pos( \ 575c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch source_positions_, \ 576c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch SourcePosition(node->position(), start_position_.InliningId())); \ 577c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch AstGraphBuilder::Visit##type(node); \ 578c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch } 579c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch AST_NODE_LIST(DEF_VISIT) 580c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch#undef DEF_VISIT 581c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch 582c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch private: 583c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch SourcePositionTable* const source_positions_; 584c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch SourcePosition const start_position_; 585c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch}; 586c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch 587958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} // namespace compiler 588958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} // namespace internal 589958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} // namespace v8 590b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 591b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif // V8_COMPILER_AST_GRAPH_BUILDER_H_ 592