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 BranchInst *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;
638 assert((IfThen == R->getExit() || IfElse == R->getExit()) &&
640 "Invariant from findScopes");
641 if (IfThen == R->getExit()) {
651 TrueBiasedRegionsGlobal, FalseBiasedRegionsGlobal,
669 TrueBiasedSelectsGlobal, FalseBiasedSelectsGlobal,
683 if (
SI->getParent() == EntryBB) {
690 assert(HoistPoint &&
"Null HoistPoint");
696 if (
SI->getParent() == EntryBB) {
703 "HoistPoint must be the first one in Selects");
712CHRScope * CHR::findScope(Region *R) {
713 CHRScope *
Result =
nullptr;
716 assert(Entry &&
"Entry must not be null");
717 assert((Exit ==
nullptr) == (
R->isTopLevelRegion()) &&
718 "Only top level region has a null exit");
729 bool EntryInSubregion = RI.getRegionFor(Entry) !=
R;
730 if (EntryInSubregion)
734 if (
R->contains(Pred))
738 for (BasicBlock *BB :
R->blocks()) {
739 if (BB->hasAddressTaken())
747 for (Instruction &
I : *BB) {
749 if (
II->getIntrinsicID() == Intrinsic::coro_id)
766 if (CB->cannotDuplicate() || CB->isConvergent())
779 CHR_DEBUG(
dbgs() <<
"BI.isConditional " << BI->isConditional() <<
"\n");
782 if (BI && BI->isConditional()) {
787 if (S0 !=
S1 && (S0 == Exit ||
S1 == Exit)) {
790 BI, R, TrueBiasedRegionsGlobal, FalseBiasedRegionsGlobal,
792 Result =
new CHRScope(RI);
793 Scopes.insert(Result);
798 return OptimizationRemarkMissed(
DEBUG_TYPE,
"BranchNotBiased", BI)
799 <<
"Branch not biased";
819 for (RegionNode *
E :
R->elements()) {
820 if (
E->isSubRegion())
827 for (Instruction &
I : *BB) {
834 if (Selects.
size() > 0) {
835 auto AddSelects = [&](RegInfo &RI) {
836 for (
auto *SI : Selects)
838 TrueBiasedSelectsGlobal,
839 FalseBiasedSelectsGlobal,
841 RI.Selects.push_back(SI);
844 return OptimizationRemarkMissed(
DEBUG_TYPE,
"SelectNotBiased", SI)
845 <<
"Select not biased";
852 Result =
new CHRScope(RI);
853 Scopes.insert(Result);
855 CHR_DEBUG(
dbgs() <<
"Found select(s) in a region with a branch\n");
856 AddSelects(
Result->RegInfos[0]);
862 checkScopeHoistable(Result);
889void CHR::checkScopeHoistable(CHRScope *Scope) {
890 RegInfo &RI =
Scope->RegInfos[0];
893 auto *
Branch = RI.HasBranch ?
896 if (RI.HasBranch || !Selects.
empty()) {
905 for (
auto it = Selects.
begin(); it != Selects.
end(); ) {
906 SelectInst *
SI = *it;
907 if (SI == InsertPoint) {
911 DenseMap<Instruction *, bool> Visited;
913 DT, Unhoistables,
nullptr, Visited);
918 "DropUnhoistableSelect", SI)
919 <<
"Dropped unhoistable select";
921 it = Selects.
erase(it);
924 Unhoistables.erase(SI);
931 if (RI.HasBranch && InsertPoint != Branch) {
932 DenseMap<Instruction *, bool> Visited;
934 DT, Unhoistables,
nullptr, Visited);
939 assert(InsertPoint != Branch &&
"Branch must not be the hoist point");
942 for (SelectInst *SI : Selects) {
943 dbgs() <<
"SI " << *
SI <<
"\n";
945 for (SelectInst *SI : Selects) {
948 "DropSelectUnhoistableBranch", SI)
949 <<
"Dropped select due to unhoistable branch";
953 return SI->getParent() == EntryBB;
955 Unhoistables.clear();
963 "Branch can't be already above the hoist point");
964 DenseMap<Instruction *, bool> Visited;
966 DT, Unhoistables,
nullptr, Visited) &&
967 "checkHoistValue for branch");
969 for (
auto *SI : Selects) {
971 "SI can't be already above the hoist point");
972 DenseMap<Instruction *, bool> Visited;
974 Unhoistables,
nullptr, Visited) &&
975 "checkHoistValue for selects");
981 for (
auto *SI : Selects) {
989CHRScope * CHR::findScopes(Region *R, Region *NextRegion, Region *ParentRegion,
990 SmallVectorImpl<CHRScope *> &Scopes) {
992 CHRScope *
Result = findScope(R);
994 CHRScope *ConsecutiveSubscope =
nullptr;
996 for (
auto It =
R->begin(); It !=
R->end(); ++It) {
997 const std::unique_ptr<Region> &SubR = *It;
998 auto NextIt = std::next(It);
999 Region *NextSubR = NextIt !=
R->end() ? NextIt->get() :
nullptr;
1000 CHR_DEBUG(
dbgs() <<
"Looking at subregion " << SubR.get()->getNameStr()
1002 CHRScope *SubCHRScope = findScopes(SubR.get(), NextSubR, R, Scopes);
1004 CHR_DEBUG(
dbgs() <<
"Subregion Scope " << *SubCHRScope <<
"\n");
1009 if (!ConsecutiveSubscope)
1010 ConsecutiveSubscope = SubCHRScope;
1011 else if (!ConsecutiveSubscope->appendable(SubCHRScope)) {
1012 Subscopes.
push_back(ConsecutiveSubscope);
1013 ConsecutiveSubscope = SubCHRScope;
1015 ConsecutiveSubscope->append(SubCHRScope);
1017 if (ConsecutiveSubscope) {
1018 Subscopes.
push_back(ConsecutiveSubscope);
1020 ConsecutiveSubscope =
nullptr;
1023 if (ConsecutiveSubscope) {
1024 Subscopes.
push_back(ConsecutiveSubscope);
1026 for (CHRScope *
Sub : Subscopes) {
1042 ConditionValues.
insert(BI->getCondition());
1045 ConditionValues.
insert(
SI->getCondition());
1047 return ConditionValues;
1065 for (
Value *V : PrevConditionValues) {
1066 dbgs() << *V <<
", ";
1068 dbgs() <<
" ConditionValues ";
1069 for (
Value *V : ConditionValues) {
1070 dbgs() << *V <<
", ";
1074 for (
Value *V : ConditionValues) {
1077 CHR_DEBUG(
dbgs() <<
"Split. checkHoistValue false " << *V <<
"\n");
1084 if (!PrevConditionValues.
empty() && !ConditionValues.
empty()) {
1086 std::set<Value *> PrevBases, Bases;
1088 for (
Value *V : PrevConditionValues) {
1089 const std::set<Value *> &BaseValues =
getBaseValues(V, DT, Visited);
1090 PrevBases.insert(BaseValues.begin(), BaseValues.end());
1092 for (
Value *V : ConditionValues) {
1093 const std::set<Value *> &BaseValues =
getBaseValues(V, DT, Visited);
1094 Bases.insert(BaseValues.begin(), BaseValues.end());
1097 dbgs() <<
"PrevBases ";
1098 for (
Value *V : PrevBases) {
1099 dbgs() << *V <<
", ";
1101 dbgs() <<
" Bases ";
1102 for (
Value *V : Bases) {
1103 dbgs() << *V <<
", ";
1106 std::vector<Value *> Intersection;
1107 std::set_intersection(PrevBases.begin(), PrevBases.end(), Bases.begin(),
1108 Bases.end(), std::back_inserter(Intersection));
1109 if (Intersection.empty()) {
1121 for (
RegInfo &RI : Scope->RegInfos)
1123 for (CHRScope *
Sub : Scope->Subs)
1127void CHR::splitScopes(SmallVectorImpl<CHRScope *> &Input,
1128 SmallVectorImpl<CHRScope *> &Output) {
1129 for (CHRScope *Scope : Input) {
1131 "BranchInsertPoint must not be set");
1132 DenseSet<Instruction *> Unhoistables;
1134 splitScope(Scope,
nullptr,
nullptr,
nullptr, Output, Unhoistables);
1137 for (CHRScope *Scope : Output) {
1138 assert(
Scope->BranchInsertPoint &&
"BranchInsertPoint must be set");
1146 DenseSet<Value *> *OuterConditionValues,
1147 Instruction *OuterInsertPoint,
1148 SmallVectorImpl<CHRScope *> &Output,
1149 DenseSet<Instruction *> &Unhoistables) {
1151 assert(OuterConditionValues &&
"Null OuterConditionValues");
1152 assert(OuterInsertPoint &&
"Null OuterInsertPoint");
1154 bool PrevSplitFromOuter =
true;
1155 DenseSet<Value *> PrevConditionValues;
1160 SmallVector<Instruction *, 8> SplitsInsertPoints;
1162 for (RegInfo &RI : RegInfos) {
1166 dbgs() <<
"ConditionValues ";
1167 for (
Value *V : ConditionValues) {
1168 dbgs() << *
V <<
", ";
1171 if (RI.R == RegInfos[0].R) {
1176 << RI.R->getNameStr() <<
"\n");
1177 if (
shouldSplit(OuterInsertPoint, *OuterConditionValues,
1178 ConditionValues, DT, Unhoistables)) {
1179 PrevConditionValues = ConditionValues;
1180 PrevInsertPoint = InsertPoint;
1183 "SplitScopeFromOuter",
1184 RI.R->getEntry()->getTerminator())
1185 <<
"Split scope from outer due to unhoistable branch/select "
1186 <<
"and/or lack of common condition values";
1191 PrevSplitFromOuter =
false;
1192 PrevConditionValues = *OuterConditionValues;
1194 PrevInsertPoint = OuterInsertPoint;
1198 PrevConditionValues = ConditionValues;
1199 PrevInsertPoint = InsertPoint;
1203 << RI.R->getNameStr() <<
"\n");
1204 if (
shouldSplit(PrevInsertPoint, PrevConditionValues, ConditionValues,
1205 DT, Unhoistables)) {
1209 SplitsSplitFromOuter.
push_back(PrevSplitFromOuter);
1210 SplitsConditionValues.
push_back(PrevConditionValues);
1211 SplitsInsertPoints.
push_back(PrevInsertPoint);
1213 PrevConditionValues = ConditionValues;
1214 PrevInsertPoint = InsertPoint;
1215 PrevSplitFromOuter =
true;
1218 "SplitScopeFromPrev",
1219 RI.R->getEntry()->getTerminator())
1220 <<
"Split scope from previous due to unhoistable branch/select "
1221 <<
"and/or lack of common condition values";
1230 SplitsSplitFromOuter.
push_back(PrevSplitFromOuter);
1231 SplitsConditionValues.
push_back(PrevConditionValues);
1232 assert(PrevInsertPoint &&
"Null PrevInsertPoint");
1233 SplitsInsertPoints.
push_back(PrevInsertPoint);
1235 Splits.
size() == SplitsSplitFromOuter.
size() &&
1236 Splits.
size() == SplitsInsertPoints.
size() &&
"Mismatching sizes");
1237 for (
size_t I = 0;
I < Splits.
size(); ++
I) {
1238 CHRScope *
Split = Splits[
I];
1239 DenseSet<Value *> &SplitConditionValues = SplitsConditionValues[
I];
1242 DenseSet<Instruction *> SplitUnhoistables;
1244 for (CHRScope *
Sub :
Split->Subs) {
1246 Sub, Split, &SplitConditionValues, SplitInsertPoint, Output,
1250 Split->Subs = NewSubs;
1253 for (
size_t I = 0;
I < Splits.
size(); ++
I) {
1254 CHRScope *
Split = Splits[
I];
1255 if (SplitsSplitFromOuter[
I]) {
1258 Split->BranchInsertPoint = SplitsInsertPoints[
I];
1259 CHR_DEBUG(
dbgs() <<
"BranchInsertPoint " << *SplitsInsertPoints[
I]
1268 "If no outer (top-level), must return no nested ones");
1272void CHR::classifyBiasedScopes(SmallVectorImpl<CHRScope *> &Scopes) {
1273 for (CHRScope *Scope : Scopes) {
1274 assert(
Scope->TrueBiasedRegions.empty() &&
Scope->FalseBiasedRegions.empty() &&
"Empty");
1275 classifyBiasedScopes(Scope, Scope);
1277 dbgs() <<
"classifyBiasedScopes " << *Scope <<
"\n";
1278 dbgs() <<
"TrueBiasedRegions ";
1279 for (Region *R :
Scope->TrueBiasedRegions) {
1280 dbgs() <<
R->getNameStr() <<
", ";
1283 dbgs() <<
"FalseBiasedRegions ";
1284 for (Region *R :
Scope->FalseBiasedRegions) {
1285 dbgs() <<
R->getNameStr() <<
", ";
1288 dbgs() <<
"TrueBiasedSelects ";
1289 for (SelectInst *SI :
Scope->TrueBiasedSelects) {
1293 dbgs() <<
"FalseBiasedSelects ";
1294 for (SelectInst *SI :
Scope->FalseBiasedSelects) {
1301void CHR::classifyBiasedScopes(CHRScope *Scope, CHRScope *OutermostScope) {
1302 for (RegInfo &RI :
Scope->RegInfos) {
1305 if (TrueBiasedRegionsGlobal.contains(R))
1306 OutermostScope->TrueBiasedRegions.insert(R);
1307 else if (FalseBiasedRegionsGlobal.contains(R))
1308 OutermostScope->FalseBiasedRegions.insert(R);
1312 for (SelectInst *SI : RI.Selects) {
1313 if (TrueBiasedSelectsGlobal.contains(SI))
1314 OutermostScope->TrueBiasedSelects.insert(SI);
1315 else if (FalseBiasedSelectsGlobal.contains(SI))
1316 OutermostScope->FalseBiasedSelects.insert(SI);
1321 for (CHRScope *
Sub :
Scope->Subs) {
1322 classifyBiasedScopes(
Sub, OutermostScope);
1327 unsigned NumBiased = Scope->TrueBiasedRegions.size() +
1328 Scope->FalseBiasedRegions.size() +
1329 Scope->TrueBiasedSelects.size() +
1330 Scope->FalseBiasedSelects.size();
1334void CHR::filterScopes(SmallVectorImpl<CHRScope *> &Input,
1335 SmallVectorImpl<CHRScope *> &Output) {
1336 for (CHRScope *Scope : Input) {
1339 CHR_DEBUG(
dbgs() <<
"Filtered out by biased branches truthy-regions "
1340 <<
Scope->TrueBiasedRegions.size()
1341 <<
" falsy-regions " <<
Scope->FalseBiasedRegions.size()
1342 <<
" true-selects " <<
Scope->TrueBiasedSelects.size()
1343 <<
" false-selects " <<
Scope->FalseBiasedSelects.size() <<
"\n");
1345 return OptimizationRemarkMissed(
1347 "DropScopeWithOneBranchOrSelect",
1348 Scope->RegInfos[0].R->getEntry()->getTerminator())
1349 <<
"Drop scope with < "
1351 <<
" biased branch(es) or select(s)";
1359void CHR::setCHRRegions(SmallVectorImpl<CHRScope *> &Input,
1360 SmallVectorImpl<CHRScope *> &Output) {
1361 for (CHRScope *Scope : Input) {
1364 setCHRRegions(Scope, Scope);
1367 dbgs() <<
"setCHRRegions HoistStopMap " << *Scope <<
"\n";
1368 for (
auto pair :
Scope->HoistStopMap) {
1369 Region *R = pair.first;
1370 dbgs() <<
"Region " << R->getNameStr() <<
"\n";
1371 for (Instruction *I : pair.second) {
1372 dbgs() <<
"HoistStop " << *I <<
"\n";
1375 dbgs() <<
"CHRRegions" <<
"\n";
1376 for (RegInfo &RI :
Scope->CHRRegions) {
1377 dbgs() << RI.R->getNameStr() <<
"\n";
1382void CHR::setCHRRegions(CHRScope *Scope, CHRScope *OutermostScope) {
1383 DenseSet<Instruction *> Unhoistables;
1387 for (RegInfo &RI :
Scope->RegInfos)
1389 Instruction *InsertPoint = OutermostScope->BranchInsertPoint;
1390 for (RegInfo &RI :
Scope->RegInfos) {
1392 DenseSet<Instruction *> HoistStops;
1393 bool IsHoisted =
false;
1395 assert((OutermostScope->TrueBiasedRegions.contains(R) ||
1396 OutermostScope->FalseBiasedRegions.contains(R)) &&
1397 "Must be truthy or falsy");
1400 DenseMap<Instruction *, bool> Visited;
1401 bool IsHoistable =
checkHoistValue(BI->getCondition(), InsertPoint, DT,
1402 Unhoistables, &HoistStops, Visited);
1403 assert(IsHoistable &&
"Must be hoistable");
1404 (void)(IsHoistable);
1407 for (SelectInst *SI : RI.Selects) {
1408 assert((OutermostScope->TrueBiasedSelects.contains(SI) ||
1409 OutermostScope->FalseBiasedSelects.contains(SI)) &&
1410 "Must be true or false biased");
1412 DenseMap<Instruction *, bool> Visited;
1414 Unhoistables, &HoistStops, Visited);
1415 assert(IsHoistable &&
"Must be hoistable");
1416 (void)(IsHoistable);
1420 OutermostScope->CHRRegions.push_back(RI);
1421 OutermostScope->HoistStopMap[
R] = HoistStops;
1425 setCHRRegions(
Sub, OutermostScope);
1429 return Scope1->RegInfos[0].R->getDepth() < Scope2->RegInfos[0].R->getDepth();
1432void CHR::sortScopes(SmallVectorImpl<CHRScope *> &Input,
1433 SmallVectorImpl<CHRScope *> &Output) {
1442 HoistStopMapTy &HoistStopMap,
1446 auto IT = HoistStopMap.find(R);
1447 assert(
IT != HoistStopMap.end() &&
"Region must be in hoist stop map");
1450 if (
I == HoistPoint)
1455 if (TrivialPHIs.
count(PN))
1465 assert(DT.
getNode(
I->getParent()) &&
"DT must contain I's block");
1467 "DT must contain HoistPoint block");
1479 hoistValue(
Op, HoistPoint, R, HoistStopMap, HoistedSet, TrivialPHIs, DT);
1493 for (
const RegInfo &RI : Scope->CHRRegions) {
1495 bool IsTrueBiased = Scope->TrueBiasedRegions.count(R);
1496 bool IsFalseBiased = Scope->FalseBiasedRegions.count(R);
1497 if (RI.HasBranch && (IsTrueBiased || IsFalseBiased)) {
1499 hoistValue(BI->getCondition(), HoistPoint, R, Scope->HoistStopMap,
1500 HoistedSet, TrivialPHIs, DT);
1503 bool IsTrueBiased = Scope->TrueBiasedSelects.count(
SI);
1504 bool IsFalseBiased = Scope->FalseBiasedSelects.count(
SI);
1505 if (!(IsTrueBiased || IsFalseBiased))
1507 hoistValue(
SI->getCondition(), HoistPoint, R, Scope->HoistStopMap,
1508 HoistedSet, TrivialPHIs, DT);
1519 if (U == ExcludedUser)
1528 if (U == ExcludedUser)
1531 assert(BI->isConditional() &&
"Must be conditional");
1532 BI->swapSuccessors();
1543 SI->swapProfMetadata();
1544 if (Scope->TrueBiasedSelects.count(
SI)) {
1545 assert(!Scope->FalseBiasedSelects.contains(
SI) &&
1546 "Must not be already in");
1547 Scope->FalseBiasedSelects.insert(
SI);
1548 }
else if (Scope->FalseBiasedSelects.count(
SI)) {
1549 assert(!Scope->TrueBiasedSelects.contains(
SI) &&
1550 "Must not be already in");
1551 Scope->TrueBiasedSelects.insert(
SI);
1568 for (
RegInfo &RI : Scope->RegInfos) {
1571 BlocksInScope.
insert(BB);
1575 dbgs() <<
"Inserting redundant phis\n";
1577 dbgs() <<
"BlockInScope " << BB->getName() <<
"\n";
1582 for (
User *U :
I.users()) {
1584 if (!BlocksInScope.
contains(UI->getParent()) &&
1588 CHR_DEBUG(
dbgs() <<
"Used outside scope by user " << *UI <<
"\n");
1589 Users.push_back(UI);
1590 }
else if (UI->getParent() == EntryBlock &&
isa<PHINode>(UI)) {
1595 <<
"Used at entry block (for a back edge) by a phi user "
1597 Users.push_back(UI);
1601 if (
Users.size() > 0) {
1612 bool FoundLifetimeAnnotation =
false;
1617 if (UI->isLifetimeStartOrEnd()) {
1618 UI->eraseFromParent();
1619 FoundLifetimeAnnotation =
true;
1622 for (
unsigned J = 0,
NumOps = UI->getNumOperands(); J <
NumOps; ++J) {
1623 if (UI->getOperand(J) == &
I) {
1624 UI->setOperand(J, PN);
1630 if (FoundLifetimeAnnotation) {
1633 if (UI->isLifetimeStartOrEnd())
1634 UI->eraseFromParent();
1643[[maybe_unused]]
static void
1646 auto HasBiasedBranchOrSelect = [](
RegInfo &RI, CHRScope *Scope) {
1647 if (Scope->TrueBiasedRegions.count(RI.R) ||
1648 Scope->FalseBiasedRegions.count(RI.R))
1651 if (Scope->TrueBiasedSelects.count(
SI) ||
1652 Scope->FalseBiasedSelects.count(
SI))
1656 for (
RegInfo &RI : Scope->CHRRegions) {
1657 assert(HasBiasedBranchOrSelect(RI, Scope) &&
1658 "Must have biased branch or select");
1665[[maybe_unused]]
static void
1669 for (
RegInfo &RI : Scope->CHRRegions) {
1671 bool IsTrueBiased = Scope->TrueBiasedRegions.count(R);
1672 bool IsFalseBiased = Scope->FalseBiasedRegions.count(R);
1673 if (RI.HasBranch && (IsTrueBiased || IsFalseBiased)) {
1675 Value *V = BI->getCondition();
1679 assert((
I->getParent() == PreEntryBlock ||
1680 !Scope->contains(
I)) &&
1681 "Must have been hoisted to PreEntryBlock or outside the scope");
1685 bool IsTrueBiased = Scope->TrueBiasedSelects.count(
SI);
1686 bool IsFalseBiased = Scope->FalseBiasedSelects.count(
SI);
1687 if (!(IsTrueBiased || IsFalseBiased))
1689 Value *V =
SI->getCondition();
1693 assert((
I->getParent() == PreEntryBlock ||
1694 !Scope->contains(
I)) &&
1695 "Must have been hoisted to PreEntryBlock or outside the scope");
1701void CHR::transformScopes(CHRScope *Scope, DenseSet<PHINode *> &TrivialPHIs) {
1704 assert(
Scope->RegInfos.size() >= 1 &&
"Should have at least one Region");
1706 for (RegInfo &RI :
Scope->RegInfos) {
1708 unsigned Duplication = getRegionDuplicationCount(R);
1713 <<
" for this region");
1715 return OptimizationRemarkMissed(
DEBUG_TYPE,
"DupThresholdReached",
1716 R->getEntry()->getTerminator())
1717 <<
"Reached the duplication threshold for the region";
1722 for (RegInfo &RI :
Scope->RegInfos) {
1723 DuplicationCount[RI.R]++;
1733 for (Instruction &
I : *EntryBlock) {
1735 if (AI->isStaticAlloca())
1747 CHR_DEBUG(
dbgs() <<
"Splitting entry block " << EntryBlock->getName()
1748 <<
" at " << *
Scope->BranchInsertPoint <<
"\n");
1752 "NewEntryBlock's only pred must be EntryBlock");
1757 for (AllocaInst *AI : StaticAllocas)
1758 AI->moveBefore(EntryBlock->begin());
1774 cloneScopeBlocks(Scope, PreEntryBlock, ExitBlock, LastRegion, VMap);
1778 BranchInst *MergedBr = createMergedBranch(PreEntryBlock, EntryBlock,
1779 NewEntryBlock, VMap);
1794 fixupBranchesAndSelects(Scope, PreEntryBlock, MergedBr,
1801void CHR::cloneScopeBlocks(CHRScope *Scope,
1802 BasicBlock *PreEntryBlock,
1803 BasicBlock *ExitBlock,
1811 SmallVector<BasicBlock*, 8> NewBlocks;
1812 for (RegInfo &RI :
Scope->RegInfos)
1813 for (BasicBlock *BB : RI.R->blocks()) {
1815 assert(BB != PreEntryBlock &&
"Don't copy the preetntry block");
1823 PN.removeIncomingValueIf([&](
unsigned Idx) {
1831 F.splice(ExitBlock->
getIterator(), &
F, NewBlocks[0]->getIterator(),
1835 for (BasicBlock *NewBB : NewBlocks)
1836 for (Instruction &
I : *NewBB)
1844 for (PHINode &PN : ExitBlock->
phis())
1845 for (
unsigned I = 0,
NumOps = PN.getNumIncomingValues();
I <
NumOps;
1849 Value *
V = PN.getIncomingValue(
I);
1850 auto It = VMap.
find(V);
1851 if (It != VMap.
end())
V = It->second;
1852 assert(VMap.
find(Pred) != VMap.
end() &&
"Pred must have been cloned");
1860BranchInst *CHR::createMergedBranch(BasicBlock *PreEntryBlock,
1861 BasicBlock *EntryBlock,
1862 BasicBlock *NewEntryBlock,
1866 "SplitBlock did not work correctly!");
1868 "NewEntryBlock's only pred must be EntryBlock");
1870 "NewEntryBlock must have been copied");
1879 assert(NewEntryBlock->getSinglePredecessor() == EntryBlock &&
1880 "NewEntryBlock's only pred must be EntryBlock");
1886void CHR::fixupBranchesAndSelects(CHRScope *Scope,
1887 BasicBlock *PreEntryBlock,
1888 BranchInst *MergedBR,
1891 BranchProbability CHRBranchBias(1, 1);
1892 uint64_t NumCHRedBranches = 0;
1894 for (RegInfo &RI :
Scope->CHRRegions) {
1897 fixupBranch(R, Scope, IRB, MergedCondition, CHRBranchBias);
1900 for (SelectInst *SI : RI.Selects) {
1901 fixupSelect(SI, Scope, IRB, MergedCondition, CHRBranchBias);
1905 assert(NumCHRedBranches > 0);
1906 Stats.NumBranchesDelta += NumCHRedBranches - 1;
1913 <<
"Merged " <<
ore::NV(
"NumCHRedBranches", NumCHRedBranches)
1914 <<
" branches or selects";
1917 uint32_t Weights[] = {
1918 static_cast<uint32_t
>(CHRBranchBias.scale(1000)),
1919 static_cast<uint32_t
>(CHRBranchBias.getCompl().
scale(1000)),
1922 CHR_DEBUG(
dbgs() <<
"CHR branch bias " << Weights[0] <<
":" << Weights[1]
1928void CHR::fixupBranch(Region *R, CHRScope *Scope,
1930 Value *&MergedCondition,
1931 BranchProbability &CHRBranchBias) {
1932 bool IsTrueBiased =
Scope->TrueBiasedRegions.count(R);
1933 assert((IsTrueBiased ||
Scope->FalseBiasedRegions.count(R)) &&
1934 "Must be truthy or falsy");
1936 assert(BranchBiasMap.contains(R) &&
"Must be in the bias map");
1937 BranchProbability Bias = BranchBiasMap[
R];
1940 if (CHRBranchBias > Bias)
1941 CHRBranchBias = Bias;
1945 assert(RegionExitBlock &&
"Null ExitBlock");
1946 assert((IfThen == RegionExitBlock || IfElse == RegionExitBlock) &&
1947 IfThen != IfElse &&
"Invariant from findScopes");
1948 if (IfThen == RegionExitBlock) {
1954 <<
" IfElse " << IfElse->
getName() <<
"\n");
1956 BasicBlock *HotTarget = IsTrueBiased ? IfThen : IfElse;
1957 bool ConditionTrue = HotTarget == BI->getSuccessor(0);
1958 addToMergedCondition(ConditionTrue,
Cond, BI, Scope, IRB,
1961 assert(ConditionTrue == (HotTarget == BI->getSuccessor(0)) &&
1962 "The successor shouldn't change");
1963 Value *NewCondition = ConditionTrue ?
1966 BI->setCondition(NewCondition);
1971void CHR::fixupSelect(SelectInst *SI, CHRScope *Scope,
1973 Value *&MergedCondition,
1974 BranchProbability &CHRBranchBias) {
1975 bool IsTrueBiased =
Scope->TrueBiasedSelects.count(SI);
1977 Scope->FalseBiasedSelects.count(SI)) &&
"Must be biased");
1978 assert(SelectBiasMap.contains(SI) &&
"Must be in the bias map");
1979 BranchProbability Bias = SelectBiasMap[
SI];
1982 if (CHRBranchBias > Bias)
1983 CHRBranchBias = Bias;
1985 addToMergedCondition(IsTrueBiased,
Cond, SI, Scope, IRB,
1987 Value *NewCondition = IsTrueBiased ?
1990 SI->setCondition(NewCondition);
1995void CHR::addToMergedCondition(
bool IsTrueBiased,
Value *
Cond,
1996 Instruction *BranchOrSelect, CHRScope *Scope,
1998 if (!IsTrueBiased) {
2018void CHR::transformScopes(SmallVectorImpl<CHRScope *> &CHRScopes) {
2020 DenseSet<PHINode *> TrivialPHIs;
2021 for (CHRScope *Scope : CHRScopes) {
2022 transformScopes(Scope, TrivialPHIs);
2024 std::ostringstream oss;
2025 oss <<
" after transformScopes " <<
I++;
2026 dumpIR(
F, oss.str().c_str(),
nullptr));
2032 const char *Label) {
2033 dbgs() << Label <<
" " << Scopes.size() <<
"\n";
2034 for (CHRScope *Scope : Scopes) {
2035 dbgs() << *Scope <<
"\n";
2048 dbgs() <<
"RegionInfo:\n";
2054 findScopes(AllScopes);
2063 splitScopes(AllScopes, SplitScopes);
2068 classifyBiasedScopes(SplitScopes);
2074 filterScopes(SplitScopes, FilteredScopes);
2079 setCHRRegions(FilteredScopes, SetScopes);
2086 sortScopes(SetScopes, SortedScopes);
2090 dbgs() <<
"RegionInfo:\n";
2094 if (!SortedScopes.
empty()) {
2095 transformScopes(SortedScopes);
2103 return OptimizationRemark(
DEBUG_TYPE,
"Stats", &
F)
2105 <<
"Reduced the number of branches in hot paths by "
2108 <<
ore::NV(
"WeightedNumBranchesDelta",
Stats.WeightedNumBranchesDelta)
2109 <<
" (weighted by PGO count)";
2126 if (!PPSI || !PPSI->hasProfileSummary())
2133 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 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 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()
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.
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 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.
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.
LLVM_ABI InstListType::iterator eraseFromParent()
This method unlinks 'this' from the containing basic block and deletes it.
LLVM_ABI 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,...
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.
void dropAllReferences()
Drop all references to operands.
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.