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* js_heap_broker) 16 : AdvancedReducer(editor), 17 jsgraph_(jsgraph), 18 js_heap_broker_(js_heap_broker) {} 19 20 ConstantFoldingReducer::~ConstantFoldingReducer() {} 21 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