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) ||
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);
474 Intrinsic::experimental_cttz_elts, {ResType, PredMatchCmp->
getType()},
475 {PredMatchCmp, Builder.
getInt1(
true)});
477 Value *VectorLoopRes64 = Builder.
CreateAdd(VectorFoundIndex, Ctz,
"",
479 return Builder.
CreateTrunc(VectorLoopRes64, ResType);
482Value *LoopIdiomVectorize::createPredicatedFindMismatch(
487 Type *ResType = I32Type;
493 Builder.
Insert(JumpToVectorLoop);
496 VectorLoopStartBlock}});
501 auto *VectorIndexPhi = Builder.
CreatePHI(I64Type, 2,
"mismatch_vector_index");
502 VectorIndexPhi->
addIncoming(ExtStart, VectorLoopPreheaderBlock);
505 Value *AVL = Builder.
CreateSub(ExtEnd, VectorIndexPhi,
"avl",
true,
509 auto *VF = ConstantInt::get(I32Type, ByteCompareVF);
512 {I64Type}, {AVL, VF, Builder.
getTrue()});
513 Value *GepOffset = VectorIndexPhi;
515 Value *VectorLhsGep =
521 Intrinsic::vp_load, {VectorLoadType, VectorLhsGep->
getType()},
522 {VectorLhsGep, AllTrueMask, VL},
nullptr,
"lhs.load");
524 Value *VectorRhsGep =
527 Intrinsic::vp_load, {VectorLoadType, VectorLhsGep->
getType()},
528 {VectorRhsGep, AllTrueMask, VL},
nullptr,
"rhs.load");
534 Intrinsic::vp_icmp, {VectorLhsLoad->
getType()},
535 {VectorLhsLoad, VectorRhsLoad, Pred, AllTrueMask, VL},
nullptr,
538 Intrinsic::vp_cttz_elts, {ResType, VectorMatchCmp->
getType()},
539 {VectorMatchCmp, Builder.
getInt1(
false), AllTrueMask,
543 VectorLoopIncBlock, MismatchFound);
544 Builder.
Insert(VectorEarlyExit);
555 Value *NewVectorIndexPhi =
556 Builder.
CreateAdd(VectorIndexPhi, VL64,
"",
558 VectorIndexPhi->
addIncoming(NewVectorIndexPhi, VectorLoopIncBlock);
560 auto *VectorLoopBranchBack =
562 Builder.
Insert(VectorLoopBranchBack);
574 CTZLCSSAPhi->
addIncoming(CTZ, VectorLoopStartBlock);
575 auto *VectorIndexLCSSAPhi =
577 VectorIndexLCSSAPhi->
addIncoming(VectorIndexPhi, VectorLoopStartBlock);
580 Value *VectorLoopRes64 = Builder.
CreateAdd(VectorIndexLCSSAPhi, CTZI64,
"",
582 return Builder.
CreateTrunc(VectorLoopRes64, ResType);
585Value *LoopIdiomVectorize::expandFindMismatch(
592 BasicBlock *Preheader = CurLoop->getLoopPreheader();
599 EndBlock =
SplitBlock(Preheader, PHBranch, DT, LI,
nullptr,
"mismatch_end");
615 Ctx,
"mismatch_min_it_check", EndBlock->getParent(), EndBlock);
621 Ctx,
"mismatch_mem_check", EndBlock->getParent(), EndBlock);
624 Ctx,
"mismatch_vec_loop_preheader", EndBlock->getParent(), EndBlock);
627 EndBlock->getParent(), EndBlock);
630 EndBlock->getParent(), EndBlock);
633 EndBlock->getParent(), EndBlock);
636 Ctx,
"mismatch_loop_pre", EndBlock->getParent(), EndBlock);
642 Ctx,
"mismatch_loop_inc", EndBlock->getParent(), EndBlock);
648 auto VectorLoop = LI->AllocateLoop();
649 auto ScalarLoop = LI->AllocateLoop();
651 if (CurLoop->getParentLoop()) {
652 CurLoop->getParentLoop()->addBasicBlockToLoop(MinItCheckBlock, *LI);
653 CurLoop->getParentLoop()->addBasicBlockToLoop(MemCheckBlock, *LI);
654 CurLoop->getParentLoop()->addBasicBlockToLoop(VectorLoopPreheaderBlock,
656 CurLoop->getParentLoop()->addChildLoop(VectorLoop);
657 CurLoop->getParentLoop()->addBasicBlockToLoop(VectorLoopMismatchBlock, *LI);
658 CurLoop->getParentLoop()->addBasicBlockToLoop(LoopPreHeaderBlock, *LI);
659 CurLoop->getParentLoop()->addChildLoop(ScalarLoop);
661 LI->addTopLevelLoop(VectorLoop);
662 LI->addTopLevelLoop(ScalarLoop);
666 VectorLoop->addBasicBlockToLoop(VectorLoopStartBlock, *LI);
667 VectorLoop->addBasicBlockToLoop(VectorLoopIncBlock, *LI);
669 ScalarLoop->addBasicBlockToLoop(LoopStartBlock, *LI);
670 ScalarLoop->addBasicBlockToLoop(LoopIncBlock, *LI);
685 LLVMContext::MD_prof,
687 Builder.
Insert(MinItCheckBr);
727 Value *CombinedPageCmp = Builder.
CreateOr(LhsPageCmp, RhsPageCmp);
729 LoopPreHeaderBlock, VectorLoopPreheaderBlock, CombinedPageCmp);
733 Builder.
Insert(CombinedPageCmpCmpBr);
749 Value *VectorLoopRes =
nullptr;
750 switch (VectorizeStyle) {
753 createMaskedFindMismatch(Builder, DTU, GEPA, GEPB, ExtStart, ExtEnd);
756 VectorLoopRes = createPredicatedFindMismatch(Builder, DTU, GEPA, GEPB,
792 Builder.
Insert(MatchCmpBr);
799 Value *PhiInc = Builder.
CreateAdd(IndexPhi, ConstantInt::get(ResType, 1),
"",
800 Index->hasNoUnsignedWrap(),
801 Index->hasNoSignedWrap());
817 Builder.
SetInsertPoint(EndBlock, EndBlock->getFirstInsertionPt());
822 ResPhi->
addIncoming(VectorLoopRes, VectorLoopMismatchBlock);
827 ScalarLoop->verifyLoop();
828 VectorLoop->verifyLoop();
829 if (!VectorLoop->isRecursivelyLCSSAForm(*DT, *LI))
831 if (!ScalarLoop->isRecursivelyLCSSAForm(*DT, *LI))
846 BasicBlock *Preheader = CurLoop->getLoopPreheader();
855 Start = Builder.
CreateAdd(Start, ConstantInt::get(Start->getType(), 1));
858 expandFindMismatch(Builder, DTU, GEPA, GEPB,
Index, Start, MaxLen);
862 assert(IndPhi->
hasOneUse() &&
"Index phi node has more than one use!");
863 Index->replaceAllUsesWith(ByteCmpRes);
866 "Expected preheader to terminate with an unconditional branch.");
872 CmpBB->moveBefore(EndBB);
885 if (FoundBB != EndBB) {
896 auto fixSuccessorPhis = [&](
BasicBlock *SuccBB) {
897 for (
PHINode &PN : SuccBB->phis()) {
903 if (
Op == ByteCmpRes) {
920 if (CurLoop->contains(BB)) {
929 fixSuccessorPhis(EndBB);
930 if (EndBB != FoundBB)
931 fixSuccessorPhis(FoundBB);
935 if (!CurLoop->isOutermost())
936 CurLoop->getParentLoop()->addBasicBlockToLoop(CmpBB, *LI);
939 CurLoop->getParentLoop()->verifyLoop();
940 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< typename DomTreeT::UpdateType > 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 * 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.
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.
SpecificCmpClass_match< LHS, RHS, ICmpInst, ICmpInst::Predicate > m_SpecificICmp(ICmpInst::Predicate MatchPred, const LHS &L, const RHS &R)
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