9 #define DEBUG_TYPE "hexagon-lir" 77 cl::desc(
"Disable generation of memcpy in loop idiom recognition"));
81 cl::desc(
"Disable generation of memmove in loop idiom recognition"));
85 "check guarding the memmove."));
89 cl::desc(
"Threshold (in bytes) to perform the transformation, if the " 90 "runtime loop count (mem transfer size) is known at compile-time."));
94 cl::desc(
"Only enable generating memmove in non-nested loops"));
98 cl::desc(
"Enable Hexagon-specific memcpy for volatile destination."));
104 =
"hexagon_memcpy_forward_vp4cp4n2";
116 class HexagonLoopIdiomRecognize :
public LoopPass {
120 explicit HexagonLoopIdiomRecognize() :
LoopPass(ID) {
125 return "Recognize Hexagon-specific loop idioms";
151 bool runOnCountableLoop(
Loop *L);
159 bool HasMemcpy, HasMemmove;
164 using FuncType = std::function<Value* (Instruction*, LLVMContext&)>;
170 void addRule(
StringRef N,
const Rule::FuncType &
F) {
171 Rules.push_back(Rule(N, F));
175 struct WorkListType {
176 WorkListType() =
default;
178 void push_back(
Value* V) {
180 if (!S.count(V)) { Q.push_back(V); S.insert(V); }
183 Value *pop_front_val() {
184 Value *V = Q.front(); Q.pop_front(); S.erase(V);
188 bool empty()
const {
return Q.empty(); }
191 std::deque<Value*> Q;
195 using ValueSetType = std::set<Value *>;
197 std::vector<Rule> Rules;
219 friend struct Simplifier;
224 template <
typename FuncT>
void traverse(
Value *V, FuncT F);
225 void record(
Value *V);
227 void unuse(
Value *V);
248 P.C.print(OS, P.V ? P.V : P.C.Root);
257 "Recognize Hexagon-specific loop idioms",
false,
false)
266 "Recognize Hexagon-specific loop
idioms",
false, false)
268 template <typename FuncT>
287 OS << V <<
'(' << *V <<
')';
291 if (U->getParent()) {
293 U->printAsOperand(OS,
true);
298 unsigned N = U->getNumOperands();
301 OS << U->getOpcodeName();
302 for (
const Value *
Op : U->operands()) {
320 Value *V = Q.pop_front_val();
321 if (M.find(V) != M.end())
324 if (isa<PHINode>(U) || U->getParent() != Block)
326 for (
Value *
Op : U->operands())
328 M.insert({U, U->clone()});
332 for (std::pair<Value*,Value*>
P : M) {
341 auto R = M.find(Exp);
349 void Simplifier::Context::record(
Value *V) {
365 void Simplifier::Context::unuse(
Value *V) {
366 if (!isa<Instruction>(V) || cast<Instruction>(V)->
getParent() !=
nullptr)
420 Value *V = Q.pop_front_val();
426 NewV = subst(NewV, V, DupV);
434 Root = subst(Root, OldV, NewV);
439 for (
Value *V : Clones) {
445 for (
Value *V : Clones) {
468 if (!
equal(InI, InJ))
470 }
else if (InI != InJ || !InI)
482 Value *V = Q.pop_front_val();
488 if (SubI &&
equal(SubI, U))
512 if (
Instruction *RootI = dyn_cast<Instruction>(Root))
524 if (Count++ >= Limit)
527 if (!U || U->
getParent() || !C.Used.count(U))
529 bool Changed =
false;
530 for (Rule &R : Rules) {
531 Value *
W = R.Fn(U, C.Ctx);
545 return Count < Limit ? C.Root :
nullptr;
556 class PolynomialMultiplyRecognize {
558 explicit PolynomialMultiplyRecognize(
Loop *loop,
const DataLayout &dl,
561 : CurLoop(loop), DL(dl), DT(dt), TLI(tli), SE(se) {}
569 LLVMContext &Ctx = CurLoop->getHeader()->getParent()->getContext();
578 bool findCycle(
Value *Out,
Value *In, ValueSeq &Cycle);
579 void classifyCycle(
Instruction *DivI, ValueSeq &Cycle, ValueSeq &Early,
581 bool classifyInst(
Instruction *UseI, ValueSeq &Early, ValueSeq &Late);
583 bool highBitsAreZero(
Value *V,
unsigned IterCount);
584 bool keepsHighBitsZero(
Value *V,
unsigned IterCount);
590 struct ParsedValues {
591 ParsedValues() =
default;
599 unsigned IterCount = 0;
605 bool matchRightShift(
SelectInst *SelI, ParsedValues &PV);
607 Value *CIV, ParsedValues &PV,
bool PreScan);
608 unsigned getInverseMxN(
unsigned QP);
611 void setupPreSimplifier(Simplifier &S);
612 void setupPostSimplifier(Simplifier &S);
625 if (std::distance(PI, PE) != 2)
627 BasicBlock *PB = (*PI == BB) ? *std::next(PI) : *PI;
629 for (
auto I = BB->
begin(),
E = BB->
end(); I !=
E && isa<PHINode>(
I); ++
I) {
630 auto *PN = cast<PHINode>(
I);
631 Value *InitV = PN->getIncomingValueForBlock(PB);
632 if (!isa<ConstantInt>(InitV) || !cast<ConstantInt>(InitV)->
isZero())
634 Value *IterV = PN->getIncomingValueForBlock(BB);
640 Value *IncV =
nullptr;
641 if (BO->getOperand(0) == PN)
642 IncV = BO->getOperand(1);
643 else if (BO->getOperand(1) == PN)
644 IncV = BO->getOperand(0);
648 if (
auto *
T = dyn_cast<ConstantInt>(IncV))
649 if (
T->getZExtValue() == 1)
657 Use &TheUse = UI.getUse();
659 if (
auto *II = dyn_cast<Instruction>(TheUse.
getUser()))
661 II->replaceUsesOfWith(I, J);
665 bool PolynomialMultiplyRecognize::matchLeftShift(
SelectInst *SelI,
666 Value *CIV, ParsedValues &PV) {
681 Value *A =
nullptr, *B =
nullptr, *C =
nullptr;
691 Value *
X =
nullptr, *Sh1 =
nullptr;
719 Value *ShouldSameV =
nullptr, *ShouldXoredV =
nullptr;
722 ShouldXoredV = FalseV;
724 ShouldSameV = FalseV;
725 ShouldXoredV = TrueV;
728 Value *Q =
nullptr, *R =
nullptr, *
Y =
nullptr, *
Z =
nullptr;
734 if (ShouldSameV ==
Y)
736 else if (ShouldSameV ==
Z)
780 bool PolynomialMultiplyRecognize::matchRightShift(
SelectInst *SelI,
823 Value *R =
nullptr, *Q =
nullptr;
855 bool PolynomialMultiplyRecognize::scanSelect(
SelectInst *SelI,
897 if (matchLeftShift(SelI, CIV, PV)) {
906 if (SelI != RPhi->getIncomingValueForBlock(LoopB))
912 if (CurLoop->isLoopInvariant(PV.X)) {
922 Value *Var =
nullptr, *Inv =
nullptr, *X1 =
nullptr, *X2 =
nullptr;
927 if (!I1 || I1->getParent() != LoopB) {
930 }
else if (!I2 || I2->getParent() != LoopB) {
941 Value *EntryP = RPhi->getIncomingValueForBlock(PrehB);
948 if (matchRightShift(SelI, PV)) {
951 if (PV.Inv && !isa<ConstantInt>(PV.Q))
962 bool PolynomialMultiplyRecognize::isPromotableTo(
Value *Val,
981 case Instruction::PHI:
982 case Instruction::ZExt:
983 case Instruction::And:
984 case Instruction::Or:
985 case Instruction::Xor:
986 case Instruction::LShr:
988 case Instruction::Trunc:
990 case Instruction::ICmp:
991 if (
CmpInst *CI = cast<CmpInst>(In))
992 return CI->isEquality() || CI->isUnsigned();
1000 void PolynomialMultiplyRecognize::promoteTo(
Instruction *
In,
1011 if (
PHINode *
P = dyn_cast<PHINode>(In)) {
1012 unsigned N =
P->getNumIncomingValues();
1013 for (
unsigned i = 0; i !=
N; ++i) {
1017 Value *InV =
P->getIncomingValue(i);
1020 if (Ty !=
P->getType()) {
1025 P->setIncomingValue(i, InV);
1028 }
else if (
ZExtInst *
Z = dyn_cast<ZExtInst>(In)) {
1031 Z->replaceAllUsesWith(Op);
1032 Z->eraseFromParent();
1035 if (
TruncInst *
T = dyn_cast<TruncInst>(In)) {
1039 T->replaceAllUsesWith(And);
1040 T->eraseFromParent();
1047 if (CI->getType()->getBitWidth() < DestBW)
1052 bool PolynomialMultiplyRecognize::promoteTypes(
BasicBlock *LoopB,
1066 if (
P.getNumIncomingValues() != 1)
1068 assert(
P.getIncomingBlock(0) == LoopB);
1070 if (!T || T->getBitWidth() > DestBW)
1076 if (!In.
isTerminator() && !isPromotableTo(&In, DestTy))
1080 std::vector<Instruction*> LoopIns;
1081 std::transform(LoopB->begin(), LoopB->end(), std::back_inserter(LoopIns),
1085 promoteTo(In, DestTy, LoopB);
1090 for (
auto I = ExitB->
begin(); I != End; ++
I) {
1106 cast<Instruction>(
T)->setOperand(0, P);
1113 bool PolynomialMultiplyRecognize::findCycle(
Value *Out,
Value *In,
1119 auto *BB = cast<Instruction>(Out)->
getParent();
1120 bool HadPhi =
false;
1122 for (
auto U : Out->
users()) {
1124 if (I ==
nullptr || I->
getParent() != BB)
1131 bool IsPhi = isa<PHINode>(
I);
1132 if (IsPhi && HadPhi)
1138 if (findCycle(I, In, Cycle))
1142 return !Cycle.empty();
1145 void PolynomialMultiplyRecognize::classifyCycle(
Instruction *DivI,
1146 ValueSeq &Cycle, ValueSeq &Early, ValueSeq &Late) {
1152 unsigned I,
N = Cycle.size();
1153 for (I = 0; I <
N; ++
I) {
1157 else if (!isa<PHINode>(V))
1164 ValueSeq &First = !IsE ? Early : Late;
1165 for (
unsigned J = 0; J <
I; ++J)
1166 First.insert(Cycle[J]);
1168 ValueSeq &Second = IsE ? Early : Late;
1169 Second.insert(Cycle[I]);
1170 for (++I; I <
N; ++
I) {
1172 if (DivI == V || isa<PHINode>(V))
1178 First.insert(Cycle[I]);
1181 bool PolynomialMultiplyRecognize::classifyInst(
Instruction *UseI,
1182 ValueSeq &Early, ValueSeq &Late) {
1188 if (Early.count(TV) || Early.count(FV)) {
1189 if (Late.count(TV) || Late.count(FV))
1192 }
else if (Late.count(TV) || Late.count(FV)) {
1193 if (Early.count(TV) || Early.count(FV))
1205 bool AE =
true,
AL =
true;
1207 if (Early.count(&*I))
1209 else if (Late.count(&*I))
1233 bool PolynomialMultiplyRecognize::commutesWithShift(
Instruction *I) {
1235 case Instruction::And:
1236 case Instruction::Or:
1237 case Instruction::Xor:
1238 case Instruction::LShr:
1239 case Instruction::Shl:
1241 case Instruction::ICmp:
1242 case Instruction::PHI:
1250 bool PolynomialMultiplyRecognize::highBitsAreZero(
Value *V,
1251 unsigned IterCount) {
1258 return Known.countMinLeadingZeros() >= IterCount;
1261 bool PolynomialMultiplyRecognize::keepsHighBitsZero(
Value *V,
1262 unsigned IterCount) {
1265 if (
auto *C = dyn_cast<ConstantInt>(V))
1266 return C->getValue().countLeadingZeros() >= IterCount;
1268 if (
auto *I = dyn_cast<Instruction>(V)) {
1270 case Instruction::And:
1271 case Instruction::Or:
1272 case Instruction::Xor:
1273 case Instruction::LShr:
1275 case Instruction::ICmp:
1276 case Instruction::PHI:
1277 case Instruction::ZExt:
1287 if (Opc == Instruction::Shl || Opc == Instruction::LShr)
1292 bool PolynomialMultiplyRecognize::convertShiftsToLeft(
BasicBlock *LoopB,
1294 Value *CIV = getCountIV(LoopB);
1298 if (CIVTy ==
nullptr)
1302 ValueSeq Early, Late, Cycled;
1312 if (!findCycle(&I, V, C))
1317 classifyCycle(&I, C, Early, Late);
1318 Cycled.insert(C.begin(), C.end());
1324 ValueSeq
Users(Cycled.begin(), Cycled.end());
1325 for (
unsigned i = 0; i <
Users.size(); ++i) {
1327 if (!isa<IntegerType>(V->
getType()))
1329 auto *R = cast<Instruction>(V);
1332 if (!commutesWithShift(R))
1334 for (
auto I = R->user_begin(),
E = R->user_end(); I !=
E; ++
I) {
1335 auto *
T = cast<Instruction>(*I);
1339 if (
T->getParent() != LoopB || RShifts.count(
T) || isa<PHINode>(
T))
1343 if (!classifyInst(
T, Early, Late))
1352 ValueSeq Internal(
Users.begin(),
Users.end());
1354 for (
unsigned i = 0; i < Internal.size(); ++i) {
1358 for (
Value *Op : R->operands()) {
1360 if (
T &&
T->getParent() != LoopB)
1363 Internal.insert(Op);
1366 for (
Value *V : Inputs)
1367 if (!highBitsAreZero(V, IterCount))
1369 for (
Value *V : Internal)
1370 if (!keepsHighBitsZero(V, IterCount))
1375 std::map<Value*,Value*> ShiftMap;
1377 using CastMapType = std::map<std::pair<Value *, Type *>,
Value *>;
1379 CastMapType CastMap;
1381 auto upcast = [] (CastMapType &CM,
IRBuilder<> &IRB, Value *V,
1383 auto H = CM.find(std::make_pair(V, Ty));
1386 Value *CV = IRB.CreateIntCast(V, Ty,
false);
1387 CM.insert(std::make_pair(std::make_pair(V, Ty), CV));
1391 for (
auto I = LoopB->begin(),
E = LoopB->end(); I !=
E; ++
I) {
1394 if (isa<PHINode>(I) || !
Users.count(&*I))
1406 Value *Op = J.get();
1407 if (!isOperandShifted(&*I, Op))
1409 if (
Users.count(Op))
1412 if (isa<ConstantInt>(Op) && cast<ConstantInt>(
Op)->
isZero())
1415 auto F = ShiftMap.find(Op);
1416 Value *
W = (
F != ShiftMap.end()) ?
F->second :
nullptr;
1418 IRB.SetInsertPoint(&*I);
1422 Value *ShAmt = CIV, *ShVal =
Op;
1423 auto *VTy = cast<IntegerType>(ShVal->getType());
1424 auto *ATy = cast<IntegerType>(ShAmt->
getType());
1425 if (Late.count(&*I))
1430 if (VTy->getBitWidth() < ATy->getBitWidth())
1431 ShVal = upcast(CastMap, IRB, ShVal, ATy);
1433 ShAmt = upcast(CastMap, IRB, ShAmt, VTy);
1436 W = IRB.CreateShl(ShVal, ShAmt);
1437 ShiftMap.insert(std::make_pair(Op, W));
1449 for (
auto P = ExitB->
begin(), Q = ExitB->
end();
P != Q; ++
P) {
1450 if (!isa<PHINode>(
P))
1452 auto *PN = cast<PHINode>(
P);
1453 Value *U = PN->getIncomingValueForBlock(LoopB);
1454 if (!
Users.count(U))
1457 PN->replaceAllUsesWith(S);
1462 cast<User>(S)->replaceUsesOfWith(S, PN);
1468 void PolynomialMultiplyRecognize::cleanupLoopBody(
BasicBlock *LoopB) {
1469 for (
auto &I : *LoopB)
1473 for (
auto I = LoopB->begin(),
N =
I; I != LoopB->end(); I =
N) {
1479 unsigned PolynomialMultiplyRecognize::getInverseMxN(
unsigned QP) {
1482 std::array<char,32> Q,
C;
1484 for (
unsigned i = 0; i < 32; ++i) {
1501 for (
unsigned i = 1; i < 32; ++i) {
1509 for (
unsigned j = 0; j < i; ++j)
1510 T = T ^ (C[j] & Q[i-j]);
1515 for (
unsigned i = 0; i < 32; ++i)
1525 Module *M = At->getParent()->getParent()->getParent();
1528 Value *
P = PV.P, *Q = PV.Q, *P0 =
P;
1529 unsigned IC = PV.IterCount;
1531 if (PV.M !=
nullptr)
1537 if (PV.IterCount != 32)
1542 assert(QI && QI->getBitWidth() <= 32);
1545 unsigned M = (1 << PV.IterCount) - 1;
1546 unsigned Tmp = (QI->getZExtValue() | 1) & M;
1547 unsigned QV = getInverseMxN(Tmp) & M;
1557 if (PV.M !=
nullptr)
1564 if (
const auto *CI = dyn_cast<const ConstantInt>(V))
1565 return (CI->getType()->getSignBit() & CI->getSExtValue()) == 0;
1570 case Instruction::LShr:
1571 if (
const auto SI = dyn_cast<const ConstantInt>(I->
getOperand(1)))
1572 return SI->getZExtValue() > 0;
1574 case Instruction::Or:
1575 case Instruction::Xor:
1578 case Instruction::And:
1585 void PolynomialMultiplyRecognize::setupPreSimplifier(Simplifier &S) {
1586 S.addRule(
"sink-zext",
1589 if (I->
getOpcode() != Instruction::ZExt)
1595 case Instruction::And:
1596 case Instruction::Or:
1597 case Instruction::Xor:
1607 S.addRule(
"xor/and -> and/xor",
1616 if (And0->
getOpcode() != Instruction::And ||
1617 And1->getOpcode() != Instruction::And)
1619 if (And0->
getOperand(1) != And1->getOperand(1))
1625 S.addRule(
"sink binop into select",
1635 Value *
X = Sel->getTrueValue(), *
Y = Sel->getFalseValue();
1644 Value *
Y = Sel->getTrueValue(), *
Z = Sel->getFalseValue();
1651 S.addRule(
"fold select-select",
1661 if (Sel0->getCondition() ==
C)
1665 if (Sel1->getCondition() ==
C)
1670 S.addRule(
"or-signbit -> xor-signbit",
1682 S.addRule(
"sink lshr into binop",
1685 if (I->
getOpcode() != Instruction::LShr)
1691 case Instruction::And:
1692 case Instruction::Or:
1693 case Instruction::Xor:
1704 S.addRule(
"expose bitop-const",
1707 auto IsBitOp = [](
unsigned Op) ->
bool {
1709 case Instruction::And:
1710 case Instruction::Or:
1711 case Instruction::Xor:
1717 if (!BitOp1 || !IsBitOp(BitOp1->
getOpcode()))
1720 if (!BitOp2 || !IsBitOp(BitOp2->
getOpcode()))
1733 void PolynomialMultiplyRecognize::setupPostSimplifier(Simplifier &S) {
1734 S.addRule(
"(and (xor (and x a) y) b) -> (and (xor x y) b), if b == b&a",
1742 if (Xor->
getOpcode() != Instruction::Xor)
1747 if (!And0 || And0->
getOpcode() != Instruction::And)
1754 if (V0 != (V0 & V1))
1761 bool PolynomialMultiplyRecognize::recognize() {
1762 LLVM_DEBUG(
dbgs() <<
"Starting PolynomialMultiplyRecognize on loop\n" 1763 << *CurLoop <<
'\n');
1772 if (LoopB != CurLoop->getLoopLatch())
1775 if (ExitB ==
nullptr)
1777 BasicBlock *EntryB = CurLoop->getLoopPreheader();
1778 if (EntryB ==
nullptr)
1781 unsigned IterCount = 0;
1782 const SCEV *CT = SE.getBackedgeTakenCount(CurLoop);
1783 if (isa<SCEVCouldNotCompute>(CT))
1785 if (
auto *CV = dyn_cast<SCEVConstant>(CT))
1786 IterCount = CV->getValue()->getZExtValue() + 1;
1788 Value *CIV = getCountIV(LoopB);
1791 PV.IterCount = IterCount;
1792 LLVM_DEBUG(
dbgs() <<
"Loop IV: " << *CIV <<
"\nIterCount: " << IterCount
1795 setupPreSimplifier(PreSimp);
1803 bool FoundPreScan =
false;
1804 auto FeedsPHI = [LoopB](
const Value *V) ->
bool {
1806 if (
const auto *
P = dyn_cast<const PHINode>(U))
1807 if (
P->getParent() == LoopB)
1814 if (!SI || !FeedsPHI(SI))
1818 Value *
T = PreSimp.simplify(C);
1819 SelectInst *SelI = (T && isa<SelectInst>(
T)) ? cast<SelectInst>(
T) : SI;
1820 LLVM_DEBUG(
dbgs() <<
"scanSelect(pre-scan): " << PE(C, SelI) <<
'\n');
1821 if (scanSelect(SelI, LoopB, EntryB, CIV, PV,
true)) {
1822 FoundPreScan =
true;
1832 if (!FoundPreScan) {
1842 if (!promoteTypes(LoopB, ExitB))
1845 Simplifier PostSimp;
1846 setupPostSimplifier(PostSimp);
1849 if (!SI || !FeedsPHI(SI))
1852 Value *
T = PostSimp.simplify(C);
1853 SelectInst *SelI = dyn_cast_or_null<SelectInst>(
T);
1862 if (!convertShiftsToLeft(LoopB, ExitB, IterCount))
1864 cleanupLoopBody(LoopB);
1868 bool FoundScan =
false;
1874 FoundScan = scanSelect(SelI, LoopB, EntryB, CIV, PV,
false);
1883 dbgs() <<
"Found pmpy idiom: R = " << PP <<
".Q\n";
1885 dbgs() <<
"Found inverse pmpy idiom: R = (" << PP <<
"/Q).Q) + " 1887 dbgs() <<
" Res:" << *PV.Res <<
"\n P:" << *PV.P <<
"\n";
1889 dbgs() <<
" M:" << *PV.M <<
"\n";
1890 dbgs() <<
" Q:" << *PV.Q <<
"\n";
1891 dbgs() <<
" Iteration count:" << PV.IterCount <<
"\n";
1895 Value *PM = generate(At, PV);
1899 if (PM->getType() != PV.Res->getType())
1902 PV.Res->replaceAllUsesWith(PM);
1903 PV.Res->eraseFromParent();
1907 int HexagonLoopIdiomRecognize::getSCEVStride(
const SCEVAddRecExpr *S) {
1909 return SC->getAPInt().getSExtValue();
1913 bool HexagonLoopIdiomRecognize::isLegalStore(
Loop *CurLoop,
StoreInst *
SI) {
1922 uint64_t SizeInBits = DL->getTypeSizeInBits(StoredVal->
getType());
1923 if ((SizeInBits & 7) || (SizeInBits >> 32) != 0)
1930 if (!StoreEv || StoreEv->getLoop() != CurLoop || !StoreEv->isAffine())
1935 int Stride = getSCEVStride(StoreEv);
1939 if (StoreSize !=
unsigned(
std::abs(Stride)))
1952 if (!LoadEv || LoadEv->getLoop() != CurLoop || !LoadEv->isAffine())
1956 if (StoreEv->getOperand(1) != LoadEv->getOperand(1))
1968 const SCEV *BECount,
unsigned StoreSize,
1978 if (
const SCEVConstant *BECst = dyn_cast<SCEVConstant>(BECount))
1988 for (
auto *B : L->
blocks())
1990 if (Ignored.
count(&I) == 0 &&
1998 void HexagonLoopIdiomRecognize::collectStores(
Loop *CurLoop,
BasicBlock *BB,
2002 if (
StoreInst *SI = dyn_cast<StoreInst>(&I))
2003 if (isLegalStore(CurLoop, SI))
2007 bool HexagonLoopIdiomRecognize::processCopyingStore(
Loop *CurLoop,
2010 "Expected only non-volatile stores, or Hexagon-specific memcpy" 2011 "to volatile destination.");
2014 auto *StoreEv = cast<SCEVAddRecExpr>(SE->getSCEV(StorePtr));
2015 unsigned Stride = getSCEVStride(StoreEv);
2017 if (Stride != StoreSize)
2024 auto *LoadEv = cast<SCEVAddRecExpr>(SE->getSCEV(LI->getPointerOperand()));
2044 Value *LoadBasePtr =
nullptr;
2046 bool Overlap =
false;
2053 if (StoreSize != 4 || DL->getTypeSizeInBits(BECountTy) > 32) {
2057 if (StoreBasePtr && (LoadBasePtr != StoreBasePtr)) {
2059 StoreBasePtr =
nullptr;
2063 LoadBasePtr =
nullptr;
2072 StoreSize, *AA, Ignore1)) {
2076 BECount, StoreSize, *AA, Ignore1)) {
2078 goto CleanupAndExit;
2086 goto CleanupAndExit;
2092 goto CleanupAndExit;
2101 if (!coverLoop(CurLoop, Insts))
2102 goto CleanupAndExit;
2105 goto CleanupAndExit;
2108 goto CleanupAndExit;
2114 Builder.
getInt8PtrTy(LI->getPointerAddressSpace()), ExpPt);
2119 StoreSize, *AA, Ignore2))
2120 goto CleanupAndExit;
2123 bool StridePos = getSCEVStride(LoadEv) >= 0;
2126 if (!StridePos && DestVolatile)
2127 goto CleanupAndExit;
2129 bool RuntimeCheck = (Overlap || DestVolatile);
2136 if (ExitBlocks.
size() != 1)
2137 goto CleanupAndExit;
2138 ExitB = ExitBlocks[0];
2144 BECount = SE->getTruncateOrZeroExtend(BECount, IntPtrTy);
2147 const SCEV *NumBytesS =
2148 SE->getAddExpr(BECount, SE->getOne(IntPtrTy),
SCEV::FlagNUW);
2150 NumBytesS = SE->getMulExpr(NumBytesS, SE->getConstant(IntPtrTy, StoreSize),
2153 if (
Instruction *In = dyn_cast<Instruction>(NumBytes))
2161 if (
ConstantInt *CI = dyn_cast<ConstantInt>(NumBytes)) {
2162 uint64_t C = CI->getZExtValue();
2163 if (Threshold != 0 && C < Threshold)
2164 goto CleanupAndExit;
2166 goto CleanupAndExit;
2171 Loop *ParentL = LF->getLoopFor(Preheader);
2181 for (
auto &In : *Header) {
2189 DT->addNewBlock(NewPreheader, Preheader);
2190 DT->changeImmediateDominator(Header, NewPreheader);
2200 Value *LowA = StridePos ? SA : LA;
2201 Value *HighA = StridePos ? LA : SA;
2212 if (Threshold != 0) {
2220 Func, NewPreheader);
2227 DT->addNewBlock(MemmoveB, Preheader);
2232 ExitD = DT->findNearestCommonDominator(ExitD, PB);
2240 if (ExitD && DT->dominates(Preheader, ExitD)) {
2259 const SCEV *OneS = SE->getConstant(Int32Ty, 1);
2260 const SCEV *BECount32 = SE->getTruncateOrZeroExtend(BECount, Int32Ty);
2264 if (
Instruction *In = dyn_cast<Instruction>(NumWords))
2274 NewCall = CondBuilder.
CreateCall(Fn, {Op0, Op1, NumWords});
2277 LoadBasePtr, LI->getAlignment(),
2282 LoadBasePtr, LI->getAlignment(),
2291 LLVM_DEBUG(
dbgs() <<
" Formed " << (Overlap ?
"memmove: " :
"memcpy: ")
2293 <<
" from load ptr=" << *LoadEv <<
" at: " << *LI <<
"\n" 2294 <<
" from store ptr=" << *StoreEv <<
" at: " << *SI
2303 bool HexagonLoopIdiomRecognize::coverLoop(
Loop *L,
2306 for (
auto *B : L->
blocks())
2315 for (
unsigned i = 0; i < Worklist.size(); ++i) {
2322 if (!LoopBlocks.
count(PB))
2324 Worklist.insert(OpI);
2332 for (
auto *B : L->
blocks()) {
2333 for (
auto &In : *B) {
2334 if (isa<BranchInst>(In) || isa<DbgInfoIntrinsic>(
In))
2336 if (!Worklist.count(&In) && In.mayHaveSideEffects())
2338 for (
const auto &K : In.
users()) {
2343 if (LF->getLoopFor(UseB) != L)
2355 bool HexagonLoopIdiomRecognize::runOnLoopBlock(
Loop *CurLoop,
BasicBlock *BB,
2360 auto DominatedByBB = [
this,BB] (
BasicBlock *EB) ->
bool {
2361 return DT->dominates(BB, EB);
2363 if (!
all_of(ExitBlocks, DominatedByBB))
2366 bool MadeChange =
false;
2369 collectStores(CurLoop, BB, Stores);
2372 for (
auto &SI : Stores)
2373 MadeChange |= processCopyingStore(CurLoop, SI, BECount);
2378 bool HexagonLoopIdiomRecognize::runOnCountableLoop(
Loop *L) {
2379 PolynomialMultiplyRecognize PMR(L, *DL, *DT, *TLI, *SE);
2380 if (PMR.recognize())
2383 if (!HasMemcpy && !HasMemmove)
2386 const SCEV *BECount = SE->getBackedgeTakenCount(L);
2387 assert(!isa<SCEVCouldNotCompute>(BECount) &&
2388 "runOnCountableLoop() called on a loop without a predictable" 2389 "backedge-taken count");
2394 bool Changed =
false;
2399 if (LF->getLoopFor(BB) != L)
2401 Changed |= runOnLoopBlock(L, BB, BECount, ExitBlocks);
2422 if (Name ==
"memset" || Name ==
"memcpy" || Name ==
"memmove")
2425 AA = &getAnalysis<AAResultsWrapperPass>().getAAResults();
2427 DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree();
2428 LF = &getAnalysis<LoopInfoWrapperPass>().getLoopInfo();
2429 TLI = &getAnalysis<TargetLibraryInfoWrapperPass>().getTLI(
2431 SE = &getAnalysis<ScalarEvolutionWrapperPass>().getSE();
2433 HasMemcpy = TLI->has(LibFunc_memcpy);
2434 HasMemmove = TLI->has(LibFunc_memmove);
2436 if (SE->hasLoopInvariantBackedgeTakenCount(L))
2437 return runOnCountableLoop(L);
2442 return new HexagonLoopIdiomRecognize();
The access may reference and may modify the value stored in memory.
Pass interface - Implemented by all 'passes'.
static cl::opt< unsigned > CompileTimeMemSizeThreshold("compile-time-mem-idiom-threshold", cl::Hidden, cl::init(64), cl::desc("Threshold (in bytes) to perform the transformation, if the " "runtime loop count (mem transfer size) is known at compile-time."))
static cl::opt< unsigned > RuntimeMemSizeThreshold("runtime-mem-idiom-threshold", cl::Hidden, cl::init(0), cl::desc("Threshold (in bytes) for the runtime " "check guarding the memmove."))
BinaryOp_match< LHS, RHS, Instruction::And > m_And(const LHS &L, const RHS &R)
void computeKnownBits(const Value *V, KnownBits &Known, const DataLayout &DL, unsigned Depth=0, AssumptionCache *AC=nullptr, const Instruction *CxtI=nullptr, const DominatorTree *DT=nullptr, OptimizationRemarkEmitter *ORE=nullptr, bool UseInstrInfo=true)
Determine which bits of V are known to be either zero or one and return them in the KnownZero/KnownOn...
Value * getValueOperand()
SymbolTableList< Instruction >::iterator eraseFromParent()
This method unlinks 'this' from the containing basic block and deletes it.
IntegerType * getType() const
getType - Specialize the getType() method to always return an IntegerType, which reduces the amount o...
A parsed version of the target data layout string in and methods for querying it. ...
const std::string & getTargetTriple() const
Get the target triple which is a string describing the target host.
BranchInst * CreateCondBr(Value *Cond, BasicBlock *True, BasicBlock *False, MDNode *BranchWeights=nullptr, MDNode *Unpredictable=nullptr)
Create a conditional 'br Cond, TrueDest, FalseDest' instruction.
class_match< Value > m_Value()
Match an arbitrary value and ignore it.
This class is the base class for the comparison instructions.
static GCMetadataPrinterRegistry::Add< ErlangGCPrinter > X("erlang", "erlang-compatible garbage collector")
AnalysisUsage & addPreserved()
Add the specified Pass class to the set of analyses preserved by this pass.
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
Value * CreateBinOp(Instruction::BinaryOps Opc, Value *LHS, Value *RHS, const Twine &Name="", MDNode *FPMathTag=nullptr)
is_zero m_Zero()
Match any null constant or a vector with all elements equal to 0.
void dropAllReferences()
Drop all references to operands.
bool isSameOperationAs(const Instruction *I, unsigned flags=0) const
This function determines if the specified instruction executes the same operation as the current one...
This class represents lattice values for constants.
BinaryOps getOpcode() const
Value * CreateICmpULT(Value *LHS, Value *RHS, const Twine &Name="")
Value * CreateXor(Value *LHS, Value *RHS, const Twine &Name="")
A Module instance is used to store all the information related to an LLVM module. ...
amdgpu Simplify well known AMD library false FunctionCallee Value const Twine & Name
static constexpr LocationSize unknown()
A handy container for a FunctionType+Callee-pointer pair, which can be passed around as a single enti...
This class represents zero extension of integer types.
void push_back(const T &Elt)
static cl::opt< bool > DisableMemmoveIdiom("disable-memmove-idiom", cl::Hidden, cl::init(false), cl::desc("Disable generation of memmove in loop idiom recognition"))
The main scalar evolution driver.
This class represents a function call, abstracting a target machine's calling convention.
static APInt getLowBitsSet(unsigned numBits, unsigned loBitsSet)
Get a value with low bits set.
static PointerType * getInt32PtrTy(LLVMContext &C, unsigned AS=0)
BlockT * getLoopPreheader() const
If there is a preheader for this loop, return it.
void replace(Container &Cont, typename Container::iterator ContIt, typename Container::iterator ContEnd, RandomAccessIterator ValIt, RandomAccessIterator ValEnd)
Given a sequence container Cont, replace the range [ContIt, ContEnd) with the range [ValIt...
const Value * getTrueValue() const
LLVMContext & getContext() const
All values hold a context through their type.
bool isTerminator() const
static LocationSize precise(uint64_t Value)
void deleteValue()
Delete a pointer to a generic Value.
bool hasFnAttribute(Attribute::AttrKind Kind) const
Return true if the function has the attribute.
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly...
static void cleanup(BlockFrequencyInfoImplBase &BFI)
Clear all memory not needed downstream.
An instruction for reading from memory.
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...
iv Induction Variable Users
static bool mayLoopAccessLocation(Value *Ptr, ModRefInfo Access, Loop *L, const SCEV *BECount, unsigned StoreSize, AliasAnalysis &AA, SmallPtrSetImpl< Instruction *> &Ignored)
mayLoopAccessLocation - Return true if the specified loop might access the specified pointer location...
bool hasNoSignedWrap() const
Determine whether the no signed wrap flag is set.
INITIALIZE_PASS_BEGIN(HexagonLoopIdiomRecognize, "hexagon-loop-idiom", "Recognize Hexagon-specific loop idioms", false, false) INITIALIZE_PASS_END(HexagonLoopIdiomRecognize
iterator begin()
Instruction iterator methods.
bool isIdenticalTo(const Instruction *I) const
Return true if the specified instruction is exactly identical to the current one. ...
static GCMetadataPrinterRegistry::Add< OcamlGCMetadataPrinter > Y("ocaml", "ocaml 3.10-compatible collector")
bool match(Val *V, const Pattern &P)
AnalysisUsage & addRequired()
const Module * getModule() const
Return the module owning the function this basic block belongs to, or nullptr if the function does no...
#define INITIALIZE_PASS_DEPENDENCY(depName)
BinaryOp_match< LHS, RHS, Instruction::Xor > m_Xor(const LHS &L, const RHS &R)
This class represents the LLVM 'select' instruction.
static const char * HexagonVolatileMemcpyName
const DataLayout & getDataLayout() const
Get the data layout for the module's target platform.
int getBasicBlockIndex(const BasicBlock *BB) const
Return the first index of the specified basic block in the value list for this PHI.
A Use represents the edge between a Value definition and its users.
static Optional< unsigned > getOpcode(ArrayRef< VPValue *> Values)
Returns the opcode of Values or ~0 if they do not all agree.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
bool isIntegerTy() const
True if this is an instance of IntegerType.
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
IntegerType * getIntPtrTy(const DataLayout &DL, unsigned AddrSpace=0)
Fetch the type representing a pointer to an integer value.
This file contains the simple types necessary to represent the attributes associated with functions a...
void setName(const Twine &Name)
Change the name of the value.
CallInst * CreateMemMove(Value *Dst, unsigned DstAlign, Value *Src, unsigned SrcAlign, uint64_t Size, bool isVolatile=false, MDNode *TBAATag=nullptr, MDNode *ScopeTag=nullptr, MDNode *NoAliasTag=nullptr)
Create and insert a memmove between the specified pointers.
This file implements a class to represent arbitrary precision integral constant values and operations...
BlockT * getHeader() const
unsigned getPointerAddressSpace() const
Returns the address space of the pointer operand.
User * getUser() const LLVM_READONLY
Returns the User that contains this Use.
Value * CreateBitCast(Value *V, Type *DestTy, const Twine &Name="")
Type * getType() const
All values are typed, get the type of this value.
void addBasicBlockToLoop(BlockT *NewBB, LoopInfoBase< BlockT, LoopT > &LI)
This method is used by other analyses to update loop information.
This node represents a polynomial recurrence on the trip count of the specified loop.
CastClass_match< OpTy, Instruction::ZExt > m_ZExt(const OpTy &Op)
Matches ZExt.
static void initialize(TargetLibraryInfoImpl &TLI, const Triple &T, ArrayRef< StringLiteral > StandardNames)
Initialize the set of available library functions based on the specified target triple.
unsigned getOpcode() const
Returns a member of one of the enums like Instruction::Add.
Value * CreateSub(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
An instruction for storing to memory.
void replaceAllUsesWith(Value *V)
Change all uses of this to point to a new Value.
Value * CreateZExt(Value *V, Type *DestTy, const Twine &Name="")
unsigned getBitWidth() const
Get the number of bits in this IntegerType.
Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree...
Function * getDeclaration(Module *M, ID id, ArrayRef< Type *> Tys=None)
Create or insert an LLVM Function declaration for an intrinsic, and return it.
This class represents a truncation of integer types.
void SetInsertPoint(BasicBlock *TheBB)
This specifies that created instructions should be appended to the end of the specified block...
Value * getOperand(unsigned i) const
void replaceUsesOfWith(Value *From, Value *To)
Replace uses of one Value with another.
Value * CreateOr(Value *LHS, Value *RHS, const Twine &Name="")
void clear()
Erase the contents of the InsertedExpressions map so that users trying to expand the same expression ...
bool isVoidTy() const
Return true if this is 'void'.
initializer< Ty > init(const Ty &Val)
const SCEV * getOperand(unsigned i) const
BinaryOp_match< LHS, RHS, Instruction::LShr > m_LShr(const LHS &L, const RHS &R)
void initializeHexagonLoopIdiomRecognizePass(PassRegistry &)
const Instruction * getFirstNonPHI() const
Returns a pointer to the first instruction in this block that is not a PHINode instruction.
uint64_t getZExtValue() const
Return the constant as a 64-bit unsigned integer value after it has been zero extended as appropriate...
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
* if(!EatIfPresent(lltok::kw_thread_local)) return false
ParseOptionalThreadLocal := /*empty.
const_iterator getFirstInsertionPt() const
Returns an iterator to the first instruction in this block that is suitable for inserting a non-PHI i...
void setDebugLoc(DebugLoc Loc)
Set the debug location information for this instruction.
const BasicBlock * getSinglePredecessor() const
Return the predecessor of this block if it has a single predecessor block.
Move duplicate certain instructions close to their use
LLVM Basic Block Representation.
The instances of the Type class are immutable: once they are created, they are never changed...
This is an important class for using LLVM in a threaded context.
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
SmallSet - This maintains a set of unique values, optimizing for the case when the set is small (less...
This file contains the declarations for the subclasses of Constant, which represent the different fla...
Value * CreateSelect(Value *C, Value *True, Value *False, const Twine &Name="", Instruction *MDFrom=nullptr)
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
Interval::pred_iterator pred_begin(Interval *I)
pred_begin/pred_end - define methods so that Intervals may be used just like BasicBlocks can with the...
specificval_ty m_Specific(const Value *V)
Match if we have a specific specified value.
Represent the analysis usage information of a pass.
static Type * getVoidTy(LLVMContext &C)
BinaryOp_match< LHS, RHS, Instruction::Shl > m_Shl(const LHS &L, const RHS &R)
Predicate
This enumeration lists the possible predicates for CmpInst subclasses.
Value * expandCodeFor(const SCEV *SH, Type *Ty, Instruction *I)
Insert code to directly compute the specified SCEV expression into the program.
static void replace(Module &M, GlobalVariable *Old, GlobalVariable *New)
Interval::pred_iterator pred_end(Interval *I)
Value * getPointerOperand()
static BasicBlock * Create(LLVMContext &Context, const Twine &Name="", Function *Parent=nullptr, BasicBlock *InsertBefore=nullptr)
Creates a new BasicBlock.
static void print(raw_ostream &Out, object::Archive::Kind Kind, T Val)
size_type count(ConstPtrType Ptr) const
count - Return 1 if the specified pointer is in the set, 0 otherwise.
self_iterator getIterator()
Class to represent integer types.
std::pair< NoneType, bool > insert(const T &V)
insert - Insert an element into the set if it isn't already there.
static cl::opt< bool > OnlyNonNestedMemmove("only-nonnested-memmove-idiom", cl::Hidden, cl::init(true), cl::desc("Only enable generating memmove in non-nested loops"))
const Value * getCondition() const
LLVMContext & getContext() const
getContext - Return a reference to the LLVMContext associated with this function. ...
bool RecursivelyDeleteTriviallyDeadInstructions(Value *V, const TargetLibraryInfo *TLI=nullptr, MemorySSAUpdater *MSSAU=nullptr)
If the specified value is a trivially dead instruction, delete it.
Value * getIncomingValue(unsigned i) const
Return incoming value number x.
static void replaceAllUsesOfWithIn(Value *I, Value *J, BasicBlock *BB)
auto find(R &&Range, const T &Val) -> decltype(adl_begin(Range))
Provide wrappers to std::find which take ranges instead of having to pass begin/end explicitly...
PointerType * getInt8PtrTy(unsigned AddrSpace=0)
Fetch the type representing a pointer to an 8-bit integer value.
INITIALIZE_PASS_END(RegBankSelect, DEBUG_TYPE, "Assign register bank of generic virtual registers", false, false) RegBankSelect
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Value * CreateTrunc(Value *V, Type *DestTy, const Twine &Name="")
Triple - Helper class for working with autoconf configuration names.
hexagon loop Recognize Hexagon specific loop idioms
static cl::opt< unsigned > SimplifyLimit("hlir-simplify-limit", cl::init(10000), cl::Hidden, cl::desc("Maximum number of simplification steps in HLIR"))
constexpr bool empty(const T &RangeOrContainer)
Test whether RangeOrContainer is empty. Similar to C++17 std::empty.
Representation for a specific memory location.
const InstListType & getInstList() const
Return the underlying instruction list container.
static IntegerType * get(LLVMContext &C, unsigned NumBits)
This static method is the primary way of constructing an IntegerType.
Iterator for intrusive lists based on ilist_node.
unsigned getNumOperands() const
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements...
This is the shared class of boolean and integer constants.
Type * getType() const
Return the LLVM type of this SCEV expression.
void setIncomingBlock(unsigned i, BasicBlock *BB)
AnalysisUsage & addRequiredID(const void *ID)
Value * CreateIntCast(Value *V, Type *DestTy, bool isSigned, const Twine &Name="")
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small...
Module.h This file contains the declarations for the Module class.
Provides information about what library functions are available for the current target.
CHAIN = SC CHAIN, Imm128 - System call.
CallInst * CreateMemCpy(Value *Dst, unsigned DstAlign, Value *Src, unsigned SrcAlign, uint64_t Size, bool isVolatile=false, MDNode *TBAATag=nullptr, MDNode *TBAAStructTag=nullptr, MDNode *ScopeTag=nullptr, MDNode *NoAliasTag=nullptr)
Create and insert a memcpy between the specified pointers.
static Constant * get(Type *Ty, uint64_t V, bool isSigned=false)
If Ty is a vector type, return a Constant with a splat of the given value.
FunctionCallee getOrInsertFunction(StringRef Name, FunctionType *T, AttributeList AttributeList)
Look up the specified function in the module symbol table.
void setOperand(unsigned i, Value *Val)
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
The access may modify the value stored in memory.
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
iterator_range< user_iterator > users()
static cl::opt< bool > DisableMemcpyIdiom("disable-memcpy-idiom", cl::Hidden, cl::init(false), cl::desc("Disable generation of memcpy in loop idiom recognition"))
static cl::opt< unsigned > Threshold("loop-unswitch-threshold", cl::desc("Max loop size to unswitch"), cl::init(100), cl::Hidden)
This class uses information about analyze scalars to rewrite expressions in canonical form...
const Value * getFalseValue() const
LoopT * getParentLoop() const
static bool isZero(Value *V, const DataLayout &DL, DominatorTree *DT, AssumptionCache *AC)
bool isVolatile() const
Return true if this is a store to a volatile memory location.
iterator insert(iterator where, pointer New)
const DebugLoc & getDebugLoc() const
Return the debug location for this node as a DebugLoc.
This class represents an analyzed expression in the program.
static IntegerType * getInt32Ty(LLVMContext &C)
Represents a single loop in the control flow graph.
ArrayRef< BlockT * > getBlocks() const
Get a list of the basic blocks which make up this loop.
This file provides utility analysis objects describing memory locations.
StringRef getName() const
Return a constant reference to the value's name.
const Function * getParent() const
Return the enclosing method, or null if none.
LLVM_NODISCARD ModRefInfo intersectModRef(const ModRefInfo MRI1, const ModRefInfo MRI2)
APFloat abs(APFloat X)
Returns the absolute value of the argument.
Pass * createHexagonLoopIdiomPass()
LLVM_NODISCARD std::enable_if<!is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type >::type dyn_cast(const Y &Val)
uint64_t getSignBit() const
Return a uint64_t with just the most significant bit set (the sign bit, if the value is treated as a ...
iterator_range< const_phi_iterator > phis() const
Returns a range that iterates over the phis in the basic block.
CallInst * CreateCall(FunctionType *FTy, Value *Callee, ArrayRef< Value *> Args=None, const Twine &Name="", MDNode *FPMathTag=nullptr)
bool hasNoUnsignedWrap() const
Determine whether the no unsigned wrap flag is set.
raw_ostream & operator<<(raw_ostream &OS, const APInt &I)
unsigned getAlignment() const
Return the alignment of the access that is being performed.
void mutateType(Type *Ty)
Mutate the type of this Value to be of the specified type.
Value * CreateAnd(Value *LHS, Value *RHS, const Twine &Name="")
Value * CreatePtrToInt(Value *V, Type *DestTy, const Twine &Name="")
OutputIt transform(R &&Range, OutputIt d_first, UnaryPredicate P)
Wrapper function around std::transform to apply a function to a range and store the result elsewhere...
static cl::opt< bool > HexagonVolatileMemcpy("disable-hexagon-volatile-memcpy", cl::Hidden, cl::init(false), cl::desc("Enable Hexagon-specific memcpy for volatile destination."))
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
user_iterator user_begin()
Module * getParent()
Get the module that this global value is contained inside of...
LLVM Value Representation.
cst_pred_ty< is_one > m_One()
Match an integer 1 or a vector with all elements equal to 1.
BranchInst * CreateBr(BasicBlock *Dest)
Create an unconditional 'br label X' instruction.
std::underlying_type< E >::type Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
static const Function * getParent(const Value *V)
Value * CreateLShr(Value *LHS, Value *RHS, const Twine &Name="", bool isExact=false)
This class implements an extremely fast bulk output stream that can only output to a stream...
ModRefInfo
Flags indicating whether a memory access modifies or references memory.
The legacy pass manager's analysis pass to compute loop information.
void getUniqueExitBlocks(SmallVectorImpl< BlockT *> &ExitBlocks) const
Return all unique successor blocks of this loop.
bool hasOneUse() const
Return true if there is exactly one user of this value.
StringRef - Represent a constant reference to a string, i.e.
PassRegistry - This class manages the registration and intitialization of the pass subsystem as appli...
Legacy analysis pass which computes a DominatorTree.
LLVM_NODISCARD bool isModOrRefSet(const ModRefInfo MRI)
A wrapper pass to provide the legacy pass manager access to a suitably prepared AAResults object...
ModRefInfo getModRefInfo(const CallBase *Call, const MemoryLocation &Loc)
getModRefInfo (for call sites) - Return information about whether a particular call site modifies or ...
iterator_range< block_iterator > blocks() const
Value * SimplifyInstruction(Instruction *I, const SimplifyQuery &Q, OptimizationRemarkEmitter *ORE=nullptr)
See if we can compute a simplified version of this instruction.
Value * CreateICmpSLE(Value *LHS, Value *RHS, const Twine &Name="")
Value * getPointerOperand()
static bool hasZeroSignBit(const Value *V)
const BasicBlock * getParent() const
This class represents a constant integer value.
CmpClass_match< LHS, RHS, ICmpInst, ICmpInst::Predicate > m_ICmp(ICmpInst::Predicate &Pred, const LHS &L, const RHS &R)
void setIDom(DomTreeNodeBase *NewIDom)
size_type count(const T &V) const
count - Return 1 if the element is in the set, 0 otherwise.
#define LLVM_ATTRIBUTE_USED