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 928279 : ConstantFoldingReducer::ConstantFoldingReducer(Editor* editor, JSGraph* jsgraph,
15 : JSHeapBroker* broker)
16 928279 : : AdvancedReducer(editor), jsgraph_(jsgraph), broker_(broker) {}
17 :
18 : ConstantFoldingReducer::~ConstantFoldingReducer() = default;
19 :
20 70101349 : 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 109390448 : 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 32120600 : 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 30987519 : Type upper = NodeProperties::GetType(node);
35 30987519 : if (!upper.IsNone()) {
36 : Node* replacement = nullptr;
37 30951465 : if (upper.IsHeapConstant()) {
38 192586 : replacement = jsgraph()->Constant(upper.AsHeapConstant()->Ref());
39 30759461 : } 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 30759345 : } else if (upper.Is(Type::NaN())) {
44 397 : replacement = jsgraph()->NaNConstant();
45 30758945 : } else if (upper.Is(Type::Null())) {
46 1 : replacement = jsgraph()->NullConstant();
47 30758852 : } else if (upper.Is(Type::PlainNumber()) && upper.Min() == upper.Max()) {
48 35762 : replacement = jsgraph()->Constant(upper.Min());
49 30723116 : } else if (upper.Is(Type::Undefined())) {
50 1 : replacement = jsgraph()->UndefinedConstant();
51 : }
52 30952184 : if (replacement) {
53 : // Make sure the node has a type.
54 228769 : 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 121996 : } // namespace v8
|