LLVM: lib/Transforms/Scalar/StraightLineStrengthReduce.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
85#include
86#include
87#include
88#include
89#include
90
91using namespace llvm;
93
95 std::numeric_limits::max();
96
97DEBUG_COUNTER(StraightLineStrengthReduceCounter, "slsr-counter",
98 "Controls whether rewriteCandidateWithBasis is executed.");
99
100namespace {
101
102class StraightLineStrengthReduceLegacyPass : public FunctionPass {
104
105public:
106 static char ID;
107
108 StraightLineStrengthReduceLegacyPass() : FunctionPass(ID) {
111 }
112
113 void getAnalysisUsage(AnalysisUsage &AU) const override {
114 AU.addRequired();
115 AU.addRequired();
116 AU.addRequired();
117
119 }
120
121 bool doInitialization(Module &M) override {
122 DL = &M.getDataLayout();
123 return false;
124 }
125
127};
128
129class StraightLineStrengthReduce {
130public:
131 StraightLineStrengthReduce(const DataLayout *DL, DominatorTree *DT,
132 ScalarEvolution *SE, TargetTransformInfo *TTI)
133 : DL(DL), DT(DT), SE(SE), TTI(TTI) {}
134
135
136
137 struct Candidate {
138 enum Kind {
139 Invalid,
140 Add,
141 Mul,
142 GEP,
143 };
144
145 Candidate() = default;
146 Candidate(Kind CT, const SCEV *B, ConstantInt *Idx, Value *S,
147 Instruction *I)
148 : CandidateKind(CT), Base(B), Index(Idx), Stride(S), Ins(I) {}
149
150 Kind CandidateKind = Invalid;
151
152 const SCEV *Base = nullptr;
153
154
155
156
157 ConstantInt *Index = nullptr;
158
159 Value *Stride = nullptr;
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
176
177
178
179 Candidate *Basis = nullptr;
180 };
181
183
184private:
185
186
187 bool isBasisFor(const Candidate &Basis, const Candidate &C);
188
189
190 bool isFoldable(const Candidate &C, TargetTransformInfo *TTI,
191 const DataLayout *DL);
192
193
194
195 bool isSimplestForm(const Candidate &C);
196
197
198
199 void allocateCandidatesAndFindBasis(Instruction *I);
200
201
202 void allocateCandidatesAndFindBasisForAdd(Instruction *I);
203
204
205
206 void allocateCandidatesAndFindBasisForAdd(Value *LHS, Value *RHS,
207 Instruction *I);
208
209 void allocateCandidatesAndFindBasisForMul(Instruction *I);
210
211
212
213 void allocateCandidatesAndFindBasisForMul(Value *LHS, Value *RHS,
214 Instruction *I);
215
216
217 void allocateCandidatesAndFindBasisForGEP(GetElementPtrInst *GEP);
218
219
220
221 void allocateCandidatesAndFindBasisForGEP(const SCEV *B, ConstantInt *Idx,
222 Value *S, uint64_t ElementSize,
223 Instruction *I);
224
225
226
227 void allocateCandidatesAndFindBasis(Candidate::Kind CT, const SCEV *B,
228 ConstantInt *Idx, Value *S,
229 Instruction *I);
230
231
232 void rewriteCandidateWithBasis(const Candidate &C, const Candidate &Basis);
233
234
235
236
237 void factorArrayIndex(Value *ArrayIdx, const SCEV *Base, uint64_t ElementSize,
238 GetElementPtrInst *GEP);
239
240
241 static Value *emitBump(const Candidate &Basis, const Candidate &C,
242 IRBuilder<> &Builder, const DataLayout *DL);
243
244 const DataLayout *DL = nullptr;
245 DominatorTree *DT = nullptr;
246 ScalarEvolution *SE;
247 TargetTransformInfo *TTI = nullptr;
248 std::list Candidates;
249
250
251
252
253 std::vector<Instruction *> UnlinkedInstructions;
254};
255
256}
257
258char StraightLineStrengthReduceLegacyPass::ID = 0;
259
261 "Straight line strength reduction", false, false)
266 "Straight line strength reduction", false, false)
267
269 return new StraightLineStrengthReduceLegacyPass();
270}
271
272bool StraightLineStrengthReduce::isBasisFor(const Candidate &Basis,
273 const Candidate &C) {
274 return (Basis.Ins != C.Ins &&
275
276
277 Basis.Ins->getType() == C.Ins->getType() &&
278
279 DT->dominates(Basis.Ins->getParent(), C.Ins->getParent()) &&
280
281 Basis.Base == C.Base && Basis.Stride == C.Stride &&
282 Basis.CandidateKind == C.CandidateKind);
283}
284
288 return TTI->getGEPCost(GEP->getSourceElementType(), GEP->getPointerOperand(),
290}
291
292
295
296 return Index->getBitWidth() <= 64 &&
297 TTI->isLegalAddressingMode(Base->getType(), nullptr, 0, true,
299}
300
301bool StraightLineStrengthReduce::isFoldable(const Candidate &C,
302 TargetTransformInfo *TTI,
303 const DataLayout *DL) {
304 if (C.CandidateKind == Candidate::Add)
306 if (C.CandidateKind == Candidate::GEP)
308 return false;
309}
310
311
313 unsigned NumNonZeroIndices = 0;
314 for (Use &Idx : GEP->indices()) {
316 if (ConstIdx == nullptr || !ConstIdx->isZero())
317 ++NumNonZeroIndices;
318 }
319 return NumNonZeroIndices <= 1;
320}
321
322bool StraightLineStrengthReduce::isSimplestForm(const Candidate &C) {
323 if (C.CandidateKind == Candidate::Add) {
324
325 return C.Index->isOne() || C.Index->isMinusOne();
326 }
327 if (C.CandidateKind == Candidate::Mul) {
328
329 return C.Index->isZero();
330 }
331 if (C.CandidateKind == Candidate::GEP) {
332
333 return ((C.Index->isOne() || C.Index->isMinusOne()) &&
335 }
336 return false;
337}
338
339
340
341
342
343
344
345
346void StraightLineStrengthReduce::allocateCandidatesAndFindBasis(
347 Candidate::Kind CT, const SCEV *B, ConstantInt *Idx, Value *S,
348 Instruction *I) {
349 Candidate C(CT, B, Idx, S, I);
350
351
352
353
354
355
356
357
358
359
360
361
362
363 if (!isFoldable(C, TTI, DL) && !isSimplestForm(C)) {
364
365 unsigned NumIterations = 0;
366
367 static const unsigned MaxNumIterations = 50;
368 for (auto Basis = Candidates.rbegin();
369 Basis != Candidates.rend() && NumIterations < MaxNumIterations;
370 ++Basis, ++NumIterations) {
371 if (isBasisFor(*Basis, C)) {
372 C.Basis = &(*Basis);
373 break;
374 }
375 }
376 }
377
378
379 Candidates.push_back(C);
380}
381
382void StraightLineStrengthReduce::allocateCandidatesAndFindBasis(
383 Instruction *I) {
384 switch (I->getOpcode()) {
385 case Instruction::Add:
386 allocateCandidatesAndFindBasisForAdd(I);
387 break;
388 case Instruction::Mul:
389 allocateCandidatesAndFindBasisForMul(I);
390 break;
391 case Instruction::GetElementPtr:
393 break;
394 }
395}
396
397void StraightLineStrengthReduce::allocateCandidatesAndFindBasisForAdd(
398 Instruction *I) {
399
401 return;
402
403 assert(I->getNumOperands() == 2 && "isn't I an add?");
404 Value *LHS = I->getOperand(0), *RHS = I->getOperand(1);
405 allocateCandidatesAndFindBasisForAdd(LHS, RHS, I);
407 allocateCandidatesAndFindBasisForAdd(RHS, LHS, I);
408}
409
410void StraightLineStrengthReduce::allocateCandidatesAndFindBasisForAdd(
412 Value *S = nullptr;
413 ConstantInt *Idx = nullptr;
415
416 allocateCandidatesAndFindBasis(Candidate::Add, SE->getSCEV(LHS), Idx, S, I);
418
421 allocateCandidatesAndFindBasis(Candidate::Add, SE->getSCEV(LHS), Idx, S, I);
422 } else {
423
424 ConstantInt *One = ConstantInt::get(cast(I->getType()), 1);
425 allocateCandidatesAndFindBasis(Candidate::Add, SE->getSCEV(LHS), One, RHS,
426 I);
427 }
428}
429
430
434
435
439
440void StraightLineStrengthReduce::allocateCandidatesAndFindBasisForMul(
443 ConstantInt *Idx = nullptr;
445
446
447 allocateCandidatesAndFindBasis(Candidate::Mul, SE->getSCEV(B), Idx, RHS, I);
449
450
451
452
453 allocateCandidatesAndFindBasis(Candidate::Mul, SE->getSCEV(B), Idx, RHS, I);
454 } else {
455
457 allocateCandidatesAndFindBasis(Candidate::Mul, SE->getSCEV(LHS), Zero, RHS,
458 I);
459 }
460}
461
462void StraightLineStrengthReduce::allocateCandidatesAndFindBasisForMul(
463 Instruction *I) {
464
465
467 return;
468
469 assert(I->getNumOperands() == 2 && "isn't I a mul?");
470 Value *LHS = I->getOperand(0), *RHS = I->getOperand(1);
471 allocateCandidatesAndFindBasisForMul(LHS, RHS, I);
473
474 allocateCandidatesAndFindBasisForMul(RHS, LHS, I);
475 }
476}
477
478void StraightLineStrengthReduce::allocateCandidatesAndFindBasisForGEP(
479 const SCEV *B, ConstantInt *Idx, Value *S, uint64_t ElementSize,
480 Instruction *I) {
481
482
483
484
486 ConstantInt *ScaledIdx = ConstantInt::get(
487 PtrIdxTy, Idx->getSExtValue() * (int64_t)ElementSize, true);
488 allocateCandidatesAndFindBasis(Candidate::GEP, B, ScaledIdx, S, I);
489}
490
491void StraightLineStrengthReduce::factorArrayIndex(Value *ArrayIdx,
492 const SCEV *Base,
493 uint64_t ElementSize,
494 GetElementPtrInst *GEP) {
495
496 allocateCandidatesAndFindBasisForGEP(
498 ArrayIdx, ElementSize, GEP);
500 ConstantInt *RHS = nullptr;
501
502
503
504
505
506
507
508
509
510
511
513
514
515 allocateCandidatesAndFindBasisForGEP(Base, RHS, LHS, ElementSize, GEP);
517
518
519 APInt One(RHS->getBitWidth(), 1);
520 ConstantInt *PowerOf2 =
522 allocateCandidatesAndFindBasisForGEP(Base, PowerOf2, LHS, ElementSize, GEP);
523 }
524}
525
526void StraightLineStrengthReduce::allocateCandidatesAndFindBasisForGEP(
527 GetElementPtrInst *GEP) {
528
529 if (GEP->getType()->isVectorTy())
530 return;
531
533 for (Use &Idx : GEP->indices())
535
537 for (unsigned I = 1, E = GEP->getNumOperands(); I != E; ++I, ++GTI) {
539 continue;
540
541 const SCEV *OrigIndexExpr = IndexExprs[I - 1];
542 IndexExprs[I - 1] = SE->getZero(OrigIndexExpr->getType());
543
544
545
547 Value *ArrayIdx = GEP->getOperand(I);
550 DL->getIndexSizeInBits(GEP->getAddressSpace())) {
551
552
553 factorArrayIndex(ArrayIdx, BaseExpr, ElementSize, GEP);
554 }
555
556
557
558 Value *TruncatedArrayIdx = nullptr;
561 DL->getIndexSizeInBits(GEP->getAddressSpace())) {
562
563
564 factorArrayIndex(TruncatedArrayIdx, BaseExpr, ElementSize, GEP);
565 }
566
567 IndexExprs[I - 1] = OrigIndexExpr;
568 }
569}
570
571
573 if (A.getBitWidth() < B.getBitWidth())
574 A = A.sext(B.getBitWidth());
575 else if (A.getBitWidth() > B.getBitWidth())
576 B = B.sext(A.getBitWidth());
577}
578
579Value *StraightLineStrengthReduce::emitBump(const Candidate &Basis,
580 const Candidate &C,
582 const DataLayout *DL) {
583 APInt Idx = C.Index->getValue(), BasisIdx = Basis.Index->getValue();
585 APInt IndexOffset = Idx - BasisIdx;
586
587
588
589 if (IndexOffset == 1)
590 return C.Stride;
591
594
595
596
597 IntegerType *DeltaType =
601
602 ConstantInt *Exponent = ConstantInt::get(DeltaType, IndexOffset.logBase2());
604 }
606
608 ConstantInt::get(DeltaType, (-IndexOffset).logBase2());
610 }
611 Constant *Delta = ConstantInt::get(DeltaType, IndexOffset);
612 return Builder.CreateMul(ExtendedStride, Delta);
613}
614
615void StraightLineStrengthReduce::rewriteCandidateWithBasis(
616 const Candidate &C, const Candidate &Basis) {
618 return;
619
620 assert(C.CandidateKind == Basis.CandidateKind && C.Base == Basis.Base &&
621 C.Stride == Basis.Stride);
622
623
624 assert(Basis.Ins->getParent() != nullptr && "the basis is unlinked");
625
626
627
628
629
630 if (.Ins->getParent())
631 return;
632
634 Value *Bump = emitBump(Basis, C, Builder, DL);
635 Value *Reduced = nullptr;
636 switch (C.CandidateKind) {
637 case Candidate::Add:
638 case Candidate::Mul: {
639
642
643 Reduced = Builder.CreateSub(Basis.Ins, NegBump);
644
645
647 } else {
648
649
650
651
652
653
654
655
656
657 Reduced = Builder.CreateAdd(Basis.Ins, Bump);
658 }
659 break;
660 }
661 case Candidate::GEP: {
663
664 Reduced = Builder.CreatePtrAdd(Basis.Ins, Bump, "", InBounds);
665 break;
666 }
667 default:
669 };
671 C.Ins->replaceAllUsesWith(Reduced);
672
673
674 C.Ins->removeFromParent();
675 UnlinkedInstructions.push_back(C.Ins);
676}
677
678bool StraightLineStrengthReduceLegacyPass::runOnFunction(Function &F) {
679 if (skipFunction(F))
680 return false;
681
682 auto *TTI = &getAnalysis().getTTI(F);
683 auto *DT = &getAnalysis().getDomTree();
684 auto *SE = &getAnalysis().getSE();
685 return StraightLineStrengthReduce(DL, DT, SE, TTI).runOnFunction(F);
686}
687
688bool StraightLineStrengthReduce::runOnFunction(Function &F) {
689
690
692 for (auto &I : *(Node->getBlock()))
693 allocateCandidatesAndFindBasis(&I);
694
695
696
697 while (!Candidates.empty()) {
698 const Candidate &C = Candidates.back();
699 if (C.Basis != nullptr) {
700 rewriteCandidateWithBasis(C, *C.Basis);
701 }
702 Candidates.pop_back();
703 }
704
705
706 for (auto *UnlinkedInst : UnlinkedInstructions) {
707 for (unsigned I = 0, E = UnlinkedInst->getNumOperands(); I != E; ++I) {
708 Value *Op = UnlinkedInst->getOperand(I);
709 UnlinkedInst->setOperand(I, nullptr);
711 }
712 UnlinkedInst->deleteValue();
713 }
714 bool Ret = !UnlinkedInstructions.empty();
715 UnlinkedInstructions.clear();
716 return Ret;
717}
718
719PreservedAnalyses
725
728
734 return PA;
735}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
This file implements a class to represent arbitrary precision integral constant values and operations...
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
This file contains the declarations for the subclasses of Constant, which represent the different fla...
This file provides an implementation of debug counters.
#define DEBUG_COUNTER(VARNAME, COUNTERNAME, DESC)
This file builds on the ADT/GraphTraits.h file to build generic depth first graph iterator.
static bool runOnFunction(Function &F, bool PostInlining)
Module.h This file contains the declarations for the Module class.
Machine Check Debug Module
static bool isGEPFoldable(GetElementPtrInst *GEP, const TargetTransformInfo *TTI)
#define INITIALIZE_PASS_DEPENDENCY(depName)
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
#define INITIALIZE_PASS_BEGIN(passName, arg, name, cfg, analysis)
This file defines the SmallVector class.
static bool matchesOr(Value *A, Value *&B, ConstantInt *&C)
Definition StraightLineStrengthReduce.cpp:436
static bool isAddFoldable(const SCEV *Base, ConstantInt *Index, Value *Stride, TargetTransformInfo *TTI)
Definition StraightLineStrengthReduce.cpp:293
static bool hasOnlyOneNonZeroIndex(GetElementPtrInst *GEP)
Definition StraightLineStrengthReduce.cpp:312
static void unifyBitWidth(APInt &A, APInt &B)
Definition StraightLineStrengthReduce.cpp:572
static bool matchesAdd(Value *A, Value *&B, ConstantInt *&C)
Definition StraightLineStrengthReduce.cpp:431
static const unsigned UnknownAddressSpace
Definition StraightLineStrengthReduce.cpp:94
This pass exposes codegen information to IR-level passes.
Class for arbitrary precision integers.
bool isNegatedPowerOf2() const
Check if this APInt's negated value is a power of two greater than zero.
bool isAllOnes() const
Determine if all bits are set. This is true for zero-width values.
unsigned getBitWidth() const
Return the number of bits in the APInt.
unsigned logBase2() const
bool isPowerOf2() const
Check if this APInt's value is a power of two greater than zero.
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
AnalysisUsage & addRequired()
LLVM_ABI void setPreservesCFG()
This function should be called by the pass, iff they do not:
Represents analyses that only rely on functions' control flow.
This is the shared class of boolean and integer constants.
bool isZero() const
This is just a convenience method to make client code smaller for a common code.
int64_t getSExtValue() const
Return the constant as a 64-bit integer value after it has been sign extended as appropriate for the ...
unsigned getBitWidth() const
getBitWidth - Return the scalar bitwidth of this constant.
const APInt & getValue() const
Return the constant as an APInt value reference.
A parsed version of the target data layout string in and methods for querying it.
static bool shouldExecute(CounterInfo &Counter)
Analysis pass which computes a DominatorTree.
Legacy analysis pass which computes a DominatorTree.
LLVM_ABI bool dominates(const BasicBlock *BB, const Use &U) const
Return true if the (end of the) basic block BB dominates the use U.
FunctionPass class - This class is used to implement most global optimizations.
an instruction for type-safe pointer arithmetic to access elements of arrays and structs
Value * CreatePtrAdd(Value *Ptr, Value *Offset, const Twine &Name="", GEPNoWrapFlags NW=GEPNoWrapFlags::none())
Value * CreateNeg(Value *V, const Twine &Name="", bool HasNSW=false)
Value * CreateSub(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
Value * CreateShl(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
Value * CreateAdd(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
Value * CreateSExtOrTrunc(Value *V, Type *DestTy, const Twine &Name="")
Create a SExt or Trunc from the integer value V to DestTy.
Value * CreateMul(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
static LLVM_ABI IntegerType * get(LLVMContext &C, unsigned NumBits)
This static method is the primary way of constructing an IntegerType.
static LLVM_ABI PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
A set of analyses that are preserved following a run of a transformation pass.
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
PreservedAnalyses & preserveSet()
Mark an analysis set as preserved.
PreservedAnalyses & preserve()
Mark an analysis as preserved.
This class represents an analyzed expression in the program.
LLVM_ABI Type * getType() const
Return the LLVM type of this SCEV expression.
Analysis pass that exposes the ScalarEvolution for a function.
const SCEV * getZero(Type *Ty)
Return a SCEV for the constant 0 of a specific type.
LLVM_ABI const SCEV * getSCEV(Value *V)
Return a SCEV expression for the full generality of the specified expression.
LLVM_ABI const SCEV * getGEPExpr(GEPOperator *GEP, ArrayRef< const SCEV * > IndexExprs)
Returns an expression for a GEP.
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM)
Definition StraightLineStrengthReduce.cpp:720
Analysis pass providing the TargetTransformInfo.
Wrapper pass for TargetTransformInfo.
This pass provides access to the codegen interfaces that are needed for IR-level transformations.
@ TCC_Free
Expected to fold away in lowering.
LLVM_ABI unsigned getIntegerBitWidth() const
A Use represents the edge between a Value definition and its users.
LLVM Value Representation.
Type * getType() const
All values are typed, get the type of this value.
LLVM_ABI LLVMContext & getContext() const
All values hold a context through their type.
LLVM_ABI void takeName(Value *V)
Transfer the name from V to this value.
TypeSize getSequentialElementStride(const DataLayout &DL) const
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
@ C
The default llvm calling convention, compatible with C.
BinaryOp_match< SpecificConstantMatch, SrcTy, TargetOpcode::G_SUB > m_Neg(const SrcTy &&Src)
Matches a register negated by a G_SUB.
bool match(Val *V, const Pattern &P)
class_match< ConstantInt > m_ConstantInt()
Match an arbitrary ConstantInt and ignore it.
BinaryOp_match< LHS, RHS, Instruction::Mul > m_Mul(const LHS &L, const RHS &R)
OverflowingBinaryOp_match< LHS, RHS, Instruction::Shl, OverflowingBinaryOperator::NoSignedWrap > m_NSWShl(const LHS &L, const RHS &R)
BinaryOp_match< LHS, RHS, Instruction::Add, true > m_c_Add(const LHS &L, const RHS &R)
Matches a Add with LHS and RHS in either order.
class_match< Value > m_Value()
Match an arbitrary value and ignore it.
BinaryOp_match< LHS, RHS, Instruction::Shl > m_Shl(const LHS &L, const RHS &R)
CastInst_match< OpTy, SExtInst > m_SExt(const OpTy &Op)
Matches SExt.
BinaryOp_match< LHS, RHS, Instruction::Or, true > m_c_Or(const LHS &L, const RHS &R)
Matches an Or with LHS and RHS in either order.
OverflowingBinaryOp_match< LHS, RHS, Instruction::Mul, OverflowingBinaryOperator::NoSignedWrap > m_NSWMul(const LHS &L, const RHS &R)
NodeAddr< NodeBase * > Node
friend class Instruction
Iterator for Instructions in a `BasicBlock.
This is an optimization pass for GlobalISel generic memory operations.
LLVM_ABI bool haveNoCommonBitsSet(const WithCache< const Value * > &LHSCache, const WithCache< const Value * > &RHSCache, const SimplifyQuery &SQ)
Return true if LHS and RHS have no common bits set.
FunctionAddr VTableAddr Value
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.
decltype(auto) dyn_cast(const From &Val)
dyn_cast - Return the argument parameter cast to the specified type.
LLVM_ABI void initializeStraightLineStrengthReduceLegacyPassPass(PassRegistry &)
generic_gep_type_iterator<> gep_type_iterator
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
bool isa(const From &Val)
isa - Return true if the parameter to the template is an instance of one of the template type argu...
IRBuilder(LLVMContext &, FolderTy, InserterTy, MDNode *, ArrayRef< OperandBundleDef >) -> IRBuilder< FolderTy, InserterTy >
DWARFExpression::Operation Op
decltype(auto) cast(const From &Val)
cast - Return the argument parameter cast to the specified type.
gep_type_iterator gep_type_begin(const User *GEP)
iterator_range< df_iterator< T > > depth_first(const T &G)
AnalysisManager< Function > FunctionAnalysisManager
Convenience typedef for the Function analysis manager.
LLVM_ABI FunctionPass * createStraightLineStrengthReducePass()
Definition StraightLineStrengthReduce.cpp:268