LLVM 24.0.0git
SLPReductionUtils.cpp
Go to the documentation of this file.
1//===- SLPReductionUtils.cpp - SLP reduction match helpers ----------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#include "SLPReductionUtils.h"
10
11#include "SLPCostAnalysis.h"
12#include "SLPUtils.h"
13
17#include "llvm/IR/Constants.h"
18#include "llvm/IR/DataLayout.h"
19#include "llvm/IR/IRBuilder.h"
21#include "llvm/IR/Intrinsics.h"
23#include "llvm/IR/Type.h"
24
25using namespace llvm;
26using namespace llvm::PatternMatch;
27
28namespace llvm::slpvectorizer {
29
30static bool matchRdxBop(Instruction *I, Value *&V0, Value *&V1) {
31 if (match(I, m_BinOp(m_Value(V0), m_Value(V1))))
32 return true;
33 if (match(I, m_FMaxNum(m_Value(V0), m_Value(V1))))
34 return true;
35 if (match(I, m_FMinNum(m_Value(V0), m_Value(V1))))
36 return true;
37 if (match(I, m_FMaximum(m_Value(V0), m_Value(V1))))
38 return true;
39 if (match(I, m_FMinimum(m_Value(V0), m_Value(V1))))
40 return true;
42 return true;
44 return true;
46 return true;
48 return true;
49 return false;
50}
51
53 Value *Op0 = nullptr;
54 Value *Op1 = nullptr;
55 if (!matchRdxBop(I, Op0, Op1))
56 return nullptr;
57 return dyn_cast<Instruction>(Op0 == Phi ? Op1 : Op0);
58}
59
61 bool IsSelect = match(I, m_Select(m_Value(), m_Value(), m_Value()));
62 Value *B0 = nullptr, *B1 = nullptr;
63 bool IsBinop = matchRdxBop(I, B0, B1);
64 return IsBinop || IsSelect;
65}
66
67Type *getBoolReduxWideTy(RecurKind RdxKind, Type *RootTy, Type *LeafTy) {
68 if ((RdxKind == RecurKind::And || RdxKind == RecurKind::Or) &&
69 RootTy->isIntegerTy(1) && LeafTy->isIntegerTy() &&
70 !LeafTy->isIntegerTy(1))
71 return LeafTy;
72 return nullptr;
73}
74
76 RecurKind RdxKind,
77 const SmallDenseMap<Value *, NarrowedLeafInfo> &NarrowedLeafShifts,
78 const DataLayout &DL) {
79 if (RdxKind != RecurKind::Or || DL.isBigEndian() ||
80 NarrowedLeafShifts.empty())
81 return BoolBitmask::None;
82 unsigned NumLeaves = NarrowedLeafShifts.size();
83 SmallBitVector Seen(NumLeaves);
84 bool NeedMask = false;
85 for (const auto &[V, L] : NarrowedLeafShifts) {
86 if (L.Shift >= NumLeaves || Seen.test(L.Shift))
87 return BoolBitmask::None;
88 Seen.set(L.Shift);
90 // The masked leaf must be known to be 0 or 1.
91 if ((L.Mask & ~Known.Zero).ugt(1))
92 return BoolBitmask::None;
93 // The mask is redundant if it keeps all not-known-zero bits.
94 NeedMask |= !(Known.Zero | L.Mask).isAllOnes();
95 }
97}
98
101 RecurKind RdxKind, Value *Vec,
102 const Value *Root, FastMathFlags FMF,
104 auto *VecTy = cast<FixedVectorType>(Vec->getType());
105 unsigned VF = VecTy->getNumElements();
106 auto *I1VecTy = FixedVectorType::get(Builder.getInt1Ty(), VF);
107 DebugLoc DL = Builder.getCurrentDebugLocation();
108 Builder.SetCurrentDebugLocation(cast<Instruction>(Root)->getDebugLoc());
109 Value *T = Builder.CreateTrunc(Vec, I1VecTy);
110 Value *BC = Builder.CreateBitCast(T, Builder.getIntNTy(VF));
111 CmpInst::Predicate Pred =
113 Constant *RHS = RdxKind == RecurKind::And
116 Value *Res = Builder.CreateICmp(Pred, BC, RHS);
117 // The costs are evaluated from the emitted instructions; they are dropped
118 // if the wide reduction form is cheaper.
119 auto CastCost = [&](Value *V, unsigned Opcode, Type *SrcTy) {
120 auto *I = dyn_cast<Instruction>(V);
121 if (!I)
122 return InstructionCost(0);
123 return TTI.getCastInstrCost(Opcode, I->getType(), SrcTy,
124 TTI.getCastContextHint(I), CostKind, I);
125 };
126 InstructionCost BitcastCmpCost = CastCost(T, Instruction::Trunc, VecTy) +
127 CastCost(BC, Instruction::BitCast, I1VecTy);
128 if (auto *Cmp = dyn_cast<Instruction>(Res))
129 BitcastCmpCost += TTI.getCmpSelInstrCost(
130 Instruction::ICmp, BC->getType(), /*CondTy=*/nullptr, Pred, CostKind,
131 TTI.getOperandInfo(BC), TTI.getOperandInfo(RHS), Cmp);
132 if (BitcastCmpCost >=
133 getBoolReduxWideRdxCost(TTI, RdxKind, VecTy, Root, FMF, CostKind)) {
134 for (Value *V : {Res, BC, T})
135 if (auto *I = dyn_cast<Instruction>(V))
136 I->eraseFromParent();
137 Builder.SetCurrentDebugLocation(DL);
138 return nullptr;
139 }
140 Builder.SetCurrentDebugLocation(DL);
141 return Res;
142}
143
144} // namespace llvm::slpvectorizer
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
This file contains the declarations for the subclasses of Constant, which represent the different fla...
static cl::opt< OutputCostKind > CostKind("cost-kind", cl::desc("Target cost kind"), cl::init(OutputCostKind::RecipThroughput), cl::values(clEnumValN(OutputCostKind::RecipThroughput, "throughput", "Reciprocal throughput"), clEnumValN(OutputCostKind::Latency, "latency", "Instruction latency"), clEnumValN(OutputCostKind::CodeSize, "code-size", "Code size"), clEnumValN(OutputCostKind::SizeAndLatency, "size-latency", "Code size and latency"), clEnumValN(OutputCostKind::All, "all", "Print all cost kinds")))
#define I(x, y, z)
Definition MD5.cpp:57
#define T
static bool IsSelect(unsigned Opcode, bool CheckOnlyCC=false)
Check if the opcode is a SELECT or SELECT_CC variant.
Func MI getDebugLoc()))
This file implements the SmallBitVector class.
Predicate
This enumeration lists the possible predicates for CmpInst subclasses.
Definition InstrTypes.h:740
@ ICMP_NE
not equal
Definition InstrTypes.h:762
This is an important base class in LLVM.
Definition Constant.h:43
static LLVM_ABI Constant * getAllOnesValue(Type *Ty)
static LLVM_ABI Constant * getNullValue(Type *Ty)
Constructor to create a '0' constant of arbitrary type.
A parsed version of the target data layout string in and methods for querying it.
Definition DataLayout.h:64
A debug info location.
Definition DebugLoc.h:126
bool empty() const
Definition DenseMap.h:732
unsigned size() const
Definition DenseMap.h:733
Convenience struct for specifying and reasoning about fast-math flags.
Definition FMF.h:23
static LLVM_ABI FixedVectorType * get(Type *ElementType, unsigned NumElts)
Definition Type.cpp:843
Common base class shared among various IRBuilders.
Definition IRBuilder.h:114
This is a 'bitvector' (really, a variable-sized bit array), optimized for the case when the array is ...
SmallBitVector & set()
bool test(unsigned Idx) const
Returns true if bit Idx is set.
This pass provides access to the codegen interfaces that are needed for IR-level transformations.
TargetCostKind
The kind of cost model.
The instances of the Type class are immutable: once they are created, they are never changed.
Definition Type.h:46
bool isIntegerTy() const
True if this is an instance of IntegerType.
Definition Type.h:252
LLVM Value Representation.
Definition Value.h:75
Type * getType() const
All values are typed, get the type of this value.
Definition Value.h:257
bool match(Val *V, const Pattern &P)
ThreeOps_match< Cond, LHS, RHS, Instruction::Select > m_Select(const Cond &C, const LHS &L, const RHS &R)
Matches SelectInst.
auto m_BinOp()
Match an arbitrary binary operation and ignore it.
auto m_FMinimum(const Opnd0 &Op0, const Opnd1 &Op1)
auto m_Value()
Match an arbitrary value and ignore it.
auto m_FMaximum(const Opnd0 &Op0, const Opnd1 &Op1)
auto m_Intrinsic(const Ts &...Ops)
Match intrinsic calls like this: m_Intrinsic<Intrinsic::fabs>(m_Value(X))
auto m_FMinNum(const Opnd0 &Op0, const Opnd1 &Op1)
auto m_FMaxNum(const Opnd0 &Op0, const Opnd1 &Op1)
A private "module" namespace for types and utilities used by this pass.
Type * getBoolReduxWideTy(RecurKind RdxKind, Type *RootTy, Type *LeafTy)
Value * tryEmitBoolReduxBitcastCmp(IRBuilderBase &Builder, const TargetTransformInfo &TTI, RecurKind RdxKind, Value *Vec, const Value *Root, FastMathFlags FMF, const TTI::TargetCostKind CostKind)
Emits the booleanized logical and/or reduction of Vec with the i1 root Root as trunc+bitcast+cmp (all...
BoolBitmask isBoolBitmaskRdx(RecurKind RdxKind, const SmallDenseMap< Value *, NarrowedLeafInfo > &NarrowedLeafShifts, const DataLayout &DL)
InstructionCost getBoolReduxWideRdxCost(const TargetTransformInfo &TTI, RecurKind RdxKind, FixedVectorType *VecTy, const Value *Root, FastMathFlags FMF, const TTI::TargetCostKind CostKind)
Returns the cost of the booleanized logical and/or reduction of a vector of type VecTy with the i1 ro...
static bool matchRdxBop(Instruction *I, Value *&V0, Value *&V1)
Instruction * getNonPhiOperand(Instruction *I, PHINode *Phi)
bool isReductionCandidate(Instruction *I)
BoolBitmask
The result of matching a boolean bitmask reduction over narrowed leaves.
This is an optimization pass for GlobalISel generic memory operations.
@ Known
Known to have no common set bits.
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:643
LLVM_ABI void computeKnownBits(const Value *V, KnownBits &Known, const DataLayout &DL, AssumptionCache *AC=nullptr, const Instruction *CtxI=nullptr, const DominatorTree *DT=nullptr, bool UseInstrInfo=true, unsigned Depth=0)
Determine which bits of V are known to be either zero or one and return them in the KnownZero/KnownOn...
TargetTransformInfo TTI
RecurKind
These are the kinds of recurrences that we support.
@ Or
Bitwise or logical OR of integers.
@ And
Bitwise or logical AND of integers.
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:559