LCOV - code coverage report
Current view: top level - src/compiler - node-properties.h (source / functions) Hit Total Coverage
Test: app.info Lines: 4 4 100.0 %
Date: 2019-04-19 Functions: 0 0 -

          Line data    Source code
       1             : // Copyright 2013 the V8 project authors. All rights reserved.
       2             : // Use of this source code is governed by a BSD-style license that can be
       3             : // found in the LICENSE file.
       4             : 
       5             : #ifndef V8_COMPILER_NODE_PROPERTIES_H_
       6             : #define V8_COMPILER_NODE_PROPERTIES_H_
       7             : 
       8             : #include "src/compiler/node.h"
       9             : #include "src/compiler/types.h"
      10             : #include "src/globals.h"
      11             : #include "src/objects/map.h"
      12             : #include "src/zone/zone-handle-set.h"
      13             : 
      14             : namespace v8 {
      15             : namespace internal {
      16             : namespace compiler {
      17             : 
      18             : class Graph;
      19             : class Operator;
      20             : class CommonOperatorBuilder;
      21             : 
      22             : // A facade that simplifies access to the different kinds of inputs to a node.
      23             : class V8_EXPORT_PRIVATE NodeProperties final {
      24             :  public:
      25             :   // ---------------------------------------------------------------------------
      26             :   // Input layout.
      27             :   // Inputs are always arranged in order as follows:
      28             :   //     0 [ values, context, frame state, effects, control ] node->InputCount()
      29             : 
      30             :   static int FirstValueIndex(Node* node) { return 0; }
      31       24721 :   static int FirstContextIndex(Node* node) { return PastValueIndex(node); }
      32         544 :   static int FirstFrameStateIndex(Node* node) { return PastContextIndex(node); }
      33  1188028300 :   static int FirstEffectIndex(Node* node) { return PastFrameStateIndex(node); }
      34    62157405 :   static int FirstControlIndex(Node* node) { return PastEffectIndex(node); }
      35             :   static int PastValueIndex(Node* node);
      36             :   static int PastContextIndex(Node* node);
      37             :   static int PastFrameStateIndex(Node* node);
      38             :   static int PastEffectIndex(Node* node);
      39             :   static int PastControlIndex(Node* node);
      40             : 
      41             : 
      42             :   // ---------------------------------------------------------------------------
      43             :   // Input accessors.
      44             : 
      45             :   static Node* GetValueInput(Node* node, int index);
      46             :   static Node* GetContextInput(Node* node);
      47             :   static Node* GetFrameStateInput(Node* node);
      48             :   static Node* GetEffectInput(Node* node, int index = 0);
      49             :   static Node* GetControlInput(Node* node, int index = 0);
      50             : 
      51             : 
      52             :   // ---------------------------------------------------------------------------
      53             :   // Edge kinds.
      54             : 
      55             :   static bool IsValueEdge(Edge edge);
      56             :   static bool IsContextEdge(Edge edge);
      57             :   static bool IsFrameStateEdge(Edge edge);
      58             :   static bool IsEffectEdge(Edge edge);
      59             :   static bool IsControlEdge(Edge edge);
      60             : 
      61             : 
      62             :   // ---------------------------------------------------------------------------
      63             :   // Miscellaneous predicates.
      64             : 
      65             :   static bool IsCommon(Node* node) {
      66             :     return IrOpcode::IsCommonOpcode(node->opcode());
      67             :   }
      68             :   static bool IsControl(Node* node) {
      69             :     return IrOpcode::IsControlOpcode(node->opcode());
      70             :   }
      71             :   static bool IsConstant(Node* node) {
      72             :     return IrOpcode::IsConstantOpcode(node->opcode());
      73             :   }
      74             :   static bool IsPhi(Node* node) {
      75             :     return IrOpcode::IsPhiOpcode(node->opcode());
      76             :   }
      77             : 
      78             :   // Determines whether exceptions thrown by the given node are handled locally
      79             :   // within the graph (i.e. an IfException projection is present). Optionally
      80             :   // the present IfException projection is returned via {out_exception}.
      81             :   static bool IsExceptionalCall(Node* node, Node** out_exception = nullptr);
      82             : 
      83             :   // Returns the node producing the successful control output of {node}. This is
      84             :   // the IfSuccess projection of {node} if present and {node} itself otherwise.
      85             :   static Node* FindSuccessfulControlProjection(Node* node);
      86             : 
      87             :   // ---------------------------------------------------------------------------
      88             :   // Miscellaneous mutators.
      89             : 
      90             :   static void ReplaceValueInput(Node* node, Node* value, int index);
      91             :   static void ReplaceContextInput(Node* node, Node* context);
      92             :   static void ReplaceControlInput(Node* node, Node* control, int index = 0);
      93             :   static void ReplaceEffectInput(Node* node, Node* effect, int index = 0);
      94             :   static void ReplaceFrameStateInput(Node* node, Node* frame_state);
      95             :   static void RemoveNonValueInputs(Node* node);
      96             :   static void RemoveValueInputs(Node* node);
      97             : 
      98             :   // Replaces all value inputs of {node} with the single input {value}.
      99             :   static void ReplaceValueInputs(Node* node, Node* value);
     100             : 
     101             :   // Merge the control node {node} into the end of the graph, introducing a
     102             :   // merge node or expanding an existing merge node if necessary.
     103             :   static void MergeControlToEnd(Graph* graph, CommonOperatorBuilder* common,
     104             :                                 Node* node);
     105             : 
     106             :   // Replace all uses of {node} with the given replacement nodes. All occurring
     107             :   // use kinds need to be replaced, {nullptr} is only valid if a use kind is
     108             :   // guaranteed not to exist.
     109             :   static void ReplaceUses(Node* node, Node* value, Node* effect = nullptr,
     110             :                           Node* success = nullptr, Node* exception = nullptr);
     111             : 
     112             :   // Safe wrapper to mutate the operator of a node. Checks that the node is
     113             :   // currently in a state that satisfies constraints of the new operator.
     114             :   static void ChangeOp(Node* node, const Operator* new_op);
     115             : 
     116             :   // ---------------------------------------------------------------------------
     117             :   // Miscellaneous utilities.
     118             : 
     119             :   // Find the last frame state that is effect-wise before the given node. This
     120             :   // assumes a linear effect-chain up to a {CheckPoint} node in the graph.
     121             :   static Node* FindFrameStateBefore(Node* node);
     122             : 
     123             :   // Collect the output-value projection for the given output index.
     124             :   static Node* FindProjection(Node* node, size_t projection_index);
     125             : 
     126             :   // Collect the value projections from a node.
     127             :   static void CollectValueProjections(Node* node, Node** proj, size_t count);
     128             : 
     129             :   // Collect the branch-related projections from a node, such as IfTrue,
     130             :   // IfFalse, IfSuccess, IfException, IfValue and IfDefault.
     131             :   //  - Branch: [ IfTrue, IfFalse ]
     132             :   //  - Call  : [ IfSuccess, IfException ]
     133             :   //  - Switch: [ IfValue, ..., IfDefault ]
     134             :   static void CollectControlProjections(Node* node, Node** proj, size_t count);
     135             : 
     136             :   // Checks if two nodes are the same, looking past {CheckHeapObject}.
     137             :   static bool IsSame(Node* a, Node* b);
     138             : 
     139             :   // Check if two nodes have equal operators and reference-equal inputs. Used
     140             :   // for value numbering/hash-consing.
     141             :   static bool Equals(Node* a, Node* b);
     142             :   // A corresponding hash function.
     143             :   static size_t HashCode(Node* node);
     144             : 
     145             :   // Walks up the {effect} chain to find a witness that provides map
     146             :   // information about the {receiver}. Can look through potentially
     147             :   // side effecting nodes.
     148             :   enum InferReceiverMapsResult {
     149             :     kNoReceiverMaps,         // No receiver maps inferred.
     150             :     kReliableReceiverMaps,   // Receiver maps can be trusted.
     151             :     kUnreliableReceiverMaps  // Receiver maps might have changed (side-effect),
     152             :                              // but instance type is reliable.
     153             :   };
     154             :   static InferReceiverMapsResult InferReceiverMaps(
     155             :       JSHeapBroker* broker, Node* receiver, Node* effect,
     156             :       ZoneHandleSet<Map>* maps_return);
     157             : 
     158             :   // Return the initial map of the new-target if the allocation can be inlined.
     159             :   static base::Optional<MapRef> GetJSCreateMap(JSHeapBroker* broker,
     160             :                                                Node* receiver);
     161             : 
     162             :   static bool HasInstanceTypeWitness(JSHeapBroker* broker, Node* receiver,
     163             :                                      Node* effect, InstanceType instance_type);
     164             : 
     165             :   // Walks up the {effect} chain to check that there's no observable side-effect
     166             :   // between the {effect} and it's {dominator}. Aborts the walk if there's join
     167             :   // in the effect chain.
     168             :   static bool NoObservableSideEffectBetween(Node* effect, Node* dominator);
     169             : 
     170             :   // Returns true if the {receiver} can be a primitive value (i.e. is not
     171             :   // definitely a JavaScript object); might walk up the {effect} chain to
     172             :   // find map checks on {receiver}.
     173             :   static bool CanBePrimitive(JSHeapBroker* broker, Node* receiver,
     174             :                              Node* effect);
     175             : 
     176             :   // Returns true if the {receiver} can be null or undefined. Might walk
     177             :   // up the {effect} chain to find map checks for {receiver}.
     178             :   static bool CanBeNullOrUndefined(JSHeapBroker* broker, Node* receiver,
     179             :                                    Node* effect);
     180             : 
     181             :   // ---------------------------------------------------------------------------
     182             :   // Context.
     183             : 
     184             :   // Walk up the context chain from the given {node} until we reduce the {depth}
     185             :   // to 0 or hit a node that does not extend the context chain ({depth} will be
     186             :   // updated accordingly).
     187             :   static Node* GetOuterContext(Node* node, size_t* depth);
     188             : 
     189             :   // ---------------------------------------------------------------------------
     190             :   // Type.
     191             : 
     192             :   static bool IsTyped(Node* node) { return !node->type().IsInvalid(); }
     193             :   static Type GetType(Node* node) {
     194             :     DCHECK(IsTyped(node));
     195             :     return node->type();
     196             :   }
     197             :   static Type GetTypeOrAny(Node* node);
     198             :   static void SetType(Node* node, Type type) {
     199             :     DCHECK(!type.IsInvalid());
     200             :     node->set_type(type);
     201             :   }
     202             :   static void RemoveType(Node* node) { node->set_type(Type::Invalid()); }
     203             :   static bool AllValueInputsAreTyped(Node* node);
     204             : 
     205             :  private:
     206             :   static inline bool IsInputRange(Edge edge, int first, int count);
     207             : };
     208             : 
     209             : }  // namespace compiler
     210             : }  // namespace internal
     211             : }  // namespace v8
     212             : 
     213             : #endif  // V8_COMPILER_NODE_PROPERTIES_H_

Generated by: LCOV version 1.10