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;
528 assert(InsertPoint &&
"Null InsertPoint");
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)
760 CHR_DEBUG(
dbgs() <<
"BI.isConditional " << BI->isConditional() <<
"\n");
763 if (BI && BI->isConditional()) {
768 if (S0 !=
S1 && (S0 == Exit ||
S1 == Exit)) {
771 BI, R, TrueBiasedRegionsGlobal, FalseBiasedRegionsGlobal,
773 Result =
new CHRScope(RI);
774 Scopes.insert(Result);
779 return OptimizationRemarkMissed(
DEBUG_TYPE,
"BranchNotBiased", BI)
780 <<
"Branch not biased";
800 for (RegionNode *
E :
R->elements()) {
801 if (
E->isSubRegion())
808 for (Instruction &
I : *BB) {
815 if (Selects.
size() > 0) {
816 auto AddSelects = [&](RegInfo &RI) {
817 for (
auto *SI : Selects)
819 TrueBiasedSelectsGlobal,
820 FalseBiasedSelectsGlobal,
822 RI.Selects.push_back(SI);
825 return OptimizationRemarkMissed(
DEBUG_TYPE,
"SelectNotBiased", SI)
826 <<
"Select not biased";
833 Result =
new CHRScope(RI);
834 Scopes.insert(Result);
836 CHR_DEBUG(
dbgs() <<
"Found select(s) in a region with a branch\n");
837 AddSelects(
Result->RegInfos[0]);
843 checkScopeHoistable(Result);
870void CHR::checkScopeHoistable(CHRScope *Scope) {
871 RegInfo &RI =
Scope->RegInfos[0];
874 auto *
Branch = RI.HasBranch ?
877 if (RI.HasBranch || !Selects.
empty()) {
886 for (
auto it = Selects.
begin(); it != Selects.
end(); ) {
887 SelectInst *
SI = *it;
888 if (SI == InsertPoint) {
892 DenseMap<Instruction *, bool> Visited;
894 DT, Unhoistables,
nullptr, Visited);
899 "DropUnhoistableSelect", SI)
900 <<
"Dropped unhoistable select";
902 it = Selects.
erase(it);
905 Unhoistables.erase(SI);
912 if (RI.HasBranch && InsertPoint != Branch) {
913 DenseMap<Instruction *, bool> Visited;
915 DT, Unhoistables,
nullptr, Visited);
920 assert(InsertPoint != Branch &&
"Branch must not be the hoist point");
923 for (SelectInst *SI : Selects) {
924 dbgs() <<
"SI " << *
SI <<
"\n";
926 for (SelectInst *SI : Selects) {
929 "DropSelectUnhoistableBranch", SI)
930 <<
"Dropped select due to unhoistable branch";
934 return SI->getParent() == EntryBB;
936 Unhoistables.clear();
944 "Branch can't be already above the hoist point");
945 DenseMap<Instruction *, bool> Visited;
947 DT, Unhoistables,
nullptr, Visited) &&
948 "checkHoistValue for branch");
950 for (
auto *SI : Selects) {
952 "SI can't be already above the hoist point");
953 DenseMap<Instruction *, bool> Visited;
955 Unhoistables,
nullptr, Visited) &&
956 "checkHoistValue for selects");
962 for (
auto *SI : Selects) {
970CHRScope * CHR::findScopes(Region *R, Region *NextRegion, Region *ParentRegion,
971 SmallVectorImpl<CHRScope *> &Scopes) {
973 CHRScope *
Result = findScope(R);
975 CHRScope *ConsecutiveSubscope =
nullptr;
977 for (
auto It =
R->begin(); It !=
R->end(); ++It) {
978 const std::unique_ptr<Region> &SubR = *It;
979 auto NextIt = std::next(It);
980 Region *NextSubR = NextIt !=
R->end() ? NextIt->get() :
nullptr;
981 CHR_DEBUG(
dbgs() <<
"Looking at subregion " << SubR.get()->getNameStr()
983 CHRScope *SubCHRScope = findScopes(SubR.get(), NextSubR, R, Scopes);
985 CHR_DEBUG(
dbgs() <<
"Subregion Scope " << *SubCHRScope <<
"\n");
990 if (!ConsecutiveSubscope)
991 ConsecutiveSubscope = SubCHRScope;
992 else if (!ConsecutiveSubscope->appendable(SubCHRScope)) {
993 Subscopes.
push_back(ConsecutiveSubscope);
994 ConsecutiveSubscope = SubCHRScope;
996 ConsecutiveSubscope->append(SubCHRScope);
998 if (ConsecutiveSubscope) {
999 Subscopes.
push_back(ConsecutiveSubscope);
1001 ConsecutiveSubscope =
nullptr;
1004 if (ConsecutiveSubscope) {
1005 Subscopes.
push_back(ConsecutiveSubscope);
1007 for (CHRScope *
Sub : Subscopes) {
1023 ConditionValues.
insert(BI->getCondition());
1026 ConditionValues.
insert(
SI->getCondition());
1028 return ConditionValues;
1043 assert(InsertPoint &&
"Null InsertPoint");
1045 dbgs() <<
"shouldSplit " << *InsertPoint <<
" PrevConditionValues ";
1046 for (
Value *V : PrevConditionValues) {
1047 dbgs() << *V <<
", ";
1049 dbgs() <<
" ConditionValues ";
1050 for (
Value *V : ConditionValues) {
1051 dbgs() << *V <<
", ";
1055 for (
Value *V : ConditionValues) {
1057 if (!
checkHoistValue(V, InsertPoint, DT, Unhoistables,
nullptr, Visited)) {
1058 CHR_DEBUG(
dbgs() <<
"Split. checkHoistValue false " << *V <<
"\n");
1065 if (!PrevConditionValues.
empty() && !ConditionValues.
empty()) {
1067 std::set<Value *> PrevBases, Bases;
1069 for (
Value *V : PrevConditionValues) {
1070 const std::set<Value *> &BaseValues =
getBaseValues(V, DT, Visited);
1071 PrevBases.insert(BaseValues.begin(), BaseValues.end());
1073 for (
Value *V : ConditionValues) {
1074 const std::set<Value *> &BaseValues =
getBaseValues(V, DT, Visited);
1075 Bases.insert(BaseValues.begin(), BaseValues.end());
1078 dbgs() <<
"PrevBases ";
1079 for (
Value *V : PrevBases) {
1080 dbgs() << *V <<
", ";
1082 dbgs() <<
" Bases ";
1083 for (
Value *V : Bases) {
1084 dbgs() << *V <<
", ";
1087 std::vector<Value *> Intersection;
1088 std::set_intersection(PrevBases.begin(), PrevBases.end(), Bases.begin(),
1089 Bases.end(), std::back_inserter(Intersection));
1090 if (Intersection.empty()) {
1102 for (
RegInfo &RI : Scope->RegInfos)
1104 for (CHRScope *
Sub : Scope->Subs)
1108void CHR::splitScopes(SmallVectorImpl<CHRScope *> &Input,
1109 SmallVectorImpl<CHRScope *> &Output) {
1110 for (CHRScope *Scope : Input) {
1112 "BranchInsertPoint must not be set");
1113 DenseSet<Instruction *> Unhoistables;
1115 splitScope(Scope,
nullptr,
nullptr,
nullptr, Output, Unhoistables);
1118 for (CHRScope *Scope : Output) {
1119 assert(
Scope->BranchInsertPoint &&
"BranchInsertPoint must be set");
1127 DenseSet<Value *> *OuterConditionValues,
1128 Instruction *OuterInsertPoint,
1129 SmallVectorImpl<CHRScope *> &Output,
1130 DenseSet<Instruction *> &Unhoistables) {
1132 assert(OuterConditionValues &&
"Null OuterConditionValues");
1133 assert(OuterInsertPoint &&
"Null OuterInsertPoint");
1135 bool PrevSplitFromOuter =
true;
1136 DenseSet<Value *> PrevConditionValues;
1141 SmallVector<Instruction *, 8> SplitsInsertPoints;
1143 for (RegInfo &RI : RegInfos) {
1147 dbgs() <<
"ConditionValues ";
1148 for (
Value *V : ConditionValues) {
1149 dbgs() << *
V <<
", ";
1152 if (RI.R == RegInfos[0].R) {
1157 << RI.R->getNameStr() <<
"\n");
1158 if (
shouldSplit(OuterInsertPoint, *OuterConditionValues,
1159 ConditionValues, DT, Unhoistables)) {
1160 PrevConditionValues = ConditionValues;
1161 PrevInsertPoint = InsertPoint;
1164 "SplitScopeFromOuter",
1165 RI.R->getEntry()->getTerminator())
1166 <<
"Split scope from outer due to unhoistable branch/select "
1167 <<
"and/or lack of common condition values";
1172 PrevSplitFromOuter =
false;
1173 PrevConditionValues = *OuterConditionValues;
1175 PrevInsertPoint = OuterInsertPoint;
1179 PrevConditionValues = ConditionValues;
1180 PrevInsertPoint = InsertPoint;
1184 << RI.R->getNameStr() <<
"\n");
1185 if (
shouldSplit(PrevInsertPoint, PrevConditionValues, ConditionValues,
1186 DT, Unhoistables)) {
1190 SplitsSplitFromOuter.
push_back(PrevSplitFromOuter);
1191 SplitsConditionValues.
push_back(PrevConditionValues);
1192 SplitsInsertPoints.
push_back(PrevInsertPoint);
1194 PrevConditionValues = ConditionValues;
1195 PrevInsertPoint = InsertPoint;
1196 PrevSplitFromOuter =
true;
1199 "SplitScopeFromPrev",
1200 RI.R->getEntry()->getTerminator())
1201 <<
"Split scope from previous due to unhoistable branch/select "
1202 <<
"and/or lack of common condition values";
1211 SplitsSplitFromOuter.
push_back(PrevSplitFromOuter);
1212 SplitsConditionValues.
push_back(PrevConditionValues);
1213 assert(PrevInsertPoint &&
"Null PrevInsertPoint");
1214 SplitsInsertPoints.
push_back(PrevInsertPoint);
1216 Splits.
size() == SplitsSplitFromOuter.
size() &&
1217 Splits.
size() == SplitsInsertPoints.
size() &&
"Mismatching sizes");
1218 for (
size_t I = 0;
I < Splits.
size(); ++
I) {
1219 CHRScope *
Split = Splits[
I];
1220 DenseSet<Value *> &SplitConditionValues = SplitsConditionValues[
I];
1223 DenseSet<Instruction *> SplitUnhoistables;
1225 for (CHRScope *
Sub :
Split->Subs) {
1227 Sub, Split, &SplitConditionValues, SplitInsertPoint, Output,
1231 Split->Subs = NewSubs;
1234 for (
size_t I = 0;
I < Splits.
size(); ++
I) {
1235 CHRScope *
Split = Splits[
I];
1236 if (SplitsSplitFromOuter[
I]) {
1239 Split->BranchInsertPoint = SplitsInsertPoints[
I];
1240 CHR_DEBUG(
dbgs() <<
"BranchInsertPoint " << *SplitsInsertPoints[
I]
1249 "If no outer (top-level), must return no nested ones");
1253void CHR::classifyBiasedScopes(SmallVectorImpl<CHRScope *> &Scopes) {
1254 for (CHRScope *Scope : Scopes) {
1255 assert(
Scope->TrueBiasedRegions.empty() &&
Scope->FalseBiasedRegions.empty() &&
"Empty");
1256 classifyBiasedScopes(Scope, Scope);
1258 dbgs() <<
"classifyBiasedScopes " << *Scope <<
"\n";
1259 dbgs() <<
"TrueBiasedRegions ";
1260 for (Region *R :
Scope->TrueBiasedRegions) {
1261 dbgs() <<
R->getNameStr() <<
", ";
1264 dbgs() <<
"FalseBiasedRegions ";
1265 for (Region *R :
Scope->FalseBiasedRegions) {
1266 dbgs() <<
R->getNameStr() <<
", ";
1269 dbgs() <<
"TrueBiasedSelects ";
1270 for (SelectInst *SI :
Scope->TrueBiasedSelects) {
1274 dbgs() <<
"FalseBiasedSelects ";
1275 for (SelectInst *SI :
Scope->FalseBiasedSelects) {
1282void CHR::classifyBiasedScopes(CHRScope *Scope, CHRScope *OutermostScope) {
1283 for (RegInfo &RI :
Scope->RegInfos) {
1286 if (TrueBiasedRegionsGlobal.contains(R))
1287 OutermostScope->TrueBiasedRegions.insert(R);
1288 else if (FalseBiasedRegionsGlobal.contains(R))
1289 OutermostScope->FalseBiasedRegions.insert(R);
1293 for (SelectInst *SI : RI.Selects) {
1294 if (TrueBiasedSelectsGlobal.contains(SI))
1295 OutermostScope->TrueBiasedSelects.insert(SI);
1296 else if (FalseBiasedSelectsGlobal.contains(SI))
1297 OutermostScope->FalseBiasedSelects.insert(SI);
1302 for (CHRScope *
Sub :
Scope->Subs) {
1303 classifyBiasedScopes(
Sub, OutermostScope);
1308 unsigned NumBiased = Scope->TrueBiasedRegions.size() +
1309 Scope->FalseBiasedRegions.size() +
1310 Scope->TrueBiasedSelects.size() +
1311 Scope->FalseBiasedSelects.size();
1315void CHR::filterScopes(SmallVectorImpl<CHRScope *> &Input,
1316 SmallVectorImpl<CHRScope *> &Output) {
1317 for (CHRScope *Scope : Input) {
1320 CHR_DEBUG(
dbgs() <<
"Filtered out by biased branches truthy-regions "
1321 <<
Scope->TrueBiasedRegions.size()
1322 <<
" falsy-regions " <<
Scope->FalseBiasedRegions.size()
1323 <<
" true-selects " <<
Scope->TrueBiasedSelects.size()
1324 <<
" false-selects " <<
Scope->FalseBiasedSelects.size() <<
"\n");
1326 return OptimizationRemarkMissed(
1328 "DropScopeWithOneBranchOrSelect",
1329 Scope->RegInfos[0].R->getEntry()->getTerminator())
1330 <<
"Drop scope with < "
1332 <<
" biased branch(es) or select(s)";
1340void CHR::setCHRRegions(SmallVectorImpl<CHRScope *> &Input,
1341 SmallVectorImpl<CHRScope *> &Output) {
1342 for (CHRScope *Scope : Input) {
1345 setCHRRegions(Scope, Scope);
1348 dbgs() <<
"setCHRRegions HoistStopMap " << *Scope <<
"\n";
1349 for (
auto pair :
Scope->HoistStopMap) {
1350 Region *R = pair.first;
1351 dbgs() <<
"Region " << R->getNameStr() <<
"\n";
1352 for (Instruction *I : pair.second) {
1353 dbgs() <<
"HoistStop " << *I <<
"\n";
1356 dbgs() <<
"CHRRegions" <<
"\n";
1357 for (RegInfo &RI :
Scope->CHRRegions) {
1358 dbgs() << RI.R->getNameStr() <<
"\n";
1363void CHR::setCHRRegions(CHRScope *Scope, CHRScope *OutermostScope) {
1364 DenseSet<Instruction *> Unhoistables;
1368 for (RegInfo &RI :
Scope->RegInfos)
1370 Instruction *InsertPoint = OutermostScope->BranchInsertPoint;
1371 for (RegInfo &RI :
Scope->RegInfos) {
1373 DenseSet<Instruction *> HoistStops;
1374 bool IsHoisted =
false;
1376 assert((OutermostScope->TrueBiasedRegions.contains(R) ||
1377 OutermostScope->FalseBiasedRegions.contains(R)) &&
1378 "Must be truthy or falsy");
1381 DenseMap<Instruction *, bool> Visited;
1382 bool IsHoistable =
checkHoistValue(BI->getCondition(), InsertPoint, DT,
1383 Unhoistables, &HoistStops, Visited);
1384 assert(IsHoistable &&
"Must be hoistable");
1385 (void)(IsHoistable);
1388 for (SelectInst *SI : RI.Selects) {
1389 assert((OutermostScope->TrueBiasedSelects.contains(SI) ||
1390 OutermostScope->FalseBiasedSelects.contains(SI)) &&
1391 "Must be true or false biased");
1393 DenseMap<Instruction *, bool> Visited;
1395 Unhoistables, &HoistStops, Visited);
1396 assert(IsHoistable &&
"Must be hoistable");
1397 (void)(IsHoistable);
1401 OutermostScope->CHRRegions.push_back(RI);
1402 OutermostScope->HoistStopMap[
R] = HoistStops;
1406 setCHRRegions(
Sub, OutermostScope);
1410 return Scope1->RegInfos[0].R->getDepth() < Scope2->RegInfos[0].R->getDepth();
1413void CHR::sortScopes(SmallVectorImpl<CHRScope *> &Input,
1414 SmallVectorImpl<CHRScope *> &Output) {
1423 HoistStopMapTy &HoistStopMap,
1427 auto IT = HoistStopMap.find(R);
1428 assert(
IT != HoistStopMap.end() &&
"Region must be in hoist stop map");
1431 if (
I == HoistPoint)
1436 if (TrivialPHIs.
count(PN))
1446 assert(DT.
getNode(
I->getParent()) &&
"DT must contain I's block");
1448 "DT must contain HoistPoint block");
1460 hoistValue(
Op, HoistPoint, R, HoistStopMap, HoistedSet, TrivialPHIs, DT);
1474 for (
const RegInfo &RI : Scope->CHRRegions) {
1476 bool IsTrueBiased = Scope->TrueBiasedRegions.count(R);
1477 bool IsFalseBiased = Scope->FalseBiasedRegions.count(R);
1478 if (RI.HasBranch && (IsTrueBiased || IsFalseBiased)) {
1480 hoistValue(BI->getCondition(), HoistPoint, R, Scope->HoistStopMap,
1481 HoistedSet, TrivialPHIs, DT);
1484 bool IsTrueBiased = Scope->TrueBiasedSelects.count(
SI);
1485 bool IsFalseBiased = Scope->FalseBiasedSelects.count(
SI);
1486 if (!(IsTrueBiased || IsFalseBiased))
1488 hoistValue(
SI->getCondition(), HoistPoint, R, Scope->HoistStopMap,
1489 HoistedSet, TrivialPHIs, DT);
1500 if (U == ExcludedUser)
1509 if (U == ExcludedUser)
1512 assert(BI->isConditional() &&
"Must be conditional");
1513 BI->swapSuccessors();
1524 SI->swapProfMetadata();
1525 if (Scope->TrueBiasedSelects.count(
SI)) {
1526 assert(!Scope->FalseBiasedSelects.contains(
SI) &&
1527 "Must not be already in");
1528 Scope->FalseBiasedSelects.insert(
SI);
1529 }
else if (Scope->FalseBiasedSelects.count(
SI)) {
1530 assert(!Scope->TrueBiasedSelects.contains(
SI) &&
1531 "Must not be already in");
1532 Scope->TrueBiasedSelects.insert(
SI);
1549 for (
RegInfo &RI : Scope->RegInfos) {
1552 BlocksInScope.
insert(BB);
1556 dbgs() <<
"Inserting redundant phis\n";
1558 dbgs() <<
"BlockInScope " << BB->getName() <<
"\n";
1563 for (
User *U :
I.users()) {
1565 if (!BlocksInScope.
contains(UI->getParent()) &&
1569 CHR_DEBUG(
dbgs() <<
"Used outside scope by user " << *UI <<
"\n");
1570 Users.push_back(UI);
1571 }
else if (UI->getParent() == EntryBlock &&
isa<PHINode>(UI)) {
1576 <<
"Used at entry block (for a back edge) by a phi user "
1578 Users.push_back(UI);
1582 if (
Users.size() > 0) {
1593 bool FoundLifetimeAnnotation =
false;
1598 if (UI->isLifetimeStartOrEnd()) {
1599 UI->eraseFromParent();
1600 FoundLifetimeAnnotation =
true;
1603 for (
unsigned J = 0,
NumOps = UI->getNumOperands(); J <
NumOps; ++J) {
1604 if (UI->getOperand(J) == &
I) {
1605 UI->setOperand(J, PN);
1611 if (FoundLifetimeAnnotation) {
1614 if (UI->isLifetimeStartOrEnd())
1615 UI->eraseFromParent();
1624[[maybe_unused]]
static void
1627 auto HasBiasedBranchOrSelect = [](
RegInfo &RI, CHRScope *Scope) {
1628 if (Scope->TrueBiasedRegions.count(RI.R) ||
1629 Scope->FalseBiasedRegions.count(RI.R))
1632 if (Scope->TrueBiasedSelects.count(
SI) ||
1633 Scope->FalseBiasedSelects.count(
SI))
1637 for (
RegInfo &RI : Scope->CHRRegions) {
1638 assert(HasBiasedBranchOrSelect(RI, Scope) &&
1639 "Must have biased branch or select");
1646[[maybe_unused]]
static void
1650 for (
RegInfo &RI : Scope->CHRRegions) {
1652 bool IsTrueBiased = Scope->TrueBiasedRegions.count(R);
1653 bool IsFalseBiased = Scope->FalseBiasedRegions.count(R);
1654 if (RI.HasBranch && (IsTrueBiased || IsFalseBiased)) {
1656 Value *V = BI->getCondition();
1660 assert((
I->getParent() == PreEntryBlock ||
1661 !Scope->contains(
I)) &&
1662 "Must have been hoisted to PreEntryBlock or outside the scope");
1666 bool IsTrueBiased = Scope->TrueBiasedSelects.count(
SI);
1667 bool IsFalseBiased = Scope->FalseBiasedSelects.count(
SI);
1668 if (!(IsTrueBiased || IsFalseBiased))
1670 Value *V =
SI->getCondition();
1674 assert((
I->getParent() == PreEntryBlock ||
1675 !Scope->contains(
I)) &&
1676 "Must have been hoisted to PreEntryBlock or outside the scope");
1682void CHR::transformScopes(CHRScope *Scope, DenseSet<PHINode *> &TrivialPHIs) {
1685 assert(
Scope->RegInfos.size() >= 1 &&
"Should have at least one Region");
1687 for (RegInfo &RI :
Scope->RegInfos) {
1689 unsigned Duplication = getRegionDuplicationCount(R);
1694 <<
" for this region");
1696 return OptimizationRemarkMissed(
DEBUG_TYPE,
"DupThresholdReached",
1697 R->getEntry()->getTerminator())
1698 <<
"Reached the duplication threshold for the region";
1703 for (RegInfo &RI :
Scope->RegInfos) {
1704 DuplicationCount[RI.R]++;
1714 for (Instruction &
I : *EntryBlock) {
1716 if (AI->isStaticAlloca())
1728 CHR_DEBUG(
dbgs() <<
"Splitting entry block " << EntryBlock->getName()
1729 <<
" at " << *
Scope->BranchInsertPoint <<
"\n");
1733 "NewEntryBlock's only pred must be EntryBlock");
1738 for (AllocaInst *AI : StaticAllocas)
1739 AI->moveBefore(EntryBlock->begin());
1755 cloneScopeBlocks(Scope, PreEntryBlock, ExitBlock, LastRegion, VMap);
1759 BranchInst *MergedBr = createMergedBranch(PreEntryBlock, EntryBlock,
1760 NewEntryBlock, VMap);
1775 fixupBranchesAndSelects(Scope, PreEntryBlock, MergedBr,
1782void CHR::cloneScopeBlocks(CHRScope *Scope,
1783 BasicBlock *PreEntryBlock,
1784 BasicBlock *ExitBlock,
1792 SmallVector<BasicBlock*, 8> NewBlocks;
1793 for (RegInfo &RI :
Scope->RegInfos)
1794 for (BasicBlock *BB : RI.R->blocks()) {
1796 assert(BB != PreEntryBlock &&
"Don't copy the preetntry block");
1804 PN.removeIncomingValueIf([&](
unsigned Idx) {
1812 F.splice(ExitBlock->
getIterator(), &
F, NewBlocks[0]->getIterator(),
1816 for (BasicBlock *NewBB : NewBlocks)
1817 for (Instruction &
I : *NewBB)
1825 for (PHINode &PN : ExitBlock->
phis())
1826 for (
unsigned I = 0,
NumOps = PN.getNumIncomingValues();
I <
NumOps;
1830 Value *
V = PN.getIncomingValue(
I);
1831 auto It = VMap.
find(V);
1832 if (It != VMap.
end())
V = It->second;
1833 assert(VMap.
find(Pred) != VMap.
end() &&
"Pred must have been cloned");
1841BranchInst *CHR::createMergedBranch(BasicBlock *PreEntryBlock,
1842 BasicBlock *EntryBlock,
1843 BasicBlock *NewEntryBlock,
1847 "SplitBlock did not work correctly!");
1849 "NewEntryBlock's only pred must be EntryBlock");
1851 "NewEntryBlock must have been copied");
1860 assert(NewEntryBlock->getSinglePredecessor() == EntryBlock &&
1861 "NewEntryBlock's only pred must be EntryBlock");
1867void CHR::fixupBranchesAndSelects(CHRScope *Scope,
1868 BasicBlock *PreEntryBlock,
1869 BranchInst *MergedBR,
1872 BranchProbability CHRBranchBias(1, 1);
1873 uint64_t NumCHRedBranches = 0;
1875 for (RegInfo &RI :
Scope->CHRRegions) {
1878 fixupBranch(R, Scope, IRB, MergedCondition, CHRBranchBias);
1881 for (SelectInst *SI : RI.Selects) {
1882 fixupSelect(SI, Scope, IRB, MergedCondition, CHRBranchBias);
1886 assert(NumCHRedBranches > 0);
1887 Stats.NumBranchesDelta += NumCHRedBranches - 1;
1894 <<
"Merged " <<
ore::NV(
"NumCHRedBranches", NumCHRedBranches)
1895 <<
" branches or selects";
1898 uint32_t Weights[] = {
1899 static_cast<uint32_t
>(CHRBranchBias.scale(1000)),
1900 static_cast<uint32_t
>(CHRBranchBias.getCompl().
scale(1000)),
1903 CHR_DEBUG(
dbgs() <<
"CHR branch bias " << Weights[0] <<
":" << Weights[1]
1909void CHR::fixupBranch(Region *R, CHRScope *Scope,
1911 Value *&MergedCondition,
1912 BranchProbability &CHRBranchBias) {
1913 bool IsTrueBiased =
Scope->TrueBiasedRegions.count(R);
1914 assert((IsTrueBiased ||
Scope->FalseBiasedRegions.count(R)) &&
1915 "Must be truthy or falsy");
1917 assert(BranchBiasMap.contains(R) &&
"Must be in the bias map");
1918 BranchProbability Bias = BranchBiasMap[
R];
1921 if (CHRBranchBias > Bias)
1922 CHRBranchBias = Bias;
1926 assert(RegionExitBlock &&
"Null ExitBlock");
1927 assert((IfThen == RegionExitBlock || IfElse == RegionExitBlock) &&
1928 IfThen != IfElse &&
"Invariant from findScopes");
1929 if (IfThen == RegionExitBlock) {
1935 <<
" IfElse " << IfElse->
getName() <<
"\n");
1937 BasicBlock *HotTarget = IsTrueBiased ? IfThen : IfElse;
1938 bool ConditionTrue = HotTarget == BI->getSuccessor(0);
1939 addToMergedCondition(ConditionTrue,
Cond, BI, Scope, IRB,
1942 assert(ConditionTrue == (HotTarget == BI->getSuccessor(0)) &&
1943 "The successor shouldn't change");
1944 Value *NewCondition = ConditionTrue ?
1947 BI->setCondition(NewCondition);
1952void CHR::fixupSelect(SelectInst *SI, CHRScope *Scope,
1954 Value *&MergedCondition,
1955 BranchProbability &CHRBranchBias) {
1956 bool IsTrueBiased =
Scope->TrueBiasedSelects.count(SI);
1958 Scope->FalseBiasedSelects.count(SI)) &&
"Must be biased");
1959 assert(SelectBiasMap.contains(SI) &&
"Must be in the bias map");
1960 BranchProbability Bias = SelectBiasMap[
SI];
1963 if (CHRBranchBias > Bias)
1964 CHRBranchBias = Bias;
1966 addToMergedCondition(IsTrueBiased,
Cond, SI, Scope, IRB,
1968 Value *NewCondition = IsTrueBiased ?
1971 SI->setCondition(NewCondition);
1976void CHR::addToMergedCondition(
bool IsTrueBiased,
Value *
Cond,
1977 Instruction *BranchOrSelect, CHRScope *Scope,
1979 if (!IsTrueBiased) {
1997void CHR::transformScopes(SmallVectorImpl<CHRScope *> &CHRScopes) {
1999 DenseSet<PHINode *> TrivialPHIs;
2000 for (CHRScope *Scope : CHRScopes) {
2001 transformScopes(Scope, TrivialPHIs);
2003 std::ostringstream oss;
2004 oss <<
" after transformScopes " <<
I++;
2005 dumpIR(
F, oss.str().c_str(),
nullptr));
2011 const char *Label) {
2012 dbgs() << Label <<
" " << Scopes.size() <<
"\n";
2013 for (CHRScope *Scope : Scopes) {
2014 dbgs() << *Scope <<
"\n";
2027 dbgs() <<
"RegionInfo:\n";
2033 findScopes(AllScopes);
2042 splitScopes(AllScopes, SplitScopes);
2047 classifyBiasedScopes(SplitScopes);
2053 filterScopes(SplitScopes, FilteredScopes);
2058 setCHRRegions(FilteredScopes, SetScopes);
2065 sortScopes(SetScopes, SortedScopes);
2069 dbgs() <<
"RegionInfo:\n";
2073 if (!SortedScopes.
empty()) {
2074 transformScopes(SortedScopes);
2082 return OptimizationRemark(
DEBUG_TYPE,
"Stats", &
F)
2084 <<
"Reduced the number of branches in hot paths by "
2087 <<
ore::NV(
"WeightedNumBranchesDelta",
Stats.WeightedNumBranchesDelta)
2088 <<
" (weighted by PGO count)";
2105 if (!PPSI || !PPSI->hasProfileSummary())
2112 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 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, 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.
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.