node-properties.h revision bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8
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" 9b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/types.h" 10b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 11b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochnamespace v8 { 12b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochnamespace internal { 13b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochnamespace compiler { 14b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 15014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass Graph; 16b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass Operator; 17014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass CommonOperatorBuilder; 18b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 19b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// A facade that simplifies access to the different kinds of inputs to a node. 20014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass NodeProperties final { 21b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public: 22014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // --------------------------------------------------------------------------- 23014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Input layout. 24014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Inputs are always arranged in order as follows: 25014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // 0 [ values, context, frame state, effects, control ] node->InputCount() 26b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 27014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static int FirstValueIndex(Node* node) { return 0; } 28014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static int FirstContextIndex(Node* node) { return PastValueIndex(node); } 29014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static int FirstFrameStateIndex(Node* node) { return PastContextIndex(node); } 30014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static int FirstEffectIndex(Node* node) { return PastFrameStateIndex(node); } 31014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static int FirstControlIndex(Node* node) { return PastEffectIndex(node); } 32014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static int PastValueIndex(Node* node); 33014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static int PastContextIndex(Node* node); 34014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static int PastFrameStateIndex(Node* node); 35014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static int PastEffectIndex(Node* node); 36014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static int PastControlIndex(Node* node); 37014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 38014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 39014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // --------------------------------------------------------------------------- 40014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Input accessors. 41014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 42014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static Node* GetValueInput(Node* node, int index); 43014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static Node* GetContextInput(Node* node); 44014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static Node* GetFrameStateInput(Node* node, int index); 45014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static Node* GetEffectInput(Node* node, int index = 0); 46014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static Node* GetControlInput(Node* node, int index = 0); 47014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 48014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 49014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // --------------------------------------------------------------------------- 50014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Edge kinds. 51014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 52014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static bool IsValueEdge(Edge edge); 53014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static bool IsContextEdge(Edge edge); 54014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static bool IsFrameStateEdge(Edge edge); 55014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static bool IsEffectEdge(Edge edge); 56014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static bool IsControlEdge(Edge edge); 57014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 58014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 59014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // --------------------------------------------------------------------------- 60014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Miscellaneous predicates. 61014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 62014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static bool IsCommon(Node* node) { 63014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return IrOpcode::IsCommonOpcode(node->opcode()); 64014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 65014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static bool IsControl(Node* node) { 66014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return IrOpcode::IsControlOpcode(node->opcode()); 67014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 68014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static bool IsConstant(Node* node) { 69014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return IrOpcode::IsConstantOpcode(node->opcode()); 70014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 71014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static bool IsPhi(Node* node) { 72014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return IrOpcode::IsPhiOpcode(node->opcode()); 73014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 74014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 75014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Determines whether exceptions thrown by the given node are handled locally 76014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // within the graph (i.e. an IfException projection is present). 77014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static bool IsExceptionalCall(Node* node); 78014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 79014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // --------------------------------------------------------------------------- 80014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Miscellaneous mutators. 81014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 82014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static void ReplaceValueInput(Node* node, Node* value, int index); 83014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static void ReplaceContextInput(Node* node, Node* context); 84bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch static void ReplaceControlInput(Node* node, Node* control, int index = 0); 85014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static void ReplaceEffectInput(Node* node, Node* effect, int index = 0); 86014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static void ReplaceFrameStateInput(Node* node, int index, Node* frame_state); 87014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static void RemoveFrameStateInput(Node* node, int index); 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 112014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static Node* FindProjection(Node* node, size_t projection_index); 113014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 114014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Collect the branch-related projections from a node, such as IfTrue, 115014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // IfFalse, IfSuccess, IfException, IfValue and IfDefault. 116014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // - Branch: [ IfTrue, IfFalse ] 117014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // - Call : [ IfSuccess, IfException ] 118014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // - Switch: [ IfValue, ..., IfDefault ] 119014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static void CollectControlProjections(Node* node, Node** proj, size_t count); 120014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 121014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // --------------------------------------------------------------------------- 122014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Context. 123014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 124014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Try to retrieve the specialization context from the given {node}, 125014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // optionally utilizing the knowledge about the (outermost) function 126014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // {context}. 127014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static MaybeHandle<Context> GetSpecializationContext( 128014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* node, MaybeHandle<Context> context = MaybeHandle<Context>()); 129014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 130014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Try to retrieve the specialization native context from the given 131014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // {node}, optionally utilizing the knowledge about the (outermost) 132014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // {native_context}. 133014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static MaybeHandle<Context> GetSpecializationNativeContext( 134014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* node, MaybeHandle<Context> native_context = MaybeHandle<Context>()); 135014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 136014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Try to retrieve the specialization global object from the given 137014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // {node}, optionally utilizing the knowledge about the (outermost) 138014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // {native_context}. 139014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static MaybeHandle<JSGlobalObject> GetSpecializationGlobalObject( 140014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch Node* node, MaybeHandle<Context> native_context = MaybeHandle<Context>()); 141014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 142014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // --------------------------------------------------------------------------- 143014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch // Type. 144014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 145014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static bool IsTyped(Node* node) { return node->type() != nullptr; } 146014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static Type* GetType(Node* node) { 147014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK(IsTyped(node)); 148014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch return node->type(); 149014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 150014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static Type* GetTypeOrAny(Node* node); 151014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static void SetType(Node* node, Type* type) { 152014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch DCHECK_NOT_NULL(type); 153014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch node->set_type(type); 154014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch } 155014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static void RemoveType(Node* node) { node->set_type(nullptr); } 156014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch static bool AllValueInputsAreTyped(Node* node); 157014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch 158014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch private: 159958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier static inline bool IsInputRange(Edge edge, int first, int count); 160b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}; 161b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 162b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} // namespace compiler 163b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} // namespace internal 164b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} // namespace v8 165b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 166b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif // V8_COMPILER_NODE_PROPERTIES_H_ 167