1b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Copyright 2013 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_NODE_PROPERTIES_H_ 6b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define V8_COMPILER_NODE_PROPERTIES_H_ 7b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 8b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/compiler/node.h" 9f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch#include "src/compiler/types.h" 10c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch#include "src/globals.h" 11b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 12b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochnamespace v8 { 13b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochnamespace internal { 14b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochnamespace compiler { 15b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 16014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass Graph; 17b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass Operator; 18014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass CommonOperatorBuilder; 19b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 20b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// A facade that simplifies access to the different kinds of inputs to a node. 21c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdochclass V8_EXPORT_PRIVATE NodeProperties final { 22b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public: 23014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // --------------------------------------------------------------------------- 24014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Input layout. 25014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Inputs are always arranged in order as follows: 26014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // 0 [ values, context, frame state, effects, control ] node->InputCount() 27b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 28014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static int FirstValueIndex(Node* node) { return 0; } 29014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static int FirstContextIndex(Node* node) { return PastValueIndex(node); } 30014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static int FirstFrameStateIndex(Node* node) { return PastContextIndex(node); } 31014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static int FirstEffectIndex(Node* node) { return PastFrameStateIndex(node); } 32014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static int FirstControlIndex(Node* node) { return PastEffectIndex(node); } 33014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static int PastValueIndex(Node* node); 34014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static int PastContextIndex(Node* node); 35014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static int PastFrameStateIndex(Node* node); 36014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static int PastEffectIndex(Node* node); 37014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static int PastControlIndex(Node* node); 38014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 39014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 40014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // --------------------------------------------------------------------------- 41014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Input accessors. 42014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 43014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static Node* GetValueInput(Node* node, int index); 44014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static Node* GetContextInput(Node* node); 45f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch static Node* GetFrameStateInput(Node* node); 46014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static Node* GetEffectInput(Node* node, int index = 0); 47014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static Node* GetControlInput(Node* node, int index = 0); 48014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 49014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 50014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // --------------------------------------------------------------------------- 51014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Edge kinds. 52014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 53014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static bool IsValueEdge(Edge edge); 54014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static bool IsContextEdge(Edge edge); 55014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static bool IsFrameStateEdge(Edge edge); 56014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static bool IsEffectEdge(Edge edge); 57014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static bool IsControlEdge(Edge edge); 58014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 59014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 60014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // --------------------------------------------------------------------------- 61014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Miscellaneous predicates. 62014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 63014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static bool IsCommon(Node* node) { 64014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return IrOpcode::IsCommonOpcode(node->opcode()); 65014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 66014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static bool IsControl(Node* node) { 67014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return IrOpcode::IsControlOpcode(node->opcode()); 68014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 69014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static bool IsConstant(Node* node) { 70014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return IrOpcode::IsConstantOpcode(node->opcode()); 71014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 72014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static bool IsPhi(Node* node) { 73014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return IrOpcode::IsPhiOpcode(node->opcode()); 74014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 75014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 76014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Determines whether exceptions thrown by the given node are handled locally 77014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // within the graph (i.e. an IfException projection is present). 78014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static bool IsExceptionalCall(Node* node); 79014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 80014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // --------------------------------------------------------------------------- 81014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Miscellaneous mutators. 82014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 83014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static void ReplaceValueInput(Node* node, Node* value, int index); 84014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static void ReplaceContextInput(Node* node, Node* context); 85bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch static void ReplaceControlInput(Node* node, Node* control, int index = 0); 86014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static void ReplaceEffectInput(Node* node, Node* effect, int index = 0); 87f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch static void ReplaceFrameStateInput(Node* node, Node* frame_state); 88014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static void RemoveNonValueInputs(Node* node); 89014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static void RemoveValueInputs(Node* node); 90014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 91014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Replaces all value inputs of {node} with the single input {value}. 92014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static void ReplaceValueInputs(Node* node, Node* value); 93014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 94014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Merge the control node {node} into the end of the graph, introducing a 95014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // merge node or expanding an existing merge node if necessary. 96014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static void MergeControlToEnd(Graph* graph, CommonOperatorBuilder* common, 97014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* node); 98014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 99014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Replace all uses of {node} with the given replacement nodes. All occurring 100014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // use kinds need to be replaced, {nullptr} is only valid if a use kind is 101014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // guaranteed not to exist. 102014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static void ReplaceUses(Node* node, Node* value, Node* effect = nullptr, 103014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* success = nullptr, Node* exception = nullptr); 104014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 105014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Safe wrapper to mutate the operator of a node. Checks that the node is 106014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // currently in a state that satisfies constraints of the new operator. 107014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static void ChangeOp(Node* node, const Operator* new_op); 108014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 109014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // --------------------------------------------------------------------------- 110014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Miscellaneous utilities. 111014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 11213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch // Find the last frame state that is effect-wise before the given node. This 11313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch // assumes a linear effect-chain up to a {CheckPoint} node in the graph. 11413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch static Node* FindFrameStateBefore(Node* node); 11513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch 11613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch // Collect the output-value projection for the given output index. 117014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static Node* FindProjection(Node* node, size_t projection_index); 118014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 119014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Collect the branch-related projections from a node, such as IfTrue, 120014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // IfFalse, IfSuccess, IfException, IfValue and IfDefault. 121014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // - Branch: [ IfTrue, IfFalse ] 122014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // - Call : [ IfSuccess, IfException ] 123014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // - Switch: [ IfValue, ..., IfDefault ] 124014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static void CollectControlProjections(Node* node, Node** proj, size_t count); 125014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 126014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // --------------------------------------------------------------------------- 127014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Context. 128014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 129014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Try to retrieve the specialization context from the given {node}, 130014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // optionally utilizing the knowledge about the (outermost) function 131014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // {context}. 132014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static MaybeHandle<Context> GetSpecializationContext( 133014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* node, MaybeHandle<Context> context = MaybeHandle<Context>()); 134014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 135014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // --------------------------------------------------------------------------- 136014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Type. 137014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 138014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static bool IsTyped(Node* node) { return node->type() != nullptr; } 139014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static Type* GetType(Node* node) { 140014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(IsTyped(node)); 141014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return node->type(); 142014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 143014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static Type* GetTypeOrAny(Node* node); 144014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static void SetType(Node* node, Type* type) { 145014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK_NOT_NULL(type); 146014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch node->set_type(type); 147014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 148014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static void RemoveType(Node* node) { node->set_type(nullptr); } 149014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static bool AllValueInputsAreTyped(Node* node); 150014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 151014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch private: 152958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier static inline bool IsInputRange(Edge edge, int first, int count); 153b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}; 154b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 155b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} // namespace compiler 156b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} // namespace internal 157b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} // namespace v8 158b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 159b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif // V8_COMPILER_NODE_PROPERTIES_H_ 160