LLVM 24.0.0git
RISCVCodeGenPrepare.cpp
Go to the documentation of this file.
1//===----- RISCVCodeGenPrepare.cpp ----------------------------------------===//
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// This is a RISC-V specific version of CodeGenPrepare.
10// It munges the code in the input function to better prepare it for
11// SelectionDAG-based code generation. This works around limitations in it's
12// basic-block-at-a-time approach.
13//
14//===----------------------------------------------------------------------===//
15
16#include "RISCV.h"
17#include "RISCVTargetMachine.h"
18#include "llvm/ADT/Statistic.h"
21#include "llvm/IR/Dominators.h"
22#include "llvm/IR/IRBuilder.h"
23#include "llvm/IR/InstVisitor.h"
25#include "llvm/IR/Intrinsics.h"
28#include "llvm/Pass.h"
30
31using namespace llvm;
32
33#define DEBUG_TYPE "riscv-codegenprepare"
34#define PASS_NAME "RISC-V CodeGenPrepare"
35
36namespace {
37class RISCVCodeGenPrepareImpl
38 : public InstVisitor<RISCVCodeGenPrepareImpl, bool> {
39 Function &F;
40 const DataLayout *DL;
41 const DominatorTree *DT;
42 const RISCVSubtarget *ST;
43
44public:
45 RISCVCodeGenPrepareImpl(Function &F, const DominatorTree *DT,
46 const RISCVSubtarget *ST)
47 : F(F), DL(&F.getDataLayout()), DT(DT), ST(ST) {}
48 bool run();
49 bool visitInstruction(Instruction &I) { return false; }
50 bool visitAnd(BinaryOperator &BO);
51 bool visitMul(BinaryOperator &BO);
52 bool visitIntrinsicInst(IntrinsicInst &I);
53 bool expandVPStrideLoad(IntrinsicInst &I);
54 bool expandMulReduction(IntrinsicInst &I);
55 bool widenVPMerge(Instruction *I);
56 bool visitFreezeInst(FreezeInst &BO);
57};
58} // namespace
59
60namespace {
61class RISCVCodeGenPrepareLegacy : public FunctionPass {
62public:
63 static char ID;
64
65 RISCVCodeGenPrepareLegacy() : FunctionPass(ID) {}
66
67 bool runOnFunction(Function &F) override;
68 StringRef getPassName() const override { return PASS_NAME; }
69
70 void getAnalysisUsage(AnalysisUsage &AU) const override {
71 AU.setPreservesCFG();
72 AU.addRequired<DominatorTreeWrapperPass>();
73 AU.addRequired<TargetPassConfig>();
74 }
75};
76} // namespace
77
78// Try to optimize (i64 (and (zext/sext (i32 X), C1))) if C1 has bit 31 set,
79// but bits 63:32 are zero. If we know that bit 31 of X is 0, we can fill
80// the upper 32 bits with ones.
81bool RISCVCodeGenPrepareImpl::visitAnd(BinaryOperator &BO) {
82 if (!ST->is64Bit())
83 return false;
84
85 if (!BO.getType()->isIntegerTy(64))
86 return false;
87
88 using namespace PatternMatch;
89
90 // Left hand side should be a zext nneg.
91 Value *LHSSrc;
92 if (!match(BO.getOperand(0), m_NNegZExt(m_Value(LHSSrc))))
93 return false;
94
95 if (!LHSSrc->getType()->isIntegerTy(32))
96 return false;
97
98 // Right hand side should be a constant.
99 Value *RHS = BO.getOperand(1);
100
101 auto *CI = dyn_cast<ConstantInt>(RHS);
102 if (!CI)
103 return false;
104 uint64_t C = CI->getZExtValue();
105
106 // Look for constants that fit in 32 bits but not simm12, and can be made
107 // into simm12 by sign extending bit 31. This will allow use of ANDI.
108 // TODO: Is worth making simm32?
110 return false;
111
112 // Sign extend the constant and replace the And operand.
114 BO.setOperand(1, ConstantInt::get(RHS->getType(), C));
115
116 return true;
117}
118
119// Look for (mul (zext X), (splat Y)) where zext is doubling the
120// element size and Y is known to be zero extended. Replace with
121// (mul (zext X), (zext (splat (trunc Y)))) to encourage the use of
122// widening multiply. Only do this if the splat isn't already in the same
123// basic block as the mul. We put the zext with the mul and the new
124// splat and trunc in the basic block with the original splat.
125// We only need to do this when sinkSplatOperands() is false, otherwise
126// CodeGenPrepare will just sink the splat and SelectionDAG can sort it out.
127// TODO: Extend to sign extend or mismatched extends.
128bool RISCVCodeGenPrepareImpl::visitMul(BinaryOperator &BO) {
129 using namespace PatternMatch;
130
131 if (!ST->hasVInstructions() || ST->sinkSplatOperands())
132 return false;
133
134 Value *LHS = BO.getOperand(0);
135 Value *RHS = BO.getOperand(1);
136
137 // Canonicalize zext to the LHS.
138 if (isa<ZExtInst>(RHS))
139 std::swap(LHS, RHS);
140
141 // LHS should be a zext.
142 Value *ZExtSrc;
143 if (!match(LHS, m_ZExt(m_Value(ZExtSrc))))
144 return false;
145
146 // RHS should be a splat shuffle.
147 Value *SplatVal;
148 Instruction *RHSI;
149 if (!match(RHS, m_Instruction(RHSI, m_OneUse(m_Splat(m_Value(SplatVal))))))
150 return false;
151
152 // zext should be in the same basic block as the mul.
154 return false;
155
156 // The extend should be doubling.
157 unsigned Size = BO.getType()->getScalarSizeInBits();
158 unsigned SrcSize = ZExtSrc->getType()->getScalarSizeInBits();
159 if (Size != SrcSize * 2)
160 return false;
161
162 // Types should be legal.
163 if (Size != 64 && Size != 32 && Size != 16)
164 return false;
165 if (Size == 64 && !ST->hasVInstructionsI64())
166 return false;
167
168 // Splat should be in another basic block.
169 if (RHSI->getParent() == BO.getParent())
170 return false;
171
172 // Make sure we can freely truncate the value.
173 KnownBits Known = computeKnownBits(SplatVal, *DL);
174 if (Known.countMaxActiveBits() > SrcSize)
175 return false;
176
177 VectorType *VecTy = cast<VectorType>(ZExtSrc->getType());
178 Type *ScalarTy = VecTy->getElementType();
179 IRBuilder<> Builder(RHSI);
180 Value *Splat = Builder.CreateVectorSplat(
181 VecTy->getElementCount(), Builder.CreateTrunc(SplatVal, ScalarTy));
182
183 Builder.SetInsertPoint(&BO);
184 Value *NewZExt = Builder.CreateZExt(Splat, BO.getType());
185
186 RHSI->replaceAllUsesWith(NewZExt);
187 RHSI->eraseFromParent();
188
189 return true;
190}
191
192// With EVL tail folding, an AnyOf reduction will generate an i1 vp.merge like
193// follows:
194//
195// loop:
196// %phi = phi <vscale x 4 x i1> [zeroinitializer, %entry], [%freeze, %loop]
197// %cmp = icmp ...
198// %rec = call <vscale x 4 x i1> @llvm.vp.merge(%cmp, i1 true, %phi, %evl)
199// %freeze = freeze <vscale x 4 x i1> %rec [optional]
200// ...
201// middle:
202// %res = call i1 @llvm.vector.reduce.or(<vscale x 4 x i1> %freeze)
203//
204// However RVV doesn't have any tail undisturbed mask instructions and so we
205// need a convoluted sequence of mask instructions to lower the i1 vp.merge: see
206// llvm/test/CodeGen/RISCV/rvv/vpmerge-sdnode.ll.
207//
208// To avoid that this widens the i1 vp.merge to an i8 vp.merge, which will
209// generate a single vmerge.vim:
210//
211// loop:
212// %phi = phi <vscale x 4 x i8> [zeroinitializer, %entry], [%freeze, %loop]
213// %cmp = icmp ...
214// %rec = call <vscale x 4 x i8> @llvm.vp.merge(%cmp, i8 true, %phi, %evl)
215// %freeze = freeze <vscale x 4 x i8> %rec
216// %trunc = trunc <vscale x 4 x i8> %freeze to <vscale x 4 x i1>
217// ...
218// middle:
219// %res = call i1 @llvm.vector.reduce.or(<vscale x 4 x i1> %trunc)
220//
221// The trunc will normally be sunk outside of the loop, but even if there are
222// users inside the loop it is still profitable.
223bool RISCVCodeGenPrepareImpl::widenVPMerge(Instruction *Root) {
224 if (!Root->getType()->getScalarType()->isIntegerTy(1))
225 return false;
226
227 Value *Mask, *True, *EVL;
228 PHINode *Phi;
229 using namespace PatternMatch;
230 auto m_VPMerge = m_Intrinsic<Intrinsic::vp_merge>(
231 m_Value(Mask), m_Value(True), m_Phi(Phi), m_Value(EVL));
232 if (!match(Root, m_CombineOr(m_VPMerge, m_Freeze(m_VPMerge))))
233 return false;
234
235 if (!Phi->hasOneUse() || Phi->getNumIncomingValues() != 2 ||
236 !match(Phi->getIncomingValue(0), m_Zero()) ||
237 Phi->getIncomingValue(1) != Root)
238 return false;
239
240 Type *WideTy =
241 VectorType::get(IntegerType::getInt8Ty(Root->getContext()),
242 cast<VectorType>(Root->getType())->getElementCount());
243
244 IRBuilder<> Builder(Phi);
245 PHINode *WidePhi = Builder.CreatePHI(WideTy, 2);
247 Phi->getIncomingBlock(0));
248 Builder.SetInsertPoint(Root);
249 Value *WideTrue = Builder.CreateZExt(True, WideTy);
250 Value *WideMerge = Builder.CreateIntrinsic(Intrinsic::vp_merge, {WideTy},
251 {Mask, WideTrue, WidePhi, EVL});
252 if (isa<FreezeInst>(Root))
253 WideMerge = Builder.CreateFreeze(WideMerge);
254 WidePhi->addIncoming(WideMerge, Phi->getIncomingBlock(1));
255 Value *Trunc = Builder.CreateTrunc(WideMerge, Root->getType());
256
257 Root->replaceAllUsesWith(Trunc);
258
259 // Break the cycle and delete the old chain.
260 Phi->setIncomingValue(1, Phi->getIncomingValue(0));
262
263 return true;
264}
265
266bool RISCVCodeGenPrepareImpl::visitFreezeInst(FreezeInst &I) {
267 if (auto *II = dyn_cast<IntrinsicInst>(I.getOperand(0)))
268 if (II->getIntrinsicID() == Intrinsic::vp_merge)
269 return widenVPMerge(&I);
270 return false;
271}
272
273// LLVM vector reduction intrinsics return a scalar result, but on RISC-V vector
274// reduction instructions write the result in the first element of a vector
275// register. So when a reduction in a loop uses a scalar phi, we end up with
276// unnecessary scalar moves:
277//
278// loop:
279// vfmv.s.f v10, fa0
280// vfredosum.vs v8, v8, v10
281// vfmv.f.s fa0, v8
282//
283// This mainly affects ordered fadd reductions and VP reductions that have a
284// scalar start value, since other types of reduction typically use element-wise
285// vectorisation in the loop body. This tries to vectorize any scalar phis that
286// feed into these reductions:
287//
288// loop:
289// %phi = phi <float> [ ..., %entry ], [ %acc, %loop ]
290// %acc = call float @llvm.vector.reduce.fadd.nxv2f32(float %phi,
291// <vscale x 2 x float> %vec)
292//
293// ->
294//
295// loop:
296// %phi = phi <vscale x 2 x float> [ ..., %entry ], [ %acc.vec, %loop ]
297// %phi.scalar = extractelement <vscale x 2 x float> %phi, i64 0
298// %acc = call float @llvm.vector.reduce.fadd.nxv2f32(float %x,
299// <vscale x 2 x float> %vec)
300// %acc.vec = insertelement <vscale x 2 x float> poison, float %acc.next, i64 0
301//
302// Which eliminates the scalar -> vector -> scalar crossing during instruction
303// selection.
304bool RISCVCodeGenPrepareImpl::visitIntrinsicInst(IntrinsicInst &I) {
305 if (expandVPStrideLoad(I))
306 return true;
307
308 if (expandMulReduction(I))
309 return true;
310
311 if (widenVPMerge(&I))
312 return true;
313
314 if (I.getIntrinsicID() != Intrinsic::vector_reduce_fadd &&
316 return false;
317
318 auto *PHI = dyn_cast<PHINode>(I.getOperand(0));
319 if (!PHI || !PHI->hasOneUse() ||
320 !llvm::is_contained(PHI->incoming_values(), &I))
321 return false;
322
323 Type *VecTy = I.getOperand(1)->getType();
324 IRBuilder<> Builder(PHI);
325 auto *VecPHI = Builder.CreatePHI(VecTy, PHI->getNumIncomingValues());
326
327 for (auto *BB : PHI->blocks()) {
328 Builder.SetInsertPoint(BB->getTerminator());
329 Value *InsertElt = Builder.CreateInsertElement(
330 VecTy, PHI->getIncomingValueForBlock(BB), (uint64_t)0);
331 VecPHI->addIncoming(InsertElt, BB);
332 }
333
334 Builder.SetInsertPoint(&I);
335 I.setOperand(0, Builder.CreateExtractElement(VecPHI, (uint64_t)0));
336
337 PHI->eraseFromParent();
338
339 return true;
340}
341
342// Extract pieces of size PieceEC from Vec, then build a binary tree of
343// element-wise multiplies reducing to a single piece.
344static Value *buildMulTree(IRBuilder<> &Builder, ElementCount PieceEC,
345 Value *Vec) {
346 auto *VecTy = cast<VectorType>(Vec->getType());
347 auto *PieceTy = VectorType::get(VecTy->getElementType(), PieceEC);
348 unsigned PieceElts = PieceEC.getKnownMinValue();
349 unsigned NumPieces = VecTy->getElementCount().getKnownMinValue() / PieceElts;
350 assert(isPowerOf2_32(NumPieces));
351
352 SmallVector<Value *, 8> Pieces(NumPieces);
353 for (unsigned i = 0; i < NumPieces; i++)
354 Pieces[i] = Builder.CreateExtractVector(PieceTy, Vec, i * PieceElts);
355
356 while (Pieces.size() > 1) {
357 for (unsigned i = 0; i < Pieces.size() / 2; i++)
358 Pieces[i] =
359 Builder.CreateMul(Pieces[i * 2], Pieces[i * 2 + 1], "bin.rdx");
360 Pieces.truncate(Pieces.size() / 2);
361 }
362 return Pieces[0];
363}
364
365// Partially expand a vector_reduce_mul wider than M1 to reduce
366// register pressure and the number of vsetvlis required.
367bool RISCVCodeGenPrepareImpl::expandMulReduction(IntrinsicInst &II) {
368 if (II.getIntrinsicID() != Intrinsic::vector_reduce_mul)
369 return false;
370
371 if (!ST->hasVInstructions())
372 return false;
373
374 Value *TmpVec = II.getArgOperand(0);
375 auto *VecTy = cast<VectorType>(TmpVec->getType());
376 unsigned EltSize = VecTy->getScalarSizeInBits();
377
378 if (auto *ScalTy = dyn_cast<ScalableVectorType>(VecTy)) {
379 unsigned MinElts = ScalTy->getMinNumElements();
380
381 if (auto VLen = ST->getRealVLen()) {
382 // If VLEN is exactly known, convert to a fixed vector reduction and
383 // recurse to let the fixed path handle it (shuffle reduction instead
384 // of a scalar loop).
385 unsigned VScale = *VLen / RISCV::RVVBitsPerBlock;
386 auto *FixedTy =
387 FixedVectorType::get(VecTy->getElementType(), MinElts * VScale);
388 IRBuilder<> Builder(&II);
389 Value *Fixed = Builder.CreateExtractVector(FixedTy, TmpVec, (uint64_t)0);
390 auto *FixedRdx = cast<IntrinsicInst>(Builder.CreateIntrinsic(
391 Intrinsic::vector_reduce_mul, {FixedTy}, {Fixed}));
392 II.replaceAllUsesWith(FixedRdx);
393 II.eraseFromParent();
394 expandMulReduction(*FixedRdx);
395 return true;
396 }
397
398 unsigned M1MinElts = RISCV::RVVBitsPerBlock / EltSize;
399 if (MinElts <= M1MinElts || !isPowerOf2_32(MinElts / M1MinElts))
400 return false;
401
402 IRBuilder<> Builder(&II);
403 auto M1EC = ElementCount::getScalable(M1MinElts);
404 Value *Reduced = buildMulTree(Builder, M1EC, TmpVec);
405 Value *Rdx = Builder.CreateIntrinsic(Intrinsic::vector_reduce_mul,
406 {Reduced->getType()}, {Reduced});
407 II.replaceAllUsesWith(Rdx);
408 II.eraseFromParent();
409 return true;
410 }
411
412 unsigned VF = cast<FixedVectorType>(VecTy)->getNumElements();
413 unsigned MinVLen = ST->getRealMinVLen();
414 unsigned M1VF = MinVLen / EltSize;
415
416 if (!isPowerOf2_32(VF) || VF <= M1VF)
417 return false;
418
419 IRBuilder<> Builder(&II);
420 auto M1EC = ElementCount::getFixed(M1VF);
421 auto *M1Ty = VectorType::get(VecTy->getElementType(), M1EC);
422
423 // When VLEN is exactly known, extract m1 pieces and build a mul tree.
424 // This greatly reduces register pressure during the reduction, and
425 // avoids all but one vsetvli (the one from original LMUL to m1).
426 // TODO: Generalize to handle the splitting case.
427 if (MinVLen == ST->getRealMaxVLen() && VF <= 8 * M1VF) {
428 TmpVec = buildMulTree(Builder, M1EC, TmpVec);
429 } else {
430 // For non-exact VLEN, shuffle-reduce at the original vector width down to
431 // m1, then extract. This prioritizes reducing the number of vsetvli
432 // over maximal reduction of LMUL for the intermediate states.
433 SmallVector<int, 32> ShuffleMask(VF);
434 for (unsigned LiveElts = VF; LiveElts > M1VF; LiveElts /= 2) {
435 unsigned Half = LiveElts / 2;
436 std::iota(ShuffleMask.begin(), ShuffleMask.begin() + Half, Half);
437 std::fill(ShuffleMask.begin() + Half, ShuffleMask.end(), -1);
438 Value *Shuf =
439 Builder.CreateShuffleVector(TmpVec, ShuffleMask, "rdx.shuf");
440 TmpVec = Builder.CreateMul(TmpVec, Shuf, "bin.rdx");
441 }
442 // Extract the M1-sized subvector and emit the final reduction intrinsic.
443 // This is the reason we're here - to force a vsetvli toggle once at m1.
444 TmpVec = Builder.CreateExtractVector(M1Ty, TmpVec, (uint64_t)0, "rdx.sub");
445 }
446
447 Value *Rdx =
448 Builder.CreateIntrinsic(Intrinsic::vector_reduce_mul, {M1Ty}, {TmpVec});
449 II.replaceAllUsesWith(Rdx);
450 II.eraseFromParent();
451 return true;
452}
453
454// Always expand zero strided loads so we match more .vx splat patterns, even if
455// we have +optimized-zero-stride-loads. RISCVDAGToDAGISel::Select will convert
456// it back to a strided load if it's optimized.
457bool RISCVCodeGenPrepareImpl::expandVPStrideLoad(IntrinsicInst &II) {
458 Value *BasePtr, *VL;
459
460 using namespace PatternMatch;
462 m_Value(BasePtr), m_Zero(), m_AllOnes(), m_Value(VL))))
463 return false;
464
465 // If SEW>XLEN then a splat will get lowered as a zero strided load anyway, so
466 // avoid expanding here.
467 if (II.getType()->getScalarSizeInBits() > ST->getXLen())
468 return false;
469
470 if (!isKnownNonZero(VL, {*DL, DT, nullptr, &II}))
471 return false;
472
473 auto *VTy = cast<VectorType>(II.getType());
474
475 IRBuilder<> Builder(&II);
476 Type *STy = VTy->getElementType();
477 Value *Val = Builder.CreateLoad(STy, BasePtr);
478 Value *Res = Builder.CreateIntrinsic(
479 Intrinsic::vp_merge, VTy,
480 {II.getOperand(2), Builder.CreateVectorSplat(VTy->getElementCount(), Val),
481 PoisonValue::get(VTy), VL});
482
483 II.replaceAllUsesWith(Res);
484 II.eraseFromParent();
485 return true;
486}
487
488bool RISCVCodeGenPrepareImpl::run() {
489 bool MadeChange = false;
490 for (auto &BB : F)
491 for (Instruction &I : llvm::make_early_inc_range(BB))
492 MadeChange |= visit(I);
493
494 return MadeChange;
495}
496
497bool RISCVCodeGenPrepareLegacy::runOnFunction(Function &F) {
498 if (skipFunction(F))
499 return false;
500
501 auto &TPC = getAnalysis<TargetPassConfig>();
502 auto &TM = TPC.getTM<RISCVTargetMachine>();
503 auto ST = &TM.getSubtarget<RISCVSubtarget>(F);
504 auto DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree();
505
506 RISCVCodeGenPrepareImpl RVCGP(F, DT, ST);
507 return RVCGP.run();
508}
509
510INITIALIZE_PASS_BEGIN(RISCVCodeGenPrepareLegacy, DEBUG_TYPE, PASS_NAME, false,
511 false)
513INITIALIZE_PASS_END(RISCVCodeGenPrepareLegacy, DEBUG_TYPE, PASS_NAME, false,
514 false)
515
516char RISCVCodeGenPrepareLegacy::ID = 0;
517
519 return new RISCVCodeGenPrepareLegacy();
520}
521
524 DominatorTree *DT = &FAM.getResult<DominatorTreeAnalysis>(F);
525 auto ST = &TM->getSubtarget<RISCVSubtarget>(F);
526 bool Changed = RISCVCodeGenPrepareImpl(F, DT, ST).run();
527 if (!Changed)
528 return PreservedAnalyses::all();
529
532 return PA;
533}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
uint64_t uint64_t
Rewrite undef for PHI
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static const Function * getParent(const Value *V)
static GCRegistry::Add< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
static bool runOnFunction(Function &F, bool PostInlining)
#define DEBUG_TYPE
#define F(x, y, z)
Definition MD5.cpp:54
#define I(x, y, z)
Definition MD5.cpp:57
uint64_t IntrinsicInst * II
FunctionAnalysisManager FAM
#define INITIALIZE_PASS_DEPENDENCY(depName)
Definition PassSupport.h:42
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
Definition PassSupport.h:44
#define INITIALIZE_PASS_BEGIN(passName, arg, name, cfg, analysis)
Definition PassSupport.h:39
static Value * buildMulTree(IRBuilder<> &Builder, ElementCount PieceEC, Value *Vec)
#define PASS_NAME
static void visit(BasicBlock &Start, std::function< bool(BasicBlock *)> op)
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
Target-Independent Code Generator Pass Configuration Options pass.
#define PASS_NAME
Value * RHS
Value * LHS
AnalysisUsage & addRequired()
LLVM_ABI void setPreservesCFG()
This function should be called by the pass, iff they do not:
Definition Pass.cpp:280
Represents analyses that only rely on functions' control flow.
Definition Analysis.h:73
static LLVM_ABI ConstantAggregateZero * get(Type *Ty)
A parsed version of the target data layout string in and methods for querying it.
Definition DataLayout.h:64
Analysis pass which computes a DominatorTree.
Definition Dominators.h:241
Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree.
Definition Dominators.h:122
static constexpr ElementCount getScalable(ScalarTy MinVal)
Definition TypeSize.h:309
static constexpr ElementCount getFixed(ScalarTy MinVal)
Definition TypeSize.h:306
static LLVM_ABI FixedVectorType * get(Type *ElementType, unsigned NumElts)
Definition Type.cpp:843
This class represents a freeze function that returns random concrete value if an operand is either a ...
FunctionPass class - This class is used to implement most global optimizations.
Definition Pass.h:312
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
Definition IRBuilder.h:2909
Base class for instruction visitors.
Definition InstVisitor.h:78
LLVM_ABI InstListType::iterator eraseFromParent()
This method unlinks 'this' from the containing basic block and deletes it.
A wrapper class for inspecting calls to intrinsic functions.
void addIncoming(Value *V, BasicBlock *BB)
Add an incoming value to the end of the PHI list.
static LLVM_ABI PoisonValue * get(Type *T)
Static factory methods - Return an 'poison' object of the specified type.
A set of analyses that are preserved following a run of a transformation pass.
Definition Analysis.h:112
static PreservedAnalyses none()
Convenience factory function for the empty preserved set.
Definition Analysis.h:115
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
Definition Analysis.h:118
PreservedAnalyses & preserveSet()
Mark an analysis set as preserved.
Definition Analysis.h:151
PreservedAnalyses run(Function &F, FunctionAnalysisManager &FAM)
bool hasVInstructionsI64() const
unsigned getRealMinVLen() const
unsigned getXLen() const
bool hasVInstructions() const
std::optional< unsigned > getRealVLen() const
unsigned getRealMaxVLen() const
void truncate(size_type N)
Like resize, but requires that N is less than size().
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Target-Independent Code Generator Pass Configuration Options.
Type * getScalarType() const
If this is a vector type, return the element type, otherwise return 'this'.
Definition Type.h:363
LLVM_ABI unsigned getScalarSizeInBits() const LLVM_READONLY
If this is a vector type, return the getPrimitiveSizeInBits value for the element type.
Definition Type.cpp:222
bool isIntegerTy() const
True if this is an instance of IntegerType.
Definition Type.h:252
void setOperand(unsigned i, Value *Val)
Definition User.h:212
Value * getOperand(unsigned i) const
Definition User.h:207
LLVM Value Representation.
Definition Value.h:75
Type * getType() const
All values are typed, get the type of this value.
Definition Value.h:257
LLVM_ABI void replaceAllUsesWith(Value *V)
Change all uses of this to point to a new Value.
Definition Value.cpp:549
LLVMContext & getContext() const
All values hold a context through their type.
Definition Value.h:260
static LLVM_ABI VectorType * get(Type *ElementType, ElementCount EC)
This static method is the primary way to construct an VectorType.
constexpr ScalarTy getKnownMinValue() const
Returns the minimum value this quantity can represent.
Definition TypeSize.h:166
const ParentTy * getParent() const
Definition ilist_node.h:34
Changed
constexpr std::underlying_type_t< E > Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
AllOnesConstantMatch m_AllOnes()
OneUse_match< SubPat > m_OneUse(const SubPat &SP)
match_combine_or< Ty... > m_CombineOr(const Ty &...Ps)
Combine pattern matchers matching any of Ps patterns.
match_bind< PHINode > m_Phi(PHINode *&PN)
Match a PHI node, capturing it if we match.
OneOps_match< OpTy, Instruction::Freeze > m_Freeze(const OpTy &Op)
Matches FreezeInst.
bool match(Val *V, const Pattern &P)
match_bind< Instruction > m_Instruction(Instruction *&I)
Match an instruction, capturing it if we match.
auto m_Value()
Match an arbitrary value and ignore it.
NNegZExt_match< OpTy > m_NNegZExt(const OpTy &Op)
CastInst_match< OpTy, ZExtInst > m_ZExt(const OpTy &Op)
Matches ZExt.
Splat_match< T > m_Splat(const T &SubPattern)
Match a vector splat.
is_zero< true > m_Zero()
Match any null constant or a vector with all elements equal to 0.
auto m_Intrinsic(const Ts &...Ops)
Match intrinsic calls like this: m_Intrinsic<Intrinsic::fabs>(m_Value(X))
static constexpr unsigned RVVBitsPerBlock
NodeAddr< PhiNode * > Phi
Definition RDFGraph.h:390
friend class Instruction
Iterator for Instructions in a `BasicBlock.
Definition BasicBlock.h:73
This is an optimization pass for GlobalISel generic memory operations.
LLVM_ABI bool RecursivelyDeleteTriviallyDeadInstructions(Value *V, const TargetLibraryInfo *TLI=nullptr, MemorySSAUpdater *MSSAU=nullptr, std::function< void(Value *)> AboutToDeleteCallback=std::function< void(Value *)>())
If the specified value is a trivially dead instruction, delete it.
Definition Local.cpp:522
constexpr bool isInt(int64_t x)
Checks if an integer fits into the given bit width.
Definition MathExtras.h:166
@ Known
Known to have no common set bits.
FunctionPass * createRISCVCodeGenPrepareLegacyPass()
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:643
iterator_range< early_inc_iterator_impl< detail::IterOfRange< RangeT > > > make_early_inc_range(RangeT &&Range)
Make a range that does early increment to allow mutation of the underlying range without disrupting i...
Definition STLExtras.h:649
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...
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Value
Definition InstrProf.h:143
constexpr bool isPowerOf2_32(uint32_t Value)
Return true if the argument is a power of two > 0.
Definition MathExtras.h:280
IRBuilder(LLVMContext &, FolderTy, InserterTy) -> IRBuilder< FolderTy, InserterTy >
constexpr bool isUInt(uint64_t x)
Checks if an unsigned integer fits into the given bit width.
Definition MathExtras.h:190
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
Definition Casting.h:547
LLVM_ABI bool isKnownNonZero(const Value *V, const SimplifyQuery &Q, unsigned Depth=0)
Return true if the given value is known to be non-zero when defined.
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:559
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.
Definition STLExtras.h:1963
constexpr int64_t SignExtend64(uint64_t x)
Sign-extend the number in the bottom B bits of X to a 64-bit integer.
Definition MathExtras.h:567
AnalysisManager< Function > FunctionAnalysisManager
Convenience typedef for the Function analysis manager.
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
Definition BitVector.h:880