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