47#define DEBUG_TYPE "chr"
49#define CHR_DEBUG(X) LLVM_DEBUG(X)
52 cl::desc(
"Disable CHR for all functions"));
55 cl::desc(
"Apply CHR for all functions"));
59 cl::desc(
"CHR considers a branch bias greater than this ratio as biased"));
63 cl::desc(
"CHR merges a group of N branches/selects where N >= this value"));
67 cl::desc(
"Specify file to retrieve the list of modules to apply CHR to"));
71 cl::desc(
"Specify file to retrieve the list of functions to apply CHR to"));
75 cl::desc(
"Max number of duplications by CHR for a region"));
84 errs() <<
"Error: Couldn't read the chr-module-list file " <<
CHRModuleList <<
"\n";
87 StringRef Buf = FileOrErr->get()->getBuffer();
89 Buf.
split(Lines,
'\n');
102 StringRef Buf = FileOrErr->get()->getBuffer();
104 Buf.
split(Lines,
'\n');
116 CHRStats() =
default;
117 void print(raw_ostream &OS)
const {
118 OS <<
"CHRStats: NumBranches " << NumBranches
119 <<
" NumBranchesDelta " << NumBranchesDelta
120 <<
" WeightedNumBranchesDelta " << WeightedNumBranchesDelta;
123 uint64_t NumBranches = 0;
126 uint64_t NumBranchesDelta = 0;
128 uint64_t WeightedNumBranchesDelta = 0;
134 RegInfo(Region *RegionIn) :
R(RegionIn) {}
136 bool HasBranch =
false;
147 CHRScope(RegInfo RI) : BranchInsertPoint(nullptr) {
148 assert(RI.R &&
"Null RegionIn");
149 RegInfos.push_back(RI);
152 Region *getParentRegion() {
153 assert(RegInfos.size() > 0 &&
"Empty CHRScope");
154 Region *Parent = RegInfos[0].R->getParent();
155 assert(Parent &&
"Unexpected to call this on the top-level region");
160 assert(RegInfos.size() > 0 &&
"Empty CHRScope");
161 return RegInfos.front().R->getEntry();
165 assert(RegInfos.size() > 0 &&
"Empty CHRScope");
166 return RegInfos.back().R->getExit();
169 bool appendable(CHRScope *
Next) {
174 if (getExitBlock() != NextEntry)
177 Region *LastRegion = RegInfos.back().R;
187 assert(RegInfos.size() > 0 &&
"Empty CHRScope");
188 assert(
Next->RegInfos.size() > 0 &&
"Empty CHRScope");
189 assert(getParentRegion() ==
Next->getParentRegion() &&
191 assert(getExitBlock() ==
Next->getEntryBlock() &&
193 RegInfos.append(
Next->RegInfos.begin(),
Next->RegInfos.end());
194 Subs.append(
Next->Subs.begin(),
Next->Subs.end());
197 void addSub(CHRScope *SubIn) {
199 bool IsChild =
false;
200 for (RegInfo &RI : RegInfos)
201 if (RI.R == SubIn->getParentRegion()) {
205 assert(IsChild &&
"Must be a child");
207 Subs.push_back(SubIn);
212 CHRScope *
split(Region *Boundary) {
213 assert(Boundary &&
"Boundary null");
214 assert(RegInfos.begin()->R != Boundary &&
215 "Can't be split at beginning");
217 RegInfos, [&Boundary](
const RegInfo &RI) {
return Boundary == RI.R; });
218 if (BoundaryIt == RegInfos.end())
221 DenseSet<Region *> TailRegionSet;
222 for (
const RegInfo &RI : TailRegInfos)
223 TailRegionSet.
insert(RI.R);
226 std::stable_partition(Subs.begin(), Subs.end(), [&](CHRScope *
Sub) {
227 assert(Sub &&
"null Sub");
228 Region *Parent = Sub->getParentRegion();
229 if (TailRegionSet.count(Parent))
234 [&Parent](const RegInfo &RI) { return Parent == RI.R; }) &&
240 assert(HoistStopMap.empty() &&
"MapHoistStops must be empty");
241 auto *
Scope =
new CHRScope(TailRegInfos, TailSubs);
242 RegInfos.erase(BoundaryIt, RegInfos.end());
243 Subs.erase(TailIt, Subs.end());
249 for (
const RegInfo &RI : RegInfos)
250 if (RI.R->contains(Parent))
279 HoistStopMapTy HoistStopMap;
283 : RegInfos(RegInfosIn), Subs(SubsIn), BranchInsertPoint(nullptr) {}
288 CHR(Function &Fin, BlockFrequencyInfo &BFIin, DominatorTree &DTin,
289 ProfileSummaryInfo &PSIin, RegionInfo &RIin,
290 OptimizationRemarkEmitter &OREin)
291 : F(Fin), BFI(BFIin), DT(DTin), PSI(PSIin), RI(RIin), ORE(OREin) {}
294 for (CHRScope *Scope : Scopes) {
305 void findScopes(SmallVectorImpl<CHRScope *> &Output) {
306 Region *
R = RI.getTopLevelRegion();
307 if (CHRScope *Scope = findScopes(R,
nullptr,
nullptr, Output)) {
311 CHRScope *findScopes(Region *R, Region *NextRegion, Region *ParentRegion,
312 SmallVectorImpl<CHRScope *> &Scopes);
313 CHRScope *findScope(Region *R);
314 void checkScopeHoistable(CHRScope *Scope);
316 void splitScopes(SmallVectorImpl<CHRScope *> &Input,
317 SmallVectorImpl<CHRScope *> &Output);
320 DenseSet<Value *> *OuterConditionValues,
321 Instruction *OuterInsertPoint,
322 SmallVectorImpl<CHRScope *> &Output,
323 DenseSet<Instruction *> &Unhoistables);
325 void classifyBiasedScopes(SmallVectorImpl<CHRScope *> &Scopes);
326 void classifyBiasedScopes(CHRScope *Scope, CHRScope *OutermostScope);
328 void filterScopes(SmallVectorImpl<CHRScope *> &Input,
329 SmallVectorImpl<CHRScope *> &Output);
331 void setCHRRegions(SmallVectorImpl<CHRScope *> &Input,
332 SmallVectorImpl<CHRScope *> &Output);
333 void setCHRRegions(CHRScope *Scope, CHRScope *OutermostScope);
335 void sortScopes(SmallVectorImpl<CHRScope *> &Input,
336 SmallVectorImpl<CHRScope *> &Output);
338 void transformScopes(SmallVectorImpl<CHRScope *> &CHRScopes);
339 void transformScopes(CHRScope *Scope, DenseSet<PHINode *> &TrivialPHIs);
340 void cloneScopeBlocks(CHRScope *Scope,
341 BasicBlock *PreEntryBlock,
342 BasicBlock *ExitBlock,
345 CondBrInst *createMergedBranch(BasicBlock *PreEntryBlock,
346 BasicBlock *EntryBlock,
347 BasicBlock *NewEntryBlock,
349 void fixupBranchesAndSelects(CHRScope *Scope, BasicBlock *PreEntryBlock,
351 void fixupBranch(Region *R, CHRScope *Scope,
IRBuilder<> &IRB,
352 Value *&MergedCondition, BranchProbability &CHRBranchBias);
353 void fixupSelect(SelectInst *SI, CHRScope *Scope,
IRBuilder<> &IRB,
354 Value *&MergedCondition, BranchProbability &CHRBranchBias);
355 void addToMergedCondition(
bool IsTrueBiased,
Value *
Cond,
356 Instruction *BranchOrSelect, CHRScope *Scope,
358 unsigned getRegionDuplicationCount(
const Region *R) {
365 Count += DuplicationCount[
R];
372 BlockFrequencyInfo &BFI;
374 ProfileSummaryInfo &PSI;
376 OptimizationRemarkEmitter &ORE;
380 DenseSet<Region *> TrueBiasedRegionsGlobal;
382 DenseSet<Region *> FalseBiasedRegionsGlobal;
384 DenseSet<SelectInst *> TrueBiasedSelectsGlobal;
386 DenseSet<SelectInst *> FalseBiasedSelectsGlobal;
388 DenseMap<Region *, BranchProbability> BranchBiasMap;
390 DenseMap<SelectInst *, BranchProbability> SelectBiasMap;
392 DenseSet<CHRScope *> Scopes;
394 DenseMap<const Region *, unsigned> DuplicationCount;
400 const CHRStats &
Stats) {
442 assert(RegInfos.size() > 0 &&
"Empty CHRScope");
444 OS << RegInfos.size() <<
", Regions[";
445 for (
const RegInfo &RI : RegInfos) {
446 OS << RI.R->getNameStr();
449 if (RI.Selects.size() > 0)
450 OS <<
" S" << RI.Selects.size();
453 if (RegInfos[0].
R->getParent()) {
454 OS <<
"], Parent " << RegInfos[0].R->getParent()->getNameStr();
460 for (CHRScope *
Sub : Subs) {
487static const std::set<Value *> &
490 auto It = Visited.find(V);
491 if (It != Visited.end()) {
494 std::set<Value *> Result;
501 return Visited.insert(std::make_pair(V, std::move(Result))).first->second;
506 Result.insert(OpResult.begin(), OpResult.end());
508 return Visited.insert(std::make_pair(V, std::move(Result))).first->second;
516 return Visited.insert(std::make_pair(V, std::move(Result))).first->second;
530 auto It = Visited.
find(
I);
531 if (It != Visited.
end()) {
534 assert(DT.
getNode(
I->getParent()) &&
"DT must contain I's parent block");
536 if (Unhoistables.
count(
I)) {
553 bool AllOpsHoisted =
true;
557 AllOpsHoisted =
false;
585 uint64_t SumWeight = TrueWeight + FalseWeight;
587 assert(SumWeight >= TrueWeight && SumWeight >= FalseWeight &&
588 "Overflow calculating branch probabilities.");
608template <
typename K,
typename S,
typename M>
613 if (TrueProb >= Threshold) {
615 BiasMap[
Key] = TrueProb;
617 }
else if (FalseProb >= Threshold) {
618 FalseSet.insert(
Key);
619 BiasMap[
Key] = FalseProb;
637 assert((IfThen == R->getExit() || IfElse == R->getExit()) &&
639 "Invariant from findScopes");
640 if (IfThen == R->getExit()) {
650 TrueBiasedRegionsGlobal, FalseBiasedRegionsGlobal,
668 TrueBiasedSelectsGlobal, FalseBiasedSelectsGlobal,
682 if (
SI->getParent() == EntryBB) {
689 assert(HoistPoint &&
"Null HoistPoint");
695 if (
SI->getParent() == EntryBB) {
702 "HoistPoint must be the first one in Selects");
711CHRScope * CHR::findScope(Region *R) {
712 CHRScope *
Result =
nullptr;
715 assert(Entry &&
"Entry must not be null");
716 assert((Exit ==
nullptr) == (
R->isTopLevelRegion()) &&
717 "Only top level region has a null exit");
728 bool EntryInSubregion = RI.getRegionFor(Entry) !=
R;
729 if (EntryInSubregion)
733 if (
R->contains(Pred))
737 for (BasicBlock *BB :
R->blocks()) {
738 if (BB->hasAddressTaken())
746 for (Instruction &
I : *BB) {
748 if (
II->getIntrinsicID() == Intrinsic::coro_id)
765 if (CB->cannotDuplicate() || CB->isConvergent())
782 if (S0 !=
S1 && (S0 == Exit ||
S1 == Exit)) {
785 BI, R, TrueBiasedRegionsGlobal, FalseBiasedRegionsGlobal,
787 Result =
new CHRScope(RI);
788 Scopes.insert(Result);
793 return OptimizationRemarkMissed(
DEBUG_TYPE,
"BranchNotBiased", BI)
794 <<
"Branch not biased";
814 for (RegionNode *
E :
R->elements()) {
815 if (
E->isSubRegion())
822 for (Instruction &
I : *BB) {
829 if (Selects.
size() > 0) {
830 auto AddSelects = [&](RegInfo &RI) {
831 for (
auto *SI : Selects)
833 TrueBiasedSelectsGlobal,
834 FalseBiasedSelectsGlobal,
836 RI.Selects.push_back(SI);
839 return OptimizationRemarkMissed(
DEBUG_TYPE,
"SelectNotBiased", SI)
840 <<
"Select not biased";
847 Result =
new CHRScope(RI);
848 Scopes.insert(Result);
850 CHR_DEBUG(
dbgs() <<
"Found select(s) in a region with a branch\n");
851 AddSelects(
Result->RegInfos[0]);
857 checkScopeHoistable(Result);
884void CHR::checkScopeHoistable(CHRScope *Scope) {
885 RegInfo &RI =
Scope->RegInfos[0];
891 if (RI.HasBranch || !Selects.
empty()) {
900 for (
auto it = Selects.
begin(); it != Selects.
end(); ) {
901 SelectInst *
SI = *it;
902 if (SI == InsertPoint) {
906 DenseMap<Instruction *, bool> Visited;
908 DT, Unhoistables,
nullptr, Visited);
913 "DropUnhoistableSelect", SI)
914 <<
"Dropped unhoistable select";
916 it = Selects.
erase(it);
919 Unhoistables.erase(SI);
926 if (RI.HasBranch && InsertPoint != Branch) {
927 DenseMap<Instruction *, bool> Visited;
929 DT, Unhoistables,
nullptr, Visited);
934 assert(InsertPoint != Branch &&
"Branch must not be the hoist point");
937 for (SelectInst *SI : Selects) {
938 dbgs() <<
"SI " << *
SI <<
"\n";
940 for (SelectInst *SI : Selects) {
943 "DropSelectUnhoistableBranch", SI)
944 <<
"Dropped select due to unhoistable branch";
948 return SI->getParent() == EntryBB;
950 Unhoistables.clear();
958 "Branch can't be already above the hoist point");
959 DenseMap<Instruction *, bool> Visited;
961 DT, Unhoistables,
nullptr, Visited) &&
962 "checkHoistValue for branch");
964 for (
auto *SI : Selects) {
966 "SI can't be already above the hoist point");
967 DenseMap<Instruction *, bool> Visited;
969 Unhoistables,
nullptr, Visited) &&
970 "checkHoistValue for selects");
976 for (
auto *SI : Selects) {
984CHRScope * CHR::findScopes(Region *R, Region *NextRegion, Region *ParentRegion,
985 SmallVectorImpl<CHRScope *> &Scopes) {
987 CHRScope *
Result = findScope(R);
989 CHRScope *ConsecutiveSubscope =
nullptr;
991 for (
auto It =
R->begin(); It !=
R->end(); ++It) {
992 const std::unique_ptr<Region> &SubR = *It;
993 auto NextIt = std::next(It);
994 Region *NextSubR = NextIt !=
R->end() ? NextIt->get() :
nullptr;
995 CHR_DEBUG(
dbgs() <<
"Looking at subregion " << SubR.get()->getNameStr()
997 CHRScope *SubCHRScope = findScopes(SubR.get(), NextSubR, R, Scopes);
999 CHR_DEBUG(
dbgs() <<
"Subregion Scope " << *SubCHRScope <<
"\n");
1004 if (!ConsecutiveSubscope)
1005 ConsecutiveSubscope = SubCHRScope;
1006 else if (!ConsecutiveSubscope->appendable(SubCHRScope)) {
1007 Subscopes.
push_back(ConsecutiveSubscope);
1008 ConsecutiveSubscope = SubCHRScope;
1010 ConsecutiveSubscope->append(SubCHRScope);
1012 if (ConsecutiveSubscope) {
1013 Subscopes.
push_back(ConsecutiveSubscope);
1015 ConsecutiveSubscope =
nullptr;
1018 if (ConsecutiveSubscope) {
1019 Subscopes.
push_back(ConsecutiveSubscope);
1021 for (CHRScope *
Sub : Subscopes) {
1037 ConditionValues.
insert(BI->getCondition());
1040 ConditionValues.
insert(
SI->getCondition());
1042 return ConditionValues;
1060 for (
Value *V : PrevConditionValues) {
1061 dbgs() << *V <<
", ";
1063 dbgs() <<
" ConditionValues ";
1064 for (
Value *V : ConditionValues) {
1065 dbgs() << *V <<
", ";
1069 for (
Value *V : ConditionValues) {
1072 CHR_DEBUG(
dbgs() <<
"Split. checkHoistValue false " << *V <<
"\n");
1079 if (!PrevConditionValues.
empty() && !ConditionValues.
empty()) {
1081 std::set<Value *> PrevBases, Bases;
1083 for (
Value *V : PrevConditionValues) {
1084 const std::set<Value *> &BaseValues =
getBaseValues(V, DT, Visited);
1085 PrevBases.insert(BaseValues.begin(), BaseValues.end());
1087 for (
Value *V : ConditionValues) {
1088 const std::set<Value *> &BaseValues =
getBaseValues(V, DT, Visited);
1089 Bases.insert(BaseValues.begin(), BaseValues.end());
1092 dbgs() <<
"PrevBases ";
1093 for (
Value *V : PrevBases) {
1094 dbgs() << *V <<
", ";
1096 dbgs() <<
" Bases ";
1097 for (
Value *V : Bases) {
1098 dbgs() << *V <<
", ";
1101 std::vector<Value *> Intersection;
1102 std::set_intersection(PrevBases.begin(), PrevBases.end(), Bases.begin(),
1103 Bases.end(), std::back_inserter(Intersection));
1104 if (Intersection.empty()) {
1116 for (
RegInfo &RI : Scope->RegInfos)
1118 for (CHRScope *
Sub : Scope->Subs)
1122void CHR::splitScopes(SmallVectorImpl<CHRScope *> &Input,
1123 SmallVectorImpl<CHRScope *> &Output) {
1124 for (CHRScope *Scope : Input) {
1126 "BranchInsertPoint must not be set");
1127 DenseSet<Instruction *> Unhoistables;
1129 splitScope(Scope,
nullptr,
nullptr,
nullptr, Output, Unhoistables);
1132 for (CHRScope *Scope : Output) {
1133 assert(
Scope->BranchInsertPoint &&
"BranchInsertPoint must be set");
1141 DenseSet<Value *> *OuterConditionValues,
1142 Instruction *OuterInsertPoint,
1143 SmallVectorImpl<CHRScope *> &Output,
1144 DenseSet<Instruction *> &Unhoistables) {
1146 assert(OuterConditionValues &&
"Null OuterConditionValues");
1147 assert(OuterInsertPoint &&
"Null OuterInsertPoint");
1149 bool PrevSplitFromOuter =
true;
1150 DenseSet<Value *> PrevConditionValues;
1155 SmallVector<Instruction *, 8> SplitsInsertPoints;
1157 for (RegInfo &RI : RegInfos) {
1161 dbgs() <<
"ConditionValues ";
1162 for (
Value *V : ConditionValues) {
1163 dbgs() << *
V <<
", ";
1166 if (RI.R == RegInfos[0].R) {
1171 << RI.R->getNameStr() <<
"\n");
1172 if (
shouldSplit(OuterInsertPoint, *OuterConditionValues,
1173 ConditionValues, DT, Unhoistables)) {
1174 PrevConditionValues = ConditionValues;
1175 PrevInsertPoint = InsertPoint;
1178 "SplitScopeFromOuter",
1179 RI.R->getEntry()->getTerminator())
1180 <<
"Split scope from outer due to unhoistable branch/select "
1181 <<
"and/or lack of common condition values";
1186 PrevSplitFromOuter =
false;
1187 PrevConditionValues = *OuterConditionValues;
1189 PrevInsertPoint = OuterInsertPoint;
1193 PrevConditionValues = ConditionValues;
1194 PrevInsertPoint = InsertPoint;
1198 << RI.R->getNameStr() <<
"\n");
1199 if (
shouldSplit(PrevInsertPoint, PrevConditionValues, ConditionValues,
1200 DT, Unhoistables)) {
1204 SplitsSplitFromOuter.
push_back(PrevSplitFromOuter);
1205 SplitsConditionValues.
push_back(PrevConditionValues);
1206 SplitsInsertPoints.
push_back(PrevInsertPoint);
1208 PrevConditionValues = ConditionValues;
1209 PrevInsertPoint = InsertPoint;
1210 PrevSplitFromOuter =
true;
1213 "SplitScopeFromPrev",
1214 RI.R->getEntry()->getTerminator())
1215 <<
"Split scope from previous due to unhoistable branch/select "
1216 <<
"and/or lack of common condition values";
1225 SplitsSplitFromOuter.
push_back(PrevSplitFromOuter);
1226 SplitsConditionValues.
push_back(PrevConditionValues);
1227 assert(PrevInsertPoint &&
"Null PrevInsertPoint");
1228 SplitsInsertPoints.
push_back(PrevInsertPoint);
1230 Splits.
size() == SplitsSplitFromOuter.
size() &&
1231 Splits.
size() == SplitsInsertPoints.
size() &&
"Mismatching sizes");
1232 for (
size_t I = 0;
I < Splits.
size(); ++
I) {
1233 CHRScope *
Split = Splits[
I];
1234 DenseSet<Value *> &SplitConditionValues = SplitsConditionValues[
I];
1237 DenseSet<Instruction *> SplitUnhoistables;
1239 for (CHRScope *
Sub :
Split->Subs) {
1241 Sub, Split, &SplitConditionValues, SplitInsertPoint, Output,
1245 Split->Subs = NewSubs;
1248 for (
size_t I = 0;
I < Splits.
size(); ++
I) {
1249 CHRScope *
Split = Splits[
I];
1250 if (SplitsSplitFromOuter[
I]) {
1253 Split->BranchInsertPoint = SplitsInsertPoints[
I];
1254 CHR_DEBUG(
dbgs() <<
"BranchInsertPoint " << *SplitsInsertPoints[
I]
1263 "If no outer (top-level), must return no nested ones");
1267void CHR::classifyBiasedScopes(SmallVectorImpl<CHRScope *> &Scopes) {
1268 for (CHRScope *Scope : Scopes) {
1269 assert(
Scope->TrueBiasedRegions.empty() &&
Scope->FalseBiasedRegions.empty() &&
"Empty");
1270 classifyBiasedScopes(Scope, Scope);
1272 dbgs() <<
"classifyBiasedScopes " << *Scope <<
"\n";
1273 dbgs() <<
"TrueBiasedRegions ";
1274 for (Region *R :
Scope->TrueBiasedRegions) {
1275 dbgs() <<
R->getNameStr() <<
", ";
1278 dbgs() <<
"FalseBiasedRegions ";
1279 for (Region *R :
Scope->FalseBiasedRegions) {
1280 dbgs() <<
R->getNameStr() <<
", ";
1283 dbgs() <<
"TrueBiasedSelects ";
1284 for (SelectInst *SI :
Scope->TrueBiasedSelects) {
1288 dbgs() <<
"FalseBiasedSelects ";
1289 for (SelectInst *SI :
Scope->FalseBiasedSelects) {
1296void CHR::classifyBiasedScopes(CHRScope *Scope, CHRScope *OutermostScope) {
1297 for (RegInfo &RI :
Scope->RegInfos) {
1300 if (TrueBiasedRegionsGlobal.contains(R))
1301 OutermostScope->TrueBiasedRegions.insert(R);
1302 else if (FalseBiasedRegionsGlobal.contains(R))
1303 OutermostScope->FalseBiasedRegions.insert(R);
1307 for (SelectInst *SI : RI.Selects) {
1308 if (TrueBiasedSelectsGlobal.contains(SI))
1309 OutermostScope->TrueBiasedSelects.insert(SI);
1310 else if (FalseBiasedSelectsGlobal.contains(SI))
1311 OutermostScope->FalseBiasedSelects.insert(SI);
1316 for (CHRScope *
Sub :
Scope->Subs) {
1317 classifyBiasedScopes(
Sub, OutermostScope);
1322 unsigned NumBiased = Scope->TrueBiasedRegions.size() +
1323 Scope->FalseBiasedRegions.size() +
1324 Scope->TrueBiasedSelects.size() +
1325 Scope->FalseBiasedSelects.size();
1329void CHR::filterScopes(SmallVectorImpl<CHRScope *> &Input,
1330 SmallVectorImpl<CHRScope *> &Output) {
1331 for (CHRScope *Scope : Input) {
1334 CHR_DEBUG(
dbgs() <<
"Filtered out by biased branches truthy-regions "
1335 <<
Scope->TrueBiasedRegions.size()
1336 <<
" falsy-regions " <<
Scope->FalseBiasedRegions.size()
1337 <<
" true-selects " <<
Scope->TrueBiasedSelects.size()
1338 <<
" false-selects " <<
Scope->FalseBiasedSelects.size() <<
"\n");
1340 return OptimizationRemarkMissed(
1342 "DropScopeWithOneBranchOrSelect",
1343 Scope->RegInfos[0].R->getEntry()->getTerminator())
1344 <<
"Drop scope with < "
1346 <<
" biased branch(es) or select(s)";
1354void CHR::setCHRRegions(SmallVectorImpl<CHRScope *> &Input,
1355 SmallVectorImpl<CHRScope *> &Output) {
1356 for (CHRScope *Scope : Input) {
1359 setCHRRegions(Scope, Scope);
1362 dbgs() <<
"setCHRRegions HoistStopMap " << *Scope <<
"\n";
1363 for (
auto pair :
Scope->HoistStopMap) {
1364 Region *R = pair.first;
1365 dbgs() <<
"Region " << R->getNameStr() <<
"\n";
1366 for (Instruction *I : pair.second) {
1367 dbgs() <<
"HoistStop " << *I <<
"\n";
1370 dbgs() <<
"CHRRegions" <<
"\n";
1371 for (RegInfo &RI :
Scope->CHRRegions) {
1372 dbgs() << RI.R->getNameStr() <<
"\n";
1377void CHR::setCHRRegions(CHRScope *Scope, CHRScope *OutermostScope) {
1378 DenseSet<Instruction *> Unhoistables;
1382 for (RegInfo &RI :
Scope->RegInfos)
1384 Instruction *InsertPoint = OutermostScope->BranchInsertPoint;
1385 for (RegInfo &RI :
Scope->RegInfos) {
1387 DenseSet<Instruction *> HoistStops;
1388 bool IsHoisted =
false;
1390 assert((OutermostScope->TrueBiasedRegions.contains(R) ||
1391 OutermostScope->FalseBiasedRegions.contains(R)) &&
1392 "Must be truthy or falsy");
1395 DenseMap<Instruction *, bool> Visited;
1396 bool IsHoistable =
checkHoistValue(BI->getCondition(), InsertPoint, DT,
1397 Unhoistables, &HoistStops, Visited);
1398 assert(IsHoistable &&
"Must be hoistable");
1399 (void)(IsHoistable);
1402 for (SelectInst *SI : RI.Selects) {
1403 assert((OutermostScope->TrueBiasedSelects.contains(SI) ||
1404 OutermostScope->FalseBiasedSelects.contains(SI)) &&
1405 "Must be true or false biased");
1407 DenseMap<Instruction *, bool> Visited;
1409 Unhoistables, &HoistStops, Visited);
1410 assert(IsHoistable &&
"Must be hoistable");
1411 (void)(IsHoistable);
1415 OutermostScope->CHRRegions.push_back(RI);
1416 OutermostScope->HoistStopMap[
R] = HoistStops;
1420 setCHRRegions(
Sub, OutermostScope);
1424 return Scope1->RegInfos[0].R->getDepth() < Scope2->RegInfos[0].R->getDepth();
1427void CHR::sortScopes(SmallVectorImpl<CHRScope *> &Input,
1428 SmallVectorImpl<CHRScope *> &Output) {
1437 HoistStopMapTy &HoistStopMap,
1441 auto IT = HoistStopMap.find(R);
1442 assert(
IT != HoistStopMap.end() &&
"Region must be in hoist stop map");
1445 if (
I == HoistPoint)
1450 if (TrivialPHIs.
count(PN))
1460 assert(DT.
getNode(
I->getParent()) &&
"DT must contain I's block");
1462 "DT must contain HoistPoint block");
1474 hoistValue(
Op, HoistPoint, R, HoistStopMap, HoistedSet, TrivialPHIs, DT);
1488 for (
const RegInfo &RI : Scope->CHRRegions) {
1490 bool IsTrueBiased = Scope->TrueBiasedRegions.count(R);
1491 bool IsFalseBiased = Scope->FalseBiasedRegions.count(R);
1492 if (RI.HasBranch && (IsTrueBiased || IsFalseBiased)) {
1494 hoistValue(BI->getCondition(), HoistPoint, R, Scope->HoistStopMap,
1495 HoistedSet, TrivialPHIs, DT);
1498 bool IsTrueBiased = Scope->TrueBiasedSelects.count(
SI);
1499 bool IsFalseBiased = Scope->FalseBiasedSelects.count(
SI);
1500 if (!(IsTrueBiased || IsFalseBiased))
1502 hoistValue(
SI->getCondition(), HoistPoint, R, Scope->HoistStopMap,
1503 HoistedSet, TrivialPHIs, DT);
1514 if (U == ExcludedUser)
1523 if (U == ExcludedUser)
1526 BI->swapSuccessors();
1537 SI->swapProfMetadata();
1538 if (Scope->TrueBiasedSelects.count(
SI)) {
1539 assert(!Scope->FalseBiasedSelects.contains(
SI) &&
1540 "Must not be already in");
1541 Scope->FalseBiasedSelects.insert(
SI);
1542 }
else if (Scope->FalseBiasedSelects.count(
SI)) {
1543 assert(!Scope->TrueBiasedSelects.contains(
SI) &&
1544 "Must not be already in");
1545 Scope->TrueBiasedSelects.insert(
SI);
1562 for (
RegInfo &RI : Scope->RegInfos) {
1565 BlocksInScope.
insert(BB);
1569 dbgs() <<
"Inserting redundant phis\n";
1571 dbgs() <<
"BlockInScope " << BB->getName() <<
"\n";
1576 for (
User *U :
I.users()) {
1578 if (!BlocksInScope.
contains(UI->getParent()) &&
1582 CHR_DEBUG(
dbgs() <<
"Used outside scope by user " << *UI <<
"\n");
1583 Users.push_back(UI);
1584 }
else if (UI->getParent() == EntryBlock &&
isa<PHINode>(UI)) {
1589 <<
"Used at entry block (for a back edge) by a phi user "
1591 Users.push_back(UI);
1595 if (
Users.size() > 0) {
1606 bool FoundLifetimeAnnotation =
false;
1611 if (UI->isLifetimeStartOrEnd()) {
1612 UI->eraseFromParent();
1613 FoundLifetimeAnnotation =
true;
1616 for (
unsigned J = 0,
NumOps = UI->getNumOperands(); J <
NumOps; ++J) {
1617 if (UI->getOperand(J) == &
I) {
1618 UI->setOperand(J, PN);
1624 if (FoundLifetimeAnnotation) {
1627 if (UI->isLifetimeStartOrEnd())
1628 UI->eraseFromParent();
1637[[maybe_unused]]
static void
1640 auto HasBiasedBranchOrSelect = [](
RegInfo &RI, CHRScope *Scope) {
1641 if (Scope->TrueBiasedRegions.count(RI.R) ||
1642 Scope->FalseBiasedRegions.count(RI.R))
1645 if (Scope->TrueBiasedSelects.count(
SI) ||
1646 Scope->FalseBiasedSelects.count(
SI))
1650 for (
RegInfo &RI : Scope->CHRRegions) {
1651 assert(HasBiasedBranchOrSelect(RI, Scope) &&
1652 "Must have biased branch or select");
1659[[maybe_unused]]
static void
1663 for (
RegInfo &RI : Scope->CHRRegions) {
1665 bool IsTrueBiased = Scope->TrueBiasedRegions.count(R);
1666 bool IsFalseBiased = Scope->FalseBiasedRegions.count(R);
1667 if (RI.HasBranch && (IsTrueBiased || IsFalseBiased)) {
1669 Value *V = BI->getCondition();
1673 assert((
I->getParent() == PreEntryBlock ||
1674 !Scope->contains(
I)) &&
1675 "Must have been hoisted to PreEntryBlock or outside the scope");
1679 bool IsTrueBiased = Scope->TrueBiasedSelects.count(
SI);
1680 bool IsFalseBiased = Scope->FalseBiasedSelects.count(
SI);
1681 if (!(IsTrueBiased || IsFalseBiased))
1683 Value *V =
SI->getCondition();
1687 assert((
I->getParent() == PreEntryBlock ||
1688 !Scope->contains(
I)) &&
1689 "Must have been hoisted to PreEntryBlock or outside the scope");
1695void CHR::transformScopes(CHRScope *Scope, DenseSet<PHINode *> &TrivialPHIs) {
1698 assert(
Scope->RegInfos.size() >= 1 &&
"Should have at least one Region");
1700 for (RegInfo &RI :
Scope->RegInfos) {
1702 unsigned Duplication = getRegionDuplicationCount(R);
1707 <<
" for this region");
1709 return OptimizationRemarkMissed(
DEBUG_TYPE,
"DupThresholdReached",
1710 R->getEntry()->getTerminator())
1711 <<
"Reached the duplication threshold for the region";
1716 for (RegInfo &RI :
Scope->RegInfos) {
1717 DuplicationCount[RI.R]++;
1727 for (Instruction &
I : *EntryBlock) {
1729 if (AI->isStaticAlloca())
1741 CHR_DEBUG(
dbgs() <<
"Splitting entry block " << EntryBlock->getName()
1742 <<
" at " << *
Scope->BranchInsertPoint <<
"\n");
1746 "NewEntryBlock's only pred must be EntryBlock");
1751 for (AllocaInst *AI : StaticAllocas)
1752 AI->moveBefore(EntryBlock->begin());
1768 cloneScopeBlocks(Scope, PreEntryBlock, ExitBlock, LastRegion, VMap);
1772 CondBrInst *MergedBr =
1773 createMergedBranch(PreEntryBlock, EntryBlock, NewEntryBlock, VMap);
1788 fixupBranchesAndSelects(Scope, PreEntryBlock, MergedBr,
1795void CHR::cloneScopeBlocks(CHRScope *Scope,
1796 BasicBlock *PreEntryBlock,
1797 BasicBlock *ExitBlock,
1805 SmallVector<BasicBlock*, 8> NewBlocks;
1806 for (RegInfo &RI :
Scope->RegInfos)
1807 for (BasicBlock *BB : RI.R->blocks()) {
1809 assert(BB != PreEntryBlock &&
"Don't copy the preetntry block");
1817 PN.removeIncomingValueIf([&](
unsigned Idx) {
1825 F.splice(ExitBlock->
getIterator(), &
F, NewBlocks[0]->getIterator(),
1829 for (BasicBlock *NewBB : NewBlocks)
1830 for (Instruction &
I : *NewBB)
1838 for (PHINode &PN : ExitBlock->
phis())
1839 for (
unsigned I = 0,
NumOps = PN.getNumIncomingValues();
I <
NumOps;
1843 Value *
V = PN.getIncomingValue(
I);
1844 auto It = VMap.
find(V);
1845 if (It != VMap.
end())
V = It->second;
1846 assert(VMap.
find(Pred) != VMap.
end() &&
"Pred must have been cloned");
1854CondBrInst *CHR::createMergedBranch(BasicBlock *PreEntryBlock,
1855 BasicBlock *EntryBlock,
1856 BasicBlock *NewEntryBlock,
1860 "SplitBlock did not work correctly!");
1862 "NewEntryBlock's only pred must be EntryBlock");
1864 "NewEntryBlock must have been copied");
1865 OldBR->dropAllReferences();
1866 OldBR->eraseFromParent();
1872 NewBR->insertInto(PreEntryBlock, PreEntryBlock->
end());
1874 "NewEntryBlock's only pred must be EntryBlock");
1880void CHR::fixupBranchesAndSelects(CHRScope *Scope, BasicBlock *PreEntryBlock,
1883 BranchProbability CHRBranchBias(1, 1);
1884 uint64_t NumCHRedBranches = 0;
1886 for (RegInfo &RI :
Scope->CHRRegions) {
1889 fixupBranch(R, Scope, IRB, MergedCondition, CHRBranchBias);
1892 for (SelectInst *SI : RI.Selects) {
1893 fixupSelect(SI, Scope, IRB, MergedCondition, CHRBranchBias);
1897 assert(NumCHRedBranches > 0);
1898 Stats.NumBranchesDelta += NumCHRedBranches - 1;
1905 <<
"Merged " <<
ore::NV(
"NumCHRedBranches", NumCHRedBranches)
1906 <<
" branches or selects";
1909 uint32_t Weights[] = {
1910 static_cast<uint32_t
>(CHRBranchBias.scale(1000)),
1911 static_cast<uint32_t
>(CHRBranchBias.getCompl().
scale(1000)),
1914 CHR_DEBUG(
dbgs() <<
"CHR branch bias " << Weights[0] <<
":" << Weights[1]
1920void CHR::fixupBranch(Region *R, CHRScope *Scope,
1922 Value *&MergedCondition,
1923 BranchProbability &CHRBranchBias) {
1924 bool IsTrueBiased =
Scope->TrueBiasedRegions.count(R);
1925 assert((IsTrueBiased ||
Scope->FalseBiasedRegions.count(R)) &&
1926 "Must be truthy or falsy");
1928 assert(BranchBiasMap.contains(R) &&
"Must be in the bias map");
1929 BranchProbability Bias = BranchBiasMap[
R];
1932 if (CHRBranchBias > Bias)
1933 CHRBranchBias = Bias;
1937 assert(RegionExitBlock &&
"Null ExitBlock");
1938 assert((IfThen == RegionExitBlock || IfElse == RegionExitBlock) &&
1939 IfThen != IfElse &&
"Invariant from findScopes");
1940 if (IfThen == RegionExitBlock) {
1946 <<
" IfElse " << IfElse->
getName() <<
"\n");
1948 BasicBlock *HotTarget = IsTrueBiased ? IfThen : IfElse;
1949 bool ConditionTrue = HotTarget == BI->getSuccessor(0);
1950 addToMergedCondition(ConditionTrue,
Cond, BI, Scope, IRB,
1953 assert(ConditionTrue == (HotTarget == BI->getSuccessor(0)) &&
1954 "The successor shouldn't change");
1955 Value *NewCondition = ConditionTrue ?
1958 BI->setCondition(NewCondition);
1963void CHR::fixupSelect(SelectInst *SI, CHRScope *Scope,
1965 Value *&MergedCondition,
1966 BranchProbability &CHRBranchBias) {
1967 bool IsTrueBiased =
Scope->TrueBiasedSelects.count(SI);
1969 Scope->FalseBiasedSelects.count(SI)) &&
"Must be biased");
1970 assert(SelectBiasMap.contains(SI) &&
"Must be in the bias map");
1971 BranchProbability Bias = SelectBiasMap[
SI];
1974 if (CHRBranchBias > Bias)
1975 CHRBranchBias = Bias;
1977 addToMergedCondition(IsTrueBiased,
Cond, SI, Scope, IRB,
1979 Value *NewCondition = IsTrueBiased ?
1982 SI->setCondition(NewCondition);
1987void CHR::addToMergedCondition(
bool IsTrueBiased,
Value *
Cond,
1988 Instruction *BranchOrSelect, CHRScope *Scope,
1990 if (!IsTrueBiased) {
2010void CHR::transformScopes(SmallVectorImpl<CHRScope *> &CHRScopes) {
2012 DenseSet<PHINode *> TrivialPHIs;
2013 for (CHRScope *Scope : CHRScopes) {
2014 transformScopes(Scope, TrivialPHIs);
2016 std::ostringstream oss;
2017 oss <<
" after transformScopes " <<
I++;
2018 dumpIR(
F, oss.str().c_str(),
nullptr));
2024 const char *Label) {
2025 dbgs() << Label <<
" " << Scopes.size() <<
"\n";
2026 for (CHRScope *Scope : Scopes) {
2027 dbgs() << *Scope <<
"\n";
2040 dbgs() <<
"RegionInfo:\n";
2046 findScopes(AllScopes);
2055 splitScopes(AllScopes, SplitScopes);
2060 classifyBiasedScopes(SplitScopes);
2066 filterScopes(SplitScopes, FilteredScopes);
2071 setCHRRegions(FilteredScopes, SetScopes);
2078 sortScopes(SetScopes, SortedScopes);
2082 dbgs() <<
"RegionInfo:\n";
2086 if (!SortedScopes.
empty()) {
2087 transformScopes(SortedScopes);
2095 return OptimizationRemark(
DEBUG_TYPE,
"Stats", &
F)
2097 <<
"Reduced the number of branches in hot paths by "
2100 <<
ore::NV(
"WeightedNumBranchesDelta",
Stats.WeightedNumBranchesDelta)
2101 <<
" (weighted by PGO count)";
2118 if (!PPSI || !PPSI->hasProfileSummary())
2125 bool Changed = CHR(
F, BFI, DT, PSI, RI, ORE).run();
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
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 uint64_t scale(uint64_t Num, uint32_t N, uint32_t D)
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static void insertTrivialPHIs(CHRScope *Scope, BasicBlock *EntryBlock, BasicBlock *ExitBlock, DenseSet< PHINode * > &TrivialPHIs)
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 checkBiasedBranch(CondBrInst *BI, Region *R, DenseSet< Region * > &TrueBiasedRegionsGlobal, DenseSet< Region * > &FalseBiasedRegionsGlobal, DenseMap< Region *, BranchProbability > &BranchBiasMap)
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 void assertCHRRegionsHaveBiasedBranchOrSelect(CHRScope *Scope)
static bool hasAtLeastTwoBiasedBranches(CHRScope *Scope)
static bool shouldApply(Function &F, ProfileSummaryInfo &PSI)
static void dumpIR(Function &F, const char *Label, CHRStats *Stats)
static void getSelectsInScope(CHRScope *Scope, DenseSet< Instruction * > &Output)
static void dumpScopes(SmallVectorImpl< CHRScope * > &Scopes, const char *Label)
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 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 assertBranchOrSelectConditionHoisted(CHRScope *Scope, BasicBlock *PreEntryBlock)
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 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 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()
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.
static Value * getCondition(Instruction *I)
This file provides various utilities for inspecting and working with the control flow graph in LLVM I...
Module.h This file contains the declarations for the Module class.
This header defines various interfaces for pass management in LLVM.
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.
const size_t AbstractManglingParser< Derived, Alloc >::NumOps
block placement Basic Block Placement Stats
uint64_t IntrinsicInst * II
FunctionAnalysisManager FAM
This file contains the declarations for profiling metadata utility functions.
const SmallVectorImpl< MachineOperand > & Cond
static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)
This file defines the SmallVector class.
StringSet - A set-like wrapper for the StringMap.
early Early Tail Duplication
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.
LLVM_ABI 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.
LLVM_ABI std::optional< uint64_t > getBlockProfileCount(const BasicBlock *BB, bool AllowSynthetic=false) const
Returns the estimated profile count of BB.
static LLVM_ABI 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.
Conditional Branch instruction.
static CondBrInst * Create(Value *Cond, BasicBlock *IfTrue, BasicBlock *IfFalse, InsertPosition InsertBefore=nullptr)
void setCondition(Value *V)
BasicBlock * getSuccessor(unsigned i) const
static LLVM_ABI ConstantInt * getTrue(LLVMContext &Context)
ControlHeightReductionPass()
PreservedAnalyses run(Function &F, FunctionAnalysisManager &FAM)
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.
LLVM_ABI bool isReachableFromEntry(const Use &U) const
Provide an overload for a Use.
LLVM_ABI bool dominates(const BasicBlock *BB, const Use &U) const
Return true if the (end of the) basic block BB dominates the use U.
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="", Instruction *MDFrom=nullptr)
Value * CreateXor(Value *LHS, Value *RHS, const Twine &Name="")
LLVM_ABI void insertBefore(InstListType::iterator InsertPos)
Insert an unlinked instruction into a basic block immediately before the specified position.
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,...
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.
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 contains(const_arg_type key) const
Check if the SetVector contains the given key.
bool insert(const value_type &X)
Insert a new element into the SetVector.
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...
iterator erase(const_iterator CI)
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
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.
BasicBlock * getSuccessor(unsigned i=0) const
iterator find(const KeyT &Val)
LLVM Value Representation.
iterator_range< user_iterator > users()
LLVM_ABI StringRef getName() const
Return a constant reference to the value's name.
std::pair< iterator, bool > insert(const ValueT &V)
void insert_range(Range &&R)
bool contains(const_arg_type_t< ValueT > V) const
Check if the set contains the given element.
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...
@ BasicBlock
Various leaf nodes.
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
Context & getContext() const
friend class Instruction
Iterator for Instructions in a `BasicBlock.
LLVM_ABI 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.
FunctionAddr VTableAddr Value
void stable_sort(R &&Range)
Printable print(const GCNRegPressure &RP, const GCNSubtarget *ST=nullptr, unsigned DynamicVGPRBlockSize=0)
LLVM_ABI BasicBlock * CloneBasicBlock(const BasicBlock *BB, ValueToValueMapTy &VMap, const Twine &NameSuffix="", Function *F=nullptr, ClonedCodeInfo *CodeInfo=nullptr, bool MapAtoms=true)
Return a copy of the specified basic block, but without embedding the block into a particular functio...
LLVM_ABI void setExplicitlyUnknownBranchWeightsIfProfiled(Instruction &I, StringRef PassName, const Function *F=nullptr)
Like setExplicitlyUnknownBranchWeights(...), but only sets unknown branch weights in the new instruct...
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
OuterAnalysisManagerProxy< ModuleAnalysisManager, Function > ModuleAnalysisManagerFunctionProxy
Provide the ModuleAnalysisManager to Function proxy.
constexpr from_range_t from_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...
auto pred_size(const MachineBasicBlock *BB)
LLVM_ABI bool isSafeToSpeculativelyExecute(const Instruction *I, const Instruction *CtxI=nullptr, AssumptionCache *AC=nullptr, const DominatorTree *DT=nullptr, const TargetLibraryInfo *TLI=nullptr, bool UseVariableInfo=true, bool IgnoreUBImplyingAttrs=true)
Return true if the instruction does not have any effects besides calculating the result and does not ...
LLVM_ABI void setBranchWeights(Instruction &I, ArrayRef< uint32_t > Weights, bool IsExpected, bool ElideAllZero=false)
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...
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
FunctionAddr VTableAddr Count
Function::ProfileCount ProfileCount
iterator_range< SplittingIterator > split(StringRef Str, StringRef Separator)
Split the specified string over a separator and return a range-compatible iterable over its partition...
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
LLVM_ATTRIBUTE_VISIBILITY_DEFAULT AnalysisKey InnerAnalysisManagerProxy< AnalysisManagerT, IRUnitT, ExtraArgTs... >::Key
LLVM_ABI raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
IRBuilder(LLVMContext &, FolderTy, InserterTy, MDNode *, ArrayRef< OperandBundleDef >) -> IRBuilder< FolderTy, InserterTy >
@ Sub
Subtraction of integers.
LLVM_ABI BasicBlock * SplitBlock(BasicBlock *Old, BasicBlock::iterator SplitPt, DominatorTree *DT, LoopInfo *LI=nullptr, MemorySSAUpdater *MSSAU=nullptr, const Twine &BBName="")
Split the specified block at the specified instruction.
FunctionAddr VTableAddr Next
void RemapInstruction(Instruction *I, ValueToValueMapTy &VM, RemapFlags Flags=RF_None, ValueMapTypeRemapper *TypeMapper=nullptr, ValueMaterializer *Materializer=nullptr, const MetadataPredicate *IdentityMD=nullptr)
Convert the instruction operands from referencing the current values into those specified by VM.
DWARFExpression::Operation Op
raw_ostream & operator<<(raw_ostream &OS, const APFixedPoint &FX)
LLVM_ABI 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.
ArrayRef(const T &OneElt) -> ArrayRef< T >
OutputIt copy(R &&Range, OutputIt Out)
ValueMap< const Value *, WeakTrackingVH > ValueToValueMapTy
LLVM_ABI bool extractBranchWeights(const MDNode *ProfileData, SmallVectorImpl< uint32_t > &Weights)
Extract branch weights from MD_prof metadata.
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
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)
AnalysisManager< Function > FunctionAnalysisManager
Convenience typedef for the Function analysis manager.
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.