v8
V8 is Google’s open source high-performance JavaScript and WebAssembly engine, written in C++.
Loading...
Searching...
No Matches
instruction-selection-normalization-reducer.h
Go to the documentation of this file.
1// Copyright 2024 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#ifndef V8_COMPILER_TURBOSHAFT_INSTRUCTION_SELECTION_NORMALIZATION_REDUCER_H_
6#define V8_COMPILER_TURBOSHAFT_INSTRUCTION_SELECTION_NORMALIZATION_REDUCER_H_
7
8#include "src/base/bits.h"
14
16
17// InstructionSelectionNormalizationReducer performs some normalization of the
18// graph in order to simplify Instruction Selection. It should run only once,
19// right before Instruction Selection. The normalizations currently performed
20// are:
21//
22// * Making sure that Constants are on the right-hand side of commutative
23// binary operations.
24//
25// * Replacing multiplications by small powers of 2 with shifts.
26
28
29template <typename Next>
31 public:
32 TURBOSHAFT_REDUCER_BOILERPLATE(InstructionSelectionNormalization)
33
34 V<Word> REDUCE(WordBinop)(V<Word> left, V<Word> right, WordBinopOp::Kind kind,
36 // Putting constant on the right side.
38 if (!IsSimpleConstant(right) && IsSimpleConstant(left)) {
39 std::swap(left, right);
40 } else if (!IsComplexConstant(right) && IsComplexConstant(left)) {
41 std::swap(left, right);
42 }
43 }
44
45 // Transforming multiplications by power of two constants into shifts
47 int64_t cst;
48 if (__ matcher().MatchPowerOfTwoWordConstant(right, &cst, rep) &&
49 cst < rep.bit_width()) {
50 return __ ShiftLeft(left, base::bits::WhichPowerOfTwo(cst), rep);
51 }
52 }
53
54 return Next::ReduceWordBinop(left, right, kind, rep);
55 }
56
61 if (!IsSimpleConstant(right) && IsSimpleConstant(left)) {
62 std::swap(left, right);
63 } else if (!IsComplexConstant(right) && IsComplexConstant(left)) {
64 std::swap(left, right);
65 }
66 }
67 return Next::ReduceComparison(left, right, kind, rep);
68 }
69
70 private:
71 // Return true if {index} is a literal ConsantOp.
73 return __ Get(index).template Is<ConstantOp>();
74 }
75 // Return true if {index} is a ConstantOp or a (chain of) Change/Cast/Bitcast
76 // of a ConstantOp. Such an operation is succeptible to be recognized as a
77 // constant by the instruction selector, and as such should rather be on the
78 // right-hande side of commutative binops.
80 const Operation& op = __ Get(index);
81 switch (op.opcode) {
82 case Opcode::kConstant:
83 return true;
84 case Opcode::kChange:
85 return IsComplexConstant(op.Cast<ChangeOp>().input());
86 case Opcode::kTaggedBitcast:
88 case Opcode::kTryChange:
89 return IsComplexConstant(op.Cast<ChangeOp>().input());
90 default:
91 return false;
92 }
93 }
94};
95
97
98} // namespace v8::internal::compiler::turboshaft
99
100#endif // V8_COMPILER_TURBOSHAFT_INSTRUCTION_SELECTION_NORMALIZATION_REDUCER_H_
#define REDUCE(operation)
Builtins::Kind kind
Definition builtins.cc:40
V< Word > REDUCE WordBinop(V< Word > left, V< Word > right, WordBinopOp::Kind kind, WordRepresentation rep)
V< Word32 > REDUCE Comparison(V< Any > left, V< Any > right, ComparisonOp::Kind kind, RegisterRepresentation rep)
#define TURBOSHAFT_REDUCER_BOILERPLATE(Name)
Definition assembler.h:823
constexpr int WhichPowerOfTwo(T value)
Definition bits.h:195
V8_INLINE const Operation & Get(const Graph &graph, OpIndex index)
Definition graph.h:1231
bool Is(IndirectHandle< U > value)
Definition handles-inl.h:51
underlying_operation_t< Op > & Cast()
Definition operations.h:980