• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2022 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_SIMPLIFIED_LOWERING_VERIFIER_H_
6 #define V8_COMPILER_SIMPLIFIED_LOWERING_VERIFIER_H_
7 
8 #include "src/compiler/representation-change.h"
9 
10 namespace v8 {
11 namespace internal {
12 namespace compiler {
13 
14 class OperationTyper;
15 
16 class SimplifiedLoweringVerifier final {
17  public:
18   struct PerNodeData {
19     base::Optional<Type> type = base::nullopt;
20     Truncation truncation = Truncation::Any(IdentifyZeros::kDistinguishZeros);
21   };
22 
SimplifiedLoweringVerifier(Zone * zone,Graph * graph)23   SimplifiedLoweringVerifier(Zone* zone, Graph* graph)
24       : hints_(zone), data_(zone), graph_(graph) {}
25 
26   void VisitNode(Node* node, OperationTyper& op_typer);
27 
RecordHint(Node * node)28   void RecordHint(Node* node) {
29     DCHECK_EQ(node->opcode(), IrOpcode::kSLVerifierHint);
30     hints_.push_back(node);
31   }
inserted_hints()32   const ZoneVector<Node*>& inserted_hints() const { return hints_; }
33 
GetType(Node * node)34   base::Optional<Type> GetType(Node* node) const {
35     if (NodeProperties::IsTyped(node)) {
36       return NodeProperties::GetType(node);
37     }
38     // For nodes that have not been typed before SL, we use the type that has
39     // been inferred by the verifier.
40     if (node->id() < data_.size()) {
41       return data_[node->id()].type;
42     }
43     return base::nullopt;
44   }
45 
46  private:
ResizeDataIfNecessary(Node * node)47   void ResizeDataIfNecessary(Node* node) {
48     if (data_.size() <= node->id()) {
49       data_.resize(node->id() + 1);
50     }
51     DCHECK_EQ(data_[node->id()].truncation,
52               Truncation::Any(IdentifyZeros::kDistinguishZeros));
53   }
54 
SetType(Node * node,const Type & type)55   void SetType(Node* node, const Type& type) {
56     ResizeDataIfNecessary(node);
57     data_[node->id()].type = type;
58   }
59 
InputType(Node * node,int input_index)60   Type InputType(Node* node, int input_index) const {
61     // TODO(nicohartmann): Check that inputs are typed, once all operators are
62     // supported.
63     Node* input = node->InputAt(input_index);
64     if (NodeProperties::IsTyped(input)) {
65       return NodeProperties::GetType(input);
66     }
67     // For nodes that have not been typed before SL, we use the type that has
68     // been inferred by the verifier.
69     base::Optional<Type> type_opt;
70     if (input->id() < data_.size()) {
71       type_opt = data_[input->id()].type;
72     }
73     return type_opt.has_value() ? *type_opt : Type::None();
74   }
75 
SetTruncation(Node * node,const Truncation & truncation)76   void SetTruncation(Node* node, const Truncation& truncation) {
77     ResizeDataIfNecessary(node);
78     data_[node->id()].truncation = truncation;
79   }
80 
InputTruncation(Node * node,int input_index)81   Truncation InputTruncation(Node* node, int input_index) const {
82     static const Truncation any_truncation =
83         Truncation::Any(IdentifyZeros::kDistinguishZeros);
84 
85     Node* input = node->InputAt(input_index);
86     if (input->id() < data_.size()) {
87       return data_[input->id()].truncation;
88     }
89     return any_truncation;
90   }
91 
92   void CheckType(Node* node, const Type& type);
93   void CheckAndSet(Node* node, const Type& type, const Truncation& trunc);
94 
95   // Generalize to a less strict truncation in the context of a given type. For
96   // example, a Truncation::kWord32[kIdentifyZeros] does not have any effect on
97   // a type Range(0, 100), because all equivalence classes are singleton, for
98   // the values of the given type. We can use Truncation::Any[kDistinguishZeros]
99   // instead to avoid a combinatorial explosion of occurring type-truncation-
100   // pairs.
101   Truncation GeneralizeTruncation(const Truncation& truncation,
102                                   const Type& type) const;
103 
graph_zone()104   Zone* graph_zone() const { return graph_->zone(); }
105 
106   ZoneVector<Node*> hints_;
107   ZoneVector<PerNodeData> data_;
108   Graph* graph_;
109 };
110 
111 }  // namespace compiler
112 }  // namespace internal
113 }  // namespace v8
114 
115 #endif  // V8_COMPILER_SIMPLIFIED_LOWERING_VERIFIER_H_
116