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) {
811 if (Selects.
size() > 0) {
812 auto AddSelects = [&](RegInfo &RI) {
813 for (
auto *SI : Selects)
815 FalseBiasedSelectsGlobal, SelectBiasMap))
816 RI.Selects.push_back(SI);
819 return OptimizationRemarkMissed(
DEBUG_TYPE,
"SelectNotBiased", SI)
820 <<
"Select not biased";
827 Result =
new CHRScope(RI);
828 Scopes.insert(Result);
830 CHR_DEBUG(
dbgs() <<
"Found select(s) in a region with a branch\n");
831 AddSelects(
Result->RegInfos[0]);
837 checkScopeHoistable(Result);
864void CHR::checkScopeHoistable(CHRScope *Scope) {
865 RegInfo &RI =
Scope->RegInfos[0];
871 if (RI.HasBranch || !Selects.
empty()) {
880 for (
auto it = Selects.
begin(); it != Selects.
end(); ) {
881 SelectInst *
SI = *it;
882 if (SI == InsertPoint) {
886 DenseMap<Instruction *, bool> Visited;
888 DT, Unhoistables,
nullptr, Visited);
893 "DropUnhoistableSelect", SI)
894 <<
"Dropped unhoistable select";
896 it = Selects.
erase(it);
899 Unhoistables.erase(SI);
906 if (RI.HasBranch && InsertPoint != Branch) {
907 DenseMap<Instruction *, bool> Visited;
909 DT, Unhoistables,
nullptr, Visited);
914 assert(InsertPoint != Branch &&
"Branch must not be the hoist point");
917 for (SelectInst *SI : Selects) {
918 dbgs() <<
"SI " << *
SI <<
"\n";
920 for (SelectInst *SI : Selects) {
923 "DropSelectUnhoistableBranch", SI)
924 <<
"Dropped select due to unhoistable branch";
928 return SI->getParent() == EntryBB;
930 Unhoistables.clear();
938 "Branch can't be already above the hoist point");
939 DenseMap<Instruction *, bool> Visited;
941 DT, Unhoistables,
nullptr, Visited) &&
942 "checkHoistValue for branch");
944 for (
auto *SI : Selects) {
946 "SI can't be already above the hoist point");
947 DenseMap<Instruction *, bool> Visited;
949 Unhoistables,
nullptr, Visited) &&
950 "checkHoistValue for selects");
956 for (
auto *SI : Selects) {
964CHRScope * CHR::findScopes(Region *R, Region *NextRegion, Region *ParentRegion,
965 SmallVectorImpl<CHRScope *> &Scopes) {
967 CHRScope *
Result = findScope(R);
969 CHRScope *ConsecutiveSubscope =
nullptr;
971 for (
auto It =
R->begin(); It !=
R->end(); ++It) {
972 const std::unique_ptr<Region> &SubR = *It;
973 auto NextIt = std::next(It);
974 Region *NextSubR = NextIt !=
R->end() ? NextIt->get() :
nullptr;
975 CHR_DEBUG(
dbgs() <<
"Looking at subregion " << SubR.get()->getNameStr()
977 CHRScope *SubCHRScope = findScopes(SubR.get(), NextSubR, R, Scopes);
979 CHR_DEBUG(
dbgs() <<
"Subregion Scope " << *SubCHRScope <<
"\n");
984 if (!ConsecutiveSubscope)
985 ConsecutiveSubscope = SubCHRScope;
986 else if (!ConsecutiveSubscope->appendable(SubCHRScope)) {
987 Subscopes.
push_back(ConsecutiveSubscope);
988 ConsecutiveSubscope = SubCHRScope;
990 ConsecutiveSubscope->append(SubCHRScope);
992 if (ConsecutiveSubscope) {
993 Subscopes.
push_back(ConsecutiveSubscope);
995 ConsecutiveSubscope =
nullptr;
998 if (ConsecutiveSubscope) {
999 Subscopes.
push_back(ConsecutiveSubscope);
1001 for (CHRScope *
Sub : Subscopes) {
1017 ConditionValues.
insert(BI->getCondition());
1020 ConditionValues.
insert(
SI->getCondition());
1022 return ConditionValues;
1040 for (
Value *V : PrevConditionValues) {
1041 dbgs() << *V <<
", ";
1043 dbgs() <<
" ConditionValues ";
1044 for (
Value *V : ConditionValues) {
1045 dbgs() << *V <<
", ";
1049 for (
Value *V : ConditionValues) {
1052 CHR_DEBUG(
dbgs() <<
"Split. checkHoistValue false " << *V <<
"\n");
1059 if (!PrevConditionValues.
empty() && !ConditionValues.
empty()) {
1061 std::set<Value *> PrevBases, Bases;
1063 for (
Value *V : PrevConditionValues) {
1064 const std::set<Value *> &BaseValues =
getBaseValues(V, DT, Visited);
1065 PrevBases.insert(BaseValues.begin(), BaseValues.end());
1067 for (
Value *V : ConditionValues) {
1068 const std::set<Value *> &BaseValues =
getBaseValues(V, DT, Visited);
1069 Bases.insert(BaseValues.begin(), BaseValues.end());
1072 dbgs() <<
"PrevBases ";
1073 for (
Value *V : PrevBases) {
1074 dbgs() << *V <<
", ";
1076 dbgs() <<
" Bases ";
1077 for (
Value *V : Bases) {
1078 dbgs() << *V <<
", ";
1081 std::vector<Value *> Intersection;
1082 std::set_intersection(PrevBases.begin(), PrevBases.end(), Bases.begin(),
1083 Bases.end(), std::back_inserter(Intersection));
1084 if (Intersection.empty()) {
1096 for (
RegInfo &RI : Scope->RegInfos)
1098 for (CHRScope *
Sub : Scope->Subs)
1102void CHR::splitScopes(SmallVectorImpl<CHRScope *> &Input,
1103 SmallVectorImpl<CHRScope *> &Output) {
1104 for (CHRScope *Scope : Input) {
1106 "BranchInsertPoint must not be set");
1107 DenseSet<Instruction *> Unhoistables;
1109 splitScope(Scope,
nullptr,
nullptr,
nullptr, Output, Unhoistables);
1112 for (CHRScope *Scope : Output) {
1113 assert(
Scope->BranchInsertPoint &&
"BranchInsertPoint must be set");
1121 DenseSet<Value *> *OuterConditionValues,
1122 Instruction *OuterInsertPoint,
1123 SmallVectorImpl<CHRScope *> &Output,
1124 DenseSet<Instruction *> &Unhoistables) {
1126 assert(OuterConditionValues &&
"Null OuterConditionValues");
1127 assert(OuterInsertPoint &&
"Null OuterInsertPoint");
1129 bool PrevSplitFromOuter =
true;
1130 DenseSet<Value *> PrevConditionValues;
1135 SmallVector<Instruction *, 8> SplitsInsertPoints;
1137 for (RegInfo &RI : RegInfos) {
1141 dbgs() <<
"ConditionValues ";
1142 for (
Value *V : ConditionValues) {
1143 dbgs() << *
V <<
", ";
1146 if (RI.R == RegInfos[0].R) {
1151 << RI.R->getNameStr() <<
"\n");
1152 if (
shouldSplit(OuterInsertPoint, *OuterConditionValues,
1153 ConditionValues, DT, Unhoistables)) {
1154 PrevConditionValues = ConditionValues;
1155 PrevInsertPoint = InsertPoint;
1158 "SplitScopeFromOuter",
1159 RI.R->getEntry()->getTerminator())
1160 <<
"Split scope from outer due to unhoistable branch/select "
1161 <<
"and/or lack of common condition values";
1166 PrevSplitFromOuter =
false;
1167 PrevConditionValues = *OuterConditionValues;
1169 PrevInsertPoint = OuterInsertPoint;
1173 PrevConditionValues = ConditionValues;
1174 PrevInsertPoint = InsertPoint;
1178 << RI.R->getNameStr() <<
"\n");
1179 if (
shouldSplit(PrevInsertPoint, PrevConditionValues, ConditionValues,
1180 DT, Unhoistables)) {
1184 SplitsSplitFromOuter.
push_back(PrevSplitFromOuter);
1185 SplitsConditionValues.
push_back(PrevConditionValues);
1186 SplitsInsertPoints.
push_back(PrevInsertPoint);
1188 PrevConditionValues = ConditionValues;
1189 PrevInsertPoint = InsertPoint;
1190 PrevSplitFromOuter =
true;
1193 "SplitScopeFromPrev",
1194 RI.R->getEntry()->getTerminator())
1195 <<
"Split scope from previous due to unhoistable branch/select "
1196 <<
"and/or lack of common condition values";
1205 SplitsSplitFromOuter.
push_back(PrevSplitFromOuter);
1206 SplitsConditionValues.
push_back(PrevConditionValues);
1207 assert(PrevInsertPoint &&
"Null PrevInsertPoint");
1208 SplitsInsertPoints.
push_back(PrevInsertPoint);
1210 Splits.
size() == SplitsSplitFromOuter.
size() &&
1211 Splits.
size() == SplitsInsertPoints.
size() &&
"Mismatching sizes");
1212 for (
size_t I = 0;
I < Splits.
size(); ++
I) {
1213 CHRScope *
Split = Splits[
I];
1214 DenseSet<Value *> &SplitConditionValues = SplitsConditionValues[
I];
1217 DenseSet<Instruction *> SplitUnhoistables;
1219 for (CHRScope *
Sub :
Split->Subs) {
1221 Sub, Split, &SplitConditionValues, SplitInsertPoint, Output,
1225 Split->Subs = NewSubs;
1228 for (
size_t I = 0;
I < Splits.
size(); ++
I) {
1229 CHRScope *
Split = Splits[
I];
1230 if (SplitsSplitFromOuter[
I]) {
1233 Split->BranchInsertPoint = SplitsInsertPoints[
I];
1234 CHR_DEBUG(
dbgs() <<
"BranchInsertPoint " << *SplitsInsertPoints[
I]
1243 "If no outer (top-level), must return no nested ones");
1247void CHR::classifyBiasedScopes(SmallVectorImpl<CHRScope *> &Scopes) {
1248 for (CHRScope *Scope : Scopes) {
1249 assert(
Scope->TrueBiasedRegions.empty() &&
Scope->FalseBiasedRegions.empty() &&
"Empty");
1250 classifyBiasedScopes(Scope, Scope);
1252 dbgs() <<
"classifyBiasedScopes " << *Scope <<
"\n";
1253 dbgs() <<
"TrueBiasedRegions ";
1254 for (Region *R :
Scope->TrueBiasedRegions) {
1255 dbgs() <<
R->getNameStr() <<
", ";
1258 dbgs() <<
"FalseBiasedRegions ";
1259 for (Region *R :
Scope->FalseBiasedRegions) {
1260 dbgs() <<
R->getNameStr() <<
", ";
1263 dbgs() <<
"TrueBiasedSelects ";
1264 for (SelectInst *SI :
Scope->TrueBiasedSelects) {
1268 dbgs() <<
"FalseBiasedSelects ";
1269 for (SelectInst *SI :
Scope->FalseBiasedSelects) {
1276void CHR::classifyBiasedScopes(CHRScope *Scope, CHRScope *OutermostScope) {
1277 for (RegInfo &RI :
Scope->RegInfos) {
1280 if (TrueBiasedRegionsGlobal.contains(R))
1281 OutermostScope->TrueBiasedRegions.insert(R);
1282 else if (FalseBiasedRegionsGlobal.contains(R))
1283 OutermostScope->FalseBiasedRegions.insert(R);
1287 for (SelectInst *SI : RI.Selects) {
1288 if (TrueBiasedSelectsGlobal.contains(SI))
1289 OutermostScope->TrueBiasedSelects.insert(SI);
1290 else if (FalseBiasedSelectsGlobal.contains(SI))
1291 OutermostScope->FalseBiasedSelects.insert(SI);
1296 for (CHRScope *
Sub :
Scope->Subs) {
1297 classifyBiasedScopes(
Sub, OutermostScope);
1303 unsigned NumBiased = Scope->TrueBiasedRegions.size() +
1304 Scope->FalseBiasedRegions.size() +
1305 Scope->TrueBiasedSelects.size() +
1306 Scope->FalseBiasedSelects.size();
1307 return NumBiased >= Opts.chr_merge_threshold;
1310void CHR::filterScopes(SmallVectorImpl<CHRScope *> &Input,
1311 SmallVectorImpl<CHRScope *> &Output) {
1312 for (CHRScope *Scope : Input) {
1315 CHR_DEBUG(
dbgs() <<
"Filtered out by biased branches truthy-regions "
1316 <<
Scope->TrueBiasedRegions.size()
1317 <<
" falsy-regions " <<
Scope->FalseBiasedRegions.size()
1318 <<
" true-selects " <<
Scope->TrueBiasedSelects.size()
1319 <<
" false-selects " <<
Scope->FalseBiasedSelects.size() <<
"\n");
1321 return OptimizationRemarkMissed(
1322 DEBUG_TYPE,
"DropScopeWithOneBranchOrSelect",
1323 Scope->RegInfos[0].R->getEntry()->getTerminator())
1324 <<
"Drop scope with < "
1325 <<
ore::NV(
"CHRMergeThreshold", Opts.chr_merge_threshold)
1326 <<
" biased branch(es) or select(s)";
1334void CHR::setCHRRegions(SmallVectorImpl<CHRScope *> &Input,
1335 SmallVectorImpl<CHRScope *> &Output) {
1336 for (CHRScope *Scope : Input) {
1339 setCHRRegions(Scope, Scope);
1342 dbgs() <<
"setCHRRegions HoistStopMap " << *Scope <<
"\n";
1343 for (
auto pair :
Scope->HoistStopMap) {
1344 Region *R = pair.first;
1345 dbgs() <<
"Region " << R->getNameStr() <<
"\n";
1346 for (Instruction *I : pair.second) {
1347 dbgs() <<
"HoistStop " << *I <<
"\n";
1350 dbgs() <<
"CHRRegions" <<
"\n";
1351 for (RegInfo &RI :
Scope->CHRRegions) {
1352 dbgs() << RI.R->getNameStr() <<
"\n";
1357void CHR::setCHRRegions(CHRScope *Scope, CHRScope *OutermostScope) {
1358 DenseSet<Instruction *> Unhoistables;
1362 for (RegInfo &RI :
Scope->RegInfos)
1364 Instruction *InsertPoint = OutermostScope->BranchInsertPoint;
1365 for (RegInfo &RI :
Scope->RegInfos) {
1367 DenseSet<Instruction *> HoistStops;
1368 bool IsHoisted =
false;
1370 assert((OutermostScope->TrueBiasedRegions.contains(R) ||
1371 OutermostScope->FalseBiasedRegions.contains(R)) &&
1372 "Must be truthy or falsy");
1375 DenseMap<Instruction *, bool> Visited;
1376 bool IsHoistable =
checkHoistValue(BI->getCondition(), InsertPoint, DT,
1377 Unhoistables, &HoistStops, Visited);
1378 assert(IsHoistable &&
"Must be hoistable");
1379 (void)(IsHoistable);
1382 for (SelectInst *SI : RI.Selects) {
1383 assert((OutermostScope->TrueBiasedSelects.contains(SI) ||
1384 OutermostScope->FalseBiasedSelects.contains(SI)) &&
1385 "Must be true or false biased");
1387 DenseMap<Instruction *, bool> Visited;
1389 Unhoistables, &HoistStops, Visited);
1390 assert(IsHoistable &&
"Must be hoistable");
1391 (void)(IsHoistable);
1395 OutermostScope->CHRRegions.push_back(RI);
1396 OutermostScope->HoistStopMap[
R] = HoistStops;
1400 setCHRRegions(
Sub, OutermostScope);
1404 return Scope1->RegInfos[0].R->getDepth() < Scope2->RegInfos[0].R->getDepth();
1407void CHR::sortScopes(SmallVectorImpl<CHRScope *> &Input,
1408 SmallVectorImpl<CHRScope *> &Output) {
1417 HoistStopMapTy &HoistStopMap,
1421 auto IT = HoistStopMap.find(R);
1422 assert(
IT != HoistStopMap.end() &&
"Region must be in hoist stop map");
1425 if (
I == HoistPoint)
1430 if (TrivialPHIs.
count(PN))
1440 assert(DT.
getNode(
I->getParent()) &&
"DT must contain I's block");
1442 "DT must contain HoistPoint block");
1454 hoistValue(
Op, HoistPoint, R, HoistStopMap, HoistedSet, TrivialPHIs, DT);
1468 for (
const RegInfo &RI : Scope->CHRRegions) {
1470 bool IsTrueBiased = Scope->TrueBiasedRegions.count(R);
1471 bool IsFalseBiased = Scope->FalseBiasedRegions.count(R);
1472 if (RI.HasBranch && (IsTrueBiased || IsFalseBiased)) {
1474 hoistValue(BI->getCondition(), HoistPoint, R, Scope->HoistStopMap,
1475 HoistedSet, TrivialPHIs, DT);
1478 bool IsTrueBiased = Scope->TrueBiasedSelects.count(
SI);
1479 bool IsFalseBiased = Scope->FalseBiasedSelects.count(
SI);
1480 if (!(IsTrueBiased || IsFalseBiased))
1482 hoistValue(
SI->getCondition(), HoistPoint, R, Scope->HoistStopMap,
1483 HoistedSet, TrivialPHIs, DT);
1494 if (U == ExcludedUser)
1503 if (U == ExcludedUser)
1506 BI->swapSuccessors();
1517 SI->swapProfMetadata();
1518 if (Scope->TrueBiasedSelects.count(
SI)) {
1519 assert(!Scope->FalseBiasedSelects.contains(
SI) &&
1520 "Must not be already in");
1521 Scope->FalseBiasedSelects.insert(
SI);
1522 }
else if (Scope->FalseBiasedSelects.count(
SI)) {
1523 assert(!Scope->TrueBiasedSelects.contains(
SI) &&
1524 "Must not be already in");
1525 Scope->TrueBiasedSelects.insert(
SI);
1542 for (
RegInfo &RI : Scope->RegInfos) {
1545 BlocksInScope.
insert(BB);
1549 dbgs() <<
"Inserting redundant phis\n";
1551 dbgs() <<
"BlockInScope " << BB->getName() <<
"\n";
1556 for (
User *U :
I.users()) {
1558 if (!BlocksInScope.
contains(UI->getParent()) &&
1562 CHR_DEBUG(
dbgs() <<
"Used outside scope by user " << *UI <<
"\n");
1563 Users.push_back(UI);
1564 }
else if (UI->getParent() == EntryBlock &&
isa<PHINode>(UI)) {
1569 <<
"Used at entry block (for a back edge) by a phi user "
1571 Users.push_back(UI);
1575 if (
Users.size() > 0) {
1586 bool FoundLifetimeAnnotation =
false;
1591 if (UI->isLifetimeStartOrEnd()) {
1592 UI->eraseFromParent();
1593 FoundLifetimeAnnotation =
true;
1596 for (
unsigned J = 0,
NumOps = UI->getNumOperands(); J <
NumOps; ++J) {
1597 if (UI->getOperand(J) == &
I) {
1598 UI->setOperand(J, PN);
1604 if (FoundLifetimeAnnotation) {
1607 if (UI->isLifetimeStartOrEnd())
1608 UI->eraseFromParent();
1617[[maybe_unused]]
static void
1620 auto HasBiasedBranchOrSelect = [](
RegInfo &RI, CHRScope *Scope) {
1621 if (Scope->TrueBiasedRegions.count(RI.R) ||
1622 Scope->FalseBiasedRegions.count(RI.R))
1625 if (Scope->TrueBiasedSelects.count(
SI) ||
1626 Scope->FalseBiasedSelects.count(
SI))
1630 for (
RegInfo &RI : Scope->CHRRegions) {
1631 assert(HasBiasedBranchOrSelect(RI, Scope) &&
1632 "Must have biased branch or select");
1639[[maybe_unused]]
static void
1643 for (
RegInfo &RI : Scope->CHRRegions) {
1645 bool IsTrueBiased = Scope->TrueBiasedRegions.count(R);
1646 bool IsFalseBiased = Scope->FalseBiasedRegions.count(R);
1647 if (RI.HasBranch && (IsTrueBiased || IsFalseBiased)) {
1649 Value *V = BI->getCondition();
1653 assert((
I->getParent() == PreEntryBlock ||
1654 !Scope->contains(
I)) &&
1655 "Must have been hoisted to PreEntryBlock or outside the scope");
1659 bool IsTrueBiased = Scope->TrueBiasedSelects.count(
SI);
1660 bool IsFalseBiased = Scope->FalseBiasedSelects.count(
SI);
1661 if (!(IsTrueBiased || IsFalseBiased))
1663 Value *V =
SI->getCondition();
1667 assert((
I->getParent() == PreEntryBlock ||
1668 !Scope->contains(
I)) &&
1669 "Must have been hoisted to PreEntryBlock or outside the scope");
1675void CHR::transformScopes(CHRScope *Scope, DenseSet<PHINode *> &TrivialPHIs) {
1678 assert(
Scope->RegInfos.size() >= 1 &&
"Should have at least one Region");
1680 for (RegInfo &RI :
Scope->RegInfos) {
1682 unsigned Duplication = getRegionDuplicationCount(R);
1687 <<
" for this region");
1689 return OptimizationRemarkMissed(
DEBUG_TYPE,
"DupThresholdReached",
1690 R->getEntry()->getTerminator())
1691 <<
"Reached the duplication threshold for the region";
1696 for (RegInfo &RI :
Scope->RegInfos) {
1697 DuplicationCount[RI.R]++;
1706 SmallVector<AllocaInst *> StaticAllocas;
1707 for (Instruction &
I : *EntryBlock) {
1709 if (AI->isStaticAlloca())
1721 CHR_DEBUG(
dbgs() <<
"Splitting entry block " << EntryBlock->getName()
1722 <<
" at " << *
Scope->BranchInsertPoint <<
"\n");
1726 "NewEntryBlock's only pred must be EntryBlock");
1731 for (AllocaInst *AI : StaticAllocas)
1732 AI->moveBefore(EntryBlock->begin());
1748 cloneScopeBlocks(Scope, PreEntryBlock, ExitBlock, LastRegion, VMap);
1752 CondBrInst *MergedBr =
1753 createMergedBranch(PreEntryBlock, EntryBlock, NewEntryBlock, VMap);
1768 fixupBranchesAndSelects(Scope, PreEntryBlock, MergedBr,
1769 ProfileCount.value_or(0));
1775void CHR::cloneScopeBlocks(CHRScope *Scope,
1776 BasicBlock *PreEntryBlock,
1777 BasicBlock *ExitBlock,
1785 SmallVector<BasicBlock*, 8> NewBlocks;
1786 for (RegInfo &RI :
Scope->RegInfos)
1787 for (BasicBlock *BB : RI.R->blocks()) {
1789 assert(BB != PreEntryBlock &&
"Don't copy the preetntry block");
1797 PN.removeIncomingValueIf([&](
unsigned Idx) {
1805 F.splice(ExitBlock->
getIterator(), &
F, NewBlocks[0]->getIterator(),
1809 for (BasicBlock *NewBB : NewBlocks)
1810 for (Instruction &
I : *NewBB)
1818 for (PHINode &PN : ExitBlock->
phis())
1819 for (
unsigned I = 0,
NumOps = PN.getNumIncomingValues();
I <
NumOps;
1823 Value *
V = PN.getIncomingValue(
I);
1824 auto It = VMap.
find(V);
1825 if (It != VMap.
end())
V = It->second;
1826 assert(VMap.
find(Pred) != VMap.
end() &&
"Pred must have been cloned");
1834CondBrInst *CHR::createMergedBranch(BasicBlock *PreEntryBlock,
1835 BasicBlock *EntryBlock,
1836 BasicBlock *NewEntryBlock,
1840 "SplitBlock did not work correctly!");
1842 "NewEntryBlock's only pred must be EntryBlock");
1844 "NewEntryBlock must have been copied");
1854 "NewEntryBlock's only pred must be EntryBlock");
1860void CHR::fixupBranchesAndSelects(CHRScope *Scope, BasicBlock *PreEntryBlock,
1861 CondBrInst *MergedBR,
uint64_t ProfileCount) {
1863 BranchProbability CHRBranchBias(1, 1);
1866 for (RegInfo &RI :
Scope->CHRRegions) {
1869 fixupBranch(R, Scope, IRB, MergedCondition, CHRBranchBias);
1872 for (SelectInst *SI : RI.Selects) {
1873 fixupSelect(SI, Scope, IRB, MergedCondition, CHRBranchBias);
1877 assert(NumCHRedBranches > 0);
1878 Stats.NumBranchesDelta += NumCHRedBranches - 1;
1879 Stats.WeightedNumBranchesDelta += (NumCHRedBranches - 1) * ProfileCount;
1885 <<
"Merged " <<
ore::NV(
"NumCHRedBranches", NumCHRedBranches)
1886 <<
" branches or selects";
1889 uint32_t Weights[] = {
1890 static_cast<uint32_t
>(CHRBranchBias.scale(1000)),
1891 static_cast<uint32_t
>(CHRBranchBias.getCompl().
scale(1000)),
1894 CHR_DEBUG(
dbgs() <<
"CHR branch bias " << Weights[0] <<
":" << Weights[1]
1900void CHR::fixupBranch(Region *R, CHRScope *Scope,
1902 Value *&MergedCondition,
1903 BranchProbability &CHRBranchBias) {
1904 bool IsTrueBiased =
Scope->TrueBiasedRegions.count(R);
1905 assert((IsTrueBiased ||
Scope->FalseBiasedRegions.count(R)) &&
1906 "Must be truthy or falsy");
1908 assert(BranchBiasMap.contains(R) &&
"Must be in the bias map");
1909 BranchProbability Bias = BranchBiasMap[
R];
1912 if (CHRBranchBias > Bias)
1913 CHRBranchBias = Bias;
1917 assert(RegionExitBlock &&
"Null ExitBlock");
1918 assert((IfThen == RegionExitBlock || IfElse == RegionExitBlock) &&
1919 IfThen != IfElse &&
"Invariant from findScopes");
1920 if (IfThen == RegionExitBlock) {
1926 <<
" IfElse " << IfElse->
getName() <<
"\n");
1928 BasicBlock *HotTarget = IsTrueBiased ? IfThen : IfElse;
1929 bool ConditionTrue = HotTarget == BI->getSuccessor(0);
1930 addToMergedCondition(ConditionTrue,
Cond, BI, Scope, IRB,
1933 assert(ConditionTrue == (HotTarget == BI->getSuccessor(0)) &&
1934 "The successor shouldn't change");
1935 Value *NewCondition = ConditionTrue ?
1938 BI->setCondition(NewCondition);
1943void CHR::fixupSelect(SelectInst *SI, CHRScope *Scope,
1945 Value *&MergedCondition,
1946 BranchProbability &CHRBranchBias) {
1947 bool IsTrueBiased =
Scope->TrueBiasedSelects.count(SI);
1949 Scope->FalseBiasedSelects.count(SI)) &&
"Must be biased");
1950 assert(SelectBiasMap.contains(SI) &&
"Must be in the bias map");
1951 BranchProbability Bias = SelectBiasMap[
SI];
1954 if (CHRBranchBias > Bias)
1955 CHRBranchBias = Bias;
1957 addToMergedCondition(IsTrueBiased,
Cond, SI, Scope, IRB,
1959 Value *NewCondition = IsTrueBiased ?
1962 SI->setCondition(NewCondition);
1967void CHR::addToMergedCondition(
bool IsTrueBiased,
Value *
Cond,
1968 Instruction *BranchOrSelect, CHRScope *Scope,
1970 if (!IsTrueBiased) {
1990void CHR::transformScopes(SmallVectorImpl<CHRScope *> &CHRScopes) {
1992 DenseSet<PHINode *> TrivialPHIs;
1993 for (CHRScope *Scope : CHRScopes) {
1994 transformScopes(Scope, TrivialPHIs);
1996 std::ostringstream oss;
1997 oss <<
" after transformScopes " <<
I++;
1998 dumpIR(
F, oss.str().c_str(),
nullptr));
2004 const char *Label) {
2005 dbgs() << Label <<
" " << Scopes.size() <<
"\n";
2006 for (CHRScope *Scope : Scopes) {
2007 dbgs() << *Scope <<
"\n";
2012 if (!
shouldApply(Opts, CHRModules, CHRFunctions,
F, PSI))
2020 dbgs() <<
"RegionInfo:\n";
2026 findScopes(AllScopes);
2035 splitScopes(AllScopes, SplitScopes);
2040 classifyBiasedScopes(SplitScopes);
2046 filterScopes(SplitScopes, FilteredScopes);
2051 setCHRRegions(FilteredScopes, SetScopes);
2058 sortScopes(SetScopes, SortedScopes);
2062 dbgs() <<
"RegionInfo:\n";
2066 if (!SortedScopes.
empty()) {
2067 transformScopes(SortedScopes);
2075 return OptimizationRemark(
DEBUG_TYPE,
"Stats", &
F)
2077 <<
"Reduced the number of branches in hot paths by "
2080 <<
ore::NV(
"WeightedNumBranchesDelta",
Stats.WeightedNumBranchesDelta)
2081 <<
" (weighted by PGO count)";
2094 if (!PPSI || !PPSI->hasProfileSummary())
2101 const InstrumentationOptions &Opts =
2102 F.getContext().getLibraryOptions().get<InstrumentationOptions>();
2103 if (&Opts != ParsedOpts &&
2104 (!Opts.chr_module_list.empty() || !Opts.chr_function_list.empty())) {
2106 CHRFunctions.clear();
2111 CHR(Opts, CHRModules, CHRFunctions,
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 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.
const SmallVectorImpl< MachineOperand > & 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.
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.
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.