11cb0ef41Sopenharmony_ci// Copyright 2014 the V8 project authors. All rights reserved.
21cb0ef41Sopenharmony_ci// Use of this source code is governed by a BSD-style license that can be
31cb0ef41Sopenharmony_ci// found in the LICENSE file.
41cb0ef41Sopenharmony_ci
51cb0ef41Sopenharmony_ci#ifndef V8_COMPILER_MACHINE_OPERATOR_REDUCER_H_
61cb0ef41Sopenharmony_ci#define V8_COMPILER_MACHINE_OPERATOR_REDUCER_H_
71cb0ef41Sopenharmony_ci
81cb0ef41Sopenharmony_ci#include "src/base/compiler-specific.h"
91cb0ef41Sopenharmony_ci#include "src/common/globals.h"
101cb0ef41Sopenharmony_ci#include "src/compiler/graph-reducer.h"
111cb0ef41Sopenharmony_ci#include "src/compiler/machine-operator.h"
121cb0ef41Sopenharmony_ci
131cb0ef41Sopenharmony_cinamespace v8 {
141cb0ef41Sopenharmony_cinamespace internal {
151cb0ef41Sopenharmony_cinamespace compiler {
161cb0ef41Sopenharmony_ci
171cb0ef41Sopenharmony_ci// Forward declarations.
181cb0ef41Sopenharmony_ciclass CommonOperatorBuilder;
191cb0ef41Sopenharmony_ciclass MachineGraph;
201cb0ef41Sopenharmony_ciclass Word32Adapter;
211cb0ef41Sopenharmony_ciclass Word64Adapter;
221cb0ef41Sopenharmony_ci
231cb0ef41Sopenharmony_ci// Performs constant folding and strength reduction on nodes that have
241cb0ef41Sopenharmony_ci// machine operators.
251cb0ef41Sopenharmony_ciclass V8_EXPORT_PRIVATE MachineOperatorReducer final
261cb0ef41Sopenharmony_ci    : public NON_EXPORTED_BASE(AdvancedReducer) {
271cb0ef41Sopenharmony_ci public:
281cb0ef41Sopenharmony_ci  explicit MachineOperatorReducer(Editor* editor, MachineGraph* mcgraph,
291cb0ef41Sopenharmony_ci                                  bool allow_signalling_nan = true);
301cb0ef41Sopenharmony_ci  ~MachineOperatorReducer() override;
311cb0ef41Sopenharmony_ci
321cb0ef41Sopenharmony_ci  const char* reducer_name() const override { return "MachineOperatorReducer"; }
331cb0ef41Sopenharmony_ci
341cb0ef41Sopenharmony_ci  Reduction Reduce(Node* node) override;
351cb0ef41Sopenharmony_ci
361cb0ef41Sopenharmony_ci private:
371cb0ef41Sopenharmony_ci  friend class Word32Adapter;
381cb0ef41Sopenharmony_ci  friend class Word64Adapter;
391cb0ef41Sopenharmony_ci
401cb0ef41Sopenharmony_ci  Node* Float32Constant(volatile float value);
411cb0ef41Sopenharmony_ci  Node* Float64Constant(volatile double value);
421cb0ef41Sopenharmony_ci  Node* Int32Constant(int32_t value);
431cb0ef41Sopenharmony_ci  Node* Int64Constant(int64_t value);
441cb0ef41Sopenharmony_ci  Node* Uint32Constant(uint32_t value) {
451cb0ef41Sopenharmony_ci    return Int32Constant(bit_cast<int32_t>(value));
461cb0ef41Sopenharmony_ci  }
471cb0ef41Sopenharmony_ci  Node* Uint64Constant(uint64_t value) {
481cb0ef41Sopenharmony_ci    return Int64Constant(bit_cast<int64_t>(value));
491cb0ef41Sopenharmony_ci  }
501cb0ef41Sopenharmony_ci  Node* Float64Mul(Node* lhs, Node* rhs);
511cb0ef41Sopenharmony_ci  Node* Float64PowHalf(Node* value);
521cb0ef41Sopenharmony_ci  Node* Word32And(Node* lhs, Node* rhs);
531cb0ef41Sopenharmony_ci  Node* Word32And(Node* lhs, uint32_t rhs) {
541cb0ef41Sopenharmony_ci    return Word32And(lhs, Uint32Constant(rhs));
551cb0ef41Sopenharmony_ci  }
561cb0ef41Sopenharmony_ci  Node* Word32Sar(Node* lhs, uint32_t rhs);
571cb0ef41Sopenharmony_ci  Node* Word32Shr(Node* lhs, uint32_t rhs);
581cb0ef41Sopenharmony_ci  Node* Word32Equal(Node* lhs, Node* rhs);
591cb0ef41Sopenharmony_ci  Node* Word64And(Node* lhs, Node* rhs);
601cb0ef41Sopenharmony_ci  Node* Int32Add(Node* lhs, Node* rhs);
611cb0ef41Sopenharmony_ci  Node* Int32Sub(Node* lhs, Node* rhs);
621cb0ef41Sopenharmony_ci  Node* Int32Mul(Node* lhs, Node* rhs);
631cb0ef41Sopenharmony_ci  Node* Int32Div(Node* dividend, int32_t divisor);
641cb0ef41Sopenharmony_ci  Node* Uint32Div(Node* dividend, uint32_t divisor);
651cb0ef41Sopenharmony_ci  Node* TruncateInt64ToInt32(Node* value);
661cb0ef41Sopenharmony_ci
671cb0ef41Sopenharmony_ci  Reduction ReplaceBool(bool value) { return ReplaceInt32(value ? 1 : 0); }
681cb0ef41Sopenharmony_ci  Reduction ReplaceFloat32(volatile float value) {
691cb0ef41Sopenharmony_ci    return Replace(Float32Constant(value));
701cb0ef41Sopenharmony_ci  }
711cb0ef41Sopenharmony_ci  Reduction ReplaceFloat64(volatile double value) {
721cb0ef41Sopenharmony_ci    return Replace(Float64Constant(value));
731cb0ef41Sopenharmony_ci  }
741cb0ef41Sopenharmony_ci  Reduction ReplaceInt32(int32_t value) {
751cb0ef41Sopenharmony_ci    return Replace(Int32Constant(value));
761cb0ef41Sopenharmony_ci  }
771cb0ef41Sopenharmony_ci  Reduction ReplaceUint32(uint32_t value) {
781cb0ef41Sopenharmony_ci    return Replace(Uint32Constant(value));
791cb0ef41Sopenharmony_ci  }
801cb0ef41Sopenharmony_ci  Reduction ReplaceInt64(int64_t value) {
811cb0ef41Sopenharmony_ci    return Replace(Int64Constant(value));
821cb0ef41Sopenharmony_ci  }
831cb0ef41Sopenharmony_ci
841cb0ef41Sopenharmony_ci  Reduction ReduceInt32Add(Node* node);
851cb0ef41Sopenharmony_ci  Reduction ReduceInt64Add(Node* node);
861cb0ef41Sopenharmony_ci  Reduction ReduceInt32Sub(Node* node);
871cb0ef41Sopenharmony_ci  Reduction ReduceInt64Sub(Node* node);
881cb0ef41Sopenharmony_ci  Reduction ReduceInt64Mul(Node* node);
891cb0ef41Sopenharmony_ci  Reduction ReduceInt32Div(Node* node);
901cb0ef41Sopenharmony_ci  Reduction ReduceUint32Div(Node* node);
911cb0ef41Sopenharmony_ci  Reduction ReduceInt32Mod(Node* node);
921cb0ef41Sopenharmony_ci  Reduction ReduceUint32Mod(Node* node);
931cb0ef41Sopenharmony_ci  Reduction ReduceStore(Node* node);
941cb0ef41Sopenharmony_ci  Reduction ReduceProjection(size_t index, Node* node);
951cb0ef41Sopenharmony_ci  const Operator* Map64To32Comparison(const Operator* op, bool sign_extended);
961cb0ef41Sopenharmony_ci  Reduction ReduceWord32Comparisons(Node* node);
971cb0ef41Sopenharmony_ci  Reduction ReduceWord64Comparisons(Node* node);
981cb0ef41Sopenharmony_ci  Reduction ReduceWord32Shifts(Node* node);
991cb0ef41Sopenharmony_ci  Reduction ReduceWord32Shl(Node* node);
1001cb0ef41Sopenharmony_ci  Reduction ReduceWord64Shl(Node* node);
1011cb0ef41Sopenharmony_ci  Reduction ReduceWord32Shr(Node* node);
1021cb0ef41Sopenharmony_ci  Reduction ReduceWord64Shr(Node* node);
1031cb0ef41Sopenharmony_ci  Reduction ReduceWord32Sar(Node* node);
1041cb0ef41Sopenharmony_ci  Reduction ReduceWord64Sar(Node* node);
1051cb0ef41Sopenharmony_ci  Reduction ReduceWord32And(Node* node);
1061cb0ef41Sopenharmony_ci  Reduction ReduceWord64And(Node* node);
1071cb0ef41Sopenharmony_ci  Reduction TryMatchWord32Ror(Node* node);
1081cb0ef41Sopenharmony_ci  Reduction ReduceWord32Or(Node* node);
1091cb0ef41Sopenharmony_ci  Reduction ReduceWord64Or(Node* node);
1101cb0ef41Sopenharmony_ci  Reduction ReduceWord32Xor(Node* node);
1111cb0ef41Sopenharmony_ci  Reduction ReduceWord64Xor(Node* node);
1121cb0ef41Sopenharmony_ci  Reduction ReduceWord32Equal(Node* node);
1131cb0ef41Sopenharmony_ci  Reduction ReduceFloat64InsertLowWord32(Node* node);
1141cb0ef41Sopenharmony_ci  Reduction ReduceFloat64InsertHighWord32(Node* node);
1151cb0ef41Sopenharmony_ci  Reduction ReduceFloat64Compare(Node* node);
1161cb0ef41Sopenharmony_ci  Reduction ReduceFloat64RoundDown(Node* node);
1171cb0ef41Sopenharmony_ci  Reduction ReduceTruncateInt64ToInt32(Node* node);
1181cb0ef41Sopenharmony_ci  Reduction ReduceConditional(Node* node);
1191cb0ef41Sopenharmony_ci
1201cb0ef41Sopenharmony_ci  Graph* graph() const;
1211cb0ef41Sopenharmony_ci  MachineGraph* mcgraph() const { return mcgraph_; }
1221cb0ef41Sopenharmony_ci  CommonOperatorBuilder* common() const;
1231cb0ef41Sopenharmony_ci  MachineOperatorBuilder* machine() const;
1241cb0ef41Sopenharmony_ci
1251cb0ef41Sopenharmony_ci  // These reductions can be applied to operations of different word sizes.
1261cb0ef41Sopenharmony_ci  // Use Word32Adapter or Word64Adapter to specialize for a particular one.
1271cb0ef41Sopenharmony_ci  template <typename WordNAdapter>
1281cb0ef41Sopenharmony_ci  Reduction ReduceWordNAnd(Node* node);
1291cb0ef41Sopenharmony_ci  template <typename WordNAdapter>
1301cb0ef41Sopenharmony_ci  Reduction ReduceWordNOr(Node* node);
1311cb0ef41Sopenharmony_ci  template <typename WordNAdapter>
1321cb0ef41Sopenharmony_ci  Reduction ReduceWordNXor(Node* node);
1331cb0ef41Sopenharmony_ci
1341cb0ef41Sopenharmony_ci  // Tries to simplify "if(x == 0)" by removing the "== 0" and inverting
1351cb0ef41Sopenharmony_ci  // branches.
1361cb0ef41Sopenharmony_ci  Reduction SimplifyBranch(Node* node);
1371cb0ef41Sopenharmony_ci  // Helper for SimplifyBranch; swaps the if/else of a branch.
1381cb0ef41Sopenharmony_ci  void SwapBranches(Node* node);
1391cb0ef41Sopenharmony_ci
1401cb0ef41Sopenharmony_ci  // Helper for ReduceConditional. Does not perform the actual reduction; just
1411cb0ef41Sopenharmony_ci  // returns a new Node that could be used as the input to the condition.
1421cb0ef41Sopenharmony_ci  template <typename WordNAdapter>
1431cb0ef41Sopenharmony_ci  base::Optional<Node*> ReduceConditionalN(Node* node);
1441cb0ef41Sopenharmony_ci
1451cb0ef41Sopenharmony_ci  // Helper for finding a reduced equality condition. Does not perform the
1461cb0ef41Sopenharmony_ci  // actual reduction; just returns a new pair that could be compared for the
1471cb0ef41Sopenharmony_ci  // same outcome.
1481cb0ef41Sopenharmony_ci  template <typename WordNAdapter>
1491cb0ef41Sopenharmony_ci  base::Optional<std::pair<Node*, uint32_t>> ReduceWord32EqualForConstantRhs(
1501cb0ef41Sopenharmony_ci      Node* lhs, uint32_t rhs);
1511cb0ef41Sopenharmony_ci
1521cb0ef41Sopenharmony_ci  MachineGraph* mcgraph_;
1531cb0ef41Sopenharmony_ci  bool allow_signalling_nan_;
1541cb0ef41Sopenharmony_ci};
1551cb0ef41Sopenharmony_ci
1561cb0ef41Sopenharmony_ci}  // namespace compiler
1571cb0ef41Sopenharmony_ci}  // namespace internal
1581cb0ef41Sopenharmony_ci}  // namespace v8
1591cb0ef41Sopenharmony_ci
1601cb0ef41Sopenharmony_ci#endif  // V8_COMPILER_MACHINE_OPERATOR_REDUCER_H_
161