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
14#include "llvm/IR/Constants.h"
15#include "llvm/IR/IRBuilder.h"
17#include "llvm/IR/Intrinsics.h"
19#include "llvm/IR/Type.h"
20
21using namespace llvm;
22using namespace llvm::PatternMatch;
23
24namespace llvm::slpvectorizer {
25
26static bool matchRdxBop(Instruction *I, Value *&V0, Value *&V1) {
27 if (match(I, m_BinOp(m_Value(V0), m_Value(V1))))
28 return true;
29 if (match(I, m_FMaxNum(m_Value(V0), m_Value(V1))))
30 return true;
31 if (match(I, m_FMinNum(m_Value(V0), m_Value(V1))))
32 return true;
33 if (match(I, m_FMaximum(m_Value(V0), m_Value(V1))))
34 return true;
35 if (match(I, m_FMinimum(m_Value(V0), m_Value(V1))))
36 return true;
38 return true;
40 return true;
42 return true;
44 return true;
45 return false;
46}
47
49 Value *Op0 = nullptr;
50 Value *Op1 = nullptr;
51 if (!matchRdxBop(I, Op0, Op1))
52 return nullptr;
53 return dyn_cast<Instruction>(Op0 == Phi ? Op1 : Op0);
54}
55
57 bool IsSelect = match(I, m_Select(m_Value(), m_Value(), m_Value()));
58 Value *B0 = nullptr, *B1 = nullptr;
59 bool IsBinop = matchRdxBop(I, B0, B1);
60 return IsBinop || IsSelect;
61}
62
63Type *getBoolReduxWideTy(RecurKind RdxKind, Type *RootTy, Type *LeafTy) {
64 if ((RdxKind == RecurKind::And || RdxKind == RecurKind::Or) &&
65 RootTy->isIntegerTy(1) && LeafTy->isIntegerTy() &&
66 !LeafTy->isIntegerTy(1))
67 return LeafTy;
68 return nullptr;
69}
70
73 RecurKind RdxKind, Value *Vec,
74 const Value *Root, FastMathFlags FMF,
76 auto *VecTy = cast<FixedVectorType>(Vec->getType());
77 unsigned VF = VecTy->getNumElements();
78 auto *I1VecTy = FixedVectorType::get(Builder.getInt1Ty(), VF);
79 DebugLoc DL = Builder.getCurrentDebugLocation();
80 Builder.SetCurrentDebugLocation(cast<Instruction>(Root)->getDebugLoc());
81 Value *T = Builder.CreateTrunc(Vec, I1VecTy);
82 Value *BC = Builder.CreateBitCast(T, Builder.getIntNTy(VF));
85 Constant *RHS = RdxKind == RecurKind::And
88 Value *Res = Builder.CreateICmp(Pred, BC, RHS);
89 // The costs are evaluated from the emitted instructions; they are dropped
90 // if the wide reduction form is cheaper.
91 auto CastCost = [&](Value *V, unsigned Opcode, Type *SrcTy) {
92 auto *I = dyn_cast<Instruction>(V);
93 if (!I)
94 return InstructionCost(0);
95 return TTI.getCastInstrCost(Opcode, I->getType(), SrcTy,
96 TTI.getCastContextHint(I), CostKind, I);
97 };
98 InstructionCost BitcastCmpCost = CastCost(T, Instruction::Trunc, VecTy) +
99 CastCost(BC, Instruction::BitCast, I1VecTy);
100 if (auto *Cmp = dyn_cast<Instruction>(Res))
101 BitcastCmpCost += TTI.getCmpSelInstrCost(
102 Instruction::ICmp, BC->getType(), /*CondTy=*/nullptr, Pred, CostKind,
103 TTI.getOperandInfo(BC), TTI.getOperandInfo(RHS), Cmp);
104 if (BitcastCmpCost >=
105 getBoolReduxWideRdxCost(TTI, RdxKind, VecTy, Root, FMF, CostKind)) {
106 for (Value *V : {Res, BC, T})
107 if (auto *I = dyn_cast<Instruction>(V))
108 I->eraseFromParent();
109 Builder.SetCurrentDebugLocation(DL);
110 return nullptr;
111 }
112 Builder.SetCurrentDebugLocation(DL);
113 return Res;
114}
115
116} // 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()))
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 debug info location.
Definition DebugLoc.h:126
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 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...
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)
This is an optimization pass for GlobalISel generic memory operations.
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:643
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