V8 API Reference, 7.2.502.16 (for Deno 0.2.4)
constant-folding-reducer.cc
1 // Copyright 2018 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 #include "src/compiler/constant-folding-reducer.h"
6 
7 #include "src/compiler/js-graph.h"
8 #include "src/objects-inl.h"
9 
10 namespace v8 {
11 namespace internal {
12 namespace compiler {
13 
14 ConstantFoldingReducer::ConstantFoldingReducer(Editor* editor, JSGraph* jsgraph,
15  JSHeapBroker* broker)
16  : AdvancedReducer(editor), jsgraph_(jsgraph), broker_(broker) {}
17 
18 ConstantFoldingReducer::~ConstantFoldingReducer() = default;
19 
20 Reduction ConstantFoldingReducer::Reduce(Node* node) {
21  DisallowHeapAccess no_heap_access;
22  // Check if the output type is a singleton. In that case we already know the
23  // result value and can simply replace the node if it's eliminable.
24  if (!NodeProperties::IsConstant(node) && NodeProperties::IsTyped(node) &&
25  node->op()->HasProperty(Operator::kEliminatable)) {
26  // TODO(v8:5303): We must not eliminate FinishRegion here. This special
27  // case can be removed once we have separate operators for value and
28  // effect regions.
29  if (node->opcode() == IrOpcode::kFinishRegion) return NoChange();
30  // We can only constant-fold nodes here, that are known to not cause any
31  // side-effect, may it be a JavaScript observable side-effect or a possible
32  // eager deoptimization exit (i.e. {node} has an operator that doesn't have
33  // the Operator::kNoDeopt property).
34  Type upper = NodeProperties::GetType(node);
35  if (!upper.IsNone()) {
36  Node* replacement = nullptr;
37  if (upper.IsHeapConstant()) {
38  replacement = jsgraph()->Constant(upper.AsHeapConstant()->Ref());
39  } else if (upper.Is(Type::MinusZero())) {
40  Factory* factory = jsgraph()->isolate()->factory();
41  ObjectRef minus_zero(broker(), factory->minus_zero_value());
42  replacement = jsgraph()->Constant(minus_zero);
43  } else if (upper.Is(Type::NaN())) {
44  replacement = jsgraph()->NaNConstant();
45  } else if (upper.Is(Type::Null())) {
46  replacement = jsgraph()->NullConstant();
47  } else if (upper.Is(Type::PlainNumber()) && upper.Min() == upper.Max()) {
48  replacement = jsgraph()->Constant(upper.Min());
49  } else if (upper.Is(Type::Undefined())) {
50  replacement = jsgraph()->UndefinedConstant();
51  }
52  if (replacement) {
53  // Make sure the node has a type.
54  if (!NodeProperties::IsTyped(replacement)) {
55  NodeProperties::SetType(replacement, upper);
56  }
57  ReplaceWithValue(node, replacement);
58  return Changed(replacement);
59  }
60  }
61  }
62  return NoChange();
63 }
64 
65 } // namespace compiler
66 } // namespace internal
67 } // namespace v8
Definition: libplatform.h:13