47#define DEBUG_TYPE "chr"
49#define CHR_DEBUG(X) LLVM_DEBUG(X)
54 if (!Opts.chr_module_list.empty()) {
57 errs() <<
"Error: Couldn't read the chr-module-list file "
58 << Opts.chr_module_list <<
"\n";
61 StringRef Buf = FileOrErr->get()->getBuffer();
63 Buf.
split(Lines,
'\n');
70 if (!Opts.chr_function_list.empty()) {
73 errs() <<
"Error: Couldn't read the chr-function-list file "
74 << Opts.chr_function_list <<
"\n";
77 StringRef Buf = FileOrErr->get()->getBuffer();
79 Buf.
split(Lines,
'\n');
92 void print(raw_ostream &OS)
const {
93 OS <<
"CHRStats: NumBranches " << NumBranches
94 <<
" NumBranchesDelta " << NumBranchesDelta
95 <<
" WeightedNumBranchesDelta " << WeightedNumBranchesDelta;
103 uint64_t WeightedNumBranchesDelta = 0;
109 RegInfo(Region *RegionIn) :
R(RegionIn) {}
111 bool HasBranch =
false;
122 CHRScope(RegInfo RI) : BranchInsertPoint(nullptr) {
123 assert(RI.R &&
"Null RegionIn");
124 RegInfos.push_back(RI);
127 Region *getParentRegion() {
128 assert(RegInfos.size() > 0 &&
"Empty CHRScope");
129 Region *Parent = RegInfos[0].R->getParent();
130 assert(Parent &&
"Unexpected to call this on the top-level region");
135 assert(RegInfos.size() > 0 &&
"Empty CHRScope");
136 return RegInfos.front().R->getEntry();
140 assert(RegInfos.size() > 0 &&
"Empty CHRScope");
141 return RegInfos.back().R->getExit();
144 bool appendable(CHRScope *
Next) {
149 if (getExitBlock() != NextEntry)
152 Region *LastRegion = RegInfos.back().R;
162 assert(RegInfos.size() > 0 &&
"Empty CHRScope");
163 assert(
Next->RegInfos.size() > 0 &&
"Empty CHRScope");
164 assert(getParentRegion() ==
Next->getParentRegion() &&
166 assert(getExitBlock() ==
Next->getEntryBlock() &&
168 RegInfos.append(
Next->RegInfos.begin(),
Next->RegInfos.end());
169 Subs.append(
Next->Subs.begin(),
Next->Subs.end());
172 void addSub(CHRScope *SubIn) {
174 bool IsChild =
false;
175 for (RegInfo &RI : RegInfos)
176 if (RI.R == SubIn->getParentRegion()) {
180 assert(IsChild &&
"Must be a child");
182 Subs.push_back(SubIn);
187 CHRScope *
split(Region *Boundary) {
188 assert(Boundary &&
"Boundary null");
189 assert(RegInfos.begin()->R != Boundary &&
190 "Can't be split at beginning");
192 RegInfos, [&Boundary](
const RegInfo &RI) {
return Boundary == RI.R; });
193 if (BoundaryIt == RegInfos.end())
196 DenseSet<Region *> TailRegionSet;
197 for (
const RegInfo &RI : TailRegInfos)
198 TailRegionSet.
insert(RI.R);
201 std::stable_partition(Subs.begin(), Subs.end(), [&](CHRScope *
Sub) {
202 assert(Sub &&
"null Sub");
203 Region *Parent = Sub->getParentRegion();
204 if (TailRegionSet.count(Parent))
209 [&Parent](const RegInfo &RI) { return Parent == RI.R; }) &&
215 assert(HoistStopMap.empty() &&
"MapHoistStops must be empty");
216 auto *
Scope =
new CHRScope(TailRegInfos, TailSubs);
217 RegInfos.erase(BoundaryIt, RegInfos.end());
218 Subs.erase(TailIt, Subs.end());
224 for (
const RegInfo &RI : RegInfos)
225 if (RI.R->contains(Parent))
254 HoistStopMapTy HoistStopMap;
258 : RegInfos(RegInfosIn), Subs(SubsIn), BranchInsertPoint(nullptr) {}
263 CHR(
const InstrumentationOptions &Opts,
const StringSet<> &CHRModules,
264 const StringSet<> &CHRFunctions,
Function &Fin, BlockFrequencyInfo &BFIin,
265 DominatorTree &DTin, ProfileSummaryInfo &PSIin, RegionInfo &RIin,
266 OptimizationRemarkEmitter &OREin)
267 : Opts(Opts), CHRModules(CHRModules), CHRFunctions(CHRFunctions), F(Fin),
268 BFI(BFIin), DT(DTin), PSI(PSIin), RI(RIin), ORE(OREin) {}
271 for (CHRScope *Scope : Scopes) {
282 void findScopes(SmallVectorImpl<CHRScope *> &Output) {
283 Region *
R = RI.getTopLevelRegion();
284 if (CHRScope *Scope = findScopes(R,
nullptr,
nullptr, Output)) {
288 CHRScope *findScopes(Region *R, Region *NextRegion, Region *ParentRegion,
289 SmallVectorImpl<CHRScope *> &Scopes);
290 CHRScope *findScope(Region *R);
291 void checkScopeHoistable(CHRScope *Scope);
293 void splitScopes(SmallVectorImpl<CHRScope *> &Input,
294 SmallVectorImpl<CHRScope *> &Output);
297 DenseSet<Value *> *OuterConditionValues,
298 Instruction *OuterInsertPoint,
299 SmallVectorImpl<CHRScope *> &Output,
300 DenseSet<Instruction *> &Unhoistables);
302 void classifyBiasedScopes(SmallVectorImpl<CHRScope *> &Scopes);
303 void classifyBiasedScopes(CHRScope *Scope, CHRScope *OutermostScope);
305 void filterScopes(SmallVectorImpl<CHRScope *> &Input,
306 SmallVectorImpl<CHRScope *> &Output);
308 void setCHRRegions(SmallVectorImpl<CHRScope *> &Input,
309 SmallVectorImpl<CHRScope *> &Output);
310 void setCHRRegions(CHRScope *Scope, CHRScope *OutermostScope);
312 void sortScopes(SmallVectorImpl<CHRScope *> &Input,
313 SmallVectorImpl<CHRScope *> &Output);
315 void transformScopes(SmallVectorImpl<CHRScope *> &CHRScopes);
316 void transformScopes(CHRScope *Scope, DenseSet<PHINode *> &TrivialPHIs);
317 void cloneScopeBlocks(CHRScope *Scope,
318 BasicBlock *PreEntryBlock,
319 BasicBlock *ExitBlock,
322 CondBrInst *createMergedBranch(BasicBlock *PreEntryBlock,
323 BasicBlock *EntryBlock,
324 BasicBlock *NewEntryBlock,
326 void fixupBranchesAndSelects(CHRScope *Scope, BasicBlock *PreEntryBlock,
327 CondBrInst *MergedBR,
uint64_t ProfileCount);
328 void fixupBranch(Region *R, CHRScope *Scope,
IRBuilder<> &IRB,
329 Value *&MergedCondition, BranchProbability &CHRBranchBias);
330 void fixupSelect(SelectInst *SI, CHRScope *Scope,
IRBuilder<> &IRB,
331 Value *&MergedCondition, BranchProbability &CHRBranchBias);
332 void addToMergedCondition(
bool IsTrueBiased,
Value *
Cond,
333 Instruction *BranchOrSelect, CHRScope *Scope,
335 unsigned getRegionDuplicationCount(
const Region *R) {
342 Count += DuplicationCount[
R];
348 const InstrumentationOptions &Opts;
349 const StringSet<> &CHRModules;
350 const StringSet<> &CHRFunctions;
352 BlockFrequencyInfo &BFI;
354 ProfileSummaryInfo &PSI;
356 OptimizationRemarkEmitter &ORE;
360 DenseSet<Region *> TrueBiasedRegionsGlobal;
362 DenseSet<Region *> FalseBiasedRegionsGlobal;
364 DenseSet<SelectInst *> TrueBiasedSelectsGlobal;
366 DenseSet<SelectInst *> FalseBiasedSelectsGlobal;
368 DenseMap<Region *, BranchProbability> BranchBiasMap;
370 DenseMap<SelectInst *, BranchProbability> SelectBiasMap;
372 DenseSet<CHRScope *> Scopes;
374 DenseMap<const Region *, unsigned> DuplicationCount;
380 const CHRStats &
Stats) {
395 if (Opts.disable_chr)
401 if (!Opts.chr_module_list.empty() || !Opts.chr_function_list.empty()) {
402 if (CHRModules.
count(
F.getParent()->getName()))
404 return CHRFunctions.
count(
F.getName());
425 assert(RegInfos.size() > 0 &&
"Empty CHRScope");
427 OS << RegInfos.size() <<
", Regions[";
428 for (
const RegInfo &RI : RegInfos) {
429 OS << RI.R->getNameStr();
432 if (RI.Selects.size() > 0)
433 OS <<
" S" << RI.Selects.size();
436 if (RegInfos[0].
R->getParent()) {
437 OS <<
"], Parent " << RegInfos[0].R->getParent()->getNameStr();
443 for (CHRScope *
Sub : Subs) {
470static const std::set<Value *> &
473 auto It = Visited.find(
V);
474 if (It != Visited.end()) {
477 std::set<Value *> Result;
484 return Visited.insert(std::make_pair(
V, std::move(Result))).first->second;
489 Result.insert(OpResult.begin(), OpResult.end());
491 return Visited.insert(std::make_pair(
V, std::move(Result))).first->second;
499 return Visited.insert(std::make_pair(
V, std::move(Result))).first->second;
513 auto It = Visited.
find(
I);
514 if (It != Visited.
end()) {
517 assert(DT.
getNode(
I->getParent()) &&
"DT must contain I's parent block");
519 if (Unhoistables.
count(
I)) {
536 bool AllOpsHoisted =
true;
540 AllOpsHoisted =
false;
568 uint64_t SumWeight = TrueWeight + FalseWeight;
570 assert(SumWeight >= TrueWeight && SumWeight >= FalseWeight &&
571 "Overflow calculating branch probabilities.");
582static BranchProbability
585 static_cast<uint64_t>(Opts.chr_bias_threshold * 1000000), 1000000);
592template <
typename K,
typename S,
typename M>
595 S &TrueSet, S &FalseSet, M &BiasMap) {
597 if (TrueProb >= Threshold) {
599 BiasMap[
Key] = TrueProb;
601 }
else if (FalseProb >= Threshold) {
602 FalseSet.insert(
Key);
603 BiasMap[
Key] = FalseProb;
621 assert((IfThen == R->getExit() || IfElse == R->getExit()) &&
623 "Invariant from findScopes");
624 if (IfThen == R->getExit()) {
633 return checkBias(Opts, R, ThenProb, ElseProb, TrueBiasedRegionsGlobal,
634 FalseBiasedRegionsGlobal, BranchBiasMap);
650 return checkBias(Opts,
SI, TrueProb, FalseProb, TrueBiasedSelectsGlobal,
651 FalseBiasedSelectsGlobal, SelectBiasMap);
664 if (
SI->getParent() == EntryBB) {
671 assert(HoistPoint &&
"Null HoistPoint");
677 if (
SI->getParent() == EntryBB) {
684 "HoistPoint must be the first one in Selects");
693CHRScope * CHR::findScope(Region *R) {
694 CHRScope *
Result =
nullptr;
697 assert(Entry &&
"Entry must not be null");
698 assert((Exit ==
nullptr) == (
R->isTopLevelRegion()) &&
699 "Only top level region has a null exit");
710 bool EntryInSubregion = RI.getRegionFor(Entry) !=
R;
711 if (EntryInSubregion)
715 if (
R->contains(
Pred))
719 for (BasicBlock *BB :
R->blocks()) {
720 if (BB->hasAddressTaken())
728 for (Instruction &
I : *BB) {
730 if (
II->getIntrinsicID() == Intrinsic::coro_id)
747 if (CB->cannotDuplicate() || CB->isConvergent())
764 if (S0 !=
S1 && (S0 == Exit ||
S1 == Exit)) {
768 FalseBiasedRegionsGlobal, BranchBiasMap);
769 Result =
new CHRScope(RI);
770 Scopes.insert(Result);
775 return OptimizationRemarkMissed(
DEBUG_TYPE,
"BranchNotBiased", BI)
776 <<
"Branch not biased";
796 for (RegionNode *
E :
R->elements()) {
797 if (
E->isSubRegion())
804 for (Instruction &
I : *BB) {
809 if (
SI->getCondition()->getType()->isIntegerTy()) {
816 if (Selects.
size() > 0) {
817 auto AddSelects = [&](RegInfo &RI) {
818 for (
auto *SI : Selects)
820 FalseBiasedSelectsGlobal, SelectBiasMap))
821 RI.Selects.push_back(SI);
824 return OptimizationRemarkMissed(
DEBUG_TYPE,
"SelectNotBiased", SI)
825 <<
"Select not biased";
832 Result =
new CHRScope(RI);
833 Scopes.insert(Result);
835 CHR_DEBUG(
dbgs() <<
"Found select(s) in a region with a branch\n");
836 AddSelects(
Result->RegInfos[0]);
842 checkScopeHoistable(Result);
869void CHR::checkScopeHoistable(CHRScope *Scope) {
870 RegInfo &RI =
Scope->RegInfos[0];
876 if (RI.HasBranch || !Selects.
empty()) {
885 for (
auto it = Selects.
begin(); it != Selects.
end(); ) {
886 SelectInst *
SI = *it;
887 if (SI == InsertPoint) {
891 DenseMap<Instruction *, bool> Visited;
893 DT, Unhoistables,
nullptr, Visited);
898 "DropUnhoistableSelect", SI)
899 <<
"Dropped unhoistable select";
901 it = Selects.
erase(it);
904 Unhoistables.erase(SI);
911 if (RI.HasBranch && InsertPoint != Branch) {
912 DenseMap<Instruction *, bool> Visited;
914 DT, Unhoistables,
nullptr, Visited);
919 assert(InsertPoint != Branch &&
"Branch must not be the hoist point");
922 for (SelectInst *SI : Selects) {
923 dbgs() <<
"SI " << *
SI <<
"\n";
925 for (SelectInst *SI : Selects) {
928 "DropSelectUnhoistableBranch", SI)
929 <<
"Dropped select due to unhoistable branch";
933 return SI->getParent() == EntryBB;
935 Unhoistables.clear();
943 "Branch can't be already above the hoist point");
944 DenseMap<Instruction *, bool> Visited;
946 DT, Unhoistables,
nullptr, Visited) &&
947 "checkHoistValue for branch");
949 for (
auto *SI : Selects) {
951 "SI can't be already above the hoist point");
952 DenseMap<Instruction *, bool> Visited;
954 Unhoistables,
nullptr, Visited) &&
955 "checkHoistValue for selects");
961 for (
auto *SI : Selects) {
969CHRScope * CHR::findScopes(Region *R, Region *NextRegion, Region *ParentRegion,
970 SmallVectorImpl<CHRScope *> &Scopes) {
972 CHRScope *
Result = findScope(R);
974 CHRScope *ConsecutiveSubscope =
nullptr;
976 for (
auto It =
R->begin(); It !=
R->end(); ++It) {
977 const std::unique_ptr<Region> &SubR = *It;
978 auto NextIt = std::next(It);
979 Region *NextSubR = NextIt !=
R->end() ? NextIt->get() :
nullptr;
980 CHR_DEBUG(
dbgs() <<
"Looking at subregion " << SubR.get()->getNameStr()
982 CHRScope *SubCHRScope = findScopes(SubR.get(), NextSubR, R, Scopes);
984 CHR_DEBUG(
dbgs() <<
"Subregion Scope " << *SubCHRScope <<
"\n");
989 if (!ConsecutiveSubscope)
990 ConsecutiveSubscope = SubCHRScope;
991 else if (!ConsecutiveSubscope->appendable(SubCHRScope)) {
992 Subscopes.
push_back(ConsecutiveSubscope);
993 ConsecutiveSubscope = SubCHRScope;
995 ConsecutiveSubscope->append(SubCHRScope);
997 if (ConsecutiveSubscope) {
998 Subscopes.
push_back(ConsecutiveSubscope);
1000 ConsecutiveSubscope =
nullptr;
1003 if (ConsecutiveSubscope) {
1004 Subscopes.
push_back(ConsecutiveSubscope);
1006 for (CHRScope *
Sub : Subscopes) {
1022 ConditionValues.
insert(BI->getCondition());
1025 ConditionValues.
insert(
SI->getCondition());
1027 return ConditionValues;
1045 for (
Value *
V : PrevConditionValues) {
1046 dbgs() << *
V <<
", ";
1048 dbgs() <<
" ConditionValues ";
1049 for (
Value *
V : ConditionValues) {
1050 dbgs() << *
V <<
", ";
1054 for (
Value *
V : ConditionValues) {
1057 CHR_DEBUG(
dbgs() <<
"Split. checkHoistValue false " << *
V <<
"\n");
1064 if (!PrevConditionValues.
empty() && !ConditionValues.
empty()) {
1066 std::set<Value *> PrevBases, Bases;
1068 for (
Value *
V : PrevConditionValues) {
1069 const std::set<Value *> &BaseValues =
getBaseValues(
V, DT, Visited);
1070 PrevBases.insert(BaseValues.begin(), BaseValues.end());
1072 for (
Value *
V : ConditionValues) {
1073 const std::set<Value *> &BaseValues =
getBaseValues(
V, DT, Visited);
1074 Bases.insert(BaseValues.begin(), BaseValues.end());
1077 dbgs() <<
"PrevBases ";
1078 for (
Value *
V : PrevBases) {
1079 dbgs() << *
V <<
", ";
1081 dbgs() <<
" Bases ";
1083 dbgs() << *
V <<
", ";
1086 std::vector<Value *> Intersection;
1087 std::set_intersection(PrevBases.begin(), PrevBases.end(), Bases.begin(),
1088 Bases.end(), std::back_inserter(Intersection));
1089 if (Intersection.empty()) {
1101 for (
RegInfo &RI : Scope->RegInfos)
1102 Output.insert_range(RI.Selects);
1103 for (CHRScope *
Sub : Scope->Subs)
1107void CHR::splitScopes(SmallVectorImpl<CHRScope *> &Input,
1108 SmallVectorImpl<CHRScope *> &Output) {
1109 for (CHRScope *Scope : Input) {
1111 "BranchInsertPoint must not be set");
1112 DenseSet<Instruction *> Unhoistables;
1114 splitScope(Scope,
nullptr,
nullptr,
nullptr, Output, Unhoistables);
1117 for (CHRScope *Scope : Output) {
1118 assert(
Scope->BranchInsertPoint &&
"BranchInsertPoint must be set");
1126 DenseSet<Value *> *OuterConditionValues,
1127 Instruction *OuterInsertPoint,
1128 SmallVectorImpl<CHRScope *> &Output,
1129 DenseSet<Instruction *> &Unhoistables) {
1131 assert(OuterConditionValues &&
"Null OuterConditionValues");
1132 assert(OuterInsertPoint &&
"Null OuterInsertPoint");
1134 bool PrevSplitFromOuter =
true;
1135 DenseSet<Value *> PrevConditionValues;
1140 SmallVector<Instruction *, 8> SplitsInsertPoints;
1142 for (RegInfo &RI : RegInfos) {
1146 dbgs() <<
"ConditionValues ";
1147 for (
Value *
V : ConditionValues) {
1148 dbgs() << *
V <<
", ";
1151 if (RI.R == RegInfos[0].R) {
1156 << RI.R->getNameStr() <<
"\n");
1157 if (
shouldSplit(OuterInsertPoint, *OuterConditionValues,
1158 ConditionValues, DT, Unhoistables)) {
1159 PrevConditionValues = ConditionValues;
1160 PrevInsertPoint = InsertPoint;
1163 "SplitScopeFromOuter",
1164 RI.R->getEntry()->getTerminator())
1165 <<
"Split scope from outer due to unhoistable branch/select "
1166 <<
"and/or lack of common condition values";
1171 PrevSplitFromOuter =
false;
1172 PrevConditionValues = *OuterConditionValues;
1174 PrevInsertPoint = OuterInsertPoint;
1178 PrevConditionValues = ConditionValues;
1179 PrevInsertPoint = InsertPoint;
1183 << RI.R->getNameStr() <<
"\n");
1184 if (
shouldSplit(PrevInsertPoint, PrevConditionValues, ConditionValues,
1185 DT, Unhoistables)) {
1189 SplitsSplitFromOuter.
push_back(PrevSplitFromOuter);
1190 SplitsConditionValues.
push_back(PrevConditionValues);
1191 SplitsInsertPoints.
push_back(PrevInsertPoint);
1193 PrevConditionValues = ConditionValues;
1194 PrevInsertPoint = InsertPoint;
1195 PrevSplitFromOuter =
true;
1198 "SplitScopeFromPrev",
1199 RI.R->getEntry()->getTerminator())
1200 <<
"Split scope from previous due to unhoistable branch/select "
1201 <<
"and/or lack of common condition values";
1210 SplitsSplitFromOuter.
push_back(PrevSplitFromOuter);
1211 SplitsConditionValues.
push_back(PrevConditionValues);
1212 assert(PrevInsertPoint &&
"Null PrevInsertPoint");
1213 SplitsInsertPoints.
push_back(PrevInsertPoint);
1215 Splits.
size() == SplitsSplitFromOuter.
size() &&
1216 Splits.
size() == SplitsInsertPoints.
size() &&
"Mismatching sizes");
1217 for (
size_t I = 0;
I < Splits.
size(); ++
I) {
1218 CHRScope *
Split = Splits[
I];
1219 DenseSet<Value *> &SplitConditionValues = SplitsConditionValues[
I];
1222 DenseSet<Instruction *> SplitUnhoistables;
1224 for (CHRScope *
Sub :
Split->Subs) {
1226 Sub, Split, &SplitConditionValues, SplitInsertPoint, Output,
1230 Split->Subs = NewSubs;
1233 for (
size_t I = 0;
I < Splits.
size(); ++
I) {
1234 CHRScope *
Split = Splits[
I];
1235 if (SplitsSplitFromOuter[
I]) {
1238 Split->BranchInsertPoint = SplitsInsertPoints[
I];
1239 CHR_DEBUG(
dbgs() <<
"BranchInsertPoint " << *SplitsInsertPoints[
I]
1248 "If no outer (top-level), must return no nested ones");
1252void CHR::classifyBiasedScopes(SmallVectorImpl<CHRScope *> &Scopes) {
1253 for (CHRScope *Scope : Scopes) {
1254 assert(
Scope->TrueBiasedRegions.empty() &&
Scope->FalseBiasedRegions.empty() &&
"Empty");
1255 classifyBiasedScopes(Scope, Scope);
1257 dbgs() <<
"classifyBiasedScopes " << *Scope <<
"\n";
1258 dbgs() <<
"TrueBiasedRegions ";
1259 for (Region *R :
Scope->TrueBiasedRegions) {
1260 dbgs() <<
R->getNameStr() <<
", ";
1263 dbgs() <<
"FalseBiasedRegions ";
1264 for (Region *R :
Scope->FalseBiasedRegions) {
1265 dbgs() <<
R->getNameStr() <<
", ";
1268 dbgs() <<
"TrueBiasedSelects ";
1269 for (SelectInst *SI :
Scope->TrueBiasedSelects) {
1273 dbgs() <<
"FalseBiasedSelects ";
1274 for (SelectInst *SI :
Scope->FalseBiasedSelects) {
1281void CHR::classifyBiasedScopes(CHRScope *Scope, CHRScope *OutermostScope) {
1282 for (RegInfo &RI :
Scope->RegInfos) {
1285 if (TrueBiasedRegionsGlobal.contains(R))
1286 OutermostScope->TrueBiasedRegions.insert(R);
1287 else if (FalseBiasedRegionsGlobal.contains(R))
1288 OutermostScope->FalseBiasedRegions.insert(R);
1292 for (SelectInst *SI : RI.Selects) {
1293 if (TrueBiasedSelectsGlobal.contains(SI))
1294 OutermostScope->TrueBiasedSelects.insert(SI);
1295 else if (FalseBiasedSelectsGlobal.contains(SI))
1296 OutermostScope->FalseBiasedSelects.insert(SI);
1301 for (CHRScope *
Sub :
Scope->Subs) {
1302 classifyBiasedScopes(
Sub, OutermostScope);
1308 unsigned NumBiased = Scope->TrueBiasedRegions.size() +
1309 Scope->FalseBiasedRegions.size() +
1310 Scope->TrueBiasedSelects.size() +
1311 Scope->FalseBiasedSelects.size();
1312 return NumBiased >= Opts.chr_merge_threshold;
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(
1327 DEBUG_TYPE,
"DropScopeWithOneBranchOrSelect",
1328 Scope->RegInfos[0].R->getEntry()->getTerminator())
1329 <<
"Drop scope with < "
1330 <<
ore::NV(
"CHRMergeThreshold", Opts.chr_merge_threshold)
1331 <<
" biased branch(es) or select(s)";
1339void CHR::setCHRRegions(SmallVectorImpl<CHRScope *> &Input,
1340 SmallVectorImpl<CHRScope *> &Output) {
1341 for (CHRScope *Scope : Input) {
1344 setCHRRegions(Scope, Scope);
1347 dbgs() <<
"setCHRRegions HoistStopMap " << *Scope <<
"\n";
1348 for (
auto pair :
Scope->HoistStopMap) {
1349 Region *R = pair.first;
1350 dbgs() <<
"Region " << R->getNameStr() <<
"\n";
1351 for (Instruction *I : pair.second) {
1352 dbgs() <<
"HoistStop " << *I <<
"\n";
1355 dbgs() <<
"CHRRegions" <<
"\n";
1356 for (RegInfo &RI :
Scope->CHRRegions) {
1357 dbgs() << RI.R->getNameStr() <<
"\n";
1362void CHR::setCHRRegions(CHRScope *Scope, CHRScope *OutermostScope) {
1363 DenseSet<Instruction *> Unhoistables;
1367 for (RegInfo &RI :
Scope->RegInfos)
1369 Instruction *InsertPoint = OutermostScope->BranchInsertPoint;
1370 for (RegInfo &RI :
Scope->RegInfos) {
1372 DenseSet<Instruction *> HoistStops;
1373 bool IsHoisted =
false;
1375 assert((OutermostScope->TrueBiasedRegions.contains(R) ||
1376 OutermostScope->FalseBiasedRegions.contains(R)) &&
1377 "Must be truthy or falsy");
1380 DenseMap<Instruction *, bool> Visited;
1381 bool IsHoistable =
checkHoistValue(BI->getCondition(), InsertPoint, DT,
1382 Unhoistables, &HoistStops, Visited);
1383 assert(IsHoistable &&
"Must be hoistable");
1384 (void)(IsHoistable);
1387 for (SelectInst *SI : RI.Selects) {
1388 assert((OutermostScope->TrueBiasedSelects.contains(SI) ||
1389 OutermostScope->FalseBiasedSelects.contains(SI)) &&
1390 "Must be true or false biased");
1392 DenseMap<Instruction *, bool> Visited;
1394 Unhoistables, &HoistStops, Visited);
1395 assert(IsHoistable &&
"Must be hoistable");
1396 (void)(IsHoistable);
1400 OutermostScope->CHRRegions.push_back(RI);
1401 OutermostScope->HoistStopMap[
R] = HoistStops;
1405 setCHRRegions(
Sub, OutermostScope);
1409 return Scope1->RegInfos[0].R->getDepth() < Scope2->RegInfos[0].R->getDepth();
1412void CHR::sortScopes(SmallVectorImpl<CHRScope *> &Input,
1413 SmallVectorImpl<CHRScope *> &Output) {
1422 HoistStopMapTy &HoistStopMap,
1426 auto IT = HoistStopMap.find(R);
1427 assert(
IT != HoistStopMap.end() &&
"Region must be in hoist stop map");
1430 if (
I == HoistPoint)
1435 if (TrivialPHIs.
count(PN))
1445 assert(DT.
getNode(
I->getParent()) &&
"DT must contain I's block");
1447 "DT must contain HoistPoint block");
1459 hoistValue(
Op, HoistPoint, R, HoistStopMap, HoistedSet, TrivialPHIs, DT);
1473 for (
const RegInfo &RI : Scope->CHRRegions) {
1475 bool IsTrueBiased = Scope->TrueBiasedRegions.count(R);
1476 bool IsFalseBiased = Scope->FalseBiasedRegions.count(R);
1477 if (RI.HasBranch && (IsTrueBiased || IsFalseBiased)) {
1479 hoistValue(BI->getCondition(), HoistPoint, R, Scope->HoistStopMap,
1480 HoistedSet, TrivialPHIs, DT);
1483 bool IsTrueBiased = Scope->TrueBiasedSelects.count(
SI);
1484 bool IsFalseBiased = Scope->FalseBiasedSelects.count(
SI);
1485 if (!(IsTrueBiased || IsFalseBiased))
1487 hoistValue(
SI->getCondition(), HoistPoint, R, Scope->HoistStopMap,
1488 HoistedSet, TrivialPHIs, DT);
1499 if (U == ExcludedUser)
1508 if (U == ExcludedUser)
1511 BI->swapSuccessors();
1522 SI->swapProfMetadata();
1523 if (Scope->TrueBiasedSelects.count(
SI)) {
1524 assert(!Scope->FalseBiasedSelects.contains(
SI) &&
1525 "Must not be already in");
1526 Scope->FalseBiasedSelects.insert(
SI);
1527 }
else if (Scope->FalseBiasedSelects.count(
SI)) {
1528 assert(!Scope->TrueBiasedSelects.contains(
SI) &&
1529 "Must not be already in");
1530 Scope->TrueBiasedSelects.insert(
SI);
1547 for (
RegInfo &RI : Scope->RegInfos) {
1550 BlocksInScope.
insert(BB);
1554 dbgs() <<
"Inserting redundant phis\n";
1556 dbgs() <<
"BlockInScope " << BB->getName() <<
"\n";
1561 for (
User *U :
I.users()) {
1563 if (!BlocksInScope.
contains(UI->getParent()) &&
1567 CHR_DEBUG(
dbgs() <<
"Used outside scope by user " << *UI <<
"\n");
1568 Users.push_back(UI);
1569 }
else if (UI->getParent() == EntryBlock &&
isa<PHINode>(UI)) {
1574 <<
"Used at entry block (for a back edge) by a phi user "
1576 Users.push_back(UI);
1580 if (
Users.size() > 0) {
1591 bool FoundLifetimeAnnotation =
false;
1596 if (UI->isLifetimeStartOrEnd()) {
1597 UI->eraseFromParent();
1598 FoundLifetimeAnnotation =
true;
1601 for (
unsigned J = 0,
NumOps = UI->getNumOperands(); J <
NumOps; ++J) {
1602 if (UI->getOperand(J) == &
I) {
1603 UI->setOperand(J, PN);
1609 if (FoundLifetimeAnnotation) {
1612 if (UI->isLifetimeStartOrEnd())
1613 UI->eraseFromParent();
1622[[maybe_unused]]
static void
1625 auto HasBiasedBranchOrSelect = [](
RegInfo &RI, CHRScope *Scope) {
1626 if (Scope->TrueBiasedRegions.count(RI.R) ||
1627 Scope->FalseBiasedRegions.count(RI.R))
1630 if (Scope->TrueBiasedSelects.count(
SI) ||
1631 Scope->FalseBiasedSelects.count(
SI))
1635 for (
RegInfo &RI : Scope->CHRRegions) {
1636 assert(HasBiasedBranchOrSelect(RI, Scope) &&
1637 "Must have biased branch or select");
1644[[maybe_unused]]
static void
1648 for (
RegInfo &RI : Scope->CHRRegions) {
1650 bool IsTrueBiased = Scope->TrueBiasedRegions.count(R);
1651 bool IsFalseBiased = Scope->FalseBiasedRegions.count(R);
1652 if (RI.HasBranch && (IsTrueBiased || IsFalseBiased)) {
1654 Value *
V = BI->getCondition();
1658 assert((
I->getParent() == PreEntryBlock ||
1659 !Scope->contains(
I)) &&
1660 "Must have been hoisted to PreEntryBlock or outside the scope");
1664 bool IsTrueBiased = Scope->TrueBiasedSelects.count(
SI);
1665 bool IsFalseBiased = Scope->FalseBiasedSelects.count(
SI);
1666 if (!(IsTrueBiased || IsFalseBiased))
1672 assert((
I->getParent() == PreEntryBlock ||
1673 !Scope->contains(
I)) &&
1674 "Must have been hoisted to PreEntryBlock or outside the scope");
1680void CHR::transformScopes(CHRScope *Scope, DenseSet<PHINode *> &TrivialPHIs) {
1683 assert(
Scope->RegInfos.size() >= 1 &&
"Should have at least one Region");
1690 for (
const RegInfo &RI :
Scope->CHRRegions)
1691 for (SelectInst *SI : RI.Selects)
1692 if (!
Scope->contains(SI))
1695 for (RegInfo &RI :
Scope->RegInfos) {
1697 unsigned Duplication = getRegionDuplicationCount(R);
1702 <<
" for this region");
1704 return OptimizationRemarkMissed(
DEBUG_TYPE,
"DupThresholdReached",
1705 R->getEntry()->getTerminator())
1706 <<
"Reached the duplication threshold for the region";
1711 for (RegInfo &RI :
Scope->RegInfos) {
1712 DuplicationCount[RI.R]++;
1721 SmallVector<AllocaInst *> StaticAllocas;
1722 for (Instruction &
I : *EntryBlock) {
1724 if (AI->isStaticAlloca())
1736 CHR_DEBUG(
dbgs() <<
"Splitting entry block " << EntryBlock->getName()
1737 <<
" at " << *
Scope->BranchInsertPoint <<
"\n");
1741 "NewEntryBlock's only pred must be EntryBlock");
1746 for (AllocaInst *AI : StaticAllocas)
1747 AI->moveBefore(EntryBlock->begin());
1763 cloneScopeBlocks(Scope, PreEntryBlock, ExitBlock, LastRegion, VMap);
1767 CondBrInst *MergedBr =
1768 createMergedBranch(PreEntryBlock, EntryBlock, NewEntryBlock, VMap);
1783 fixupBranchesAndSelects(Scope, PreEntryBlock, MergedBr,
1784 ProfileCount.value_or(0));
1790void CHR::cloneScopeBlocks(CHRScope *Scope,
1791 BasicBlock *PreEntryBlock,
1792 BasicBlock *ExitBlock,
1800 SmallVector<BasicBlock*, 8> NewBlocks;
1801 for (RegInfo &RI :
Scope->RegInfos)
1802 for (BasicBlock *BB : RI.R->blocks()) {
1804 assert(BB != PreEntryBlock &&
"Don't copy the preetntry block");
1812 PN.removeIncomingValueIf([&](
unsigned Idx) {
1820 F.splice(ExitBlock->
getIterator(), &
F, NewBlocks[0]->getIterator(),
1824 for (BasicBlock *NewBB : NewBlocks)
1825 for (Instruction &
I : *NewBB)
1833 for (PHINode &PN : ExitBlock->
phis())
1834 for (
unsigned I = 0,
NumOps = PN.getNumIncomingValues();
I <
NumOps;
1838 Value *
V = PN.getIncomingValue(
I);
1839 auto It = VMap.
find(
V);
1849CondBrInst *CHR::createMergedBranch(BasicBlock *PreEntryBlock,
1850 BasicBlock *EntryBlock,
1851 BasicBlock *NewEntryBlock,
1855 "SplitBlock did not work correctly!");
1857 "NewEntryBlock's only pred must be EntryBlock");
1859 "NewEntryBlock must have been copied");
1869 "NewEntryBlock's only pred must be EntryBlock");
1875void CHR::fixupBranchesAndSelects(CHRScope *Scope, BasicBlock *PreEntryBlock,
1876 CondBrInst *MergedBR,
uint64_t ProfileCount) {
1878 BranchProbability CHRBranchBias(1, 1);
1881 for (RegInfo &RI :
Scope->CHRRegions) {
1884 fixupBranch(R, Scope, IRB, MergedCondition, CHRBranchBias);
1887 for (SelectInst *SI : RI.Selects) {
1888 fixupSelect(SI, Scope, IRB, MergedCondition, CHRBranchBias);
1892 assert(NumCHRedBranches > 0);
1893 Stats.NumBranchesDelta += NumCHRedBranches - 1;
1894 Stats.WeightedNumBranchesDelta += (NumCHRedBranches - 1) * ProfileCount;
1900 <<
"Merged " <<
ore::NV(
"NumCHRedBranches", NumCHRedBranches)
1901 <<
" branches or selects";
1904 uint32_t Weights[] = {
1905 static_cast<uint32_t
>(CHRBranchBias.scale(1000)),
1906 static_cast<uint32_t
>(CHRBranchBias.getCompl().
scale(1000)),
1909 CHR_DEBUG(
dbgs() <<
"CHR branch bias " << Weights[0] <<
":" << Weights[1]
1915void CHR::fixupBranch(Region *R, CHRScope *Scope,
1917 Value *&MergedCondition,
1918 BranchProbability &CHRBranchBias) {
1919 bool IsTrueBiased =
Scope->TrueBiasedRegions.count(R);
1920 assert((IsTrueBiased ||
Scope->FalseBiasedRegions.count(R)) &&
1921 "Must be truthy or falsy");
1923 assert(BranchBiasMap.contains(R) &&
"Must be in the bias map");
1924 BranchProbability Bias = BranchBiasMap[
R];
1927 if (CHRBranchBias > Bias)
1928 CHRBranchBias = Bias;
1932 assert(RegionExitBlock &&
"Null ExitBlock");
1933 assert((IfThen == RegionExitBlock || IfElse == RegionExitBlock) &&
1934 IfThen != IfElse &&
"Invariant from findScopes");
1935 if (IfThen == RegionExitBlock) {
1941 <<
" IfElse " << IfElse->
getName() <<
"\n");
1943 BasicBlock *HotTarget = IsTrueBiased ? IfThen : IfElse;
1944 bool ConditionTrue = HotTarget == BI->getSuccessor(0);
1945 addToMergedCondition(ConditionTrue,
Cond, BI, Scope, IRB,
1948 assert(ConditionTrue == (HotTarget == BI->getSuccessor(0)) &&
1949 "The successor shouldn't change");
1950 Value *NewCondition = ConditionTrue ?
1953 BI->setCondition(NewCondition);
1958void CHR::fixupSelect(SelectInst *SI, CHRScope *Scope,
1960 Value *&MergedCondition,
1961 BranchProbability &CHRBranchBias) {
1962 bool IsTrueBiased =
Scope->TrueBiasedSelects.count(SI);
1964 Scope->FalseBiasedSelects.count(SI)) &&
"Must be biased");
1965 assert(SelectBiasMap.contains(SI) &&
"Must be in the bias map");
1966 BranchProbability Bias = SelectBiasMap[
SI];
1969 if (CHRBranchBias > Bias)
1970 CHRBranchBias = Bias;
1972 addToMergedCondition(IsTrueBiased,
Cond, SI, Scope, IRB,
1974 Value *NewCondition = IsTrueBiased ?
1977 SI->setCondition(NewCondition);
1982void CHR::addToMergedCondition(
bool IsTrueBiased,
Value *
Cond,
1983 Instruction *BranchOrSelect, CHRScope *Scope,
1985 if (!IsTrueBiased) {
2005void CHR::transformScopes(SmallVectorImpl<CHRScope *> &CHRScopes) {
2007 DenseSet<PHINode *> TrivialPHIs;
2008 for (CHRScope *Scope : CHRScopes) {
2009 transformScopes(Scope, TrivialPHIs);
2011 std::ostringstream oss;
2012 oss <<
" after transformScopes " <<
I++;
2013 dumpIR(
F, oss.str().c_str(),
nullptr));
2019 const char *Label) {
2020 dbgs() << Label <<
" " << Scopes.size() <<
"\n";
2021 for (CHRScope *Scope : Scopes) {
2022 dbgs() << *Scope <<
"\n";
2027 if (!
shouldApply(Opts, CHRModules, CHRFunctions,
F, PSI))
2035 dbgs() <<
"RegionInfo:\n";
2041 findScopes(AllScopes);
2050 splitScopes(AllScopes, SplitScopes);
2055 classifyBiasedScopes(SplitScopes);
2061 filterScopes(SplitScopes, FilteredScopes);
2066 setCHRRegions(FilteredScopes, SetScopes);
2073 sortScopes(SetScopes, SortedScopes);
2077 dbgs() <<
"RegionInfo:\n";
2081 if (!SortedScopes.
empty()) {
2082 transformScopes(SortedScopes);
2090 return OptimizationRemark(
DEBUG_TYPE,
"Stats", &
F)
2092 <<
"Reduced the number of branches in hot paths by "
2095 <<
ore::NV(
"WeightedNumBranchesDelta",
Stats.WeightedNumBranchesDelta)
2096 <<
" (weighted by PGO count)";
2109 if (!PPSI || !PPSI->hasProfileSummary())
2117 if (&Opts != ParsedOpts &&
2118 (!Opts.chr_module_list.empty() || !Opts.chr_function_list.empty())) {
2120 CHRFunctions.clear();
2125 CHR(Opts, CHRModules, CHRFunctions,
F, BFI, DT, PSI, RI, ORE).run();
Ops append({Chain, DAG.getConstant(SVEStores[NumParts - 2], DL, MVT::i32)})
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 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 void parseCHRFilterFiles(const InstrumentationOptions &Opts, StringSet<> &CHRModules, StringSet<> &CHRFunctions)
static bool isHoistable(Instruction *I, DominatorTree &DT)
static bool shouldSplit(Instruction *InsertPoint, DenseSet< Value * > &PrevConditionValues, DenseSet< Value * > &ConditionValues, DominatorTree &DT, DenseSet< Instruction * > &Unhoistables)
static bool hasAtLeastTwoBiasedBranches(const InstrumentationOptions &Opts, CHRScope *Scope)
static bool checkBias(const InstrumentationOptions &Opts, K *Key, BranchProbability TrueProb, BranchProbability FalseProb, S &TrueSet, S &FalseSet, M &BiasMap)
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 BranchProbability getCHRBiasThreshold(const InstrumentationOptions &Opts)
static bool checkBiasedSelect(const InstrumentationOptions &Opts, SelectInst *SI, Region *R, DenseSet< SelectInst * > &TrueBiasedSelectsGlobal, DenseSet< SelectInst * > &FalseBiasedSelectsGlobal, DenseMap< SelectInst *, BranchProbability > &SelectBiasMap)
static bool shouldApply(const InstrumentationOptions &Opts, const StringSet<> &CHRModules, const StringSet<> &CHRFunctions, 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 void assertBranchOrSelectConditionHoisted(CHRScope *Scope, BasicBlock *PreEntryBlock)
static bool checkBiasedBranch(const InstrumentationOptions &Opts, CondBrInst *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)
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.
SmallVector< MachineOperand, 4 > Cond
Func getContext().diagnose(DiagnosticInfoUnsupported(Func
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
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; assumes that the block is well-formed.
Analysis pass which computes BlockFrequencyInfo.
LLVM_ABI std::optional< uint64_t > getBlockProfileCount(const BasicBlock *BB) const
Returns the estimated profile count of BB.
static LLVM_ABI BranchProbability getBranchProbability(uint64_t Numerator, uint64_t Denominator)
void setPredicate(Predicate P)
Set the predicate for this instruction to the specified value.
Predicate getInversePredicate() const
For example, EQ -> NE, UGT -> ULE, SLT -> SGE, OEQ -> UNE, UGT -> OLE, OLT -> UGE,...
Predicate getPredicate() const
Return the predicate for this instruction.
Conditional Branch instruction.
static CondBrInst * Create(Value *Cond, BasicBlock *IfTrue, BasicBlock *IfFalse, InsertPosition InsertBefore=nullptr)
void setCondition(Value *V)
BasicBlock * getSuccessor(unsigned i) const
static LLVM_ABI ConstantInt * getTrue(LLVMContext &Context)
LLVM_ABI 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.
iterator_range< user_iterator > users()
LLVM_ABI InstListType::iterator insertInto(BasicBlock *ParentBB, InstListType::iterator It)
Inserts an unlinked instruction into ParentBB at position It and returns the iterator of the inserted...
static ErrorOr< std::unique_ptr< MemoryBuffer > > getFile(const Twine &Filename, bool IsText=false, bool RequiresNullTerminator=true, bool IsVolatile=false, std::optional< Align > Alignment=std::nullopt)
Open the specified file as a MemoryBuffer, returning a new MemoryBuffer if successful,...
void addIncoming(Value *V, BasicBlock *BB)
Add an incoming value to the end of the PHI list.
static PHINode * Create(Type *Ty, unsigned NumReservedValues, const Twine &NameStr="", InsertPosition InsertBefore=nullptr)
Constructors - NumReservedValues is a hint for the number of incoming edges that this phi node will h...
A set of analyses that are preserved following a run of a transformation pass.
static PreservedAnalyses none()
Convenience factory function for the empty preserved set.
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
An analysis pass based on the new PM to deliver ProfileSummaryInfo.
Analysis providing profile information.
bool isFunctionEntryHot(const FuncT *F) const
Returns true if F has hot function entry.
BlockT * getExit() const
Get the exit BasicBlock of the Region.
void replaceEntryRecursive(BlockT *NewEntry)
Recursively replace the entry basic block of the region.
bool contains(const BlockT *BB) const
Check if the region contains a BasicBlock.
BlockT * getEntry() const
Get the entry BasicBlock of the Region.
Analysis pass that exposes the RegionInfo for a function.
This class represents the LLVM 'select' instruction.
bool contains(const_arg_type key) const
Check if the SetVector contains the given key.
bool insert(const value_type &X)
Insert a new element into the SetVector.
A SetVector that performs no allocations if smaller than a certain size.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
iterator erase(const_iterator CI)
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
size_type count(StringRef Key) const
count - Return 1 if the element is in the map, 0 otherwise.
Represent a constant reference to a string, i.e.
std::pair< StringRef, StringRef > split(char Separator) const
Split into two substrings around the first occurrence of a separator character.
StringSet - A wrapper for StringMap that provides set-like functionality.
std::pair< typename Base::iterator, bool > insert(StringRef key)
BasicBlock * getSuccessor(unsigned i=0) const
void dropAllReferences()
Drop all references to operands.
iterator find(const KeyT &Val)
LLVM Value Representation.
LLVM_ABI StringRef getName() const
Return a constant reference to the value's name.
std::pair< iterator, bool > insert(const ValueT &V)
bool contains(const_arg_type_t< ValueT > V) const
Check if the set contains the given element.
void insert_range(Range &&R)
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.
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
friend class Instruction
Iterator for Instructions in a `BasicBlock.
This is an optimization pass for GlobalISel generic memory operations.
const InstrumentationOptions & getInstrumentationOptions(const LLVMContext &C)
void stable_sort(R &&Range)
Printable print(const GCNRegPressure &RP, const GCNSubtarget *ST=nullptr, unsigned DynamicVGPRBlockSize=0)
LLVM_ABI BasicBlock * CloneBasicBlock(const BasicBlock *BB, ValueToValueMapTy &VMap, const Twine &NameSuffix="", Function *F=nullptr, ClonedCodeInfo *CodeInfo=nullptr, bool MapAtoms=true)
Return a copy of the specified basic block, but without embedding the block into a particular functio...
LLVM_ABI void setExplicitlyUnknownBranchWeightsIfProfiled(Instruction &I, StringRef PassName, const Function *F=nullptr)
Like setExplicitlyUnknownBranchWeights(...), but only sets unknown branch weights in the new instruct...
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
OuterAnalysisManagerProxy< ModuleAnalysisManager, Function > ModuleAnalysisManagerFunctionProxy
Provide the ModuleAnalysisManager to Function proxy.
constexpr from_range_t from_range
void append_range(Container &C, Range &&R)
Wrapper function to append range R to container C.
iterator_range< early_inc_iterator_impl< detail::IterOfRange< RangeT > > > make_early_inc_range(RangeT &&Range)
Make a range that does early increment to allow mutation of the underlying range without disrupting i...
auto pred_size(const MachineBasicBlock *BB)
LLVM_ABI bool isSafeToSpeculativelyExecute(const Instruction *I, const Instruction *CtxI=nullptr, AssumptionCache *AC=nullptr, const DominatorTree *DT=nullptr, const TargetLibraryInfo *TLI=nullptr, bool UseVariableInfo=true, bool IgnoreUBImplyingAttrs=true)
Return true if the instruction does not have any effects besides calculating the result and does not ...
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Value
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.
IRBuilder(LLVMContext &, FolderTy, InserterTy) -> IRBuilder< FolderTy, InserterTy >
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.
@ Sub
Subtraction of integers.
LLVM_ABI BasicBlock * SplitBlock(BasicBlock *Old, BasicBlock::iterator SplitPt, DominatorTree *DT, LoopInfo *LI=nullptr, MemorySSAUpdater *MSSAU=nullptr, const Twine &BBName="")
Split the specified block at the specified instruction.
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Count
void RemapInstruction(Instruction *I, ValueToValueMapTy &VM, RemapFlags Flags=RF_None, ValueMapTypeRemapper *TypeMapper=nullptr, ValueMaterializer *Materializer=nullptr, const MetadataPredicate *IdentityMD=nullptr)
Convert the instruction operands from referencing the current values into those specified by VM.
DWARFExpression::Operation Op
raw_ostream & operator<<(raw_ostream &OS, const APFixedPoint &FX)
LLVM_ABI bool isGuaranteedNotToBeUndefOrPoison(const Value *V, AssumptionCache *AC=nullptr, const Instruction *CtxI=nullptr, const DominatorTree *DT=nullptr, unsigned Depth=0)
Return true if this function can prove that V does not have undef bits and is never poison.
ArrayRef(const T &OneElt) -> ArrayRef< T >
OutputIt copy(R &&Range, OutputIt Out)
ValueMap< const Value *, WeakTrackingVH > ValueToValueMapTy
LLVM_ABI bool extractBranchWeights(const MDNode *ProfileData, SmallVectorImpl< uint32_t > &Weights)
Extract branch weights from MD_prof metadata.
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
auto find_if(R &&Range, UnaryPredicate P)
Provide wrappers to std::find_if which take ranges instead of having to pass begin/end explicitly.
void erase_if(Container &C, UnaryPredicate P)
Provide a container algorithm similar to C++ Library Fundamentals v2's erase_if which is equivalent t...
auto predecessors(const MachineBasicBlock *BB)
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Next
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.
std::conditional_t< IsConst, const ValueT &, ValueT & > second