47#define DEBUG_TYPE "chr"
49#define CHR_DEBUG(X) LLVM_DEBUG(X)
55 const InstrumentationOptions &Opts = InstrumentationOptions::Global;
56 if (!Opts.chr_module_list.empty()) {
59 errs() <<
"Error: Couldn't read the chr-module-list file "
60 << Opts.chr_module_list <<
"\n";
63 StringRef Buf = FileOrErr->get()->getBuffer();
65 Buf.
split(Lines,
'\n');
72 if (!Opts.chr_function_list.empty()) {
75 errs() <<
"Error: Couldn't read the chr-function-list file "
76 << Opts.chr_function_list <<
"\n";
79 StringRef Buf = FileOrErr->get()->getBuffer();
81 Buf.
split(Lines,
'\n');
94 void print(raw_ostream &OS)
const {
95 OS <<
"CHRStats: NumBranches " << NumBranches
96 <<
" NumBranchesDelta " << NumBranchesDelta
97 <<
" WeightedNumBranchesDelta " << WeightedNumBranchesDelta;
105 uint64_t WeightedNumBranchesDelta = 0;
111 RegInfo(Region *RegionIn) :
R(RegionIn) {}
113 bool HasBranch =
false;
124 CHRScope(RegInfo RI) : BranchInsertPoint(nullptr) {
125 assert(RI.R &&
"Null RegionIn");
126 RegInfos.push_back(RI);
129 Region *getParentRegion() {
130 assert(RegInfos.size() > 0 &&
"Empty CHRScope");
131 Region *Parent = RegInfos[0].R->getParent();
132 assert(Parent &&
"Unexpected to call this on the top-level region");
137 assert(RegInfos.size() > 0 &&
"Empty CHRScope");
138 return RegInfos.front().R->getEntry();
142 assert(RegInfos.size() > 0 &&
"Empty CHRScope");
143 return RegInfos.back().R->getExit();
146 bool appendable(CHRScope *
Next) {
151 if (getExitBlock() != NextEntry)
154 Region *LastRegion = RegInfos.back().R;
164 assert(RegInfos.size() > 0 &&
"Empty CHRScope");
165 assert(
Next->RegInfos.size() > 0 &&
"Empty CHRScope");
166 assert(getParentRegion() ==
Next->getParentRegion() &&
168 assert(getExitBlock() ==
Next->getEntryBlock() &&
170 RegInfos.append(
Next->RegInfos.begin(),
Next->RegInfos.end());
171 Subs.append(
Next->Subs.begin(),
Next->Subs.end());
174 void addSub(CHRScope *SubIn) {
176 bool IsChild =
false;
177 for (RegInfo &RI : RegInfos)
178 if (RI.R == SubIn->getParentRegion()) {
182 assert(IsChild &&
"Must be a child");
184 Subs.push_back(SubIn);
189 CHRScope *
split(Region *Boundary) {
190 assert(Boundary &&
"Boundary null");
191 assert(RegInfos.begin()->R != Boundary &&
192 "Can't be split at beginning");
194 RegInfos, [&Boundary](
const RegInfo &RI) {
return Boundary == RI.R; });
195 if (BoundaryIt == RegInfos.end())
198 DenseSet<Region *> TailRegionSet;
199 for (
const RegInfo &RI : TailRegInfos)
200 TailRegionSet.
insert(RI.R);
203 std::stable_partition(Subs.begin(), Subs.end(), [&](CHRScope *
Sub) {
204 assert(Sub &&
"null Sub");
205 Region *Parent = Sub->getParentRegion();
206 if (TailRegionSet.count(Parent))
211 [&Parent](const RegInfo &RI) { return Parent == RI.R; }) &&
217 assert(HoistStopMap.empty() &&
"MapHoistStops must be empty");
218 auto *
Scope =
new CHRScope(TailRegInfos, TailSubs);
219 RegInfos.erase(BoundaryIt, RegInfos.end());
220 Subs.erase(TailIt, Subs.end());
226 for (
const RegInfo &RI : RegInfos)
227 if (RI.R->contains(Parent))
256 HoistStopMapTy HoistStopMap;
260 : RegInfos(RegInfosIn), Subs(SubsIn), BranchInsertPoint(nullptr) {}
265 CHR(
const InstrumentationOptions &Opts,
Function &Fin,
266 BlockFrequencyInfo &BFIin, DominatorTree &DTin, ProfileSummaryInfo &PSIin,
267 RegionInfo &RIin, OptimizationRemarkEmitter &OREin)
268 : Opts(Opts), F(Fin), BFI(BFIin), DT(DTin), PSI(PSIin), RI(RIin),
272 for (CHRScope *Scope : Scopes) {
283 void findScopes(SmallVectorImpl<CHRScope *> &Output) {
284 Region *
R = RI.getTopLevelRegion();
285 if (CHRScope *Scope = findScopes(R,
nullptr,
nullptr, Output)) {
289 CHRScope *findScopes(Region *R, Region *NextRegion, Region *ParentRegion,
290 SmallVectorImpl<CHRScope *> &Scopes);
291 CHRScope *findScope(Region *R);
292 void checkScopeHoistable(CHRScope *Scope);
294 void splitScopes(SmallVectorImpl<CHRScope *> &Input,
295 SmallVectorImpl<CHRScope *> &Output);
298 DenseSet<Value *> *OuterConditionValues,
299 Instruction *OuterInsertPoint,
300 SmallVectorImpl<CHRScope *> &Output,
301 DenseSet<Instruction *> &Unhoistables);
303 void classifyBiasedScopes(SmallVectorImpl<CHRScope *> &Scopes);
304 void classifyBiasedScopes(CHRScope *Scope, CHRScope *OutermostScope);
306 void filterScopes(SmallVectorImpl<CHRScope *> &Input,
307 SmallVectorImpl<CHRScope *> &Output);
309 void setCHRRegions(SmallVectorImpl<CHRScope *> &Input,
310 SmallVectorImpl<CHRScope *> &Output);
311 void setCHRRegions(CHRScope *Scope, CHRScope *OutermostScope);
313 void sortScopes(SmallVectorImpl<CHRScope *> &Input,
314 SmallVectorImpl<CHRScope *> &Output);
316 void transformScopes(SmallVectorImpl<CHRScope *> &CHRScopes);
317 void transformScopes(CHRScope *Scope, DenseSet<PHINode *> &TrivialPHIs);
318 void cloneScopeBlocks(CHRScope *Scope,
319 BasicBlock *PreEntryBlock,
320 BasicBlock *ExitBlock,
323 CondBrInst *createMergedBranch(BasicBlock *PreEntryBlock,
324 BasicBlock *EntryBlock,
325 BasicBlock *NewEntryBlock,
327 void fixupBranchesAndSelects(CHRScope *Scope, BasicBlock *PreEntryBlock,
328 CondBrInst *MergedBR,
uint64_t ProfileCount);
329 void fixupBranch(Region *R, CHRScope *Scope,
IRBuilder<> &IRB,
330 Value *&MergedCondition, BranchProbability &CHRBranchBias);
331 void fixupSelect(SelectInst *SI, CHRScope *Scope,
IRBuilder<> &IRB,
332 Value *&MergedCondition, BranchProbability &CHRBranchBias);
333 void addToMergedCondition(
bool IsTrueBiased,
Value *
Cond,
334 Instruction *BranchOrSelect, CHRScope *Scope,
336 unsigned getRegionDuplicationCount(
const Region *R) {
343 Count += DuplicationCount[
R];
349 const InstrumentationOptions &Opts;
351 BlockFrequencyInfo &BFI;
353 ProfileSummaryInfo &PSI;
355 OptimizationRemarkEmitter &ORE;
359 DenseSet<Region *> TrueBiasedRegionsGlobal;
361 DenseSet<Region *> FalseBiasedRegionsGlobal;
363 DenseSet<SelectInst *> TrueBiasedSelectsGlobal;
365 DenseSet<SelectInst *> FalseBiasedSelectsGlobal;
367 DenseMap<Region *, BranchProbability> BranchBiasMap;
369 DenseMap<SelectInst *, BranchProbability> SelectBiasMap;
371 DenseSet<CHRScope *> Scopes;
373 DenseMap<const Region *, unsigned> DuplicationCount;
379 const CHRStats &
Stats) {
392 if (Opts.disable_chr)
398 if (!Opts.chr_module_list.empty() || !Opts.chr_function_list.empty()) {
422 assert(RegInfos.size() > 0 &&
"Empty CHRScope");
424 OS << RegInfos.size() <<
", Regions[";
425 for (
const RegInfo &RI : RegInfos) {
426 OS << RI.R->getNameStr();
429 if (RI.Selects.size() > 0)
430 OS <<
" S" << RI.Selects.size();
433 if (RegInfos[0].
R->getParent()) {
434 OS <<
"], Parent " << RegInfos[0].R->getParent()->getNameStr();
440 for (CHRScope *
Sub : Subs) {
467static const std::set<Value *> &
470 auto It = Visited.find(V);
471 if (It != Visited.end()) {
474 std::set<Value *> Result;
481 return Visited.insert(std::make_pair(V, std::move(Result))).first->second;
486 Result.insert(OpResult.begin(), OpResult.end());
488 return Visited.insert(std::make_pair(V, std::move(Result))).first->second;
496 return Visited.insert(std::make_pair(V, std::move(Result))).first->second;
510 auto It = Visited.
find(
I);
511 if (It != Visited.
end()) {
514 assert(DT.
getNode(
I->getParent()) &&
"DT must contain I's parent block");
516 if (Unhoistables.
count(
I)) {
533 bool AllOpsHoisted =
true;
537 AllOpsHoisted =
false;
565 uint64_t SumWeight = TrueWeight + FalseWeight;
567 assert(SumWeight >= TrueWeight && SumWeight >= FalseWeight &&
568 "Overflow calculating branch probabilities.");
579static BranchProbability
582 static_cast<uint64_t>(Opts.chr_bias_threshold * 1000000), 1000000);
589template <
typename K,
typename S,
typename M>
592 S &TrueSet, S &FalseSet, M &BiasMap) {
594 if (TrueProb >= Threshold) {
596 BiasMap[
Key] = TrueProb;
598 }
else if (FalseProb >= Threshold) {
599 FalseSet.insert(
Key);
600 BiasMap[
Key] = FalseProb;
618 assert((IfThen == R->getExit() || IfElse == R->getExit()) &&
620 "Invariant from findScopes");
621 if (IfThen == R->getExit()) {
630 return checkBias(Opts, R, ThenProb, ElseProb, TrueBiasedRegionsGlobal,
631 FalseBiasedRegionsGlobal, BranchBiasMap);
647 return checkBias(Opts,
SI, TrueProb, FalseProb, TrueBiasedSelectsGlobal,
648 FalseBiasedSelectsGlobal, SelectBiasMap);
661 if (
SI->getParent() == EntryBB) {
668 assert(HoistPoint &&
"Null HoistPoint");
674 if (
SI->getParent() == EntryBB) {
681 "HoistPoint must be the first one in Selects");
690CHRScope * CHR::findScope(Region *R) {
691 CHRScope *
Result =
nullptr;
694 assert(Entry &&
"Entry must not be null");
695 assert((Exit ==
nullptr) == (
R->isTopLevelRegion()) &&
696 "Only top level region has a null exit");
707 bool EntryInSubregion = RI.getRegionFor(Entry) !=
R;
708 if (EntryInSubregion)
712 if (
R->contains(Pred))
716 for (BasicBlock *BB :
R->blocks()) {
717 if (BB->hasAddressTaken())
725 for (Instruction &
I : *BB) {
727 if (
II->getIntrinsicID() == Intrinsic::coro_id)
744 if (CB->cannotDuplicate() || CB->isConvergent())
761 if (S0 !=
S1 && (S0 == Exit ||
S1 == Exit)) {
765 FalseBiasedRegionsGlobal, BranchBiasMap);
766 Result =
new CHRScope(RI);
767 Scopes.insert(Result);
772 return OptimizationRemarkMissed(
DEBUG_TYPE,
"BranchNotBiased", BI)
773 <<
"Branch not biased";
793 for (RegionNode *
E :
R->elements()) {
794 if (
E->isSubRegion())
801 for (Instruction &
I : *BB) {
808 if (Selects.
size() > 0) {
809 auto AddSelects = [&](RegInfo &RI) {
810 for (
auto *SI : Selects)
812 FalseBiasedSelectsGlobal, SelectBiasMap))
813 RI.Selects.push_back(SI);
816 return OptimizationRemarkMissed(
DEBUG_TYPE,
"SelectNotBiased", SI)
817 <<
"Select not biased";
824 Result =
new CHRScope(RI);
825 Scopes.insert(Result);
827 CHR_DEBUG(
dbgs() <<
"Found select(s) in a region with a branch\n");
828 AddSelects(
Result->RegInfos[0]);
834 checkScopeHoistable(Result);
861void CHR::checkScopeHoistable(CHRScope *Scope) {
862 RegInfo &RI =
Scope->RegInfos[0];
868 if (RI.HasBranch || !Selects.
empty()) {
877 for (
auto it = Selects.
begin(); it != Selects.
end(); ) {
878 SelectInst *
SI = *it;
879 if (SI == InsertPoint) {
883 DenseMap<Instruction *, bool> Visited;
885 DT, Unhoistables,
nullptr, Visited);
890 "DropUnhoistableSelect", SI)
891 <<
"Dropped unhoistable select";
893 it = Selects.
erase(it);
896 Unhoistables.erase(SI);
903 if (RI.HasBranch && InsertPoint != Branch) {
904 DenseMap<Instruction *, bool> Visited;
906 DT, Unhoistables,
nullptr, Visited);
911 assert(InsertPoint != Branch &&
"Branch must not be the hoist point");
914 for (SelectInst *SI : Selects) {
915 dbgs() <<
"SI " << *
SI <<
"\n";
917 for (SelectInst *SI : Selects) {
920 "DropSelectUnhoistableBranch", SI)
921 <<
"Dropped select due to unhoistable branch";
925 return SI->getParent() == EntryBB;
927 Unhoistables.clear();
935 "Branch can't be already above the hoist point");
936 DenseMap<Instruction *, bool> Visited;
938 DT, Unhoistables,
nullptr, Visited) &&
939 "checkHoistValue for branch");
941 for (
auto *SI : Selects) {
943 "SI can't be already above the hoist point");
944 DenseMap<Instruction *, bool> Visited;
946 Unhoistables,
nullptr, Visited) &&
947 "checkHoistValue for selects");
953 for (
auto *SI : Selects) {
961CHRScope * CHR::findScopes(Region *R, Region *NextRegion, Region *ParentRegion,
962 SmallVectorImpl<CHRScope *> &Scopes) {
964 CHRScope *
Result = findScope(R);
966 CHRScope *ConsecutiveSubscope =
nullptr;
968 for (
auto It =
R->begin(); It !=
R->end(); ++It) {
969 const std::unique_ptr<Region> &SubR = *It;
970 auto NextIt = std::next(It);
971 Region *NextSubR = NextIt !=
R->end() ? NextIt->get() :
nullptr;
972 CHR_DEBUG(
dbgs() <<
"Looking at subregion " << SubR.get()->getNameStr()
974 CHRScope *SubCHRScope = findScopes(SubR.get(), NextSubR, R, Scopes);
976 CHR_DEBUG(
dbgs() <<
"Subregion Scope " << *SubCHRScope <<
"\n");
981 if (!ConsecutiveSubscope)
982 ConsecutiveSubscope = SubCHRScope;
983 else if (!ConsecutiveSubscope->appendable(SubCHRScope)) {
984 Subscopes.
push_back(ConsecutiveSubscope);
985 ConsecutiveSubscope = SubCHRScope;
987 ConsecutiveSubscope->append(SubCHRScope);
989 if (ConsecutiveSubscope) {
990 Subscopes.
push_back(ConsecutiveSubscope);
992 ConsecutiveSubscope =
nullptr;
995 if (ConsecutiveSubscope) {
996 Subscopes.
push_back(ConsecutiveSubscope);
998 for (CHRScope *
Sub : Subscopes) {
1014 ConditionValues.
insert(BI->getCondition());
1017 ConditionValues.
insert(
SI->getCondition());
1019 return ConditionValues;
1037 for (
Value *V : PrevConditionValues) {
1038 dbgs() << *V <<
", ";
1040 dbgs() <<
" ConditionValues ";
1041 for (
Value *V : ConditionValues) {
1042 dbgs() << *V <<
", ";
1046 for (
Value *V : ConditionValues) {
1049 CHR_DEBUG(
dbgs() <<
"Split. checkHoistValue false " << *V <<
"\n");
1056 if (!PrevConditionValues.
empty() && !ConditionValues.
empty()) {
1058 std::set<Value *> PrevBases, Bases;
1060 for (
Value *V : PrevConditionValues) {
1061 const std::set<Value *> &BaseValues =
getBaseValues(V, DT, Visited);
1062 PrevBases.insert(BaseValues.begin(), BaseValues.end());
1064 for (
Value *V : ConditionValues) {
1065 const std::set<Value *> &BaseValues =
getBaseValues(V, DT, Visited);
1066 Bases.insert(BaseValues.begin(), BaseValues.end());
1069 dbgs() <<
"PrevBases ";
1070 for (
Value *V : PrevBases) {
1071 dbgs() << *V <<
", ";
1073 dbgs() <<
" Bases ";
1074 for (
Value *V : Bases) {
1075 dbgs() << *V <<
", ";
1078 std::vector<Value *> Intersection;
1079 std::set_intersection(PrevBases.begin(), PrevBases.end(), Bases.begin(),
1080 Bases.end(), std::back_inserter(Intersection));
1081 if (Intersection.empty()) {
1093 for (
RegInfo &RI : Scope->RegInfos)
1095 for (CHRScope *
Sub : Scope->Subs)
1099void CHR::splitScopes(SmallVectorImpl<CHRScope *> &Input,
1100 SmallVectorImpl<CHRScope *> &Output) {
1101 for (CHRScope *Scope : Input) {
1103 "BranchInsertPoint must not be set");
1104 DenseSet<Instruction *> Unhoistables;
1106 splitScope(Scope,
nullptr,
nullptr,
nullptr, Output, Unhoistables);
1109 for (CHRScope *Scope : Output) {
1110 assert(
Scope->BranchInsertPoint &&
"BranchInsertPoint must be set");
1118 DenseSet<Value *> *OuterConditionValues,
1119 Instruction *OuterInsertPoint,
1120 SmallVectorImpl<CHRScope *> &Output,
1121 DenseSet<Instruction *> &Unhoistables) {
1123 assert(OuterConditionValues &&
"Null OuterConditionValues");
1124 assert(OuterInsertPoint &&
"Null OuterInsertPoint");
1126 bool PrevSplitFromOuter =
true;
1127 DenseSet<Value *> PrevConditionValues;
1132 SmallVector<Instruction *, 8> SplitsInsertPoints;
1134 for (RegInfo &RI : RegInfos) {
1138 dbgs() <<
"ConditionValues ";
1139 for (
Value *V : ConditionValues) {
1140 dbgs() << *
V <<
", ";
1143 if (RI.R == RegInfos[0].R) {
1148 << RI.R->getNameStr() <<
"\n");
1149 if (
shouldSplit(OuterInsertPoint, *OuterConditionValues,
1150 ConditionValues, DT, Unhoistables)) {
1151 PrevConditionValues = ConditionValues;
1152 PrevInsertPoint = InsertPoint;
1155 "SplitScopeFromOuter",
1156 RI.R->getEntry()->getTerminator())
1157 <<
"Split scope from outer due to unhoistable branch/select "
1158 <<
"and/or lack of common condition values";
1163 PrevSplitFromOuter =
false;
1164 PrevConditionValues = *OuterConditionValues;
1166 PrevInsertPoint = OuterInsertPoint;
1170 PrevConditionValues = ConditionValues;
1171 PrevInsertPoint = InsertPoint;
1175 << RI.R->getNameStr() <<
"\n");
1176 if (
shouldSplit(PrevInsertPoint, PrevConditionValues, ConditionValues,
1177 DT, Unhoistables)) {
1181 SplitsSplitFromOuter.
push_back(PrevSplitFromOuter);
1182 SplitsConditionValues.
push_back(PrevConditionValues);
1183 SplitsInsertPoints.
push_back(PrevInsertPoint);
1185 PrevConditionValues = ConditionValues;
1186 PrevInsertPoint = InsertPoint;
1187 PrevSplitFromOuter =
true;
1190 "SplitScopeFromPrev",
1191 RI.R->getEntry()->getTerminator())
1192 <<
"Split scope from previous due to unhoistable branch/select "
1193 <<
"and/or lack of common condition values";
1202 SplitsSplitFromOuter.
push_back(PrevSplitFromOuter);
1203 SplitsConditionValues.
push_back(PrevConditionValues);
1204 assert(PrevInsertPoint &&
"Null PrevInsertPoint");
1205 SplitsInsertPoints.
push_back(PrevInsertPoint);
1207 Splits.
size() == SplitsSplitFromOuter.
size() &&
1208 Splits.
size() == SplitsInsertPoints.
size() &&
"Mismatching sizes");
1209 for (
size_t I = 0;
I < Splits.
size(); ++
I) {
1210 CHRScope *
Split = Splits[
I];
1211 DenseSet<Value *> &SplitConditionValues = SplitsConditionValues[
I];
1214 DenseSet<Instruction *> SplitUnhoistables;
1216 for (CHRScope *
Sub :
Split->Subs) {
1218 Sub, Split, &SplitConditionValues, SplitInsertPoint, Output,
1222 Split->Subs = NewSubs;
1225 for (
size_t I = 0;
I < Splits.
size(); ++
I) {
1226 CHRScope *
Split = Splits[
I];
1227 if (SplitsSplitFromOuter[
I]) {
1230 Split->BranchInsertPoint = SplitsInsertPoints[
I];
1231 CHR_DEBUG(
dbgs() <<
"BranchInsertPoint " << *SplitsInsertPoints[
I]
1240 "If no outer (top-level), must return no nested ones");
1244void CHR::classifyBiasedScopes(SmallVectorImpl<CHRScope *> &Scopes) {
1245 for (CHRScope *Scope : Scopes) {
1246 assert(
Scope->TrueBiasedRegions.empty() &&
Scope->FalseBiasedRegions.empty() &&
"Empty");
1247 classifyBiasedScopes(Scope, Scope);
1249 dbgs() <<
"classifyBiasedScopes " << *Scope <<
"\n";
1250 dbgs() <<
"TrueBiasedRegions ";
1251 for (Region *R :
Scope->TrueBiasedRegions) {
1252 dbgs() <<
R->getNameStr() <<
", ";
1255 dbgs() <<
"FalseBiasedRegions ";
1256 for (Region *R :
Scope->FalseBiasedRegions) {
1257 dbgs() <<
R->getNameStr() <<
", ";
1260 dbgs() <<
"TrueBiasedSelects ";
1261 for (SelectInst *SI :
Scope->TrueBiasedSelects) {
1265 dbgs() <<
"FalseBiasedSelects ";
1266 for (SelectInst *SI :
Scope->FalseBiasedSelects) {
1273void CHR::classifyBiasedScopes(CHRScope *Scope, CHRScope *OutermostScope) {
1274 for (RegInfo &RI :
Scope->RegInfos) {
1277 if (TrueBiasedRegionsGlobal.contains(R))
1278 OutermostScope->TrueBiasedRegions.insert(R);
1279 else if (FalseBiasedRegionsGlobal.contains(R))
1280 OutermostScope->FalseBiasedRegions.insert(R);
1284 for (SelectInst *SI : RI.Selects) {
1285 if (TrueBiasedSelectsGlobal.contains(SI))
1286 OutermostScope->TrueBiasedSelects.insert(SI);
1287 else if (FalseBiasedSelectsGlobal.contains(SI))
1288 OutermostScope->FalseBiasedSelects.insert(SI);
1293 for (CHRScope *
Sub :
Scope->Subs) {
1294 classifyBiasedScopes(
Sub, OutermostScope);
1300 unsigned NumBiased = Scope->TrueBiasedRegions.size() +
1301 Scope->FalseBiasedRegions.size() +
1302 Scope->TrueBiasedSelects.size() +
1303 Scope->FalseBiasedSelects.size();
1304 return NumBiased >= Opts.chr_merge_threshold;
1307void CHR::filterScopes(SmallVectorImpl<CHRScope *> &Input,
1308 SmallVectorImpl<CHRScope *> &Output) {
1309 for (CHRScope *Scope : Input) {
1312 CHR_DEBUG(
dbgs() <<
"Filtered out by biased branches truthy-regions "
1313 <<
Scope->TrueBiasedRegions.size()
1314 <<
" falsy-regions " <<
Scope->FalseBiasedRegions.size()
1315 <<
" true-selects " <<
Scope->TrueBiasedSelects.size()
1316 <<
" false-selects " <<
Scope->FalseBiasedSelects.size() <<
"\n");
1318 return OptimizationRemarkMissed(
1319 DEBUG_TYPE,
"DropScopeWithOneBranchOrSelect",
1320 Scope->RegInfos[0].R->getEntry()->getTerminator())
1321 <<
"Drop scope with < "
1322 <<
ore::NV(
"CHRMergeThreshold", Opts.chr_merge_threshold)
1323 <<
" biased branch(es) or select(s)";
1331void CHR::setCHRRegions(SmallVectorImpl<CHRScope *> &Input,
1332 SmallVectorImpl<CHRScope *> &Output) {
1333 for (CHRScope *Scope : Input) {
1336 setCHRRegions(Scope, Scope);
1339 dbgs() <<
"setCHRRegions HoistStopMap " << *Scope <<
"\n";
1340 for (
auto pair :
Scope->HoistStopMap) {
1341 Region *R = pair.first;
1342 dbgs() <<
"Region " << R->getNameStr() <<
"\n";
1343 for (Instruction *I : pair.second) {
1344 dbgs() <<
"HoistStop " << *I <<
"\n";
1347 dbgs() <<
"CHRRegions" <<
"\n";
1348 for (RegInfo &RI :
Scope->CHRRegions) {
1349 dbgs() << RI.R->getNameStr() <<
"\n";
1354void CHR::setCHRRegions(CHRScope *Scope, CHRScope *OutermostScope) {
1355 DenseSet<Instruction *> Unhoistables;
1359 for (RegInfo &RI :
Scope->RegInfos)
1361 Instruction *InsertPoint = OutermostScope->BranchInsertPoint;
1362 for (RegInfo &RI :
Scope->RegInfos) {
1364 DenseSet<Instruction *> HoistStops;
1365 bool IsHoisted =
false;
1367 assert((OutermostScope->TrueBiasedRegions.contains(R) ||
1368 OutermostScope->FalseBiasedRegions.contains(R)) &&
1369 "Must be truthy or falsy");
1372 DenseMap<Instruction *, bool> Visited;
1373 bool IsHoistable =
checkHoistValue(BI->getCondition(), InsertPoint, DT,
1374 Unhoistables, &HoistStops, Visited);
1375 assert(IsHoistable &&
"Must be hoistable");
1376 (void)(IsHoistable);
1379 for (SelectInst *SI : RI.Selects) {
1380 assert((OutermostScope->TrueBiasedSelects.contains(SI) ||
1381 OutermostScope->FalseBiasedSelects.contains(SI)) &&
1382 "Must be true or false biased");
1384 DenseMap<Instruction *, bool> Visited;
1386 Unhoistables, &HoistStops, Visited);
1387 assert(IsHoistable &&
"Must be hoistable");
1388 (void)(IsHoistable);
1392 OutermostScope->CHRRegions.push_back(RI);
1393 OutermostScope->HoistStopMap[
R] = HoistStops;
1397 setCHRRegions(
Sub, OutermostScope);
1401 return Scope1->RegInfos[0].R->getDepth() < Scope2->RegInfos[0].R->getDepth();
1404void CHR::sortScopes(SmallVectorImpl<CHRScope *> &Input,
1405 SmallVectorImpl<CHRScope *> &Output) {
1414 HoistStopMapTy &HoistStopMap,
1418 auto IT = HoistStopMap.find(R);
1419 assert(
IT != HoistStopMap.end() &&
"Region must be in hoist stop map");
1422 if (
I == HoistPoint)
1427 if (TrivialPHIs.
count(PN))
1437 assert(DT.
getNode(
I->getParent()) &&
"DT must contain I's block");
1439 "DT must contain HoistPoint block");
1451 hoistValue(
Op, HoistPoint, R, HoistStopMap, HoistedSet, TrivialPHIs, DT);
1465 for (
const RegInfo &RI : Scope->CHRRegions) {
1467 bool IsTrueBiased = Scope->TrueBiasedRegions.count(R);
1468 bool IsFalseBiased = Scope->FalseBiasedRegions.count(R);
1469 if (RI.HasBranch && (IsTrueBiased || IsFalseBiased)) {
1471 hoistValue(BI->getCondition(), HoistPoint, R, Scope->HoistStopMap,
1472 HoistedSet, TrivialPHIs, DT);
1475 bool IsTrueBiased = Scope->TrueBiasedSelects.count(
SI);
1476 bool IsFalseBiased = Scope->FalseBiasedSelects.count(
SI);
1477 if (!(IsTrueBiased || IsFalseBiased))
1479 hoistValue(
SI->getCondition(), HoistPoint, R, Scope->HoistStopMap,
1480 HoistedSet, TrivialPHIs, DT);
1491 if (U == ExcludedUser)
1500 if (U == ExcludedUser)
1503 BI->swapSuccessors();
1514 SI->swapProfMetadata();
1515 if (Scope->TrueBiasedSelects.count(
SI)) {
1516 assert(!Scope->FalseBiasedSelects.contains(
SI) &&
1517 "Must not be already in");
1518 Scope->FalseBiasedSelects.insert(
SI);
1519 }
else if (Scope->FalseBiasedSelects.count(
SI)) {
1520 assert(!Scope->TrueBiasedSelects.contains(
SI) &&
1521 "Must not be already in");
1522 Scope->TrueBiasedSelects.insert(
SI);
1539 for (
RegInfo &RI : Scope->RegInfos) {
1542 BlocksInScope.
insert(BB);
1546 dbgs() <<
"Inserting redundant phis\n";
1548 dbgs() <<
"BlockInScope " << BB->getName() <<
"\n";
1553 for (
User *U :
I.users()) {
1555 if (!BlocksInScope.
contains(UI->getParent()) &&
1559 CHR_DEBUG(
dbgs() <<
"Used outside scope by user " << *UI <<
"\n");
1560 Users.push_back(UI);
1561 }
else if (UI->getParent() == EntryBlock &&
isa<PHINode>(UI)) {
1566 <<
"Used at entry block (for a back edge) by a phi user "
1568 Users.push_back(UI);
1572 if (
Users.size() > 0) {
1583 bool FoundLifetimeAnnotation =
false;
1588 if (UI->isLifetimeStartOrEnd()) {
1589 UI->eraseFromParent();
1590 FoundLifetimeAnnotation =
true;
1593 for (
unsigned J = 0,
NumOps = UI->getNumOperands(); J <
NumOps; ++J) {
1594 if (UI->getOperand(J) == &
I) {
1595 UI->setOperand(J, PN);
1601 if (FoundLifetimeAnnotation) {
1604 if (UI->isLifetimeStartOrEnd())
1605 UI->eraseFromParent();
1614[[maybe_unused]]
static void
1617 auto HasBiasedBranchOrSelect = [](
RegInfo &RI, CHRScope *Scope) {
1618 if (Scope->TrueBiasedRegions.count(RI.R) ||
1619 Scope->FalseBiasedRegions.count(RI.R))
1622 if (Scope->TrueBiasedSelects.count(
SI) ||
1623 Scope->FalseBiasedSelects.count(
SI))
1627 for (
RegInfo &RI : Scope->CHRRegions) {
1628 assert(HasBiasedBranchOrSelect(RI, Scope) &&
1629 "Must have biased branch or select");
1636[[maybe_unused]]
static void
1640 for (
RegInfo &RI : Scope->CHRRegions) {
1642 bool IsTrueBiased = Scope->TrueBiasedRegions.count(R);
1643 bool IsFalseBiased = Scope->FalseBiasedRegions.count(R);
1644 if (RI.HasBranch && (IsTrueBiased || IsFalseBiased)) {
1646 Value *V = BI->getCondition();
1650 assert((
I->getParent() == PreEntryBlock ||
1651 !Scope->contains(
I)) &&
1652 "Must have been hoisted to PreEntryBlock or outside the scope");
1656 bool IsTrueBiased = Scope->TrueBiasedSelects.count(
SI);
1657 bool IsFalseBiased = Scope->FalseBiasedSelects.count(
SI);
1658 if (!(IsTrueBiased || IsFalseBiased))
1660 Value *V =
SI->getCondition();
1664 assert((
I->getParent() == PreEntryBlock ||
1665 !Scope->contains(
I)) &&
1666 "Must have been hoisted to PreEntryBlock or outside the scope");
1672void CHR::transformScopes(CHRScope *Scope, DenseSet<PHINode *> &TrivialPHIs) {
1675 assert(
Scope->RegInfos.size() >= 1 &&
"Should have at least one Region");
1677 for (RegInfo &RI :
Scope->RegInfos) {
1679 unsigned Duplication = getRegionDuplicationCount(R);
1684 <<
" for this region");
1686 return OptimizationRemarkMissed(
DEBUG_TYPE,
"DupThresholdReached",
1687 R->getEntry()->getTerminator())
1688 <<
"Reached the duplication threshold for the region";
1693 for (RegInfo &RI :
Scope->RegInfos) {
1694 DuplicationCount[RI.R]++;
1703 SmallVector<AllocaInst *> StaticAllocas;
1704 for (Instruction &
I : *EntryBlock) {
1706 if (AI->isStaticAlloca())
1718 CHR_DEBUG(
dbgs() <<
"Splitting entry block " << EntryBlock->getName()
1719 <<
" at " << *
Scope->BranchInsertPoint <<
"\n");
1723 "NewEntryBlock's only pred must be EntryBlock");
1728 for (AllocaInst *AI : StaticAllocas)
1729 AI->moveBefore(EntryBlock->begin());
1745 cloneScopeBlocks(Scope, PreEntryBlock, ExitBlock, LastRegion, VMap);
1749 CondBrInst *MergedBr =
1750 createMergedBranch(PreEntryBlock, EntryBlock, NewEntryBlock, VMap);
1765 fixupBranchesAndSelects(Scope, PreEntryBlock, MergedBr,
1766 ProfileCount.value_or(0));
1772void CHR::cloneScopeBlocks(CHRScope *Scope,
1773 BasicBlock *PreEntryBlock,
1774 BasicBlock *ExitBlock,
1782 SmallVector<BasicBlock*, 8> NewBlocks;
1783 for (RegInfo &RI :
Scope->RegInfos)
1784 for (BasicBlock *BB : RI.R->blocks()) {
1786 assert(BB != PreEntryBlock &&
"Don't copy the preetntry block");
1794 PN.removeIncomingValueIf([&](
unsigned Idx) {
1802 F.splice(ExitBlock->
getIterator(), &
F, NewBlocks[0]->getIterator(),
1806 for (BasicBlock *NewBB : NewBlocks)
1807 for (Instruction &
I : *NewBB)
1815 for (PHINode &PN : ExitBlock->
phis())
1816 for (
unsigned I = 0,
NumOps = PN.getNumIncomingValues();
I <
NumOps;
1820 Value *
V = PN.getIncomingValue(
I);
1821 auto It = VMap.
find(V);
1822 if (It != VMap.
end())
V = It->second;
1823 assert(VMap.
find(Pred) != VMap.
end() &&
"Pred must have been cloned");
1831CondBrInst *CHR::createMergedBranch(BasicBlock *PreEntryBlock,
1832 BasicBlock *EntryBlock,
1833 BasicBlock *NewEntryBlock,
1837 "SplitBlock did not work correctly!");
1839 "NewEntryBlock's only pred must be EntryBlock");
1841 "NewEntryBlock must have been copied");
1851 "NewEntryBlock's only pred must be EntryBlock");
1857void CHR::fixupBranchesAndSelects(CHRScope *Scope, BasicBlock *PreEntryBlock,
1858 CondBrInst *MergedBR,
uint64_t ProfileCount) {
1860 BranchProbability CHRBranchBias(1, 1);
1863 for (RegInfo &RI :
Scope->CHRRegions) {
1866 fixupBranch(R, Scope, IRB, MergedCondition, CHRBranchBias);
1869 for (SelectInst *SI : RI.Selects) {
1870 fixupSelect(SI, Scope, IRB, MergedCondition, CHRBranchBias);
1874 assert(NumCHRedBranches > 0);
1875 Stats.NumBranchesDelta += NumCHRedBranches - 1;
1876 Stats.WeightedNumBranchesDelta += (NumCHRedBranches - 1) * ProfileCount;
1882 <<
"Merged " <<
ore::NV(
"NumCHRedBranches", NumCHRedBranches)
1883 <<
" branches or selects";
1886 uint32_t Weights[] = {
1887 static_cast<uint32_t
>(CHRBranchBias.scale(1000)),
1888 static_cast<uint32_t
>(CHRBranchBias.getCompl().
scale(1000)),
1891 CHR_DEBUG(
dbgs() <<
"CHR branch bias " << Weights[0] <<
":" << Weights[1]
1897void CHR::fixupBranch(Region *R, CHRScope *Scope,
1899 Value *&MergedCondition,
1900 BranchProbability &CHRBranchBias) {
1901 bool IsTrueBiased =
Scope->TrueBiasedRegions.count(R);
1902 assert((IsTrueBiased ||
Scope->FalseBiasedRegions.count(R)) &&
1903 "Must be truthy or falsy");
1905 assert(BranchBiasMap.contains(R) &&
"Must be in the bias map");
1906 BranchProbability Bias = BranchBiasMap[
R];
1909 if (CHRBranchBias > Bias)
1910 CHRBranchBias = Bias;
1914 assert(RegionExitBlock &&
"Null ExitBlock");
1915 assert((IfThen == RegionExitBlock || IfElse == RegionExitBlock) &&
1916 IfThen != IfElse &&
"Invariant from findScopes");
1917 if (IfThen == RegionExitBlock) {
1923 <<
" IfElse " << IfElse->
getName() <<
"\n");
1925 BasicBlock *HotTarget = IsTrueBiased ? IfThen : IfElse;
1926 bool ConditionTrue = HotTarget == BI->getSuccessor(0);
1927 addToMergedCondition(ConditionTrue,
Cond, BI, Scope, IRB,
1930 assert(ConditionTrue == (HotTarget == BI->getSuccessor(0)) &&
1931 "The successor shouldn't change");
1932 Value *NewCondition = ConditionTrue ?
1935 BI->setCondition(NewCondition);
1940void CHR::fixupSelect(SelectInst *SI, CHRScope *Scope,
1942 Value *&MergedCondition,
1943 BranchProbability &CHRBranchBias) {
1944 bool IsTrueBiased =
Scope->TrueBiasedSelects.count(SI);
1946 Scope->FalseBiasedSelects.count(SI)) &&
"Must be biased");
1947 assert(SelectBiasMap.contains(SI) &&
"Must be in the bias map");
1948 BranchProbability Bias = SelectBiasMap[
SI];
1951 if (CHRBranchBias > Bias)
1952 CHRBranchBias = Bias;
1954 addToMergedCondition(IsTrueBiased,
Cond, SI, Scope, IRB,
1956 Value *NewCondition = IsTrueBiased ?
1959 SI->setCondition(NewCondition);
1964void CHR::addToMergedCondition(
bool IsTrueBiased,
Value *
Cond,
1965 Instruction *BranchOrSelect, CHRScope *Scope,
1967 if (!IsTrueBiased) {
1987void CHR::transformScopes(SmallVectorImpl<CHRScope *> &CHRScopes) {
1989 DenseSet<PHINode *> TrivialPHIs;
1990 for (CHRScope *Scope : CHRScopes) {
1991 transformScopes(Scope, TrivialPHIs);
1993 std::ostringstream oss;
1994 oss <<
" after transformScopes " <<
I++;
1995 dumpIR(
F, oss.str().c_str(),
nullptr));
2001 const char *Label) {
2002 dbgs() << Label <<
" " << Scopes.size() <<
"\n";
2003 for (CHRScope *Scope : Scopes) {
2004 dbgs() << *Scope <<
"\n";
2017 dbgs() <<
"RegionInfo:\n";
2023 findScopes(AllScopes);
2032 splitScopes(AllScopes, SplitScopes);
2037 classifyBiasedScopes(SplitScopes);
2043 filterScopes(SplitScopes, FilteredScopes);
2048 setCHRRegions(FilteredScopes, SetScopes);
2055 sortScopes(SetScopes, SortedScopes);
2059 dbgs() <<
"RegionInfo:\n";
2063 if (!SortedScopes.
empty()) {
2064 transformScopes(SortedScopes);
2072 return OptimizationRemark(
DEBUG_TYPE,
"Stats", &
F)
2074 <<
"Reduced the number of branches in hot paths by "
2077 <<
ore::NV(
"WeightedNumBranchesDelta",
Stats.WeightedNumBranchesDelta)
2078 <<
" (weighted by PGO count)";
2095 if (!PPSI || !PPSI->hasProfileSummary())
2103 CHR(InstrumentationOptions::Global,
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 shouldApply(const InstrumentationOptions &Opts, Function &F, ProfileSummaryInfo &PSI)
static StringSet CHRFunctions
static bool CHRScopeSorter(CHRScope *Scope1, CHRScope *Scope2)
static bool checkHoistValue(Value *V, Instruction *InsertPoint, DominatorTree &DT, DenseSet< Instruction * > &Unhoistables, DenseSet< Instruction * > *HoistStops, DenseMap< Instruction *, bool > &Visited)
static 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 StringSet CHRModules
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 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)
static void parseCHRFilterFiles()
This file defines the DenseMap class.
This file defines the DenseSet and SmallDenseSet classes.
This is the interface for a simple mod/ref and alias analysis over globals.
static Value * getCondition(Instruction *I)
This file provides various utilities for inspecting and working with the control flow graph in LLVM I...
Module.h This file contains the declarations for the Module class.
This header defines various interfaces for pass management in LLVM.
iv Induction Variable Users
static Constant * getFalse(Type *Ty)
For a boolean type or a vector of boolean type, return false or a vector with every element false.
const size_t AbstractManglingParser< Derived, Alloc >::NumOps
block placement Basic Block Placement Stats
uint64_t IntrinsicInst * II
FunctionAnalysisManager FAM
This file contains the declarations for profiling metadata utility functions.
const SmallVectorImpl< MachineOperand > & Cond
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 ControlHeightReductionPass()
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.
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.
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.