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;
401 const CHRStats &
Stats) {
443 assert(RegInfos.size() > 0 &&
"Empty CHRScope");
445 OS << RegInfos.size() <<
", Regions[";
446 for (
const RegInfo &RI : RegInfos) {
447 OS << RI.R->getNameStr();
450 if (RI.Selects.size() > 0)
451 OS <<
" S" << RI.Selects.size();
454 if (RegInfos[0].
R->getParent()) {
455 OS <<
"], Parent " << RegInfos[0].R->getParent()->getNameStr();
461 for (CHRScope *
Sub : Subs) {
488static const std::set<Value *> &
491 auto It = Visited.find(V);
492 if (It != Visited.end()) {
495 std::set<Value *> Result;
502 return Visited.insert(std::make_pair(V, std::move(Result))).first->second;
507 Result.insert(OpResult.begin(), OpResult.end());
509 return Visited.insert(std::make_pair(V, std::move(Result))).first->second;
517 return Visited.insert(std::make_pair(V, std::move(Result))).first->second;
529 assert(InsertPoint &&
"Null InsertPoint");
531 auto It = Visited.
find(
I);
532 if (It != Visited.
end()) {
535 assert(DT.
getNode(
I->getParent()) &&
"DT must contain I's parent block");
537 if (Unhoistables.
count(
I)) {
554 bool AllOpsHoisted =
true;
558 AllOpsHoisted =
false;
586 uint64_t SumWeight = TrueWeight + FalseWeight;
588 assert(SumWeight >= TrueWeight && SumWeight >= FalseWeight &&
589 "Overflow calculating branch probabilities.");
609template <
typename K,
typename S,
typename M>
614 if (TrueProb >= Threshold) {
616 BiasMap[
Key] = TrueProb;
618 }
else if (FalseProb >= Threshold) {
619 FalseSet.insert(
Key);
620 BiasMap[
Key] = FalseProb;
639 assert((IfThen == R->getExit() || IfElse == R->getExit()) &&
641 "Invariant from findScopes");
642 if (IfThen == R->getExit()) {
652 TrueBiasedRegionsGlobal, FalseBiasedRegionsGlobal,
670 TrueBiasedSelectsGlobal, FalseBiasedSelectsGlobal,
684 if (
SI->getParent() == EntryBB) {
691 assert(HoistPoint &&
"Null HoistPoint");
697 if (
SI->getParent() == EntryBB) {
704 "HoistPoint must be the first one in Selects");
713CHRScope * CHR::findScope(Region *R) {
714 CHRScope *
Result =
nullptr;
717 assert(Entry &&
"Entry must not be null");
718 assert((Exit ==
nullptr) == (
R->isTopLevelRegion()) &&
719 "Only top level region has a null exit");
730 bool EntryInSubregion = RI.getRegionFor(Entry) !=
R;
731 if (EntryInSubregion)
735 if (
R->contains(Pred))
739 for (BasicBlock *BB :
R->blocks()) {
740 if (BB->hasAddressTaken())
748 for (Instruction &
I : *BB)
750 if (
II->getIntrinsicID() == Intrinsic::coro_id)
761 CHR_DEBUG(
dbgs() <<
"BI.isConditional " << BI->isConditional() <<
"\n");
764 if (BI && BI->isConditional()) {
769 if (S0 !=
S1 && (S0 == Exit ||
S1 == Exit)) {
772 BI, R, TrueBiasedRegionsGlobal, FalseBiasedRegionsGlobal,
774 Result =
new CHRScope(RI);
775 Scopes.insert(Result);
780 return OptimizationRemarkMissed(
DEBUG_TYPE,
"BranchNotBiased", BI)
781 <<
"Branch not biased";
801 for (RegionNode *
E :
R->elements()) {
802 if (
E->isSubRegion())
809 for (Instruction &
I : *BB) {
816 if (Selects.
size() > 0) {
817 auto AddSelects = [&](RegInfo &RI) {
818 for (
auto *SI : Selects)
820 TrueBiasedSelectsGlobal,
821 FalseBiasedSelectsGlobal,
823 RI.Selects.push_back(SI);
826 return OptimizationRemarkMissed(
DEBUG_TYPE,
"SelectNotBiased", SI)
827 <<
"Select not biased";
834 Result =
new CHRScope(RI);
835 Scopes.insert(Result);
837 CHR_DEBUG(
dbgs() <<
"Found select(s) in a region with a branch\n");
838 AddSelects(
Result->RegInfos[0]);
844 checkScopeHoistable(Result);
871void CHR::checkScopeHoistable(CHRScope *Scope) {
872 RegInfo &RI =
Scope->RegInfos[0];
875 auto *
Branch = RI.HasBranch ?
878 if (RI.HasBranch || !Selects.
empty()) {
887 for (
auto it = Selects.
begin(); it != Selects.
end(); ) {
888 SelectInst *
SI = *it;
889 if (SI == InsertPoint) {
893 DenseMap<Instruction *, bool> Visited;
895 DT, Unhoistables,
nullptr, Visited);
900 "DropUnhoistableSelect", SI)
901 <<
"Dropped unhoistable select";
903 it = Selects.
erase(it);
906 Unhoistables.erase(SI);
913 if (RI.HasBranch && InsertPoint != Branch) {
914 DenseMap<Instruction *, bool> Visited;
916 DT, Unhoistables,
nullptr, Visited);
921 assert(InsertPoint != Branch &&
"Branch must not be the hoist point");
924 for (SelectInst *SI : Selects) {
925 dbgs() <<
"SI " << *
SI <<
"\n";
927 for (SelectInst *SI : Selects) {
930 "DropSelectUnhoistableBranch", SI)
931 <<
"Dropped select due to unhoistable branch";
935 return SI->getParent() == EntryBB;
937 Unhoistables.clear();
945 "Branch can't be already above the hoist point");
946 DenseMap<Instruction *, bool> Visited;
948 DT, Unhoistables,
nullptr, Visited) &&
949 "checkHoistValue for branch");
951 for (
auto *SI : Selects) {
953 "SI can't be already above the hoist point");
954 DenseMap<Instruction *, bool> Visited;
956 Unhoistables,
nullptr, Visited) &&
957 "checkHoistValue for selects");
963 for (
auto *SI : Selects) {
971CHRScope * CHR::findScopes(Region *R, Region *NextRegion, Region *ParentRegion,
972 SmallVectorImpl<CHRScope *> &Scopes) {
974 CHRScope *
Result = findScope(R);
976 CHRScope *ConsecutiveSubscope =
nullptr;
978 for (
auto It =
R->begin(); It !=
R->end(); ++It) {
979 const std::unique_ptr<Region> &SubR = *It;
980 auto NextIt = std::next(It);
981 Region *NextSubR = NextIt !=
R->end() ? NextIt->get() :
nullptr;
982 CHR_DEBUG(
dbgs() <<
"Looking at subregion " << SubR.get()->getNameStr()
984 CHRScope *SubCHRScope = findScopes(SubR.get(), NextSubR, R, Scopes);
986 CHR_DEBUG(
dbgs() <<
"Subregion Scope " << *SubCHRScope <<
"\n");
991 if (!ConsecutiveSubscope)
992 ConsecutiveSubscope = SubCHRScope;
993 else if (!ConsecutiveSubscope->appendable(SubCHRScope)) {
994 Subscopes.
push_back(ConsecutiveSubscope);
995 ConsecutiveSubscope = SubCHRScope;
997 ConsecutiveSubscope->append(SubCHRScope);
999 if (ConsecutiveSubscope) {
1000 Subscopes.
push_back(ConsecutiveSubscope);
1002 ConsecutiveSubscope =
nullptr;
1005 if (ConsecutiveSubscope) {
1006 Subscopes.
push_back(ConsecutiveSubscope);
1008 for (CHRScope *
Sub : Subscopes) {
1024 ConditionValues.
insert(BI->getCondition());
1027 ConditionValues.
insert(
SI->getCondition());
1029 return ConditionValues;
1044 assert(InsertPoint &&
"Null InsertPoint");
1046 dbgs() <<
"shouldSplit " << *InsertPoint <<
" PrevConditionValues ";
1047 for (
Value *V : PrevConditionValues) {
1048 dbgs() << *V <<
", ";
1050 dbgs() <<
" ConditionValues ";
1051 for (
Value *V : ConditionValues) {
1052 dbgs() << *V <<
", ";
1056 for (
Value *V : ConditionValues) {
1058 if (!
checkHoistValue(V, InsertPoint, DT, Unhoistables,
nullptr, Visited)) {
1059 CHR_DEBUG(
dbgs() <<
"Split. checkHoistValue false " << *V <<
"\n");
1066 if (!PrevConditionValues.
empty() && !ConditionValues.
empty()) {
1068 std::set<Value *> PrevBases, Bases;
1070 for (
Value *V : PrevConditionValues) {
1071 const std::set<Value *> &BaseValues =
getBaseValues(V, DT, Visited);
1072 PrevBases.insert(BaseValues.begin(), BaseValues.end());
1074 for (
Value *V : ConditionValues) {
1075 const std::set<Value *> &BaseValues =
getBaseValues(V, DT, Visited);
1076 Bases.insert(BaseValues.begin(), BaseValues.end());
1079 dbgs() <<
"PrevBases ";
1080 for (
Value *V : PrevBases) {
1081 dbgs() << *V <<
", ";
1083 dbgs() <<
" Bases ";
1084 for (
Value *V : Bases) {
1085 dbgs() << *V <<
", ";
1088 std::vector<Value *> Intersection;
1089 std::set_intersection(PrevBases.begin(), PrevBases.end(), Bases.begin(),
1090 Bases.end(), std::back_inserter(Intersection));
1091 if (Intersection.empty()) {
1103 for (
RegInfo &RI : Scope->RegInfos)
1105 for (CHRScope *
Sub : Scope->Subs)
1109void CHR::splitScopes(SmallVectorImpl<CHRScope *> &Input,
1110 SmallVectorImpl<CHRScope *> &Output) {
1111 for (CHRScope *Scope : Input) {
1113 "BranchInsertPoint must not be set");
1114 DenseSet<Instruction *> Unhoistables;
1116 splitScope(Scope,
nullptr,
nullptr,
nullptr, Output, Unhoistables);
1119 for (CHRScope *Scope : Output) {
1120 assert(
Scope->BranchInsertPoint &&
"BranchInsertPoint must be set");
1128 DenseSet<Value *> *OuterConditionValues,
1129 Instruction *OuterInsertPoint,
1130 SmallVectorImpl<CHRScope *> &Output,
1131 DenseSet<Instruction *> &Unhoistables) {
1133 assert(OuterConditionValues &&
"Null OuterConditionValues");
1134 assert(OuterInsertPoint &&
"Null OuterInsertPoint");
1136 bool PrevSplitFromOuter =
true;
1137 DenseSet<Value *> PrevConditionValues;
1142 SmallVector<Instruction *, 8> SplitsInsertPoints;
1144 for (RegInfo &RI : RegInfos) {
1148 dbgs() <<
"ConditionValues ";
1149 for (
Value *V : ConditionValues) {
1150 dbgs() << *
V <<
", ";
1153 if (RI.R == RegInfos[0].R) {
1158 << RI.R->getNameStr() <<
"\n");
1159 if (
shouldSplit(OuterInsertPoint, *OuterConditionValues,
1160 ConditionValues, DT, Unhoistables)) {
1161 PrevConditionValues = ConditionValues;
1162 PrevInsertPoint = InsertPoint;
1165 "SplitScopeFromOuter",
1166 RI.R->getEntry()->getTerminator())
1167 <<
"Split scope from outer due to unhoistable branch/select "
1168 <<
"and/or lack of common condition values";
1173 PrevSplitFromOuter =
false;
1174 PrevConditionValues = *OuterConditionValues;
1176 PrevInsertPoint = OuterInsertPoint;
1180 PrevConditionValues = ConditionValues;
1181 PrevInsertPoint = InsertPoint;
1185 << RI.R->getNameStr() <<
"\n");
1186 if (
shouldSplit(PrevInsertPoint, PrevConditionValues, ConditionValues,
1187 DT, Unhoistables)) {
1191 SplitsSplitFromOuter.
push_back(PrevSplitFromOuter);
1192 SplitsConditionValues.
push_back(PrevConditionValues);
1193 SplitsInsertPoints.
push_back(PrevInsertPoint);
1195 PrevConditionValues = ConditionValues;
1196 PrevInsertPoint = InsertPoint;
1197 PrevSplitFromOuter =
true;
1200 "SplitScopeFromPrev",
1201 RI.R->getEntry()->getTerminator())
1202 <<
"Split scope from previous due to unhoistable branch/select "
1203 <<
"and/or lack of common condition values";
1212 SplitsSplitFromOuter.
push_back(PrevSplitFromOuter);
1213 SplitsConditionValues.
push_back(PrevConditionValues);
1214 assert(PrevInsertPoint &&
"Null PrevInsertPoint");
1215 SplitsInsertPoints.
push_back(PrevInsertPoint);
1217 Splits.
size() == SplitsSplitFromOuter.
size() &&
1218 Splits.
size() == SplitsInsertPoints.
size() &&
"Mismatching sizes");
1219 for (
size_t I = 0;
I < Splits.
size(); ++
I) {
1220 CHRScope *
Split = Splits[
I];
1221 DenseSet<Value *> &SplitConditionValues = SplitsConditionValues[
I];
1224 DenseSet<Instruction *> SplitUnhoistables;
1226 for (CHRScope *
Sub :
Split->Subs) {
1228 Sub, Split, &SplitConditionValues, SplitInsertPoint, Output,
1232 Split->Subs = NewSubs;
1235 for (
size_t I = 0;
I < Splits.
size(); ++
I) {
1236 CHRScope *
Split = Splits[
I];
1237 if (SplitsSplitFromOuter[
I]) {
1240 Split->BranchInsertPoint = SplitsInsertPoints[
I];
1241 CHR_DEBUG(
dbgs() <<
"BranchInsertPoint " << *SplitsInsertPoints[
I]
1250 "If no outer (top-level), must return no nested ones");
1254void CHR::classifyBiasedScopes(SmallVectorImpl<CHRScope *> &Scopes) {
1255 for (CHRScope *Scope : Scopes) {
1256 assert(
Scope->TrueBiasedRegions.empty() &&
Scope->FalseBiasedRegions.empty() &&
"Empty");
1257 classifyBiasedScopes(Scope, Scope);
1259 dbgs() <<
"classifyBiasedScopes " << *Scope <<
"\n";
1260 dbgs() <<
"TrueBiasedRegions ";
1261 for (Region *R :
Scope->TrueBiasedRegions) {
1262 dbgs() <<
R->getNameStr() <<
", ";
1265 dbgs() <<
"FalseBiasedRegions ";
1266 for (Region *R :
Scope->FalseBiasedRegions) {
1267 dbgs() <<
R->getNameStr() <<
", ";
1270 dbgs() <<
"TrueBiasedSelects ";
1271 for (SelectInst *SI :
Scope->TrueBiasedSelects) {
1275 dbgs() <<
"FalseBiasedSelects ";
1276 for (SelectInst *SI :
Scope->FalseBiasedSelects) {
1283void CHR::classifyBiasedScopes(CHRScope *Scope, CHRScope *OutermostScope) {
1284 for (RegInfo &RI :
Scope->RegInfos) {
1287 if (TrueBiasedRegionsGlobal.contains(R))
1288 OutermostScope->TrueBiasedRegions.insert(R);
1289 else if (FalseBiasedRegionsGlobal.contains(R))
1290 OutermostScope->FalseBiasedRegions.insert(R);
1294 for (SelectInst *SI : RI.Selects) {
1295 if (TrueBiasedSelectsGlobal.contains(SI))
1296 OutermostScope->TrueBiasedSelects.insert(SI);
1297 else if (FalseBiasedSelectsGlobal.contains(SI))
1298 OutermostScope->FalseBiasedSelects.insert(SI);
1303 for (CHRScope *
Sub :
Scope->Subs) {
1304 classifyBiasedScopes(
Sub, OutermostScope);
1309 unsigned NumBiased = Scope->TrueBiasedRegions.size() +
1310 Scope->FalseBiasedRegions.size() +
1311 Scope->TrueBiasedSelects.size() +
1312 Scope->FalseBiasedSelects.size();
1316void CHR::filterScopes(SmallVectorImpl<CHRScope *> &Input,
1317 SmallVectorImpl<CHRScope *> &Output) {
1318 for (CHRScope *Scope : Input) {
1321 CHR_DEBUG(
dbgs() <<
"Filtered out by biased branches truthy-regions "
1322 <<
Scope->TrueBiasedRegions.size()
1323 <<
" falsy-regions " <<
Scope->FalseBiasedRegions.size()
1324 <<
" true-selects " <<
Scope->TrueBiasedSelects.size()
1325 <<
" false-selects " <<
Scope->FalseBiasedSelects.size() <<
"\n");
1327 return OptimizationRemarkMissed(
1329 "DropScopeWithOneBranchOrSelect",
1330 Scope->RegInfos[0].R->getEntry()->getTerminator())
1331 <<
"Drop scope with < "
1333 <<
" biased branch(es) or select(s)";
1341void CHR::setCHRRegions(SmallVectorImpl<CHRScope *> &Input,
1342 SmallVectorImpl<CHRScope *> &Output) {
1343 for (CHRScope *Scope : Input) {
1346 setCHRRegions(Scope, Scope);
1349 dbgs() <<
"setCHRRegions HoistStopMap " << *Scope <<
"\n";
1350 for (
auto pair :
Scope->HoistStopMap) {
1351 Region *R = pair.first;
1352 dbgs() <<
"Region " << R->getNameStr() <<
"\n";
1353 for (Instruction *I : pair.second) {
1354 dbgs() <<
"HoistStop " << *I <<
"\n";
1357 dbgs() <<
"CHRRegions" <<
"\n";
1358 for (RegInfo &RI :
Scope->CHRRegions) {
1359 dbgs() << RI.R->getNameStr() <<
"\n";
1364void CHR::setCHRRegions(CHRScope *Scope, CHRScope *OutermostScope) {
1365 DenseSet<Instruction *> Unhoistables;
1369 for (RegInfo &RI :
Scope->RegInfos)
1371 Instruction *InsertPoint = OutermostScope->BranchInsertPoint;
1372 for (RegInfo &RI :
Scope->RegInfos) {
1374 DenseSet<Instruction *> HoistStops;
1375 bool IsHoisted =
false;
1377 assert((OutermostScope->TrueBiasedRegions.contains(R) ||
1378 OutermostScope->FalseBiasedRegions.contains(R)) &&
1379 "Must be truthy or falsy");
1382 DenseMap<Instruction *, bool> Visited;
1383 bool IsHoistable =
checkHoistValue(BI->getCondition(), InsertPoint, DT,
1384 Unhoistables, &HoistStops, Visited);
1385 assert(IsHoistable &&
"Must be hoistable");
1386 (void)(IsHoistable);
1389 for (SelectInst *SI : RI.Selects) {
1390 assert((OutermostScope->TrueBiasedSelects.contains(SI) ||
1391 OutermostScope->FalseBiasedSelects.contains(SI)) &&
1392 "Must be true or false biased");
1394 DenseMap<Instruction *, bool> Visited;
1396 Unhoistables, &HoistStops, Visited);
1397 assert(IsHoistable &&
"Must be hoistable");
1398 (void)(IsHoistable);
1402 OutermostScope->CHRRegions.push_back(RI);
1403 OutermostScope->HoistStopMap[
R] = HoistStops;
1407 setCHRRegions(
Sub, OutermostScope);
1411 return Scope1->RegInfos[0].R->getDepth() < Scope2->RegInfos[0].R->getDepth();
1414void CHR::sortScopes(SmallVectorImpl<CHRScope *> &Input,
1415 SmallVectorImpl<CHRScope *> &Output) {
1424 HoistStopMapTy &HoistStopMap,
1428 auto IT = HoistStopMap.find(R);
1429 assert(
IT != HoistStopMap.end() &&
"Region must be in hoist stop map");
1432 if (
I == HoistPoint)
1437 if (TrivialPHIs.
count(PN))
1447 assert(DT.
getNode(
I->getParent()) &&
"DT must contain I's block");
1449 "DT must contain HoistPoint block");
1461 hoistValue(
Op, HoistPoint, R, HoistStopMap, HoistedSet, TrivialPHIs, DT);
1475 for (
const RegInfo &RI : Scope->CHRRegions) {
1477 bool IsTrueBiased = Scope->TrueBiasedRegions.count(R);
1478 bool IsFalseBiased = Scope->FalseBiasedRegions.count(R);
1479 if (RI.HasBranch && (IsTrueBiased || IsFalseBiased)) {
1481 hoistValue(BI->getCondition(), HoistPoint, R, Scope->HoistStopMap,
1482 HoistedSet, TrivialPHIs, DT);
1485 bool IsTrueBiased = Scope->TrueBiasedSelects.count(
SI);
1486 bool IsFalseBiased = Scope->FalseBiasedSelects.count(
SI);
1487 if (!(IsTrueBiased || IsFalseBiased))
1489 hoistValue(
SI->getCondition(), HoistPoint, R, Scope->HoistStopMap,
1490 HoistedSet, TrivialPHIs, DT);
1501 if (U == ExcludedUser)
1510 if (U == ExcludedUser)
1513 assert(BI->isConditional() &&
"Must be conditional");
1514 BI->swapSuccessors();
1525 SI->swapProfMetadata();
1526 if (Scope->TrueBiasedSelects.count(
SI)) {
1527 assert(!Scope->FalseBiasedSelects.contains(
SI) &&
1528 "Must not be already in");
1529 Scope->FalseBiasedSelects.insert(
SI);
1530 }
else if (Scope->FalseBiasedSelects.count(
SI)) {
1531 assert(!Scope->TrueBiasedSelects.contains(
SI) &&
1532 "Must not be already in");
1533 Scope->TrueBiasedSelects.insert(
SI);
1550 for (
RegInfo &RI : Scope->RegInfos) {
1553 BlocksInScope.
insert(BB);
1557 dbgs() <<
"Inserting redundant phis\n";
1559 dbgs() <<
"BlockInScope " << BB->getName() <<
"\n";
1564 for (
User *U :
I.users()) {
1566 if (!BlocksInScope.
contains(UI->getParent()) &&
1570 CHR_DEBUG(
dbgs() <<
"Used outside scope by user " << *UI <<
"\n");
1571 Users.push_back(UI);
1572 }
else if (UI->getParent() == EntryBlock &&
isa<PHINode>(UI)) {
1577 <<
"Used at entry block (for a back edge) by a phi user "
1579 Users.push_back(UI);
1583 if (
Users.size() > 0) {
1595 for (
unsigned J = 0,
NumOps = UI->getNumOperands(); J <
NumOps; ++J) {
1596 if (UI->getOperand(J) == &
I) {
1597 UI->setOperand(J, PN);
1611 auto HasBiasedBranchOrSelect = [](
RegInfo &RI, CHRScope *Scope) {
1612 if (Scope->TrueBiasedRegions.count(RI.R) ||
1613 Scope->FalseBiasedRegions.count(RI.R))
1616 if (Scope->TrueBiasedSelects.count(
SI) ||
1617 Scope->FalseBiasedSelects.count(
SI))
1621 for (
RegInfo &RI : Scope->CHRRegions) {
1622 assert(HasBiasedBranchOrSelect(RI, Scope) &&
1623 "Must have biased branch or select");
1631 CHRScope *Scope,
BasicBlock *PreEntryBlock) {
1633 for (
RegInfo &RI : Scope->CHRRegions) {
1635 bool IsTrueBiased = Scope->TrueBiasedRegions.count(R);
1636 bool IsFalseBiased = Scope->FalseBiasedRegions.count(R);
1637 if (RI.HasBranch && (IsTrueBiased || IsFalseBiased)) {
1639 Value *V = BI->getCondition();
1643 assert((
I->getParent() == PreEntryBlock ||
1644 !Scope->contains(
I)) &&
1645 "Must have been hoisted to PreEntryBlock or outside the scope");
1649 bool IsTrueBiased = Scope->TrueBiasedSelects.count(
SI);
1650 bool IsFalseBiased = Scope->FalseBiasedSelects.count(
SI);
1651 if (!(IsTrueBiased || IsFalseBiased))
1653 Value *V =
SI->getCondition();
1657 assert((
I->getParent() == PreEntryBlock ||
1658 !Scope->contains(
I)) &&
1659 "Must have been hoisted to PreEntryBlock or outside the scope");
1665void CHR::transformScopes(CHRScope *Scope, DenseSet<PHINode *> &TrivialPHIs) {
1668 assert(
Scope->RegInfos.size() >= 1 &&
"Should have at least one Region");
1670 for (RegInfo &RI :
Scope->RegInfos) {
1672 unsigned Duplication = getRegionDuplicationCount(R);
1677 <<
" for this region");
1679 return OptimizationRemarkMissed(
DEBUG_TYPE,
"DupThresholdReached",
1680 R->getEntry()->getTerminator())
1681 <<
"Reached the duplication threshold for the region";
1686 for (RegInfo &RI :
Scope->RegInfos) {
1687 DuplicationCount[RI.R]++;
1714 <<
" at " << *
Scope->BranchInsertPoint <<
"\n");
1718 "NewEntryBlock's only pred must be EntryBlock");
1726 cloneScopeBlocks(Scope, PreEntryBlock, ExitBlock, LastRegion, VMap);
1730 BranchInst *MergedBr = createMergedBranch(PreEntryBlock, EntryBlock,
1731 NewEntryBlock, VMap);
1746 fixupBranchesAndSelects(Scope, PreEntryBlock, MergedBr,
1753void CHR::cloneScopeBlocks(CHRScope *Scope,
1754 BasicBlock *PreEntryBlock,
1755 BasicBlock *ExitBlock,
1763 SmallVector<BasicBlock*, 8> NewBlocks;
1764 for (RegInfo &RI :
Scope->RegInfos)
1765 for (BasicBlock *BB : RI.R->blocks()) {
1767 assert(BB != PreEntryBlock &&
"Don't copy the preetntry block");
1775 PN.removeIncomingValueIf([&](
unsigned Idx) {
1783 F.splice(ExitBlock->
getIterator(), &
F, NewBlocks[0]->getIterator(),
1787 for (BasicBlock *NewBB : NewBlocks)
1788 for (Instruction &
I : *NewBB)
1796 for (PHINode &PN : ExitBlock->
phis())
1797 for (
unsigned I = 0,
NumOps = PN.getNumIncomingValues();
I <
NumOps;
1801 Value *
V = PN.getIncomingValue(
I);
1802 auto It = VMap.
find(V);
1803 if (It != VMap.
end())
V = It->second;
1804 assert(VMap.
find(Pred) != VMap.
end() &&
"Pred must have been cloned");
1812BranchInst *CHR::createMergedBranch(BasicBlock *PreEntryBlock,
1813 BasicBlock *EntryBlock,
1814 BasicBlock *NewEntryBlock,
1818 "SplitBlock did not work correctly!");
1820 "NewEntryBlock's only pred must be EntryBlock");
1822 "NewEntryBlock must have been copied");
1831 assert(NewEntryBlock->getSinglePredecessor() == EntryBlock &&
1832 "NewEntryBlock's only pred must be EntryBlock");
1838void CHR::fixupBranchesAndSelects(CHRScope *Scope,
1839 BasicBlock *PreEntryBlock,
1840 BranchInst *MergedBR,
1843 BranchProbability CHRBranchBias(1, 1);
1844 uint64_t NumCHRedBranches = 0;
1846 for (RegInfo &RI :
Scope->CHRRegions) {
1849 fixupBranch(R, Scope, IRB, MergedCondition, CHRBranchBias);
1852 for (SelectInst *SI : RI.Selects) {
1853 fixupSelect(SI, Scope, IRB, MergedCondition, CHRBranchBias);
1857 assert(NumCHRedBranches > 0);
1858 Stats.NumBranchesDelta += NumCHRedBranches - 1;
1865 <<
"Merged " <<
ore::NV(
"NumCHRedBranches", NumCHRedBranches)
1866 <<
" branches or selects";
1869 uint32_t Weights[] = {
1870 static_cast<uint32_t
>(CHRBranchBias.scale(1000)),
1871 static_cast<uint32_t
>(CHRBranchBias.getCompl().
scale(1000)),
1874 CHR_DEBUG(
dbgs() <<
"CHR branch bias " << Weights[0] <<
":" << Weights[1]
1880void CHR::fixupBranch(Region *R, CHRScope *Scope,
1882 Value *&MergedCondition,
1883 BranchProbability &CHRBranchBias) {
1884 bool IsTrueBiased =
Scope->TrueBiasedRegions.count(R);
1885 assert((IsTrueBiased ||
Scope->FalseBiasedRegions.count(R)) &&
1886 "Must be truthy or falsy");
1888 assert(BranchBiasMap.contains(R) &&
"Must be in the bias map");
1889 BranchProbability Bias = BranchBiasMap[
R];
1892 if (CHRBranchBias > Bias)
1893 CHRBranchBias = Bias;
1897 assert(RegionExitBlock &&
"Null ExitBlock");
1898 assert((IfThen == RegionExitBlock || IfElse == RegionExitBlock) &&
1899 IfThen != IfElse &&
"Invariant from findScopes");
1900 if (IfThen == RegionExitBlock) {
1906 <<
" IfElse " << IfElse->
getName() <<
"\n");
1908 BasicBlock *HotTarget = IsTrueBiased ? IfThen : IfElse;
1909 bool ConditionTrue = HotTarget == BI->getSuccessor(0);
1910 addToMergedCondition(ConditionTrue,
Cond, BI, Scope, IRB,
1913 assert(ConditionTrue == (HotTarget == BI->getSuccessor(0)) &&
1914 "The successor shouldn't change");
1915 Value *NewCondition = ConditionTrue ?
1918 BI->setCondition(NewCondition);
1923void CHR::fixupSelect(SelectInst *SI, CHRScope *Scope,
1925 Value *&MergedCondition,
1926 BranchProbability &CHRBranchBias) {
1927 bool IsTrueBiased =
Scope->TrueBiasedSelects.count(SI);
1929 Scope->FalseBiasedSelects.count(SI)) &&
"Must be biased");
1930 assert(SelectBiasMap.contains(SI) &&
"Must be in the bias map");
1931 BranchProbability Bias = SelectBiasMap[
SI];
1934 if (CHRBranchBias > Bias)
1935 CHRBranchBias = Bias;
1937 addToMergedCondition(IsTrueBiased,
Cond, SI, Scope, IRB,
1939 Value *NewCondition = IsTrueBiased ?
1942 SI->setCondition(NewCondition);
1947void CHR::addToMergedCondition(
bool IsTrueBiased,
Value *
Cond,
1948 Instruction *BranchOrSelect, CHRScope *Scope,
1950 if (!IsTrueBiased) {
1968void CHR::transformScopes(SmallVectorImpl<CHRScope *> &CHRScopes) {
1970 DenseSet<PHINode *> TrivialPHIs;
1971 for (CHRScope *Scope : CHRScopes) {
1972 transformScopes(Scope, TrivialPHIs);
1974 std::ostringstream oss;
1975 oss <<
" after transformScopes " <<
I++;
1976 dumpIR(
F, oss.str().c_str(),
nullptr));
1983 dbgs() << Label <<
" " << Scopes.size() <<
"\n";
1984 for (CHRScope *Scope : Scopes) {
1985 dbgs() << *Scope <<
"\n";
1998 dbgs() <<
"RegionInfo:\n";
2004 findScopes(AllScopes);
2013 splitScopes(AllScopes, SplitScopes);
2018 classifyBiasedScopes(SplitScopes);
2024 filterScopes(SplitScopes, FilteredScopes);
2029 setCHRRegions(FilteredScopes, SetScopes);
2036 sortScopes(SetScopes, SortedScopes);
2040 dbgs() <<
"RegionInfo:\n";
2044 if (!SortedScopes.
empty()) {
2045 transformScopes(SortedScopes);
2053 return OptimizationRemark(
DEBUG_TYPE,
"Stats", &
F)
2055 <<
"Reduced the number of branches in hot paths by "
2058 <<
ore::NV(
"WeightedNumBranchesDelta",
Stats.WeightedNumBranchesDelta)
2059 <<
" (weighted by PGO count)";
2078 if (!PPSI || !PPSI->hasProfileSummary())
2085 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")
#define LLVM_ATTRIBUTE_UNUSED
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 bool hasAtLeastTwoBiasedBranches(CHRScope *Scope)
static bool shouldApply(Function &F, ProfileSummaryInfo &PSI)
static void LLVM_ATTRIBUTE_UNUSED dumpIR(Function &F, const char *Label, CHRStats *Stats)
static void getSelectsInScope(CHRScope *Scope, DenseSet< Instruction * > &Output)
static void hoistScopeConditions(CHRScope *Scope, Instruction *HoistPoint, DenseSet< PHINode * > &TrivialPHIs, DominatorTree &DT)
static bool isHoistableInstructionType(Instruction *I)
static DenseSet< Value * > getCHRConditionValuesForRegion(RegInfo &RI)
static bool negateICmpIfUsedByBranchOrSelectOnly(ICmpInst *ICmp, Instruction *ExcludedUser, CHRScope *Scope)
static Instruction * getBranchInsertPoint(RegInfo &RI)
static void LLVM_ATTRIBUTE_UNUSED assertBranchOrSelectConditionHoisted(CHRScope *Scope, BasicBlock *PreEntryBlock)
static cl::opt< std::string > CHRModuleList("chr-module-list", cl::init(""), cl::Hidden, cl::desc("Specify file to retrieve the list of modules to apply CHR to"))
static void LLVM_ATTRIBUTE_UNUSED assertCHRRegionsHaveBiasedBranchOrSelect(CHRScope *Scope)
static cl::opt< double > CHRBiasThreshold("chr-bias-threshold", cl::init(0.99), cl::Hidden, cl::desc("CHR considers a branch bias greater than this ratio as biased"))
static void LLVM_ATTRIBUTE_UNUSED dumpScopes(SmallVectorImpl< CHRScope * > &Scopes, const char *Label)
static BranchProbability getCHRBiasThreshold()
static cl::opt< std::string > CHRFunctionList("chr-function-list", cl::init(""), cl::Hidden, cl::desc("Specify file to retrieve the list of functions to apply CHR to"))
static cl::opt< bool > ForceCHR("force-chr", cl::init(false), cl::Hidden, cl::desc("Apply CHR for all functions"))
static bool checkBiasedBranch(BranchInst *BI, Region *R, DenseSet< Region * > &TrueBiasedRegionsGlobal, DenseSet< Region * > &FalseBiasedRegionsGlobal, DenseMap< Region *, BranchProbability > &BranchBiasMap)
static const std::set< Value * > & getBaseValues(Value *V, DominatorTree &DT, DenseMap< Value *, std::set< Value * > > &Visited)
static bool extractBranchProbabilities(Instruction *I, BranchProbability &TrueProb, BranchProbability &FalseProb)
static void parseCHRFilterFiles()
This file defines the DenseMap class.
This file defines the DenseSet and SmallDenseSet classes.
This is the interface for a simple mod/ref and alias analysis over globals.
This file provides various utilities for inspecting and working with the control flow graph in LLVM I...
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="")
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 insert(const value_type &X)
Insert a new element into the SetVector.
bool contains(const key_type &key) const
Check if the SetVector contains the given key.
A SetVector that performs no allocations if smaller than a certain size.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
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...
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)
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.
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.
LLVM_ABI BasicBlock * SplitBlock(BasicBlock *Old, BasicBlock::iterator SplitPt, DominatorTree *DT, LoopInfo *LI=nullptr, MemorySSAUpdater *MSSAU=nullptr, const Twine &BBName="", bool Before=false)
Split the specified block at the specified instruction.
auto find_if(R &&Range, UnaryPredicate P)
Provide wrappers to std::find_if which take ranges instead of having to pass begin/end explicitly.
void erase_if(Container &C, UnaryPredicate P)
Provide a container algorithm similar to C++ Library Fundamentals v2's erase_if which is equivalent t...
auto predecessors(const MachineBasicBlock *BB)
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.