Line data Source code
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 928926 : ConstantFoldingReducer::ConstantFoldingReducer(Editor* editor, JSGraph* jsgraph,
15 : JSHeapBroker* broker)
16 928926 : : AdvancedReducer(editor), jsgraph_(jsgraph), broker_(broker) {}
17 :
18 : ConstantFoldingReducer::~ConstantFoldingReducer() = default;
19 :
20 70167704 : 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 109482533 : 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 32142160 : 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 31005367 : Type upper = NodeProperties::GetType(node);
35 31005367 : if (!upper.IsNone()) {
36 : Node* replacement = nullptr;
37 30969629 : if (upper.IsHeapConstant()) {
38 192938 : replacement = jsgraph()->Constant(upper.AsHeapConstant()->Ref());
39 30777171 : } else if (upper.Is(Type::MinusZero())) {
40 : Factory* factory = jsgraph()->isolate()->factory();
41 24 : ObjectRef minus_zero(broker(), factory->minus_zero_value());
42 24 : replacement = jsgraph()->Constant(minus_zero);
43 30777035 : } else if (upper.Is(Type::NaN())) {
44 397 : replacement = jsgraph()->NaNConstant();
45 30776663 : } else if (upper.Is(Type::Null())) {
46 1 : replacement = jsgraph()->NullConstant();
47 30776553 : } else if (upper.Is(Type::PlainNumber()) && upper.Min() == upper.Max()) {
48 35777 : replacement = jsgraph()->Constant(upper.Min());
49 30740792 : } else if (upper.Is(Type::Undefined())) {
50 1 : replacement = jsgraph()->UndefinedConstant();
51 : }
52 30970246 : if (replacement) {
53 : // Make sure the node has a type.
54 229137 : 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 122036 : } // namespace v8
|