48#define DEBUG_TYPE "chr"
50#define CHR_DEBUG(X) LLVM_DEBUG(X)
53 cl::desc(
"Disable CHR for all functions"));
56 cl::desc(
"Apply CHR for all functions"));
60 cl::desc(
"CHR considers a branch bias greater than this ratio as biased"));
64 cl::desc(
"CHR merges a group of N branches/selects where N >= this value"));
68 cl::desc(
"Specify file to retrieve the list of modules to apply CHR to"));
72 cl::desc(
"Specify file to retrieve the list of functions to apply CHR to"));
76 cl::desc(
"Max number of duplications by CHR for a region"));
85 errs() <<
"Error: Couldn't read the chr-module-list file " <<
CHRModuleList <<
"\n";
88 StringRef Buf = FileOrErr->get()->getBuffer();
90 Buf.
split(Lines,
'\n');
103 StringRef Buf = FileOrErr->get()->getBuffer();
105 Buf.
split(Lines,
'\n');
117 CHRStats() =
default;
119 OS <<
"CHRStats: NumBranches " << NumBranches
120 <<
" NumBranchesDelta " << NumBranchesDelta
121 <<
" WeightedNumBranchesDelta " << WeightedNumBranchesDelta;
129 uint64_t WeightedNumBranchesDelta = 0;
137 bool HasBranch =
false;
148 CHRScope(
RegInfo RI) : BranchInsertPoint(nullptr) {
149 assert(RI.R &&
"Null RegionIn");
150 RegInfos.push_back(RI);
153 Region *getParentRegion() {
154 assert(RegInfos.size() > 0 &&
"Empty CHRScope");
156 assert(Parent &&
"Unexpected to call this on the top-level region");
161 assert(RegInfos.size() > 0 &&
"Empty CHRScope");
162 return RegInfos.front().R->getEntry();
166 assert(RegInfos.size() > 0 &&
"Empty CHRScope");
167 return RegInfos.back().R->getExit();
170 bool appendable(CHRScope *Next) {
174 BasicBlock *NextEntry = Next->getEntryBlock();
175 if (getExitBlock() != NextEntry)
178 Region *LastRegion = RegInfos.back().R;
187 void append(CHRScope *Next) {
188 assert(RegInfos.size() > 0 &&
"Empty CHRScope");
189 assert(Next->RegInfos.size() > 0 &&
"Empty CHRScope");
190 assert(getParentRegion() == Next->getParentRegion() &&
192 assert(getExitBlock() == Next->getEntryBlock() &&
194 RegInfos.append(Next->RegInfos.begin(), Next->RegInfos.end());
195 Subs.append(Next->Subs.begin(), Next->Subs.end());
198 void addSub(CHRScope *SubIn) {
200 bool IsChild =
false;
202 if (RI.R == SubIn->getParentRegion()) {
206 assert(IsChild &&
"Must be a child");
208 Subs.push_back(SubIn);
214 assert(Boundary &&
"Boundary null");
215 assert(RegInfos.begin()->R != Boundary &&
216 "Can't be split at beginning");
218 RegInfos, [&Boundary](
const RegInfo &RI) {
return Boundary == RI.R; });
219 if (BoundaryIt == RegInfos.end())
223 for (
const RegInfo &RI : TailRegInfos)
224 TailRegionSet.
insert(RI.R);
227 std::stable_partition(Subs.begin(), Subs.end(), [&](CHRScope *Sub) {
228 assert(Sub &&
"null Sub");
229 Region *Parent = Sub->getParentRegion();
230 if (TailRegionSet.count(Parent))
235 [&Parent](const RegInfo &RI) { return Parent == RI.R; }) &&
241 assert(HoistStopMap.empty() &&
"MapHoistStops must be empty");
242 auto *
Scope =
new CHRScope(TailRegInfos, TailSubs);
243 RegInfos.erase(BoundaryIt, RegInfos.end());
244 Subs.erase(TailIt, Subs.end());
250 for (
const RegInfo &RI : RegInfos)
251 if (RI.R->contains(Parent))
280 HoistStopMapTy HoistStopMap;
284 : RegInfos(RegInfosIn), Subs(SubsIn), BranchInsertPoint(nullptr) {}
292 :
F(Fin),
BFI(BFIin), DT(DTin), PSI(PSIin), RI(RIin), ORE(OREin) {}
295 for (CHRScope *Scope : Scopes) {
307 Region *
R = RI.getTopLevelRegion();
308 if (CHRScope *Scope = findScopes(R,
nullptr,
nullptr, Output)) {
314 CHRScope *findScope(
Region *R);
315 void checkScopeHoistable(CHRScope *Scope);
327 void classifyBiasedScopes(CHRScope *Scope, CHRScope *OutermostScope);
334 void setCHRRegions(CHRScope *Scope, CHRScope *OutermostScope);
341 void cloneScopeBlocks(CHRScope *Scope,
350 void fixupBranchesAndSelects(CHRScope *Scope,
BasicBlock *PreEntryBlock,
356 void addToMergedCondition(
bool IsTrueBiased,
Value *
Cond,
359 unsigned getRegionDuplicationCount(
const Region *R) {
366 Count += DuplicationCount[
R];
402 const CHRStats &
Stats) {
444 assert(RegInfos.size() > 0 &&
"Empty CHRScope");
446 OS << RegInfos.size() <<
", Regions[";
447 for (
const RegInfo &RI : RegInfos) {
448 OS << RI.R->getNameStr();
451 if (RI.Selects.size() > 0)
452 OS <<
" S" << RI.Selects.size();
455 if (RegInfos[0].
R->getParent()) {
456 OS <<
"], Parent " << RegInfos[0].R->getParent()->getNameStr();
462 for (CHRScope *Sub : Subs) {
470 return isa<BinaryOperator>(
I) || isa<CastInst>(
I) || isa<SelectInst>(
I) ||
471 isa<GetElementPtrInst>(
I) || isa<CmpInst>(
I) ||
472 isa<InsertElementInst>(
I) || isa<ExtractElementInst>(
I) ||
473 isa<ShuffleVectorInst>(
I) || isa<ExtractValueInst>(
I) ||
474 isa<InsertValueInst>(
I);
489static const std::set<Value *> &
492 auto It = Visited.find(V);
493 if (It != Visited.end()) {
496 std::set<Value *> Result;
497 if (
auto *
I = dyn_cast<Instruction>(V)) {
503 return Visited.insert(std::make_pair(V, std::move(Result))).first->second;
508 Result.insert(OpResult.begin(), OpResult.end());
510 return Visited.insert(std::make_pair(V, std::move(Result))).first->second;
512 if (isa<Argument>(V)) {
518 return Visited.insert(std::make_pair(V, std::move(Result))).first->second;
530 assert(InsertPoint &&
"Null InsertPoint");
531 if (
auto *
I = dyn_cast<Instruction>(V)) {
532 auto It = Visited.
find(
I);
533 if (It != Visited.
end()) {
536 assert(DT.
getNode(
I->getParent()) &&
"DT must contain I's parent block");
538 if (Unhoistables.
count(
I)) {
555 bool AllOpsHoisted =
true;
559 AllOpsHoisted =
false;
587 uint64_t SumWeight = TrueWeight + FalseWeight;
589 assert(SumWeight >= TrueWeight && SumWeight >= FalseWeight &&
590 "Overflow calculating branch probabilities.");
610template <
typename K,
typename S,
typename M>
615 if (TrueProb >= Threshold) {
617 BiasMap[Key] = TrueProb;
619 }
else if (FalseProb >= Threshold) {
620 FalseSet.insert(Key);
621 BiasMap[Key] = FalseProb;
640 assert((IfThen == R->getExit() || IfElse == R->getExit()) &&
642 "Invariant from findScopes");
643 if (IfThen == R->getExit()) {
653 TrueBiasedRegionsGlobal, FalseBiasedRegionsGlobal,
670 return checkBias(SI, TrueProb, FalseProb,
671 TrueBiasedSelectsGlobal, FalseBiasedSelectsGlobal,
685 if (SI->getParent() == EntryBB) {
692 assert(HoistPoint &&
"Null HoistPoint");
698 if (SI->getParent() == EntryBB) {
699 EntryBlockSelectSet.
insert(SI);
705 "HoistPoint must be the first one in Selects");
714CHRScope * CHR::findScope(
Region *R) {
715 CHRScope *
Result =
nullptr;
718 assert(Entry &&
"Entry must not be null");
719 assert((Exit ==
nullptr) == (
R->isTopLevelRegion()) &&
720 "Only top level region has a null exit");
731 bool EntryInSubregion = RI.getRegionFor(Entry) !=
R;
732 if (EntryInSubregion)
736 if (
R->contains(Pred))
741 if (BB->hasAddressTaken())
750 if (
auto *
II = dyn_cast<IntrinsicInst>(&
I))
751 if (
II->getIntrinsicID() == Intrinsic::coro_id)
760 auto *BI = dyn_cast<BranchInst>(
Entry->getTerminator());
762 CHR_DEBUG(
dbgs() <<
"BI.isConditional " << BI->isConditional() <<
"\n");
765 if (BI && BI->isConditional()) {
770 if (S0 !=
S1 && (S0 == Exit ||
S1 == Exit)) {
773 BI, R, TrueBiasedRegionsGlobal, FalseBiasedRegionsGlobal,
775 Result =
new CHRScope(RI);
782 <<
"Branch not biased";
803 if (E->isSubRegion())
811 if (
auto *SI = dyn_cast<SelectInst>(&
I)) {
817 if (Selects.
size() > 0) {
818 auto AddSelects = [&](
RegInfo &RI) {
819 for (
auto *SI : Selects)
821 TrueBiasedSelectsGlobal,
822 FalseBiasedSelectsGlobal,
824 RI.Selects.push_back(SI);
828 <<
"Select not biased";
835 Result =
new CHRScope(RI);
838 CHR_DEBUG(
dbgs() <<
"Found select(s) in a region with a branch\n");
839 AddSelects(
Result->RegInfos[0]);
845 checkScopeHoistable(Result);
872void CHR::checkScopeHoistable(CHRScope *Scope) {
876 auto *
Branch = RI.HasBranch ?
879 if (RI.HasBranch || !Selects.
empty()) {
891 for (
auto it = Selects.begin(); it != Selects.end(); ) {
893 if (SI == InsertPoint) {
899 DT, Unhoistables,
nullptr, Visited);
904 "DropUnhoistableSelect", SI)
905 <<
"Dropped unhoistable select";
907 it = Selects.erase(it);
910 Unhoistables.
erase(SI);
917 if (RI.HasBranch && InsertPoint != Branch) {
920 DT, Unhoistables,
nullptr, Visited);
925 assert(InsertPoint != Branch &&
"Branch must not be the hoist point");
929 dbgs() <<
"SI " << *
SI <<
"\n";
934 "DropSelectUnhoistableBranch", SI)
935 <<
"Dropped select due to unhoistable branch";
939 return SI->getParent() == EntryBB;
941 Unhoistables.
clear();
948 assert(!DT.dominates(Branch, InsertPoint) &&
949 "Branch can't be already above the hoist point");
952 DT, Unhoistables,
nullptr, Visited) &&
953 "checkHoistValue for branch");
955 for (
auto *SI : Selects) {
956 assert(!DT.dominates(SI, InsertPoint) &&
957 "SI can't be already above the hoist point");
960 Unhoistables,
nullptr, Visited) &&
961 "checkHoistValue for selects");
967 for (
auto *SI : Selects) {
978 CHRScope *
Result = findScope(R);
980 CHRScope *ConsecutiveSubscope =
nullptr;
982 for (
auto It =
R->begin(); It !=
R->end(); ++It) {
983 const std::unique_ptr<Region> &SubR = *It;
984 auto NextIt = std::next(It);
985 Region *NextSubR = NextIt !=
R->end() ? NextIt->get() :
nullptr;
986 CHR_DEBUG(
dbgs() <<
"Looking at subregion " << SubR.get()->getNameStr()
988 CHRScope *SubCHRScope = findScopes(SubR.get(), NextSubR, R, Scopes);
990 CHR_DEBUG(
dbgs() <<
"Subregion Scope " << *SubCHRScope <<
"\n");
995 if (!ConsecutiveSubscope)
996 ConsecutiveSubscope = SubCHRScope;
997 else if (!ConsecutiveSubscope->appendable(SubCHRScope)) {
998 Subscopes.
push_back(ConsecutiveSubscope);
999 ConsecutiveSubscope = SubCHRScope;
1001 ConsecutiveSubscope->append(SubCHRScope);
1003 if (ConsecutiveSubscope) {
1004 Subscopes.
push_back(ConsecutiveSubscope);
1006 ConsecutiveSubscope =
nullptr;
1009 if (ConsecutiveSubscope) {
1010 Subscopes.
push_back(ConsecutiveSubscope);
1012 for (CHRScope *Sub : Subscopes) {
1027 auto *BI = cast<BranchInst>(RI.R->getEntry()->getTerminator());
1028 ConditionValues.
insert(BI->getCondition());
1031 ConditionValues.
insert(SI->getCondition());
1033 return ConditionValues;
1048 assert(InsertPoint &&
"Null InsertPoint");
1050 dbgs() <<
"shouldSplit " << *InsertPoint <<
" PrevConditionValues ";
1051 for (
Value *V : PrevConditionValues) {
1052 dbgs() << *V <<
", ";
1054 dbgs() <<
" ConditionValues ";
1055 for (
Value *V : ConditionValues) {
1056 dbgs() << *V <<
", ";
1060 for (
Value *V : ConditionValues) {
1062 if (!
checkHoistValue(V, InsertPoint, DT, Unhoistables,
nullptr, Visited)) {
1063 CHR_DEBUG(
dbgs() <<
"Split. checkHoistValue false " << *V <<
"\n");
1070 if (!PrevConditionValues.
empty() && !ConditionValues.
empty()) {
1072 std::set<Value *> PrevBases, Bases;
1074 for (
Value *V : PrevConditionValues) {
1075 const std::set<Value *> &BaseValues =
getBaseValues(V, DT, Visited);
1076 PrevBases.insert(BaseValues.begin(), BaseValues.end());
1078 for (
Value *V : ConditionValues) {
1079 const std::set<Value *> &BaseValues =
getBaseValues(V, DT, Visited);
1080 Bases.insert(BaseValues.begin(), BaseValues.end());
1083 dbgs() <<
"PrevBases ";
1084 for (
Value *V : PrevBases) {
1085 dbgs() << *V <<
", ";
1087 dbgs() <<
" Bases ";
1088 for (
Value *V : Bases) {
1089 dbgs() << *V <<
", ";
1092 std::vector<Value *> Intersection;
1093 std::set_intersection(PrevBases.begin(), PrevBases.end(), Bases.begin(),
1094 Bases.end(), std::back_inserter(Intersection));
1095 if (Intersection.empty()) {
1107 for (
RegInfo &RI : Scope->RegInfos)
1110 for (CHRScope *Sub : Scope->Subs)
1116 for (CHRScope *Scope : Input) {
1118 "BranchInsertPoint must not be set");
1121 splitScope(Scope,
nullptr,
nullptr,
nullptr, Output, Unhoistables);
1124 for (CHRScope *Scope : Output) {
1125 assert(
Scope->BranchInsertPoint &&
"BranchInsertPoint must be set");
1138 assert(OuterConditionValues &&
"Null OuterConditionValues");
1139 assert(OuterInsertPoint &&
"Null OuterInsertPoint");
1141 bool PrevSplitFromOuter =
true;
1149 for (
RegInfo &RI : RegInfos) {
1153 dbgs() <<
"ConditionValues ";
1154 for (
Value *V : ConditionValues) {
1155 dbgs() << *
V <<
", ";
1158 if (RI.R == RegInfos[0].R) {
1163 << RI.R->getNameStr() <<
"\n");
1164 if (
shouldSplit(OuterInsertPoint, *OuterConditionValues,
1165 ConditionValues, DT, Unhoistables)) {
1166 PrevConditionValues = ConditionValues;
1167 PrevInsertPoint = InsertPoint;
1170 "SplitScopeFromOuter",
1171 RI.R->getEntry()->getTerminator())
1172 <<
"Split scope from outer due to unhoistable branch/select "
1173 <<
"and/or lack of common condition values";
1178 PrevSplitFromOuter =
false;
1179 PrevConditionValues = *OuterConditionValues;
1180 PrevConditionValues.
insert(ConditionValues.begin(),
1181 ConditionValues.end());
1182 PrevInsertPoint = OuterInsertPoint;
1186 PrevConditionValues = ConditionValues;
1187 PrevInsertPoint = InsertPoint;
1191 << RI.R->getNameStr() <<
"\n");
1192 if (
shouldSplit(PrevInsertPoint, PrevConditionValues, ConditionValues,
1193 DT, Unhoistables)) {
1197 SplitsSplitFromOuter.
push_back(PrevSplitFromOuter);
1198 SplitsConditionValues.
push_back(PrevConditionValues);
1199 SplitsInsertPoints.
push_back(PrevInsertPoint);
1201 PrevConditionValues = ConditionValues;
1202 PrevInsertPoint = InsertPoint;
1203 PrevSplitFromOuter =
true;
1206 "SplitScopeFromPrev",
1207 RI.R->getEntry()->getTerminator())
1208 <<
"Split scope from previous due to unhoistable branch/select "
1209 <<
"and/or lack of common condition values";
1213 PrevConditionValues.
insert(ConditionValues.begin(), ConditionValues.end());
1218 SplitsSplitFromOuter.
push_back(PrevSplitFromOuter);
1219 SplitsConditionValues.
push_back(PrevConditionValues);
1220 assert(PrevInsertPoint &&
"Null PrevInsertPoint");
1221 SplitsInsertPoints.
push_back(PrevInsertPoint);
1223 Splits.
size() == SplitsSplitFromOuter.
size() &&
1224 Splits.
size() == SplitsInsertPoints.
size() &&
"Mismatching sizes");
1225 for (
size_t I = 0;
I < Splits.
size(); ++
I) {
1226 CHRScope *
Split = Splits[
I];
1232 for (CHRScope *Sub :
Split->Subs) {
1234 Sub, Split, &SplitConditionValues, SplitInsertPoint, Output,
1238 Split->Subs = NewSubs;
1241 for (
size_t I = 0;
I < Splits.
size(); ++
I) {
1242 CHRScope *
Split = Splits[
I];
1243 if (SplitsSplitFromOuter[
I]) {
1246 Split->BranchInsertPoint = SplitsInsertPoints[
I];
1247 CHR_DEBUG(
dbgs() <<
"BranchInsertPoint " << *SplitsInsertPoints[
I]
1256 "If no outer (top-level), must return no nested ones");
1261 for (CHRScope *Scope : Scopes) {
1262 assert(
Scope->TrueBiasedRegions.empty() &&
Scope->FalseBiasedRegions.empty() &&
"Empty");
1263 classifyBiasedScopes(Scope, Scope);
1265 dbgs() <<
"classifyBiasedScopes " << *Scope <<
"\n";
1266 dbgs() <<
"TrueBiasedRegions ";
1268 dbgs() <<
R->getNameStr() <<
", ";
1271 dbgs() <<
"FalseBiasedRegions ";
1273 dbgs() <<
R->getNameStr() <<
", ";
1276 dbgs() <<
"TrueBiasedSelects ";
1281 dbgs() <<
"FalseBiasedSelects ";
1289void CHR::classifyBiasedScopes(CHRScope *Scope, CHRScope *OutermostScope) {
1293 if (TrueBiasedRegionsGlobal.contains(R))
1294 OutermostScope->TrueBiasedRegions.insert(R);
1295 else if (FalseBiasedRegionsGlobal.contains(R))
1296 OutermostScope->FalseBiasedRegions.insert(R);
1301 if (TrueBiasedSelectsGlobal.contains(SI))
1302 OutermostScope->TrueBiasedSelects.insert(SI);
1303 else if (FalseBiasedSelectsGlobal.contains(SI))
1304 OutermostScope->FalseBiasedSelects.insert(SI);
1309 for (CHRScope *Sub :
Scope->Subs) {
1310 classifyBiasedScopes(Sub, OutermostScope);
1315 unsigned NumBiased = Scope->TrueBiasedRegions.size() +
1316 Scope->FalseBiasedRegions.size() +
1317 Scope->TrueBiasedSelects.size() +
1318 Scope->FalseBiasedSelects.size();
1324 for (CHRScope *Scope : Input) {
1327 CHR_DEBUG(
dbgs() <<
"Filtered out by biased branches truthy-regions "
1328 <<
Scope->TrueBiasedRegions.size()
1329 <<
" falsy-regions " <<
Scope->FalseBiasedRegions.size()
1330 <<
" true-selects " <<
Scope->TrueBiasedSelects.size()
1331 <<
" false-selects " <<
Scope->FalseBiasedSelects.size() <<
"\n");
1335 "DropScopeWithOneBranchOrSelect",
1336 Scope->RegInfos[0].R->getEntry()->getTerminator())
1337 <<
"Drop scope with < "
1339 <<
" biased branch(es) or select(s)";
1349 for (CHRScope *Scope : Input) {
1352 setCHRRegions(Scope, Scope);
1355 dbgs() <<
"setCHRRegions HoistStopMap " << *Scope <<
"\n";
1356 for (
auto pair :
Scope->HoistStopMap) {
1357 Region *R = pair.first;
1358 dbgs() <<
"Region " << R->getNameStr() <<
"\n";
1359 for (Instruction *I : pair.second) {
1360 dbgs() <<
"HoistStop " << *I <<
"\n";
1363 dbgs() <<
"CHRRegions" <<
"\n";
1365 dbgs() << RI.R->getNameStr() <<
"\n";
1370void CHR::setCHRRegions(CHRScope *Scope, CHRScope *OutermostScope) {
1380 Instruction *InsertPoint = OutermostScope->BranchInsertPoint;
1384 bool IsHoisted =
false;
1386 assert((OutermostScope->TrueBiasedRegions.contains(R) ||
1387 OutermostScope->FalseBiasedRegions.contains(R)) &&
1388 "Must be truthy or falsy");
1389 auto *BI = cast<BranchInst>(
R->getEntry()->getTerminator());
1392 bool IsHoistable =
checkHoistValue(BI->getCondition(), InsertPoint, DT,
1393 Unhoistables, &HoistStops, Visited);
1394 assert(IsHoistable &&
"Must be hoistable");
1395 (void)(IsHoistable);
1399 assert((OutermostScope->TrueBiasedSelects.contains(SI) ||
1400 OutermostScope->FalseBiasedSelects.contains(SI)) &&
1401 "Must be true or false biased");
1405 Unhoistables, &HoistStops, Visited);
1406 assert(IsHoistable &&
"Must be hoistable");
1407 (void)(IsHoistable);
1411 OutermostScope->CHRRegions.push_back(RI);
1412 OutermostScope->HoistStopMap[
R] = HoistStops;
1415 for (CHRScope *Sub :
Scope->Subs)
1416 setCHRRegions(Sub, OutermostScope);
1420 return Scope1->RegInfos[0].R->getDepth() < Scope2->RegInfos[0].R->getDepth();
1433 HoistStopMapTy &HoistStopMap,
1437 auto IT = HoistStopMap.find(R);
1438 assert(
IT != HoistStopMap.end() &&
"Region must be in hoist stop map");
1440 if (
auto *
I = dyn_cast<Instruction>(V)) {
1441 if (
I == HoistPoint)
1445 if (
auto *PN = dyn_cast<PHINode>(
I))
1446 if (TrivialPHIs.
count(PN))
1456 assert(DT.
getNode(
I->getParent()) &&
"DT must contain I's block");
1458 "DT must contain HoistPoint block");
1470 hoistValue(
Op, HoistPoint, R, HoistStopMap, HoistedSet, TrivialPHIs, DT);
1472 I->moveBefore(HoistPoint);
1484 for (
const RegInfo &RI : Scope->CHRRegions) {
1486 bool IsTrueBiased = Scope->TrueBiasedRegions.count(R);
1487 bool IsFalseBiased = Scope->FalseBiasedRegions.count(R);
1488 if (RI.HasBranch && (IsTrueBiased || IsFalseBiased)) {
1489 auto *BI = cast<BranchInst>(R->getEntry()->getTerminator());
1490 hoistValue(BI->getCondition(), HoistPoint, R, Scope->HoistStopMap,
1491 HoistedSet, TrivialPHIs, DT);
1494 bool IsTrueBiased = Scope->TrueBiasedSelects.count(SI);
1495 bool IsFalseBiased = Scope->FalseBiasedSelects.count(SI);
1496 if (!(IsTrueBiased || IsFalseBiased))
1498 hoistValue(SI->getCondition(), HoistPoint, R, Scope->HoistStopMap,
1499 HoistedSet, TrivialPHIs, DT);
1510 if (U == ExcludedUser)
1512 if (isa<BranchInst>(U) && cast<BranchInst>(U)->isConditional())
1514 if (isa<SelectInst>(U) && cast<SelectInst>(U)->getCondition() == ICmp)
1519 if (U == ExcludedUser)
1521 if (
auto *BI = dyn_cast<BranchInst>(U)) {
1522 assert(BI->isConditional() &&
"Must be conditional");
1523 BI->swapSuccessors();
1531 if (
auto *SI = dyn_cast<SelectInst>(U)) {
1534 SI->swapProfMetadata();
1535 if (Scope->TrueBiasedSelects.count(SI)) {
1536 assert(!Scope->FalseBiasedSelects.contains(SI) &&
1537 "Must not be already in");
1538 Scope->FalseBiasedSelects.insert(SI);
1539 }
else if (Scope->FalseBiasedSelects.count(SI)) {
1540 assert(!Scope->TrueBiasedSelects.contains(SI) &&
1541 "Must not be already in");
1542 Scope->TrueBiasedSelects.insert(SI);
1559 for (
RegInfo &RI : Scope->RegInfos) {
1562 BlocksInScope.
insert(BB);
1566 dbgs() <<
"Inserting redundant phis\n";
1568 dbgs() <<
"BlockInScope " << BB->getName() <<
"\n";
1573 for (
User *U :
I.users()) {
1574 if (
auto *UI = dyn_cast<Instruction>(U)) {
1575 if (!BlocksInScope.
contains(UI->getParent()) &&
1577 !(isa<PHINode>(UI) && UI->getParent() == ExitBlock)) {
1579 CHR_DEBUG(
dbgs() <<
"Used outside scope by user " << *UI <<
"\n");
1580 Users.push_back(UI);
1581 }
else if (UI->getParent() == EntryBlock && isa<PHINode>(UI)) {
1586 <<
"Used at entry block (for a back edge) by a phi user "
1588 Users.push_back(UI);
1592 if (
Users.size() > 0) {
1604 for (
unsigned J = 0, NumOps = UI->getNumOperands(); J < NumOps; ++J) {
1605 if (UI->getOperand(J) == &
I) {
1606 UI->setOperand(J, PN);
1620 auto HasBiasedBranchOrSelect = [](
RegInfo &RI, CHRScope *Scope) {
1621 if (Scope->TrueBiasedRegions.count(RI.R) ||
1622 Scope->FalseBiasedRegions.count(RI.R))
1625 if (Scope->TrueBiasedSelects.count(SI) ||
1626 Scope->FalseBiasedSelects.count(SI))
1630 for (
RegInfo &RI : Scope->CHRRegions) {
1631 assert(HasBiasedBranchOrSelect(RI, Scope) &&
1632 "Must have biased branch or select");
1640 CHRScope *Scope,
BasicBlock *PreEntryBlock) {
1642 for (
RegInfo &RI : Scope->CHRRegions) {
1644 bool IsTrueBiased = Scope->TrueBiasedRegions.count(R);
1645 bool IsFalseBiased = Scope->FalseBiasedRegions.count(R);
1646 if (RI.HasBranch && (IsTrueBiased || IsFalseBiased)) {
1647 auto *BI = cast<BranchInst>(R->getEntry()->getTerminator());
1648 Value *V = BI->getCondition();
1650 if (
auto *
I = dyn_cast<Instruction>(V)) {
1652 assert((
I->getParent() == PreEntryBlock ||
1653 !Scope->contains(
I)) &&
1654 "Must have been hoisted to PreEntryBlock or outside the scope");
1658 bool IsTrueBiased = Scope->TrueBiasedSelects.count(SI);
1659 bool IsFalseBiased = Scope->FalseBiasedSelects.count(SI);
1660 if (!(IsTrueBiased || IsFalseBiased))
1662 Value *V = SI->getCondition();
1664 if (
auto *
I = dyn_cast<Instruction>(V)) {
1666 assert((
I->getParent() == PreEntryBlock ||
1667 !Scope->contains(
I)) &&
1668 "Must have been hoisted to PreEntryBlock or outside the scope");
1677 assert(
Scope->RegInfos.size() >= 1 &&
"Should have at least one Region");
1681 unsigned Duplication = getRegionDuplicationCount(R);
1682 CHR_DEBUG(
dbgs() <<
"Dup count for R=" << R <<
" is " << Duplication
1685 CHR_DEBUG(
dbgs() <<
"Reached the dup threshold of " << Duplication
1686 <<
" for this region");
1689 R->getEntry()->getTerminator())
1690 <<
"Reached the duplication threshold for the region";
1696 DuplicationCount[RI.R]++;
1703 std::optional<uint64_t>
ProfileCount =
BFI.getBlockProfileCount(EntryBlock);
1723 <<
" at " << *
Scope->BranchInsertPoint <<
"\n");
1727 "NewEntryBlock's only pred must be EntryBlock");
1735 cloneScopeBlocks(Scope, PreEntryBlock, ExitBlock, LastRegion, VMap);
1739 BranchInst *MergedBr = createMergedBranch(PreEntryBlock, EntryBlock,
1740 NewEntryBlock, VMap);
1755 fixupBranchesAndSelects(Scope, PreEntryBlock, MergedBr,
1762void CHR::cloneScopeBlocks(CHRScope *Scope,
1776 assert(BB != PreEntryBlock &&
"Don't copy the preetntry block");
1784 PN.removeIncomingValueIf([&](
unsigned Idx) {
1785 return !DT.isReachableFromEntry(PN.getIncomingBlock(
Idx));
1792 F.splice(ExitBlock->
getIterator(), &
F, NewBlocks[0]->getIterator(),
1806 for (
unsigned I = 0, NumOps = PN.getNumIncomingValues();
I < NumOps;
1810 Value *
V = PN.getIncomingValue(
I);
1811 auto It = VMap.
find(V);
1812 if (It != VMap.
end())
V = It->second;
1813 assert(VMap.
find(Pred) != VMap.
end() &&
"Pred must have been cloned");
1814 PN.addIncoming(V, cast<BasicBlock>(VMap[Pred]));
1827 "SplitBlock did not work correctly!");
1829 "NewEntryBlock's only pred must be EntryBlock");
1831 "NewEntryBlock must have been copied");
1837 cast<BasicBlock>(VMap[NewEntryBlock]),
1840 assert(NewEntryBlock->getSinglePredecessor() == EntryBlock &&
1841 "NewEntryBlock's only pred must be EntryBlock");
1847void CHR::fixupBranchesAndSelects(CHRScope *Scope,
1858 fixupBranch(R, Scope, IRB, MergedCondition, CHRBranchBias);
1862 fixupSelect(SI, Scope, IRB, MergedCondition, CHRBranchBias);
1866 Stats.NumBranchesDelta += NumCHRedBranches - 1;
1873 <<
"Merged " <<
ore::NV(
"NumCHRedBranches", NumCHRedBranches)
1874 <<
" branches or selects";
1878 static_cast<uint32_t>(CHRBranchBias.scale(1000)),
1879 static_cast<uint32_t>(CHRBranchBias.getCompl().scale(1000)),
1882 CHR_DEBUG(
dbgs() <<
"CHR branch bias " << Weights[0] <<
":" << Weights[1]
1888void CHR::fixupBranch(
Region *R, CHRScope *Scope,
1890 Value *&MergedCondition,
1892 bool IsTrueBiased =
Scope->TrueBiasedRegions.count(R);
1893 assert((IsTrueBiased ||
Scope->FalseBiasedRegions.count(R)) &&
1894 "Must be truthy or falsy");
1895 auto *BI = cast<BranchInst>(
R->getEntry()->getTerminator());
1896 assert(BranchBiasMap.contains(R) &&
"Must be in the bias map");
1900 if (CHRBranchBias > Bias)
1901 CHRBranchBias = Bias;
1905 assert(RegionExitBlock &&
"Null ExitBlock");
1906 assert((IfThen == RegionExitBlock || IfElse == RegionExitBlock) &&
1907 IfThen != IfElse &&
"Invariant from findScopes");
1908 if (IfThen == RegionExitBlock) {
1914 <<
" IfElse " << IfElse->
getName() <<
"\n");
1916 BasicBlock *HotTarget = IsTrueBiased ? IfThen : IfElse;
1917 bool ConditionTrue = HotTarget == BI->getSuccessor(0);
1918 addToMergedCondition(ConditionTrue,
Cond, BI, Scope, IRB,
1921 assert(ConditionTrue == (HotTarget == BI->getSuccessor(0)) &&
1922 "The successor shouldn't change");
1923 Value *NewCondition = ConditionTrue ?
1926 BI->setCondition(NewCondition);
1931void CHR::fixupSelect(
SelectInst *SI, CHRScope *Scope,
1933 Value *&MergedCondition,
1935 bool IsTrueBiased =
Scope->TrueBiasedSelects.count(SI);
1937 Scope->FalseBiasedSelects.count(SI)) &&
"Must be biased");
1938 assert(SelectBiasMap.contains(SI) &&
"Must be in the bias map");
1942 if (CHRBranchBias > Bias)
1943 CHRBranchBias = Bias;
1945 addToMergedCondition(IsTrueBiased,
Cond, SI, Scope, IRB,
1947 Value *NewCondition = IsTrueBiased ?
1950 SI->setCondition(NewCondition);
1955void CHR::addToMergedCondition(
bool IsTrueBiased,
Value *
Cond,
1958 if (!IsTrueBiased) {
1962 auto *ICmp = dyn_cast<ICmpInst>(
Cond);
1979 for (CHRScope *Scope : CHRScopes) {
1980 transformScopes(Scope, TrivialPHIs);
1982 std::ostringstream oss;
1983 oss <<
" after transformScopes " <<
I++;
1984 dumpIR(
F, oss.str().c_str(),
nullptr));
1991 dbgs() << Label <<
" " << Scopes.size() <<
"\n";
1992 for (CHRScope *Scope : Scopes) {
1993 dbgs() << *Scope <<
"\n";
2003 bool Changed =
false;
2006 dbgs() <<
"RegionInfo:\n";
2012 findScopes(AllScopes);
2021 splitScopes(AllScopes, SplitScopes);
2026 classifyBiasedScopes(SplitScopes);
2032 filterScopes(SplitScopes, FilteredScopes);
2037 setCHRRegions(FilteredScopes, SetScopes);
2044 sortScopes(SetScopes, SortedScopes);
2048 dbgs() <<
"RegionInfo:\n";
2052 if (!SortedScopes.
empty()) {
2053 transformScopes(SortedScopes);
2063 <<
"Reduced the number of branches in hot paths by "
2066 <<
ore::NV(
"WeightedNumBranchesDelta",
Stats.WeightedNumBranchesDelta)
2067 <<
" (weighted by PGO count)";
2086 if (!PPSI || !PPSI->hasProfileSummary())
2093 bool Changed = CHR(
F, BFI, DT, PSI, RI, ORE).run();
static MachineBasicBlock * split(MachineBasicBlock::iterator I)
static cl::opt< ITMode > IT(cl::desc("IT block support"), cl::Hidden, cl::init(DefaultIT), cl::values(clEnumValN(DefaultIT, "arm-default-it", "Generate any type of IT block"), clEnumValN(RestrictedIT, "arm-restrict-it", "Disallow complex IT blocks")))
static void print(raw_ostream &Out, object::Archive::Kind Kind, T Val)
#define LLVM_ATTRIBUTE_UNUSED
static void insertTrivialPHIs(CHRScope *Scope, BasicBlock *EntryBlock, BasicBlock *ExitBlock, DenseSet< PHINode * > &TrivialPHIs)
static raw_ostream LLVM_ATTRIBUTE_UNUSED & operator<<(raw_ostream &OS, const CHRStats &Stats)
static cl::opt< bool > DisableCHR("disable-chr", cl::init(false), cl::Hidden, cl::desc("Disable CHR for all functions"))
static StringSet CHRFunctions
static bool CHRScopeSorter(CHRScope *Scope1, CHRScope *Scope2)
static bool checkHoistValue(Value *V, Instruction *InsertPoint, DominatorTree &DT, DenseSet< Instruction * > &Unhoistables, DenseSet< Instruction * > *HoistStops, DenseMap< Instruction *, bool > &Visited)
static cl::opt< unsigned > CHRMergeThreshold("chr-merge-threshold", cl::init(2), cl::Hidden, cl::desc("CHR merges a group of N branches/selects where N >= this value"))
static bool isHoistable(Instruction *I, DominatorTree &DT)
static cl::opt< unsigned > CHRDupThreshsold("chr-dup-threshold", cl::init(3), cl::Hidden, cl::desc("Max number of duplications by CHR for a region"))
static bool shouldSplit(Instruction *InsertPoint, DenseSet< Value * > &PrevConditionValues, DenseSet< Value * > &ConditionValues, DominatorTree &DT, DenseSet< Instruction * > &Unhoistables)
static bool checkBias(K *Key, BranchProbability TrueProb, BranchProbability FalseProb, S &TrueSet, S &FalseSet, M &BiasMap)
static StringSet CHRModules
static bool checkBiasedSelect(SelectInst *SI, Region *R, DenseSet< SelectInst * > &TrueBiasedSelectsGlobal, DenseSet< SelectInst * > &FalseBiasedSelectsGlobal, DenseMap< SelectInst *, BranchProbability > &SelectBiasMap)
static void hoistValue(Value *V, Instruction *HoistPoint, Region *R, HoistStopMapTy &HoistStopMap, DenseSet< Instruction * > &HoistedSet, DenseSet< PHINode * > &TrivialPHIs, DominatorTree &DT)
static bool hasAtLeastTwoBiasedBranches(CHRScope *Scope)
static bool shouldApply(Function &F, ProfileSummaryInfo &PSI)
static void LLVM_ATTRIBUTE_UNUSED dumpIR(Function &F, const char *Label, CHRStats *Stats)
static void getSelectsInScope(CHRScope *Scope, DenseSet< Instruction * > &Output)
static void hoistScopeConditions(CHRScope *Scope, Instruction *HoistPoint, DenseSet< PHINode * > &TrivialPHIs, DominatorTree &DT)
static bool isHoistableInstructionType(Instruction *I)
static DenseSet< Value * > getCHRConditionValuesForRegion(RegInfo &RI)
static bool negateICmpIfUsedByBranchOrSelectOnly(ICmpInst *ICmp, Instruction *ExcludedUser, CHRScope *Scope)
static Instruction * getBranchInsertPoint(RegInfo &RI)
static void LLVM_ATTRIBUTE_UNUSED assertBranchOrSelectConditionHoisted(CHRScope *Scope, BasicBlock *PreEntryBlock)
static cl::opt< std::string > CHRModuleList("chr-module-list", cl::init(""), cl::Hidden, cl::desc("Specify file to retrieve the list of modules to apply CHR to"))
static void LLVM_ATTRIBUTE_UNUSED assertCHRRegionsHaveBiasedBranchOrSelect(CHRScope *Scope)
static cl::opt< double > CHRBiasThreshold("chr-bias-threshold", cl::init(0.99), cl::Hidden, cl::desc("CHR considers a branch bias greater than this ratio as biased"))
static void LLVM_ATTRIBUTE_UNUSED dumpScopes(SmallVectorImpl< CHRScope * > &Scopes, const char *Label)
static BranchProbability getCHRBiasThreshold()
static cl::opt< std::string > CHRFunctionList("chr-function-list", cl::init(""), cl::Hidden, cl::desc("Specify file to retrieve the list of functions to apply CHR to"))
static cl::opt< bool > ForceCHR("force-chr", cl::init(false), cl::Hidden, cl::desc("Apply CHR for all functions"))
static bool checkBiasedBranch(BranchInst *BI, Region *R, DenseSet< Region * > &TrueBiasedRegionsGlobal, DenseSet< Region * > &FalseBiasedRegionsGlobal, DenseMap< Region *, BranchProbability > &BranchBiasMap)
static const std::set< Value * > & getBaseValues(Value *V, DominatorTree &DT, DenseMap< Value *, std::set< Value * > > &Visited)
static bool extractBranchProbabilities(Instruction *I, BranchProbability &TrueProb, BranchProbability &FalseProb)
static void parseCHRFilterFiles()
Returns the sub type a function will return at a given Idx Should correspond to the result type of an ExtractValue instruction executed with just that one unsigned Idx
This file defines the DenseMap class.
This file defines the DenseSet and SmallDenseSet classes.
This is the interface for a simple mod/ref and alias analysis over globals.
This file provides various utilities for inspecting and working with the control flow graph in LLVM I...
iv Induction Variable Users
static Constant * getFalse(Type *Ty)
For a boolean type or a vector of boolean type, return false or a vector with every element false.
block placement Basic Block Placement Stats
Module.h This file contains the declarations for the Module class.
uint64_t IntrinsicInst * II
FunctionAnalysisManager FAM
This header defines various interfaces for pass management in LLVM.
This file contains the declarations for profiling metadata utility functions.
const SmallVectorImpl< MachineOperand > & Cond
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file defines the SmallVector class.
StringSet - A set-like wrapper for the StringMap.
static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)
A container for analyses that lazily runs them and caches their results.
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
LLVM Basic Block Representation.
iterator begin()
Instruction iterator methods.
iterator_range< const_phi_iterator > phis() const
Returns a range that iterates over the phis in the basic block.
const BasicBlock * getSinglePredecessor() const
Return the predecessor of this block if it has a single predecessor block.
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...
Analysis pass which computes BlockFrequencyInfo.
BlockFrequencyInfo pass uses BlockFrequencyInfoImpl implementation to estimate IR basic block frequen...
Conditional or Unconditional Branch instruction.
void setCondition(Value *V)
bool isConditional() const
static BranchInst * Create(BasicBlock *IfTrue, InsertPosition InsertBefore=nullptr)
BasicBlock * getSuccessor(unsigned i) const
bool isUnconditional() const
static BranchProbability getBranchProbability(uint64_t Numerator, uint64_t Denominator)
void setPredicate(Predicate P)
Set the predicate for this instruction to the specified value.
Predicate getInversePredicate() const
For example, EQ -> NE, UGT -> ULE, SLT -> SGE, OEQ -> UNE, UGT -> OLE, OLT -> UGE,...
Predicate getPredicate() const
Return the predicate for this instruction.
This is the shared class of boolean and integer constants.
static ConstantInt * getTrue(LLVMContext &Context)
ControlHeightReductionPass()
PreservedAnalyses run(Function &F, FunctionAnalysisManager &FAM)
This class represents an Operation in the Expression.
iterator find(const_arg_type_t< KeyT > Val)
Implements a dense probed hash-table based set.
Analysis pass which computes a DominatorTree.
DomTreeNodeBase< NodeT > * getNode(const NodeT *BB) const
getNode - return the (Post)DominatorTree node for the specified basic block.
Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree.
bool dominates(const BasicBlock *BB, const Use &U) const
Return true if the (end of the) basic block BB dominates the use U.
Class to represent profile counts.
This instruction compares its operands according to the predicate given to the constructor.
Value * CreateFreeze(Value *V, const Twine &Name="")
Value * CreateLogicalAnd(Value *Cond1, Value *Cond2, const Twine &Name="")
Value * CreateXor(Value *LHS, Value *RHS, const Twine &Name="")
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
void insertBefore(Instruction *InsertPos)
Insert an unlinked instruction into a basic block immediately before the specified instruction.
InstListType::iterator eraseFromParent()
This method unlinks 'this' from the containing basic block and deletes it.
InstListType::iterator insertInto(BasicBlock *ParentBB, InstListType::iterator It)
Inserts an unlinked instruction into ParentBB at position It and returns the iterator of the inserted...
static ErrorOr< std::unique_ptr< MemoryBuffer > > getFile(const Twine &Filename, bool IsText=false, bool RequiresNullTerminator=true, bool IsVolatile=false, std::optional< Align > Alignment=std::nullopt)
Open the specified file as a MemoryBuffer, returning a new MemoryBuffer if successful,...
An analysis over an "inner" IR unit that provides access to an analysis manager over a "outer" IR uni...
void addIncoming(Value *V, BasicBlock *BB)
Add an incoming value to the end of the PHI list.
static PHINode * Create(Type *Ty, unsigned NumReservedValues, const Twine &NameStr="", InsertPosition InsertBefore=nullptr)
Constructors - NumReservedValues is a hint for the number of incoming edges that this phi node will h...
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.
An analysis pass based on the new PM to deliver ProfileSummaryInfo.
Analysis providing profile information.
bool isFunctionEntryHot(const FuncT *F) const
Returns true if F has hot function entry.
BlockT * getExit() const
Get the exit BasicBlock of the Region.
void replaceEntryRecursive(BlockT *NewEntry)
Recursively replace the entry basic block of the region.
bool contains(const BlockT *BB) const
Check if the region contains a BasicBlock.
RegionT * getParent() const
Get the parent of the Region.
BlockT * getEntry() const
Get the entry BasicBlock of the Region.
Analysis pass that exposes the RegionInfo for a function.
This class represents the LLVM 'select' instruction.
bool insert(const value_type &X)
Insert a new element into the SetVector.
bool contains(const key_type &key) const
Check if the SetVector contains the given key.
A SetVector that performs no allocations if smaller than a certain size.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
size_type count(StringRef Key) const
count - Return 1 if the element is in the map, 0 otherwise.
StringRef - Represent a constant reference to a string, i.e.
std::pair< StringRef, StringRef > split(char Separator) const
Split into two substrings around the first occurrence of a separator character.
StringSet - A wrapper for StringMap that provides set-like functionality.
std::pair< typename Base::iterator, bool > insert(StringRef key)
void dropAllReferences()
Drop all references to operands.
iterator find(const KeyT &Val)
LLVM Value Representation.
iterator_range< user_iterator > users()
StringRef getName() const
Return a constant reference to the value's name.
std::pair< iterator, bool > insert(const ValueT &V)
bool contains(const_arg_type_t< ValueT > V) const
Check if the set contains the given element.
bool erase(const ValueT &V)
size_type count(const_arg_type_t< ValueT > V) const
Return 1 if the specified key is in the set, 0 otherwise.
const ParentTy * getParent() const
self_iterator getIterator()
This class implements an extremely fast bulk output stream that can only output to a stream.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ Tail
Attemps to make calls as fast as possible while guaranteeing that tail call optimization can always b...
initializer< Ty > init(const Ty &Val)
PointerTypeMap run(const Module &M)
Compute the PointerTypeMap for the module M.
Scope
Defines the scope in which this symbol should be visible: Default – Visible in the public interface o...
DiagnosticInfoOptimizationBase::Argument NV
void append(SmallVectorImpl< char > &path, const Twine &a, const Twine &b="", const Twine &c="", const Twine &d="")
Append to path.
This is an optimization pass for GlobalISel generic memory operations.
void stable_sort(R &&Range)
void append_range(Container &C, Range &&R)
Wrapper function to append range R to container C.
iterator_range< early_inc_iterator_impl< detail::IterOfRange< RangeT > > > make_early_inc_range(RangeT &&Range)
Make a range that does early increment to allow mutation of the underlying range without disrupting i...
BasicBlock * CloneBasicBlock(const BasicBlock *BB, ValueToValueMapTy &VMap, const Twine &NameSuffix="", Function *F=nullptr, ClonedCodeInfo *CodeInfo=nullptr, DebugInfoFinder *DIFinder=nullptr)
Return a copy of the specified basic block, but without embedding the block into a particular functio...
void setBranchWeights(Instruction &I, ArrayRef< uint32_t > Weights, bool IsExpected)
Create a new branch_weights metadata node and add or overwrite a prof metadata reference to instructi...
@ RF_IgnoreMissingLocals
If this flag is set, the remapper ignores missing function-local entries (Argument,...
@ RF_NoModuleLevelChanges
If this flag is set, the remapper knows that only local values within a function (such as an instruct...
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
bool isSafeToSpeculativelyExecute(const Instruction *I, const Instruction *CtxI=nullptr, AssumptionCache *AC=nullptr, const DominatorTree *DT=nullptr, const TargetLibraryInfo *TLI=nullptr, bool UseVariableInfo=true)
Return true if the instruction does not have any effects besides calculating the result and does not ...
void RemapInstruction(Instruction *I, ValueToValueMapTy &VM, RemapFlags Flags=RF_None, ValueMapTypeRemapper *TypeMapper=nullptr, ValueMaterializer *Materializer=nullptr)
Convert the instruction operands from referencing the current values into those specified by VM.
raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
bool isGuaranteedNotToBeUndefOrPoison(const Value *V, AssumptionCache *AC=nullptr, const Instruction *CtxI=nullptr, const DominatorTree *DT=nullptr, unsigned Depth=0)
Return true if this function can prove that V does not have undef bits and is never poison.
OutputIt copy(R &&Range, OutputIt Out)
bool extractBranchWeights(const MDNode *ProfileData, SmallVectorImpl< uint32_t > &Weights)
Extract branch weights from MD_prof metadata.
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.
auto find_if(R &&Range, UnaryPredicate P)
Provide wrappers to std::find_if which take ranges instead of having to pass begin/end explicitly.
void erase_if(Container &C, UnaryPredicate P)
Provide a container algorithm similar to C++ Library Fundamentals v2's erase_if which is equivalent t...
auto predecessors(const MachineBasicBlock *BB)
unsigned pred_size(const MachineBasicBlock *BB)
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.