54using namespace PatternMatch;
56#define DEBUG_TYPE "loop-idiom-vectorize"
60 cl::desc(
"Disable Loop Idiom Vectorize Pass."));
64 cl::desc(
"The vectorization style for loop idiom transform."),
66 "Use masked vector intrinsics"),
67 clEnumValN(LoopIdiomVectorizeStyle::Predicated,
68 "predicated",
"Use VP intrinsics")),
69 cl::init(LoopIdiomVectorizeStyle::Masked));
74 cl::desc(
"Proceed with Loop Idiom Vectorize Pass, but do "
75 "not convert byte-compare loop(s)."));
79 cl::desc(
"The vectorization factor for byte-compare patterns."),
84 cl::desc(
"Verify loops generated Loop Idiom Vectorize Pass."));
87class LoopIdiomVectorize {
89 unsigned ByteCompareVF;
90 Loop *CurLoop =
nullptr;
98 BasicBlock *VectorLoopPreheaderBlock =
nullptr;
100 BasicBlock *VectorLoopMismatchBlock =
nullptr;
107 : VectorizeStyle(S), ByteCompareVF(VF), DT(DT), LI(LI),
TTI(
TTI),
DL(
DL) {
116 bool runOnCountableLoop();
120 bool recognizeByteCompare();
149 const auto *
DL = &L.getHeader()->getDataLayout();
155 unsigned BCVF = ByteCompareVF;
159 LoopIdiomVectorize LIV(VecStyle, BCVF, &AR.
DT, &AR.
LI, &AR.
TTI,
DL);
172bool LoopIdiomVectorize::run(
Loop *L) {
175 Function &
F = *L->getHeader()->getParent();
179 if (
F.hasFnAttribute(Attribute::NoImplicitFloat)) {
181 <<
" due to its NoImplicitFloat attribute");
187 if (!L->getLoopPreheader())
191 << CurLoop->getHeader()->getName() <<
"\n");
193 return recognizeByteCompare();
196bool LoopIdiomVectorize::recognizeByteCompare() {
211 if (CurLoop->getNumBackEdges() != 1 || CurLoop->getNumBlocks() != 2)
214 PHINode *PN = dyn_cast<PHINode>(&Header->front());
218 auto LoopBlocks = CurLoop->getBlocks();
227 if (LoopBlocks[0]->sizeWithoutDebug() > 4)
241 if (LoopBlocks[1]->sizeWithoutDebug() > 7)
245 Value *StartIdx =
nullptr;
256 if (!Index || !
Index->getType()->isIntegerTy(32) ||
265 if (&
I != PN && &
I != Index)
266 for (
User *U :
I.users())
267 if (!CurLoop->contains(cast<Instruction>(U)))
273 if (!
match(Header->getTerminator(),
277 !CurLoop->contains(WhileBB))
284 Value *LoadA, *LoadB;
289 !CurLoop->contains(TrueBB))
296 LoadInst *LoadAI = cast<LoadInst>(LoadA);
297 LoadInst *LoadBI = cast<LoadInst>(LoadB);
311 if (!CurLoop->isLoopInvariant(PtrA) || !CurLoop->isLoopInvariant(PtrB) ||
350 if (FoundBB == EndBB) {
352 Value *WhileCondVal = EndPN.getIncomingValueForBlock(Header);
353 Value *WhileBodyVal = EndPN.getIncomingValueForBlock(WhileBB);
359 if (WhileCondVal != WhileBodyVal &&
360 ((WhileCondVal != Index && WhileCondVal != MaxLen) ||
361 (WhileBodyVal != Index)))
371 transformByteCompare(GEPA, GEPB, PN, MaxLen, Index, StartIdx,
true,
376Value *LoopIdiomVectorize::createMaskedFindMismatch(
389 Intrinsic::get_active_lane_mask, {PredVTy, I64Type}, {ExtStart, ExtEnd});
393 Builder.
CreateMul(VecLen, ConstantInt::get(I64Type, ByteCompareVF),
"",
400 Builder.
Insert(JumpToVectorLoop);
403 VectorLoopStartBlock}});
408 PHINode *LoopPred = Builder.
CreatePHI(PredVTy, 2,
"mismatch_vec_loop_pred");
409 LoopPred->
addIncoming(InitialPred, VectorLoopPreheaderBlock);
410 PHINode *VectorIndexPhi = Builder.
CreatePHI(I64Type, 2,
"mismatch_vec_index");
411 VectorIndexPhi->
addIncoming(ExtStart, VectorLoopPreheaderBlock);
412 Type *VectorLoadType =
416 Value *VectorLhsGep =
419 Align(1), LoopPred, Passthru);
421 Value *VectorRhsGep =
424 Align(1), LoopPred, Passthru);
427 VectorMatchCmp = Builder.
CreateSelect(LoopPred, VectorMatchCmp, PFalse);
430 VectorLoopMismatchBlock, VectorLoopIncBlock, VectorMatchHasActiveLanes);
431 Builder.
Insert(VectorEarlyExit);
441 Value *NewVectorIndexPhi =
442 Builder.
CreateAdd(VectorIndexPhi, VecLen,
"",
444 VectorIndexPhi->
addIncoming(NewVectorIndexPhi, VectorLoopIncBlock);
447 {PredVTy, I64Type}, {NewVectorIndexPhi, ExtEnd});
448 LoopPred->
addIncoming(NewPred, VectorLoopIncBlock);
450 Value *PredHasActiveLanes =
454 Builder.
Insert(VectorLoopBranchBack);
463 PHINode *FoundPred = Builder.
CreatePHI(PredVTy, 1,
"mismatch_vec_found_pred");
464 FoundPred->
addIncoming(VectorMatchCmp, VectorLoopStartBlock);
466 Builder.
CreatePHI(PredVTy, 1,
"mismatch_vec_last_loop_pred");
467 LastLoopPred->
addIncoming(LoopPred, VectorLoopStartBlock);
469 Builder.
CreatePHI(I64Type, 1,
"mismatch_vec_found_index");
470 VectorFoundIndex->
addIncoming(VectorIndexPhi, VectorLoopStartBlock);
475 Value *VectorLoopRes64 = Builder.
CreateAdd(VectorFoundIndex, Ctz,
"",
477 return Builder.
CreateTrunc(VectorLoopRes64, ResType);
480Value *LoopIdiomVectorize::createPredicatedFindMismatch(
485 Type *ResType = I32Type;
491 Builder.
Insert(JumpToVectorLoop);
494 VectorLoopStartBlock}});
499 auto *VectorIndexPhi = Builder.
CreatePHI(I64Type, 2,
"mismatch_vector_index");
500 VectorIndexPhi->
addIncoming(ExtStart, VectorLoopPreheaderBlock);
503 Value *AVL = Builder.
CreateSub(ExtEnd, VectorIndexPhi,
"avl",
true,
507 auto *VF = ConstantInt::get(I32Type, ByteCompareVF);
510 {I64Type}, {AVL, VF, Builder.
getTrue()});
511 Value *GepOffset = VectorIndexPhi;
513 Value *VectorLhsGep =
519 Intrinsic::vp_load, {VectorLoadType, VectorLhsGep->
getType()},
520 {VectorLhsGep, AllTrueMask, VL},
nullptr,
"lhs.load");
522 Value *VectorRhsGep =
525 Intrinsic::vp_load, {VectorLoadType, VectorLhsGep->
getType()},
526 {VectorRhsGep, AllTrueMask, VL},
nullptr,
"rhs.load");
532 Intrinsic::vp_icmp, {VectorLhsLoad->
getType()},
533 {VectorLhsLoad, VectorRhsLoad, Pred, AllTrueMask, VL},
nullptr,
536 Intrinsic::vp_cttz_elts, {ResType, VectorMatchCmp->
getType()},
537 {VectorMatchCmp, Builder.
getInt1(
false), AllTrueMask,
541 VectorLoopIncBlock, MismatchFound);
542 Builder.
Insert(VectorEarlyExit);
553 Value *NewVectorIndexPhi =
554 Builder.
CreateAdd(VectorIndexPhi, VL64,
"",
556 VectorIndexPhi->
addIncoming(NewVectorIndexPhi, VectorLoopIncBlock);
558 auto *VectorLoopBranchBack =
560 Builder.
Insert(VectorLoopBranchBack);
572 CTZLCSSAPhi->
addIncoming(CTZ, VectorLoopStartBlock);
573 auto *VectorIndexLCSSAPhi =
575 VectorIndexLCSSAPhi->
addIncoming(VectorIndexPhi, VectorLoopStartBlock);
578 Value *VectorLoopRes64 = Builder.
CreateAdd(VectorIndexLCSSAPhi, CTZI64,
"",
580 return Builder.
CreateTrunc(VectorLoopRes64, ResType);
583Value *LoopIdiomVectorize::expandFindMismatch(
590 BasicBlock *Preheader = CurLoop->getLoopPreheader();
597 EndBlock =
SplitBlock(Preheader, PHBranch, DT, LI,
nullptr,
"mismatch_end");
613 Ctx,
"mismatch_min_it_check", EndBlock->getParent(), EndBlock);
619 Ctx,
"mismatch_mem_check", EndBlock->getParent(), EndBlock);
622 Ctx,
"mismatch_vec_loop_preheader", EndBlock->getParent(), EndBlock);
625 EndBlock->getParent(), EndBlock);
628 EndBlock->getParent(), EndBlock);
631 EndBlock->getParent(), EndBlock);
634 Ctx,
"mismatch_loop_pre", EndBlock->getParent(), EndBlock);
640 Ctx,
"mismatch_loop_inc", EndBlock->getParent(), EndBlock);
646 auto VectorLoop = LI->AllocateLoop();
647 auto ScalarLoop = LI->AllocateLoop();
649 if (CurLoop->getParentLoop()) {
650 CurLoop->getParentLoop()->addBasicBlockToLoop(MinItCheckBlock, *LI);
651 CurLoop->getParentLoop()->addBasicBlockToLoop(MemCheckBlock, *LI);
652 CurLoop->getParentLoop()->addBasicBlockToLoop(VectorLoopPreheaderBlock,
654 CurLoop->getParentLoop()->addChildLoop(VectorLoop);
655 CurLoop->getParentLoop()->addBasicBlockToLoop(VectorLoopMismatchBlock, *LI);
656 CurLoop->getParentLoop()->addBasicBlockToLoop(LoopPreHeaderBlock, *LI);
657 CurLoop->getParentLoop()->addChildLoop(ScalarLoop);
659 LI->addTopLevelLoop(VectorLoop);
660 LI->addTopLevelLoop(ScalarLoop);
664 VectorLoop->addBasicBlockToLoop(VectorLoopStartBlock, *LI);
665 VectorLoop->addBasicBlockToLoop(VectorLoopIncBlock, *LI);
667 ScalarLoop->addBasicBlockToLoop(LoopStartBlock, *LI);
668 ScalarLoop->addBasicBlockToLoop(LoopIncBlock, *LI);
683 LLVMContext::MD_prof,
685 Builder.
Insert(MinItCheckBr);
725 Value *CombinedPageCmp = Builder.
CreateOr(LhsPageCmp, RhsPageCmp);
727 LoopPreHeaderBlock, VectorLoopPreheaderBlock, CombinedPageCmp);
731 Builder.
Insert(CombinedPageCmpCmpBr);
747 Value *VectorLoopRes =
nullptr;
748 switch (VectorizeStyle) {
751 createMaskedFindMismatch(Builder, DTU, GEPA, GEPB, ExtStart, ExtEnd);
754 VectorLoopRes = createPredicatedFindMismatch(Builder, DTU, GEPA, GEPB,
790 Builder.
Insert(MatchCmpBr);
797 Value *PhiInc = Builder.
CreateAdd(IndexPhi, ConstantInt::get(ResType, 1),
"",
798 Index->hasNoUnsignedWrap(),
799 Index->hasNoSignedWrap());
815 Builder.
SetInsertPoint(EndBlock, EndBlock->getFirstInsertionPt());
820 ResPhi->
addIncoming(VectorLoopRes, VectorLoopMismatchBlock);
825 ScalarLoop->verifyLoop();
826 VectorLoop->verifyLoop();
827 if (!VectorLoop->isRecursivelyLCSSAForm(*DT, *LI))
829 if (!ScalarLoop->isRecursivelyLCSSAForm(*DT, *LI))
844 BasicBlock *Preheader = CurLoop->getLoopPreheader();
853 Start = Builder.
CreateAdd(Start, ConstantInt::get(Start->getType(), 1));
856 expandFindMismatch(Builder, DTU, GEPA, GEPB, Index, Start, MaxLen);
860 assert(IndPhi->
hasOneUse() &&
"Index phi node has more than one use!");
861 Index->replaceAllUsesWith(ByteCmpRes);
864 "Expected preheader to terminate with an unconditional branch.");
870 CmpBB->moveBefore(EndBB);
883 if (FoundBB != EndBB) {
894 auto fixSuccessorPhis = [&](
BasicBlock *SuccBB) {
895 for (
PHINode &PN : SuccBB->phis()) {
901 if (
Op == ByteCmpRes) {
918 if (CurLoop->contains(BB)) {
927 fixSuccessorPhis(EndBB);
928 if (EndBB != FoundBB)
929 fixSuccessorPhis(FoundBB);
933 if (!CurLoop->isOutermost())
934 CurLoop->getParentLoop()->addBasicBlockToLoop(CmpBB, *LI);
937 CurLoop->getParentLoop()->verifyLoop();
938 if (!CurLoop->getParentLoop()->isRecursivelyLCSSAForm(*DT, *LI))
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
#define clEnumValN(ENUMVAL, FLAGNAME, DESC)
static cl::opt< bool > VerifyLoops("loop-idiom-vectorize-verify", cl::Hidden, cl::init(false), cl::desc("Verify loops generated Loop Idiom Vectorize Pass."))
static cl::opt< bool > DisableAll("disable-loop-idiom-vectorize-all", cl::Hidden, cl::init(false), cl::desc("Disable Loop Idiom Vectorize Pass."))
static cl::opt< LoopIdiomVectorizeStyle > LITVecStyle("loop-idiom-vectorize-style", cl::Hidden, cl::desc("The vectorization style for loop idiom transform."), cl::values(clEnumValN(LoopIdiomVectorizeStyle::Masked, "masked", "Use masked vector intrinsics"), clEnumValN(LoopIdiomVectorizeStyle::Predicated, "predicated", "Use VP intrinsics")), cl::init(LoopIdiomVectorizeStyle::Masked))
static cl::opt< unsigned > ByteCmpVF("loop-idiom-vectorize-bytecmp-vf", cl::Hidden, cl::desc("The vectorization factor for byte-compare patterns."), cl::init(16))
static cl::opt< bool > DisableByteCmp("disable-loop-idiom-vectorize-bytecmp", cl::Hidden, cl::init(false), cl::desc("Proceed with Loop Idiom Vectorize Pass, but do " "not convert byte-compare loop(s)."))
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
A container for analyses that lazily runs them and caches their results.
LLVM Basic Block Representation.
iterator_range< const_phi_iterator > phis() const
Returns a range that iterates over the phis in the basic block.
static BasicBlock * Create(LLVMContext &Context, const Twine &Name="", Function *Parent=nullptr, BasicBlock *InsertBefore=nullptr)
Creates a new BasicBlock.
const Function * getParent() const
Return the enclosing method, or null if none.
LLVMContext & getContext() const
Get the context in which this basic block lives.
const Instruction * getTerminator() const LLVM_READONLY
Returns the terminator instruction if the block is well formed or null if the block is not well forme...
Conditional or Unconditional Branch instruction.
static BranchInst * Create(BasicBlock *IfTrue, InsertPosition InsertBefore=nullptr)
bool isUnconditional() const
static StringRef getPredicateName(Predicate P)
static Constant * getAllOnesValue(Type *Ty)
static Constant * getNullValue(Type *Ty)
Constructor to create a '0' constant of arbitrary type.
This class represents an Operation in the Expression.
A parsed version of the target data layout string in and methods for querying it.
static constexpr UpdateKind Delete
static constexpr UpdateKind Insert
Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree.
void applyUpdates(ArrayRef< UpdateT > Updates)
Submit updates to all available trees.
an instruction for type-safe pointer arithmetic to access elements of arrays and structs
bool isInBounds() const
Determine whether the GEP has the inbounds flag.
Value * getPointerOperand()
Type * getResultElementType() const
unsigned getNumIndices() const
ConstantInt * getInt1(bool V)
Get a constant value representing either true or false.
IntegerType * getInt1Ty()
Fetch the type representing a single bit.
Value * CreateExtractElement(Value *Vec, Value *Idx, const Twine &Name="")
Value * CreateVectorSplat(unsigned NumElts, Value *V, const Twine &Name="")
Return a vector value that contains.
ConstantInt * getTrue()
Get the constant value for i1 true.
CallInst * CreateIntrinsic(Intrinsic::ID ID, ArrayRef< Type * > Types, ArrayRef< Value * > Args, Instruction *FMFSource=nullptr, const Twine &Name="")
Create a call to intrinsic ID with Args, mangled using Types.
CallInst * CreateMaskedLoad(Type *Ty, Value *Ptr, Align Alignment, Value *Mask, Value *PassThru=nullptr, const Twine &Name="")
Create a call to Masked Load intrinsic.
Value * CreateSelect(Value *C, Value *True, Value *False, const Twine &Name="", Instruction *MDFrom=nullptr)
Value * CreateLShr(Value *LHS, Value *RHS, const Twine &Name="", bool isExact=false)
IntegerType * getInt32Ty()
Fetch the type representing a 32-bit integer.
void SetCurrentDebugLocation(DebugLoc L)
Set location information used by debugging information.
IntegerType * getInt64Ty()
Fetch the type representing a 64-bit integer.
Value * CreateICmpNE(Value *LHS, Value *RHS, const Twine &Name="")
Value * CreateGEP(Type *Ty, Value *Ptr, ArrayRef< Value * > IdxList, const Twine &Name="", GEPNoWrapFlags NW=GEPNoWrapFlags::none())
CallInst * CreateOrReduce(Value *Src)
Create a vector int OR reduction intrinsic of the source vector.
PHINode * CreatePHI(Type *Ty, unsigned NumReservedValues, const Twine &Name="")
Value * CreateICmpEQ(Value *LHS, Value *RHS, const Twine &Name="")
InstTy * Insert(InstTy *I, const Twine &Name="") const
Insert and return the specified instruction.
Value * CreateCountTrailingZeroElems(Type *ResTy, Value *Mask, bool ZeroIsPoison=true, const Twine &Name="")
Create a call to llvm.experimental_cttz_elts.
Value * CreateSub(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
BranchInst * CreateCondBr(Value *Cond, BasicBlock *True, BasicBlock *False, MDNode *BranchWeights=nullptr, MDNode *Unpredictable=nullptr)
Create a conditional 'br Cond, TrueDest, FalseDest' instruction.
LoadInst * CreateLoad(Type *Ty, Value *Ptr, const char *Name)
Provided to resolve 'CreateLoad(Ty, Ptr, "...")' correctly, instead of converting the string to 'bool...
Value * CreateZExt(Value *V, Type *DestTy, const Twine &Name="", bool IsNonNeg=false)
Value * CreateAnd(Value *LHS, Value *RHS, const Twine &Name="")
Value * CreateAdd(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
Value * CreatePtrToInt(Value *V, Type *DestTy, const Twine &Name="")
Value * CreateTrunc(Value *V, Type *DestTy, const Twine &Name="", bool IsNUW=false, bool IsNSW=false)
Value * CreateOr(Value *LHS, Value *RHS, const Twine &Name="")
BranchInst * CreateBr(BasicBlock *Dest)
Create an unconditional 'br label X' instruction.
void SetInsertPoint(BasicBlock *TheBB)
This specifies that created instructions should be appended to the end of the specified block.
Value * CreateICmpULE(Value *LHS, Value *RHS, const Twine &Name="")
IntegerType * getInt8Ty()
Fetch the type representing an 8-bit integer.
Value * CreateMul(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
const DebugLoc & getDebugLoc() const
Return the debug location for this node as a DebugLoc.
InstListType::iterator eraseFromParent()
This method unlinks 'this' from the containing basic block and deletes it.
void setMetadata(unsigned KindID, MDNode *Node)
Set the metadata of the specified kind to the specified node.
void setSuccessor(unsigned Idx, BasicBlock *BB)
Update the specified successor to point at the provided block.
This is an important class for using LLVM in a threaded context.
This class provides an interface for updating the loop pass manager based on mutations to the loop ne...
An instruction for reading from memory.
PreservedAnalyses run(Loop &L, LoopAnalysisManager &AM, LoopStandardAnalysisResults &AR, LPMUpdater &U)
Represents a single loop in the control flow graph.
MDNode * createBranchWeights(uint32_t TrueWeight, uint32_t FalseWeight, bool IsExpected=false)
Return metadata containing two branch weights.
static MDString * get(LLVMContext &Context, StringRef Str)
void addIncoming(Value *V, BasicBlock *BB)
Add an incoming value to the end of the PHI list.
iterator_range< const_block_iterator > blocks() const
op_range incoming_values()
Value * getIncomingValueForBlock(const BasicBlock *BB) const
BasicBlock * getIncomingBlock(unsigned i) const
Return incoming basic block number i.
Value * getIncomingValue(unsigned i) const
Return incoming value number x.
unsigned getNumIncomingValues() const
Return the number of incoming edges.
A set of analyses that are preserved following a run of a transformation pass.
static PreservedAnalyses none()
Convenience factory function for the empty preserved set.
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
This class represents an analyzed expression in the program.
Class to represent scalable SIMD vectors.
static ScalableVectorType * get(Type *ElementType, unsigned MinNumElts)
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
StringRef - Represent a constant reference to a string, i.e.
The instances of the Type class are immutable: once they are created, they are never changed.
static IntegerType * getInt8Ty(LLVMContext &C)
bool isIntegerTy() const
True if this is an instance of IntegerType.
Value * getOperand(unsigned i) const
LLVM Value Representation.
Type * getType() const
All values are typed, get the type of this value.
bool hasOneUse() const
Return true if there is exactly one use of this value.
LLVMContext & getContext() const
All values hold a context through their type.
ElementCount getElementCount() const
Return an ElementCount instance to represent the (possibly scalable) number of elements in the vector...
static VectorType * get(Type *ElementType, ElementCount EC)
This static method is the primary way to construct an VectorType.
bool match(Val *V, const Pattern &P)
specificval_ty m_Specific(const Value *V)
Match if we have a specific specified value.
cst_pred_ty< is_one > m_One()
Match an integer 1 or a vector with all elements equal to 1.
SpecificCmpClass_match< LHS, RHS, ICmpInst > m_SpecificICmp(CmpPredicate MatchPred, const LHS &L, const RHS &R)
OneOps_match< OpTy, Instruction::Load > m_Load(const OpTy &Op)
Matches LoadInst.
CastInst_match< OpTy, ZExtInst > m_ZExt(const OpTy &Op)
Matches ZExt.
brc_match< Cond_t, bind_ty< BasicBlock >, bind_ty< BasicBlock > > m_Br(const Cond_t &C, BasicBlock *&T, BasicBlock *&F)
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.
class_match< BasicBlock > m_BasicBlock()
Match an arbitrary basic block value and ignore it.
ValuesClass values(OptsTy... Options)
Helper to build a ValuesClass by forwarding a variable number of arguments as an initializer list to ...
initializer< Ty > init(const Ty &Val)
PointerTypeMap run(const Module &M)
Compute the PointerTypeMap for the module M.
This is an optimization pass for GlobalISel generic memory operations.
unsigned Log2_64(uint64_t Value)
Return the floor log base 2 of the specified value, -1 if the value is zero.
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
BasicBlock * SplitBlock(BasicBlock *Old, BasicBlock::iterator SplitPt, DominatorTree *DT, LoopInfo *LI=nullptr, MemorySSAUpdater *MSSAU=nullptr, const Twine &BBName="", bool Before=false)
Split the specified block at the specified instruction.
This struct is a compact representation of a valid (non-zero power of two) alignment.
The adaptor from a function pass to a loop pass computes these analyses and makes them available to t...
TargetTransformInfo & TTI