LLVM 24.0.0git
ControlHeightReduction.cpp
Go to the documentation of this file.
1//===-- ControlHeightReduction.cpp - Control Height Reduction -------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This pass merges conditional blocks of code and reduces the number of
10// conditional branches in the hot paths based on profiles.
11//
12//===----------------------------------------------------------------------===//
13
16#include "llvm/ADT/DenseMap.h"
17#include "llvm/ADT/DenseSet.h"
19#include "llvm/ADT/StringSet.h"
27#include "llvm/IR/CFG.h"
28#include "llvm/IR/Dominators.h"
29#include "llvm/IR/IRBuilder.h"
31#include "llvm/IR/MDBuilder.h"
32#include "llvm/IR/Module.h"
33#include "llvm/IR/PassManager.h"
40
41#include <optional>
42#include <set>
43#include <sstream>
44
45using namespace llvm;
46
47#define DEBUG_TYPE "chr"
48
49#define CHR_DEBUG(X) LLVM_DEBUG(X)
50
53
54static void parseCHRFilterFiles() {
55 const InstrumentationOptions &Opts = InstrumentationOptions::Global;
56 if (!Opts.chr_module_list.empty()) {
57 auto FileOrErr = MemoryBuffer::getFile(Opts.chr_module_list);
58 if (!FileOrErr) {
59 errs() << "Error: Couldn't read the chr-module-list file "
60 << Opts.chr_module_list << "\n";
61 std::exit(1);
62 }
63 StringRef Buf = FileOrErr->get()->getBuffer();
65 Buf.split(Lines, '\n');
66 for (StringRef Line : Lines) {
67 Line = Line.trim();
68 if (!Line.empty())
69 CHRModules.insert(Line);
70 }
71 }
72 if (!Opts.chr_function_list.empty()) {
73 auto FileOrErr = MemoryBuffer::getFile(Opts.chr_function_list);
74 if (!FileOrErr) {
75 errs() << "Error: Couldn't read the chr-function-list file "
76 << Opts.chr_function_list << "\n";
77 std::exit(1);
78 }
79 StringRef Buf = FileOrErr->get()->getBuffer();
81 Buf.split(Lines, '\n');
82 for (StringRef Line : Lines) {
83 Line = Line.trim();
84 if (!Line.empty())
85 CHRFunctions.insert(Line);
86 }
87 }
88}
89
90namespace {
91
92struct CHRStats {
93 CHRStats() = default;
94 void print(raw_ostream &OS) const {
95 OS << "CHRStats: NumBranches " << NumBranches
96 << " NumBranchesDelta " << NumBranchesDelta
97 << " WeightedNumBranchesDelta " << WeightedNumBranchesDelta;
98 }
99 // The original number of conditional branches / selects
100 uint64_t NumBranches = 0;
101 // The decrease of the number of conditional branches / selects in the hot
102 // paths due to CHR.
103 uint64_t NumBranchesDelta = 0;
104 // NumBranchesDelta weighted by the profile count at the scope entry.
105 uint64_t WeightedNumBranchesDelta = 0;
106};
107
108// RegInfo - some properties of a Region.
109struct RegInfo {
110 RegInfo() = default;
111 RegInfo(Region *RegionIn) : R(RegionIn) {}
112 Region *R = nullptr;
113 bool HasBranch = false;
115};
116
117typedef DenseMap<Region *, DenseSet<Instruction *>> HoistStopMapTy;
118
119// CHRScope - a sequence of regions to CHR together. It corresponds to a
120// sequence of conditional blocks. It can have subscopes which correspond to
121// nested conditional blocks. Nested CHRScopes form a tree.
122class CHRScope {
123 public:
124 CHRScope(RegInfo RI) : BranchInsertPoint(nullptr) {
125 assert(RI.R && "Null RegionIn");
126 RegInfos.push_back(RI);
127 }
128
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");
133 return Parent;
134 }
135
136 BasicBlock *getEntryBlock() {
137 assert(RegInfos.size() > 0 && "Empty CHRScope");
138 return RegInfos.front().R->getEntry();
139 }
140
141 BasicBlock *getExitBlock() {
142 assert(RegInfos.size() > 0 && "Empty CHRScope");
143 return RegInfos.back().R->getExit();
144 }
145
146 bool appendable(CHRScope *Next) {
147 // The next scope is appendable only if this scope is directly connected to
148 // it (which implies it post-dominates this scope) and this scope dominates
149 // it (no edge to the next scope outside this scope).
150 BasicBlock *NextEntry = Next->getEntryBlock();
151 if (getExitBlock() != NextEntry)
152 // Not directly connected.
153 return false;
154 Region *LastRegion = RegInfos.back().R;
155 for (BasicBlock *Pred : predecessors(NextEntry))
156 if (!LastRegion->contains(Pred))
157 // There's an edge going into the entry of the next scope from outside
158 // of this scope.
159 return false;
160 return true;
161 }
162
163 void append(CHRScope *Next) {
164 assert(RegInfos.size() > 0 && "Empty CHRScope");
165 assert(Next->RegInfos.size() > 0 && "Empty CHRScope");
166 assert(getParentRegion() == Next->getParentRegion() &&
167 "Must be siblings");
168 assert(getExitBlock() == Next->getEntryBlock() &&
169 "Must be adjacent");
170 RegInfos.append(Next->RegInfos.begin(), Next->RegInfos.end());
171 Subs.append(Next->Subs.begin(), Next->Subs.end());
172 }
173
174 void addSub(CHRScope *SubIn) {
175#ifndef NDEBUG
176 bool IsChild = false;
177 for (RegInfo &RI : RegInfos)
178 if (RI.R == SubIn->getParentRegion()) {
179 IsChild = true;
180 break;
181 }
182 assert(IsChild && "Must be a child");
183#endif
184 Subs.push_back(SubIn);
185 }
186
187 // Split this scope at the boundary region into two, which will belong to the
188 // tail and returns the tail.
189 CHRScope *split(Region *Boundary) {
190 assert(Boundary && "Boundary null");
191 assert(RegInfos.begin()->R != Boundary &&
192 "Can't be split at beginning");
193 auto BoundaryIt = llvm::find_if(
194 RegInfos, [&Boundary](const RegInfo &RI) { return Boundary == RI.R; });
195 if (BoundaryIt == RegInfos.end())
196 return nullptr;
197 ArrayRef<RegInfo> TailRegInfos(BoundaryIt, RegInfos.end());
198 DenseSet<Region *> TailRegionSet;
199 for (const RegInfo &RI : TailRegInfos)
200 TailRegionSet.insert(RI.R);
201
202 auto TailIt =
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))
207 return false;
208
209 assert(llvm::any_of(
210 RegInfos,
211 [&Parent](const RegInfo &RI) { return Parent == RI.R; }) &&
212 "Must be in head");
213 return true;
214 });
215 ArrayRef<CHRScope *> TailSubs(TailIt, Subs.end());
216
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());
221 return Scope;
222 }
223
224 bool contains(Instruction *I) const {
225 BasicBlock *Parent = I->getParent();
226 for (const RegInfo &RI : RegInfos)
227 if (RI.R->contains(Parent))
228 return true;
229 return false;
230 }
231
232 void print(raw_ostream &OS) const;
233
234 SmallVector<RegInfo, 8> RegInfos; // Regions that belong to this scope
235 SmallVector<CHRScope *, 8> Subs; // Subscopes.
236
237 // The instruction at which to insert the CHR conditional branch (and hoist
238 // the dependent condition values).
239 Instruction *BranchInsertPoint;
240
241 // True-biased and false-biased regions (conditional blocks),
242 // respectively. Used only for the outermost scope and includes regions in
243 // subscopes. The rest are unbiased.
244 DenseSet<Region *> TrueBiasedRegions;
245 DenseSet<Region *> FalseBiasedRegions;
246 // Among the biased regions, the regions that get CHRed.
247 SmallVector<RegInfo, 8> CHRRegions;
248
249 // True-biased and false-biased selects, respectively. Used only for the
250 // outermost scope and includes ones in subscopes.
251 DenseSet<SelectInst *> TrueBiasedSelects;
252 DenseSet<SelectInst *> FalseBiasedSelects;
253
254 // Map from one of the above regions to the instructions to stop
255 // hoisting instructions at through use-def chains.
256 HoistStopMapTy HoistStopMap;
257
258 private:
259 CHRScope(ArrayRef<RegInfo> RegInfosIn, ArrayRef<CHRScope *> SubsIn)
260 : RegInfos(RegInfosIn), Subs(SubsIn), BranchInsertPoint(nullptr) {}
261};
262
263class CHR {
264public:
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),
269 ORE(OREin) {}
270
271 ~CHR() {
272 for (CHRScope *Scope : Scopes) {
273 delete Scope;
274 }
275 }
276
277 bool run();
278
279 private:
280 // See the comments in CHR::run() for the high level flow of the algorithm and
281 // what the following functions do.
282
283 void findScopes(SmallVectorImpl<CHRScope *> &Output) {
284 Region *R = RI.getTopLevelRegion();
285 if (CHRScope *Scope = findScopes(R, nullptr, nullptr, Output)) {
286 Output.push_back(Scope);
287 }
288 }
289 CHRScope *findScopes(Region *R, Region *NextRegion, Region *ParentRegion,
290 SmallVectorImpl<CHRScope *> &Scopes);
291 CHRScope *findScope(Region *R);
292 void checkScopeHoistable(CHRScope *Scope);
293
294 void splitScopes(SmallVectorImpl<CHRScope *> &Input,
295 SmallVectorImpl<CHRScope *> &Output);
296 SmallVector<CHRScope *, 8> splitScope(CHRScope *Scope,
297 CHRScope *Outer,
298 DenseSet<Value *> *OuterConditionValues,
299 Instruction *OuterInsertPoint,
300 SmallVectorImpl<CHRScope *> &Output,
301 DenseSet<Instruction *> &Unhoistables);
302
303 void classifyBiasedScopes(SmallVectorImpl<CHRScope *> &Scopes);
304 void classifyBiasedScopes(CHRScope *Scope, CHRScope *OutermostScope);
305
306 void filterScopes(SmallVectorImpl<CHRScope *> &Input,
307 SmallVectorImpl<CHRScope *> &Output);
308
309 void setCHRRegions(SmallVectorImpl<CHRScope *> &Input,
310 SmallVectorImpl<CHRScope *> &Output);
311 void setCHRRegions(CHRScope *Scope, CHRScope *OutermostScope);
312
313 void sortScopes(SmallVectorImpl<CHRScope *> &Input,
314 SmallVectorImpl<CHRScope *> &Output);
315
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,
321 Region *LastRegion,
322 ValueToValueMapTy &VMap);
323 CondBrInst *createMergedBranch(BasicBlock *PreEntryBlock,
324 BasicBlock *EntryBlock,
325 BasicBlock *NewEntryBlock,
326 ValueToValueMapTy &VMap);
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,
335 IRBuilder<> &IRB, Value *&MergedCondition);
336 unsigned getRegionDuplicationCount(const Region *R) {
337 unsigned Count = 0;
338 // Find out how many times region R is cloned. Note that if the parent
339 // of R is cloned, R is also cloned, but R's clone count is not updated
340 // from the clone of the parent. We need to accumulate all the counts
341 // from the ancestors to get the clone count.
342 while (R) {
343 Count += DuplicationCount[R];
344 R = R->getParent();
345 }
346 return Count;
347 }
348
349 const InstrumentationOptions &Opts;
350 Function &F;
351 BlockFrequencyInfo &BFI;
352 DominatorTree &DT;
353 ProfileSummaryInfo &PSI;
354 RegionInfo &RI;
355 OptimizationRemarkEmitter &ORE;
356 CHRStats Stats;
357
358 // All the true-biased regions in the function
359 DenseSet<Region *> TrueBiasedRegionsGlobal;
360 // All the false-biased regions in the function
361 DenseSet<Region *> FalseBiasedRegionsGlobal;
362 // All the true-biased selects in the function
363 DenseSet<SelectInst *> TrueBiasedSelectsGlobal;
364 // All the false-biased selects in the function
365 DenseSet<SelectInst *> FalseBiasedSelectsGlobal;
366 // A map from biased regions to their branch bias
367 DenseMap<Region *, BranchProbability> BranchBiasMap;
368 // A map from biased selects to their branch bias
369 DenseMap<SelectInst *, BranchProbability> SelectBiasMap;
370 // All the scopes.
371 DenseSet<CHRScope *> Scopes;
372 // This maps records how many times this region is cloned.
373 DenseMap<const Region *, unsigned> DuplicationCount;
374};
375
376} // end anonymous namespace
377
378[[maybe_unused]] static inline raw_ostream &operator<<(raw_ostream &OS,
379 const CHRStats &Stats) {
380 Stats.print(OS);
381 return OS;
382}
383
384static inline
385raw_ostream &operator<<(raw_ostream &OS, const CHRScope &Scope) {
386 Scope.print(OS);
387 return OS;
388}
389
390static bool shouldApply(const InstrumentationOptions &Opts, Function &F,
391 ProfileSummaryInfo &PSI) {
392 if (Opts.disable_chr)
393 return false;
394
395 if (Opts.force_chr)
396 return true;
397
398 if (!Opts.chr_module_list.empty() || !Opts.chr_function_list.empty()) {
399 if (CHRModules.count(F.getParent()->getName()))
400 return true;
401 return CHRFunctions.count(F.getName());
402 }
403
404 return PSI.isFunctionEntryHot(&F);
405}
406
407[[maybe_unused]] static void dumpIR(Function &F, const char *Label,
408 CHRStats *Stats) {
409 StringRef FuncName = F.getName();
410 StringRef ModuleName = F.getParent()->getName();
411 (void)(FuncName); // Unused in release build.
412 (void)(ModuleName); // Unused in release build.
413 CHR_DEBUG(dbgs() << "CHR IR dump " << Label << " " << ModuleName << " "
414 << FuncName);
415 if (Stats)
416 CHR_DEBUG(dbgs() << " " << *Stats);
417 CHR_DEBUG(dbgs() << "\n");
418 CHR_DEBUG(F.dump());
419}
420
421void CHRScope::print(raw_ostream &OS) const {
422 assert(RegInfos.size() > 0 && "Empty CHRScope");
423 OS << "CHRScope[";
424 OS << RegInfos.size() << ", Regions[";
425 for (const RegInfo &RI : RegInfos) {
426 OS << RI.R->getNameStr();
427 if (RI.HasBranch)
428 OS << " B";
429 if (RI.Selects.size() > 0)
430 OS << " S" << RI.Selects.size();
431 OS << ", ";
432 }
433 if (RegInfos[0].R->getParent()) {
434 OS << "], Parent " << RegInfos[0].R->getParent()->getNameStr();
435 } else {
436 // top level region
437 OS << "]";
438 }
439 OS << ", Subs[";
440 for (CHRScope *Sub : Subs) {
441 OS << *Sub << ", ";
442 }
443 OS << "]]";
444}
445
446// Return true if the given instruction type can be hoisted by CHR.
454
455// Return true if the given instruction can be hoisted by CHR.
458 return false;
459 return isSafeToSpeculativelyExecute(I, nullptr, nullptr, &DT);
460}
461
462// Recursively traverse the use-def chains of the given value and return a set
463// of the unhoistable base values defined within the scope (excluding the
464// first-region entry block) or the (hoistable or unhoistable) base values that
465// are defined outside (including the first-region entry block) of the
466// scope. The returned set doesn't include constants.
467static const std::set<Value *> &
469 DenseMap<Value *, std::set<Value *>> &Visited) {
470 auto It = Visited.find(V);
471 if (It != Visited.end()) {
472 return It->second;
473 }
474 std::set<Value *> Result;
475 if (auto *I = dyn_cast<Instruction>(V)) {
476 // We don't stop at a block that's not in the Scope because we would miss
477 // some instructions that are based on the same base values if we stop
478 // there.
479 if (!isHoistable(I, DT)) {
480 Result.insert(I);
481 return Visited.insert(std::make_pair(V, std::move(Result))).first->second;
482 }
483 // I is hoistable above the Scope.
484 for (Value *Op : I->operands()) {
485 const std::set<Value *> &OpResult = getBaseValues(Op, DT, Visited);
486 Result.insert(OpResult.begin(), OpResult.end());
487 }
488 return Visited.insert(std::make_pair(V, std::move(Result))).first->second;
489 }
490 if (isa<Argument>(V)) {
491 Result.insert(V);
492 }
493 // We don't include others like constants because those won't lead to any
494 // chance of folding of conditions (eg two bit checks merged into one check)
495 // after CHR.
496 return Visited.insert(std::make_pair(V, std::move(Result))).first->second;
497}
498
499// Return true if V is already hoisted or can be hoisted (along with its
500// operands) above the insert point. When it returns true and HoistStops is
501// non-null, the instructions to stop hoisting at through the use-def chains are
502// inserted into HoistStops.
503static bool
505 DenseSet<Instruction *> &Unhoistables,
506 DenseSet<Instruction *> *HoistStops,
508 assert(InsertPoint && "Null InsertPoint");
509 if (auto *I = dyn_cast<Instruction>(V)) {
510 auto It = Visited.find(I);
511 if (It != Visited.end()) {
512 return It->second;
513 }
514 assert(DT.getNode(I->getParent()) && "DT must contain I's parent block");
515 assert(DT.getNode(InsertPoint->getParent()) && "DT must contain Destination");
516 if (Unhoistables.count(I)) {
517 // Don't hoist if they are not to be hoisted.
518 Visited[I] = false;
519 return false;
520 }
521 if (DT.dominates(I, InsertPoint)) {
522 // We are already above the insert point. Stop here.
523 if (HoistStops)
524 HoistStops->insert(I);
525 Visited[I] = true;
526 return true;
527 }
528 // We aren't not above the insert point, check if we can hoist it above the
529 // insert point.
530 if (isHoistable(I, DT)) {
531 // Check operands first.
532 DenseSet<Instruction *> OpsHoistStops;
533 bool AllOpsHoisted = true;
534 for (Value *Op : I->operands()) {
535 if (!checkHoistValue(Op, InsertPoint, DT, Unhoistables, &OpsHoistStops,
536 Visited)) {
537 AllOpsHoisted = false;
538 break;
539 }
540 }
541 if (AllOpsHoisted) {
542 CHR_DEBUG(dbgs() << "checkHoistValue " << *I << "\n");
543 if (HoistStops)
544 HoistStops->insert_range(OpsHoistStops);
545 Visited[I] = true;
546 return true;
547 }
548 }
549 Visited[I] = false;
550 return false;
551 }
552 // Non-instructions are considered hoistable.
553 return true;
554}
555
556// Constructs the true and false branch probabilities if the the instruction has
557// valid branch weights. Returns true when this was successful, false otherwise.
559 BranchProbability &TrueProb,
560 BranchProbability &FalseProb) {
561 uint64_t TrueWeight;
562 uint64_t FalseWeight;
563 if (!extractBranchWeights(*I, TrueWeight, FalseWeight))
564 return false;
565 uint64_t SumWeight = TrueWeight + FalseWeight;
566
567 assert(SumWeight >= TrueWeight && SumWeight >= FalseWeight &&
568 "Overflow calculating branch probabilities.");
569
570 // Guard against 0-to-0 branch weights to avoid a division-by-zero crash.
571 if (SumWeight == 0)
572 return false;
573
574 TrueProb = BranchProbability::getBranchProbability(TrueWeight, SumWeight);
575 FalseProb = BranchProbability::getBranchProbability(FalseWeight, SumWeight);
576 return true;
577}
578
579static BranchProbability
580getCHRBiasThreshold(const InstrumentationOptions &Opts) {
582 static_cast<uint64_t>(Opts.chr_bias_threshold * 1000000), 1000000);
583}
584
585// A helper for CheckBiasedBranch and CheckBiasedSelect. If TrueProb >=
586// -chr-bias-threshold, put Key into TrueSet and return true. If FalseProb >=
587// -chr-bias-threshold, put Key into FalseSet and return true. Otherwise, return
588// false.
589template <typename K, typename S, typename M>
590static bool checkBias(const InstrumentationOptions &Opts, K *Key,
591 BranchProbability TrueProb, BranchProbability FalseProb,
592 S &TrueSet, S &FalseSet, M &BiasMap) {
593 BranchProbability Threshold = getCHRBiasThreshold(Opts);
594 if (TrueProb >= Threshold) {
595 TrueSet.insert(Key);
596 BiasMap[Key] = TrueProb;
597 return true;
598 } else if (FalseProb >= Threshold) {
599 FalseSet.insert(Key);
600 BiasMap[Key] = FalseProb;
601 return true;
602 }
603 return false;
604}
605
606// Returns true and insert a region into the right biased set and the map if the
607// branch of the region is biased.
608static bool
609checkBiasedBranch(const InstrumentationOptions &Opts, CondBrInst *BI, Region *R,
610 DenseSet<Region *> &TrueBiasedRegionsGlobal,
611 DenseSet<Region *> &FalseBiasedRegionsGlobal,
613 BranchProbability ThenProb, ElseProb;
614 if (!extractBranchProbabilities(BI, ThenProb, ElseProb))
615 return false;
616 BasicBlock *IfThen = BI->getSuccessor(0);
617 BasicBlock *IfElse = BI->getSuccessor(1);
618 assert((IfThen == R->getExit() || IfElse == R->getExit()) &&
619 IfThen != IfElse &&
620 "Invariant from findScopes");
621 if (IfThen == R->getExit()) {
622 // Swap them so that IfThen/ThenProb means going into the conditional code
623 // and IfElse/ElseProb means skipping it.
624 std::swap(IfThen, IfElse);
625 std::swap(ThenProb, ElseProb);
626 }
627 CHR_DEBUG(dbgs() << "BI " << *BI << " ");
628 CHR_DEBUG(dbgs() << "ThenProb " << ThenProb << " ");
629 CHR_DEBUG(dbgs() << "ElseProb " << ElseProb << "\n");
630 return checkBias(Opts, R, ThenProb, ElseProb, TrueBiasedRegionsGlobal,
631 FalseBiasedRegionsGlobal, BranchBiasMap);
632}
633
634// Returns true and insert a select into the right biased set and the map if the
635// select is biased.
636static bool
637checkBiasedSelect(const InstrumentationOptions &Opts, SelectInst *SI, Region *R,
638 DenseSet<SelectInst *> &TrueBiasedSelectsGlobal,
639 DenseSet<SelectInst *> &FalseBiasedSelectsGlobal,
641 BranchProbability TrueProb, FalseProb;
642 if (!extractBranchProbabilities(SI, TrueProb, FalseProb))
643 return false;
644 CHR_DEBUG(dbgs() << "SI " << *SI << " ");
645 CHR_DEBUG(dbgs() << "TrueProb " << TrueProb << " ");
646 CHR_DEBUG(dbgs() << "FalseProb " << FalseProb << "\n");
647 return checkBias(Opts, SI, TrueProb, FalseProb, TrueBiasedSelectsGlobal,
648 FalseBiasedSelectsGlobal, SelectBiasMap);
649}
650
651// Returns the instruction at which to hoist the dependent condition values and
652// insert the CHR branch for a region. This is the terminator branch in the
653// entry block or the first select in the entry block, if any.
655 Region *R = RI.R;
656 BasicBlock *EntryBB = R->getEntry();
657 // The hoist point is by default the terminator of the entry block, which is
658 // the same as the branch instruction if RI.HasBranch is true.
659 Instruction *HoistPoint = EntryBB->getTerminator();
660 for (SelectInst *SI : RI.Selects) {
661 if (SI->getParent() == EntryBB) {
662 // Pick the first select in Selects in the entry block. Note Selects is
663 // sorted in the instruction order within a block (asserted below).
664 HoistPoint = SI;
665 break;
666 }
667 }
668 assert(HoistPoint && "Null HoistPoint");
669#ifndef NDEBUG
670 // Check that HoistPoint is the first one in Selects in the entry block,
671 // if any.
672 DenseSet<Instruction *> EntryBlockSelectSet;
673 for (SelectInst *SI : RI.Selects) {
674 if (SI->getParent() == EntryBB) {
675 EntryBlockSelectSet.insert(SI);
676 }
677 }
678 for (Instruction &I : *EntryBB) {
679 if (EntryBlockSelectSet.contains(&I)) {
680 assert(&I == HoistPoint &&
681 "HoistPoint must be the first one in Selects");
682 break;
683 }
684 }
685#endif
686 return HoistPoint;
687}
688
689// Find a CHR scope in the given region.
690CHRScope * CHR::findScope(Region *R) {
691 CHRScope *Result = nullptr;
692 BasicBlock *Entry = R->getEntry();
693 BasicBlock *Exit = R->getExit(); // null if top level.
694 assert(Entry && "Entry must not be null");
695 assert((Exit == nullptr) == (R->isTopLevelRegion()) &&
696 "Only top level region has a null exit");
697 if (Entry)
698 CHR_DEBUG(dbgs() << "Entry " << Entry->getName() << "\n");
699 else
700 CHR_DEBUG(dbgs() << "Entry null\n");
701 if (Exit)
702 CHR_DEBUG(dbgs() << "Exit " << Exit->getName() << "\n");
703 else
704 CHR_DEBUG(dbgs() << "Exit null\n");
705 // Exclude cases where Entry is part of a subregion (hence it doesn't belong
706 // to this region).
707 bool EntryInSubregion = RI.getRegionFor(Entry) != R;
708 if (EntryInSubregion)
709 return nullptr;
710 // Exclude loops
711 for (BasicBlock *Pred : predecessors(Entry))
712 if (R->contains(Pred))
713 return nullptr;
714 // If any of the basic blocks have address taken, we must skip this region
715 // because we cannot clone basic blocks that have address taken.
716 for (BasicBlock *BB : R->blocks()) {
717 if (BB->hasAddressTaken())
718 return nullptr;
719 // If we encounter llvm.coro.id, skip this region because if the basic block
720 // is cloned, we end up inserting a token type PHI node to the block with
721 // llvm.coro.begin.
722 // FIXME: This could lead to less optimal codegen, because the region is
723 // excluded, it can prevent CHR from merging adjacent regions into bigger
724 // scope and hoisting more branches.
725 for (Instruction &I : *BB) {
726 if (auto *II = dyn_cast<IntrinsicInst>(&I))
727 if (II->getIntrinsicID() == Intrinsic::coro_id)
728 return nullptr;
729 // Can't clone regions containing convergent or noduplicate calls.
730 //
731 // CHR clones a region into hot/cold paths guarded by a merged
732 // speculative branch. On GPU targets, this branch may be divergent
733 // (different threads evaluate it differently), splitting the set of
734 // threads that reach each copy. A convergent call (e.g. a cross-lane
735 // operation like ds_bpermute on AMDGPU) requires a specific set of
736 // threads to be active; when CHR places a copy on the hot path, only
737 // the threads that took the hot branch are active, so the operation
738 // reads stale values from threads that went to the cold path.
739 //
740 // Similarly, noduplicate calls must not be duplicated by definition.
741 //
742 // This matches SimplifyCFG's block-duplication guard.
743 if (auto *CB = dyn_cast<CallBase>(&I)) {
744 if (CB->cannotDuplicate() || CB->isConvergent())
745 return nullptr;
746 }
747 }
748 }
749
750 if (Exit) {
751 // Try to find an if-then block (check if R is an if-then).
752 // if (cond) {
753 // ...
754 // }
755 if (auto *BI = dyn_cast<CondBrInst>(Entry->getTerminator())) {
756 CHR_DEBUG(dbgs() << "BI conditional\n");
757 BasicBlock *S0 = BI->getSuccessor(0);
758 BasicBlock *S1 = BI->getSuccessor(1);
759 CHR_DEBUG(dbgs() << "S0 " << S0->getName() << "\n");
760 CHR_DEBUG(dbgs() << "S1 " << S1->getName() << "\n");
761 if (S0 != S1 && (S0 == Exit || S1 == Exit)) {
762 RegInfo RI(R);
763 RI.HasBranch =
764 checkBiasedBranch(Opts, BI, R, TrueBiasedRegionsGlobal,
765 FalseBiasedRegionsGlobal, BranchBiasMap);
766 Result = new CHRScope(RI);
767 Scopes.insert(Result);
768 CHR_DEBUG(dbgs() << "Found a region with a branch\n");
769 ++Stats.NumBranches;
770 if (!RI.HasBranch) {
771 ORE.emit([&]() {
772 return OptimizationRemarkMissed(DEBUG_TYPE, "BranchNotBiased", BI)
773 << "Branch not biased";
774 });
775 }
776 }
777 }
778 }
779 {
780 // Try to look for selects in the direct child blocks (as opposed to in
781 // subregions) of R.
782 // ...
783 // if (..) { // Some subregion
784 // ...
785 // }
786 // if (..) { // Some subregion
787 // ...
788 // }
789 // ...
790 // a = cond ? b : c;
791 // ...
793 for (RegionNode *E : R->elements()) {
794 if (E->isSubRegion())
795 continue;
796 // This returns the basic block of E if E is a direct child of R (not a
797 // subregion.)
798 BasicBlock *BB = E->getEntry();
799 // Need to push in the order to make it easier to find the first Select
800 // later.
801 for (Instruction &I : *BB) {
802 if (auto *SI = dyn_cast<SelectInst>(&I)) {
803 Selects.push_back(SI);
804 ++Stats.NumBranches;
805 }
806 }
807 }
808 if (Selects.size() > 0) {
809 auto AddSelects = [&](RegInfo &RI) {
810 for (auto *SI : Selects)
811 if (checkBiasedSelect(Opts, SI, RI.R, TrueBiasedSelectsGlobal,
812 FalseBiasedSelectsGlobal, SelectBiasMap))
813 RI.Selects.push_back(SI);
814 else
815 ORE.emit([&]() {
816 return OptimizationRemarkMissed(DEBUG_TYPE, "SelectNotBiased", SI)
817 << "Select not biased";
818 });
819 };
820 if (!Result) {
821 CHR_DEBUG(dbgs() << "Found a select-only region\n");
822 RegInfo RI(R);
823 AddSelects(RI);
824 Result = new CHRScope(RI);
825 Scopes.insert(Result);
826 } else {
827 CHR_DEBUG(dbgs() << "Found select(s) in a region with a branch\n");
828 AddSelects(Result->RegInfos[0]);
829 }
830 }
831 }
832
833 if (Result) {
834 checkScopeHoistable(Result);
835 }
836 return Result;
837}
838
839// Check that any of the branch and the selects in the region could be
840// hoisted above the the CHR branch insert point (the most dominating of
841// them, either the branch (at the end of the first block) or the first
842// select in the first block). If the branch can't be hoisted, drop the
843// selects in the first blocks.
844//
845// For example, for the following scope/region with selects, we want to insert
846// the merged branch right before the first select in the first/entry block by
847// hoisting c1, c2, c3, and c4.
848//
849// // Branch insert point here.
850// a = c1 ? b : c; // Select 1
851// d = c2 ? e : f; // Select 2
852// if (c3) { // Branch
853// ...
854// c4 = foo() // A call.
855// g = c4 ? h : i; // Select 3
856// }
857//
858// But suppose we can't hoist c4 because it's dependent on the preceding
859// call. Then, we drop Select 3. Furthermore, if we can't hoist c2, we also drop
860// Select 2. If we can't hoist c3, we drop Selects 1 & 2.
861void CHR::checkScopeHoistable(CHRScope *Scope) {
862 RegInfo &RI = Scope->RegInfos[0];
863 Region *R = RI.R;
864 BasicBlock *EntryBB = R->getEntry();
865 auto *Branch =
866 RI.HasBranch ? cast<CondBrInst>(EntryBB->getTerminator()) : nullptr;
867 SmallVector<SelectInst *, 8> &Selects = RI.Selects;
868 if (RI.HasBranch || !Selects.empty()) {
869 Instruction *InsertPoint = getBranchInsertPoint(RI);
870 CHR_DEBUG(dbgs() << "InsertPoint " << *InsertPoint << "\n");
871 // Avoid a data dependence from a select or a branch to a(nother)
872 // select. Note no instruction can't data-depend on a branch (a branch
873 // instruction doesn't produce a value).
874 // Initialize Unhoistables with the selects.
875 DenseSet<Instruction *> Unhoistables(llvm::from_range, Selects);
876 // Remove Selects that can't be hoisted.
877 for (auto it = Selects.begin(); it != Selects.end(); ) {
878 SelectInst *SI = *it;
879 if (SI == InsertPoint) {
880 ++it;
881 continue;
882 }
883 DenseMap<Instruction *, bool> Visited;
884 bool IsHoistable = checkHoistValue(SI->getCondition(), InsertPoint,
885 DT, Unhoistables, nullptr, Visited);
886 if (!IsHoistable) {
887 CHR_DEBUG(dbgs() << "Dropping select " << *SI << "\n");
888 ORE.emit([&]() {
889 return OptimizationRemarkMissed(DEBUG_TYPE,
890 "DropUnhoistableSelect", SI)
891 << "Dropped unhoistable select";
892 });
893 it = Selects.erase(it);
894 // Since we are dropping the select here, we also drop it from
895 // Unhoistables.
896 Unhoistables.erase(SI);
897 } else
898 ++it;
899 }
900 // Update InsertPoint after potentially removing selects.
901 InsertPoint = getBranchInsertPoint(RI);
902 CHR_DEBUG(dbgs() << "InsertPoint " << *InsertPoint << "\n");
903 if (RI.HasBranch && InsertPoint != Branch) {
904 DenseMap<Instruction *, bool> Visited;
905 bool IsHoistable = checkHoistValue(Branch->getCondition(), InsertPoint,
906 DT, Unhoistables, nullptr, Visited);
907 if (!IsHoistable) {
908 // If the branch isn't hoistable, drop the selects in the entry
909 // block, preferring the branch, which makes the branch the hoist
910 // point.
911 assert(InsertPoint != Branch && "Branch must not be the hoist point");
912 CHR_DEBUG(dbgs() << "Dropping selects in entry block \n");
913 CHR_DEBUG(
914 for (SelectInst *SI : Selects) {
915 dbgs() << "SI " << *SI << "\n";
916 });
917 for (SelectInst *SI : Selects) {
918 ORE.emit([&]() {
919 return OptimizationRemarkMissed(DEBUG_TYPE,
920 "DropSelectUnhoistableBranch", SI)
921 << "Dropped select due to unhoistable branch";
922 });
923 }
924 llvm::erase_if(Selects, [EntryBB](SelectInst *SI) {
925 return SI->getParent() == EntryBB;
926 });
927 Unhoistables.clear();
928 InsertPoint = Branch;
929 }
930 }
931 CHR_DEBUG(dbgs() << "InsertPoint " << *InsertPoint << "\n");
932#ifndef NDEBUG
933 if (RI.HasBranch) {
934 assert(!DT.dominates(Branch, InsertPoint) &&
935 "Branch can't be already above the hoist point");
936 DenseMap<Instruction *, bool> Visited;
937 assert(checkHoistValue(Branch->getCondition(), InsertPoint,
938 DT, Unhoistables, nullptr, Visited) &&
939 "checkHoistValue for branch");
940 }
941 for (auto *SI : Selects) {
942 assert(!DT.dominates(SI, InsertPoint) &&
943 "SI can't be already above the hoist point");
944 DenseMap<Instruction *, bool> Visited;
945 assert(checkHoistValue(SI->getCondition(), InsertPoint, DT,
946 Unhoistables, nullptr, Visited) &&
947 "checkHoistValue for selects");
948 }
949 CHR_DEBUG(dbgs() << "Result\n");
950 if (RI.HasBranch) {
951 CHR_DEBUG(dbgs() << "BI " << *Branch << "\n");
952 }
953 for (auto *SI : Selects) {
954 CHR_DEBUG(dbgs() << "SI " << *SI << "\n");
955 }
956#endif
957 }
958}
959
960// Traverse the region tree, find all nested scopes and merge them if possible.
961CHRScope * CHR::findScopes(Region *R, Region *NextRegion, Region *ParentRegion,
962 SmallVectorImpl<CHRScope *> &Scopes) {
963 CHR_DEBUG(dbgs() << "findScopes " << R->getNameStr() << "\n");
964 CHRScope *Result = findScope(R);
965 // Visit subscopes.
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()
973 << "\n");
974 CHRScope *SubCHRScope = findScopes(SubR.get(), NextSubR, R, Scopes);
975 if (SubCHRScope) {
976 CHR_DEBUG(dbgs() << "Subregion Scope " << *SubCHRScope << "\n");
977 } else {
978 CHR_DEBUG(dbgs() << "Subregion Scope null\n");
979 }
980 if (SubCHRScope) {
981 if (!ConsecutiveSubscope)
982 ConsecutiveSubscope = SubCHRScope;
983 else if (!ConsecutiveSubscope->appendable(SubCHRScope)) {
984 Subscopes.push_back(ConsecutiveSubscope);
985 ConsecutiveSubscope = SubCHRScope;
986 } else
987 ConsecutiveSubscope->append(SubCHRScope);
988 } else {
989 if (ConsecutiveSubscope) {
990 Subscopes.push_back(ConsecutiveSubscope);
991 }
992 ConsecutiveSubscope = nullptr;
993 }
994 }
995 if (ConsecutiveSubscope) {
996 Subscopes.push_back(ConsecutiveSubscope);
997 }
998 for (CHRScope *Sub : Subscopes) {
999 if (Result) {
1000 // Combine it with the parent.
1001 Result->addSub(Sub);
1002 } else {
1003 // Push Subscopes as they won't be combined with the parent.
1004 Scopes.push_back(Sub);
1005 }
1006 }
1007 return Result;
1008}
1009
1011 DenseSet<Value *> ConditionValues;
1012 if (RI.HasBranch) {
1013 auto *BI = cast<CondBrInst>(RI.R->getEntry()->getTerminator());
1014 ConditionValues.insert(BI->getCondition());
1015 }
1016 for (SelectInst *SI : RI.Selects) {
1017 ConditionValues.insert(SI->getCondition());
1018 }
1019 return ConditionValues;
1020}
1021
1022
1023// Determine whether to split a scope depending on the sets of the branch
1024// condition values of the previous region and the current region. We split
1025// (return true) it if 1) the condition values of the inner/lower scope can't be
1026// hoisted up to the outer/upper scope, or 2) the two sets of the condition
1027// values have an empty intersection (because the combined branch conditions
1028// won't probably lead to a simpler combined condition).
1030 DenseSet<Value *> &PrevConditionValues,
1031 DenseSet<Value *> &ConditionValues,
1032 DominatorTree &DT,
1033 DenseSet<Instruction *> &Unhoistables) {
1034 assert(InsertPoint && "Null InsertPoint");
1035 CHR_DEBUG(
1036 dbgs() << "shouldSplit " << *InsertPoint << " PrevConditionValues ";
1037 for (Value *V : PrevConditionValues) {
1038 dbgs() << *V << ", ";
1039 }
1040 dbgs() << " ConditionValues ";
1041 for (Value *V : ConditionValues) {
1042 dbgs() << *V << ", ";
1043 }
1044 dbgs() << "\n");
1045 // If any of Bases isn't hoistable to the hoist point, split.
1046 for (Value *V : ConditionValues) {
1048 if (!checkHoistValue(V, InsertPoint, DT, Unhoistables, nullptr, Visited)) {
1049 CHR_DEBUG(dbgs() << "Split. checkHoistValue false " << *V << "\n");
1050 return true; // Not hoistable, split.
1051 }
1052 }
1053 // If PrevConditionValues or ConditionValues is empty, don't split to avoid
1054 // unnecessary splits at scopes with no branch/selects. If
1055 // PrevConditionValues and ConditionValues don't intersect at all, split.
1056 if (!PrevConditionValues.empty() && !ConditionValues.empty()) {
1057 // Use std::set as DenseSet doesn't work with set_intersection.
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());
1063 }
1064 for (Value *V : ConditionValues) {
1065 const std::set<Value *> &BaseValues = getBaseValues(V, DT, Visited);
1066 Bases.insert(BaseValues.begin(), BaseValues.end());
1067 }
1068 CHR_DEBUG(
1069 dbgs() << "PrevBases ";
1070 for (Value *V : PrevBases) {
1071 dbgs() << *V << ", ";
1072 }
1073 dbgs() << " Bases ";
1074 for (Value *V : Bases) {
1075 dbgs() << *V << ", ";
1076 }
1077 dbgs() << "\n");
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()) {
1082 // Empty intersection, split.
1083 CHR_DEBUG(dbgs() << "Split. Intersection empty\n");
1084 return true;
1085 }
1086 }
1087 CHR_DEBUG(dbgs() << "No split\n");
1088 return false; // Don't split.
1089}
1090
1091static void getSelectsInScope(CHRScope *Scope,
1092 DenseSet<Instruction *> &Output) {
1093 for (RegInfo &RI : Scope->RegInfos)
1094 Output.insert_range(RI.Selects);
1095 for (CHRScope *Sub : Scope->Subs)
1096 getSelectsInScope(Sub, Output);
1097}
1098
1099void CHR::splitScopes(SmallVectorImpl<CHRScope *> &Input,
1100 SmallVectorImpl<CHRScope *> &Output) {
1101 for (CHRScope *Scope : Input) {
1102 assert(!Scope->BranchInsertPoint &&
1103 "BranchInsertPoint must not be set");
1104 DenseSet<Instruction *> Unhoistables;
1105 getSelectsInScope(Scope, Unhoistables);
1106 splitScope(Scope, nullptr, nullptr, nullptr, Output, Unhoistables);
1107 }
1108#ifndef NDEBUG
1109 for (CHRScope *Scope : Output) {
1110 assert(Scope->BranchInsertPoint && "BranchInsertPoint must be set");
1111 }
1112#endif
1113}
1114
1115SmallVector<CHRScope *, 8> CHR::splitScope(
1116 CHRScope *Scope,
1117 CHRScope *Outer,
1118 DenseSet<Value *> *OuterConditionValues,
1119 Instruction *OuterInsertPoint,
1120 SmallVectorImpl<CHRScope *> &Output,
1121 DenseSet<Instruction *> &Unhoistables) {
1122 if (Outer) {
1123 assert(OuterConditionValues && "Null OuterConditionValues");
1124 assert(OuterInsertPoint && "Null OuterInsertPoint");
1125 }
1126 bool PrevSplitFromOuter = true;
1127 DenseSet<Value *> PrevConditionValues;
1128 Instruction *PrevInsertPoint = nullptr;
1130 SmallVector<bool, 8> SplitsSplitFromOuter;
1131 SmallVector<DenseSet<Value *>, 8> SplitsConditionValues;
1132 SmallVector<Instruction *, 8> SplitsInsertPoints;
1133 SmallVector<RegInfo, 8> RegInfos(Scope->RegInfos); // Copy
1134 for (RegInfo &RI : RegInfos) {
1135 Instruction *InsertPoint = getBranchInsertPoint(RI);
1136 DenseSet<Value *> ConditionValues = getCHRConditionValuesForRegion(RI);
1137 CHR_DEBUG(
1138 dbgs() << "ConditionValues ";
1139 for (Value *V : ConditionValues) {
1140 dbgs() << *V << ", ";
1141 }
1142 dbgs() << "\n");
1143 if (RI.R == RegInfos[0].R) {
1144 // First iteration. Check to see if we should split from the outer.
1145 if (Outer) {
1146 CHR_DEBUG(dbgs() << "Outer " << *Outer << "\n");
1147 CHR_DEBUG(dbgs() << "Should split from outer at "
1148 << RI.R->getNameStr() << "\n");
1149 if (shouldSplit(OuterInsertPoint, *OuterConditionValues,
1150 ConditionValues, DT, Unhoistables)) {
1151 PrevConditionValues = ConditionValues;
1152 PrevInsertPoint = InsertPoint;
1153 ORE.emit([&]() {
1154 return OptimizationRemarkMissed(DEBUG_TYPE,
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";
1159 });
1160 } else {
1161 // Not splitting from the outer. Use the outer bases and insert
1162 // point. Union the bases.
1163 PrevSplitFromOuter = false;
1164 PrevConditionValues = *OuterConditionValues;
1165 PrevConditionValues.insert_range(ConditionValues);
1166 PrevInsertPoint = OuterInsertPoint;
1167 }
1168 } else {
1169 CHR_DEBUG(dbgs() << "Outer null\n");
1170 PrevConditionValues = ConditionValues;
1171 PrevInsertPoint = InsertPoint;
1172 }
1173 } else {
1174 CHR_DEBUG(dbgs() << "Should split from prev at "
1175 << RI.R->getNameStr() << "\n");
1176 if (shouldSplit(PrevInsertPoint, PrevConditionValues, ConditionValues,
1177 DT, Unhoistables)) {
1178 CHRScope *Tail = Scope->split(RI.R);
1179 Scopes.insert(Tail);
1180 Splits.push_back(Scope);
1181 SplitsSplitFromOuter.push_back(PrevSplitFromOuter);
1182 SplitsConditionValues.push_back(PrevConditionValues);
1183 SplitsInsertPoints.push_back(PrevInsertPoint);
1184 Scope = Tail;
1185 PrevConditionValues = ConditionValues;
1186 PrevInsertPoint = InsertPoint;
1187 PrevSplitFromOuter = true;
1188 ORE.emit([&]() {
1189 return OptimizationRemarkMissed(DEBUG_TYPE,
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";
1194 });
1195 } else {
1196 // Not splitting. Union the bases. Keep the hoist point.
1197 PrevConditionValues.insert_range(ConditionValues);
1198 }
1199 }
1200 }
1201 Splits.push_back(Scope);
1202 SplitsSplitFromOuter.push_back(PrevSplitFromOuter);
1203 SplitsConditionValues.push_back(PrevConditionValues);
1204 assert(PrevInsertPoint && "Null PrevInsertPoint");
1205 SplitsInsertPoints.push_back(PrevInsertPoint);
1206 assert(Splits.size() == SplitsConditionValues.size() &&
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];
1212 Instruction *SplitInsertPoint = SplitsInsertPoints[I];
1214 DenseSet<Instruction *> SplitUnhoistables;
1215 getSelectsInScope(Split, SplitUnhoistables);
1216 for (CHRScope *Sub : Split->Subs) {
1217 SmallVector<CHRScope *, 8> SubSplits = splitScope(
1218 Sub, Split, &SplitConditionValues, SplitInsertPoint, Output,
1219 SplitUnhoistables);
1220 llvm::append_range(NewSubs, SubSplits);
1221 }
1222 Split->Subs = NewSubs;
1223 }
1225 for (size_t I = 0; I < Splits.size(); ++I) {
1226 CHRScope *Split = Splits[I];
1227 if (SplitsSplitFromOuter[I]) {
1228 // Split from the outer.
1229 Output.push_back(Split);
1230 Split->BranchInsertPoint = SplitsInsertPoints[I];
1231 CHR_DEBUG(dbgs() << "BranchInsertPoint " << *SplitsInsertPoints[I]
1232 << "\n");
1233 } else {
1234 // Connected to the outer.
1235 Result.push_back(Split);
1236 }
1237 }
1238 if (!Outer)
1239 assert(Result.empty() &&
1240 "If no outer (top-level), must return no nested ones");
1241 return Result;
1242}
1243
1244void CHR::classifyBiasedScopes(SmallVectorImpl<CHRScope *> &Scopes) {
1245 for (CHRScope *Scope : Scopes) {
1246 assert(Scope->TrueBiasedRegions.empty() && Scope->FalseBiasedRegions.empty() && "Empty");
1247 classifyBiasedScopes(Scope, Scope);
1248 CHR_DEBUG(
1249 dbgs() << "classifyBiasedScopes " << *Scope << "\n";
1250 dbgs() << "TrueBiasedRegions ";
1251 for (Region *R : Scope->TrueBiasedRegions) {
1252 dbgs() << R->getNameStr() << ", ";
1253 }
1254 dbgs() << "\n";
1255 dbgs() << "FalseBiasedRegions ";
1256 for (Region *R : Scope->FalseBiasedRegions) {
1257 dbgs() << R->getNameStr() << ", ";
1258 }
1259 dbgs() << "\n";
1260 dbgs() << "TrueBiasedSelects ";
1261 for (SelectInst *SI : Scope->TrueBiasedSelects) {
1262 dbgs() << *SI << ", ";
1263 }
1264 dbgs() << "\n";
1265 dbgs() << "FalseBiasedSelects ";
1266 for (SelectInst *SI : Scope->FalseBiasedSelects) {
1267 dbgs() << *SI << ", ";
1268 }
1269 dbgs() << "\n";);
1270 }
1271}
1272
1273void CHR::classifyBiasedScopes(CHRScope *Scope, CHRScope *OutermostScope) {
1274 for (RegInfo &RI : Scope->RegInfos) {
1275 if (RI.HasBranch) {
1276 Region *R = RI.R;
1277 if (TrueBiasedRegionsGlobal.contains(R))
1278 OutermostScope->TrueBiasedRegions.insert(R);
1279 else if (FalseBiasedRegionsGlobal.contains(R))
1280 OutermostScope->FalseBiasedRegions.insert(R);
1281 else
1282 llvm_unreachable("Must be biased");
1283 }
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);
1289 else
1290 llvm_unreachable("Must be biased");
1291 }
1292 }
1293 for (CHRScope *Sub : Scope->Subs) {
1294 classifyBiasedScopes(Sub, OutermostScope);
1295 }
1296}
1297
1298static bool hasAtLeastTwoBiasedBranches(const InstrumentationOptions &Opts,
1299 CHRScope *Scope) {
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;
1305}
1306
1307void CHR::filterScopes(SmallVectorImpl<CHRScope *> &Input,
1308 SmallVectorImpl<CHRScope *> &Output) {
1309 for (CHRScope *Scope : Input) {
1310 // Filter out the ones with only one region and no subs.
1311 if (!hasAtLeastTwoBiasedBranches(Opts, Scope)) {
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");
1317 ORE.emit([&]() {
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)";
1324 });
1325 continue;
1326 }
1327 Output.push_back(Scope);
1328 }
1329}
1330
1331void CHR::setCHRRegions(SmallVectorImpl<CHRScope *> &Input,
1332 SmallVectorImpl<CHRScope *> &Output) {
1333 for (CHRScope *Scope : Input) {
1334 assert(Scope->HoistStopMap.empty() && Scope->CHRRegions.empty() &&
1335 "Empty");
1336 setCHRRegions(Scope, Scope);
1337 Output.push_back(Scope);
1338 CHR_DEBUG(
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";
1345 }
1346 }
1347 dbgs() << "CHRRegions" << "\n";
1348 for (RegInfo &RI : Scope->CHRRegions) {
1349 dbgs() << RI.R->getNameStr() << "\n";
1350 });
1351 }
1352}
1353
1354void CHR::setCHRRegions(CHRScope *Scope, CHRScope *OutermostScope) {
1355 DenseSet<Instruction *> Unhoistables;
1356 // Put the biased selects in Unhoistables because they should stay where they
1357 // are and constant-folded after CHR (in case one biased select or a branch
1358 // can depend on another biased select.)
1359 for (RegInfo &RI : Scope->RegInfos)
1360 Unhoistables.insert_range(RI.Selects);
1361 Instruction *InsertPoint = OutermostScope->BranchInsertPoint;
1362 for (RegInfo &RI : Scope->RegInfos) {
1363 Region *R = RI.R;
1364 DenseSet<Instruction *> HoistStops;
1365 bool IsHoisted = false;
1366 if (RI.HasBranch) {
1367 assert((OutermostScope->TrueBiasedRegions.contains(R) ||
1368 OutermostScope->FalseBiasedRegions.contains(R)) &&
1369 "Must be truthy or falsy");
1370 auto *BI = cast<CondBrInst>(R->getEntry()->getTerminator());
1371 // Note checkHoistValue fills in HoistStops.
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); // Unused in release build
1377 IsHoisted = true;
1378 }
1379 for (SelectInst *SI : RI.Selects) {
1380 assert((OutermostScope->TrueBiasedSelects.contains(SI) ||
1381 OutermostScope->FalseBiasedSelects.contains(SI)) &&
1382 "Must be true or false biased");
1383 // Note checkHoistValue fills in HoistStops.
1384 DenseMap<Instruction *, bool> Visited;
1385 bool IsHoistable = checkHoistValue(SI->getCondition(), InsertPoint, DT,
1386 Unhoistables, &HoistStops, Visited);
1387 assert(IsHoistable && "Must be hoistable");
1388 (void)(IsHoistable); // Unused in release build
1389 IsHoisted = true;
1390 }
1391 if (IsHoisted) {
1392 OutermostScope->CHRRegions.push_back(RI);
1393 OutermostScope->HoistStopMap[R] = HoistStops;
1394 }
1395 }
1396 for (CHRScope *Sub : Scope->Subs)
1397 setCHRRegions(Sub, OutermostScope);
1398}
1399
1400static bool CHRScopeSorter(CHRScope *Scope1, CHRScope *Scope2) {
1401 return Scope1->RegInfos[0].R->getDepth() < Scope2->RegInfos[0].R->getDepth();
1402}
1403
1404void CHR::sortScopes(SmallVectorImpl<CHRScope *> &Input,
1405 SmallVectorImpl<CHRScope *> &Output) {
1406 Output.resize(Input.size());
1407 llvm::copy(Input, Output.begin());
1409}
1410
1411// Return true if V is already hoisted or was hoisted (along with its operands)
1412// to the insert point.
1413static void hoistValue(Value *V, Instruction *HoistPoint, Region *R,
1414 HoistStopMapTy &HoistStopMap,
1415 DenseSet<Instruction *> &HoistedSet,
1416 DenseSet<PHINode *> &TrivialPHIs,
1417 DominatorTree &DT) {
1418 auto IT = HoistStopMap.find(R);
1419 assert(IT != HoistStopMap.end() && "Region must be in hoist stop map");
1420 DenseSet<Instruction *> &HoistStops = IT->second;
1421 if (auto *I = dyn_cast<Instruction>(V)) {
1422 if (I == HoistPoint)
1423 return;
1424 if (HoistStops.count(I))
1425 return;
1426 if (auto *PN = dyn_cast<PHINode>(I))
1427 if (TrivialPHIs.count(PN))
1428 // The trivial phi inserted by the previous CHR scope could replace a
1429 // non-phi in HoistStops. Note that since this phi is at the exit of a
1430 // previous CHR scope, which dominates this scope, it's safe to stop
1431 // hoisting there.
1432 return;
1433 if (HoistedSet.count(I))
1434 // Already hoisted, return.
1435 return;
1436 assert(isHoistableInstructionType(I) && "Unhoistable instruction type");
1437 assert(DT.getNode(I->getParent()) && "DT must contain I's block");
1438 assert(DT.getNode(HoistPoint->getParent()) &&
1439 "DT must contain HoistPoint block");
1440 if (DT.dominates(I, HoistPoint))
1441 // We are already above the hoist point. Stop here. This may be necessary
1442 // when multiple scopes would independently hoist the same
1443 // instruction. Since an outer (dominating) scope would hoist it to its
1444 // entry before an inner (dominated) scope would to its entry, the inner
1445 // scope may see the instruction already hoisted, in which case it
1446 // potentially wrong for the inner scope to hoist it and could cause bad
1447 // IR (non-dominating def), but safe to skip hoisting it instead because
1448 // it's already in a block that dominates the inner scope.
1449 return;
1450 for (Value *Op : I->operands()) {
1451 hoistValue(Op, HoistPoint, R, HoistStopMap, HoistedSet, TrivialPHIs, DT);
1452 }
1453 I->moveBefore(HoistPoint->getIterator());
1454 HoistedSet.insert(I);
1455 CHR_DEBUG(dbgs() << "hoistValue " << *I << "\n");
1456 }
1457}
1458
1459// Hoist the dependent condition values of the branches and the selects in the
1460// scope to the insert point.
1461static void hoistScopeConditions(CHRScope *Scope, Instruction *HoistPoint,
1462 DenseSet<PHINode *> &TrivialPHIs,
1463 DominatorTree &DT) {
1464 DenseSet<Instruction *> HoistedSet;
1465 for (const RegInfo &RI : Scope->CHRRegions) {
1466 Region *R = RI.R;
1467 bool IsTrueBiased = Scope->TrueBiasedRegions.count(R);
1468 bool IsFalseBiased = Scope->FalseBiasedRegions.count(R);
1469 if (RI.HasBranch && (IsTrueBiased || IsFalseBiased)) {
1470 auto *BI = cast<CondBrInst>(R->getEntry()->getTerminator());
1471 hoistValue(BI->getCondition(), HoistPoint, R, Scope->HoistStopMap,
1472 HoistedSet, TrivialPHIs, DT);
1473 }
1474 for (SelectInst *SI : RI.Selects) {
1475 bool IsTrueBiased = Scope->TrueBiasedSelects.count(SI);
1476 bool IsFalseBiased = Scope->FalseBiasedSelects.count(SI);
1477 if (!(IsTrueBiased || IsFalseBiased))
1478 continue;
1479 hoistValue(SI->getCondition(), HoistPoint, R, Scope->HoistStopMap,
1480 HoistedSet, TrivialPHIs, DT);
1481 }
1482 }
1483}
1484
1485// Negate the predicate if an ICmp if it's used only by branches or selects by
1486// swapping the operands of the branches or the selects. Returns true if success.
1488 Instruction *ExcludedUser,
1489 CHRScope *Scope) {
1490 for (User *U : ICmp->users()) {
1491 if (U == ExcludedUser)
1492 continue;
1493 if (isa<CondBrInst>(U))
1494 continue;
1495 if (isa<SelectInst>(U) && cast<SelectInst>(U)->getCondition() == ICmp)
1496 continue;
1497 return false;
1498 }
1499 for (User *U : ICmp->users()) {
1500 if (U == ExcludedUser)
1501 continue;
1502 if (auto *BI = dyn_cast<CondBrInst>(U)) {
1503 BI->swapSuccessors();
1504 // Don't need to swap this in terms of
1505 // TrueBiasedRegions/FalseBiasedRegions because true-based/false-based
1506 // mean whether the branch is likely go into the if-then rather than
1507 // successor0/successor1 and because we can tell which edge is the then or
1508 // the else one by comparing the destination to the region exit block.
1509 continue;
1510 }
1511 if (auto *SI = dyn_cast<SelectInst>(U)) {
1512 // Swap operands
1513 SI->swapValues();
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);
1523 }
1524 continue;
1525 }
1526 llvm_unreachable("Must be a branch or a select");
1527 }
1529 return true;
1530}
1531
1532// A helper for transformScopes. Insert a trivial phi at the scope exit block
1533// for a value that's defined in the scope but used outside it (meaning it's
1534// alive at the exit block).
1535static void insertTrivialPHIs(CHRScope *Scope,
1536 BasicBlock *EntryBlock, BasicBlock *ExitBlock,
1537 DenseSet<PHINode *> &TrivialPHIs) {
1538 SmallSetVector<BasicBlock *, 8> BlocksInScope;
1539 for (RegInfo &RI : Scope->RegInfos) {
1540 for (BasicBlock *BB : RI.R->blocks()) { // This includes the blocks in the
1541 // sub-Scopes.
1542 BlocksInScope.insert(BB);
1543 }
1544 }
1545 CHR_DEBUG({
1546 dbgs() << "Inserting redundant phis\n";
1547 for (BasicBlock *BB : BlocksInScope)
1548 dbgs() << "BlockInScope " << BB->getName() << "\n";
1549 });
1550 for (BasicBlock *BB : BlocksInScope) {
1551 for (Instruction &I : *BB) {
1553 for (User *U : I.users()) {
1554 if (auto *UI = dyn_cast<Instruction>(U)) {
1555 if (!BlocksInScope.contains(UI->getParent()) &&
1556 // Unless there's already a phi for I at the exit block.
1557 !(isa<PHINode>(UI) && UI->getParent() == ExitBlock)) {
1558 CHR_DEBUG(dbgs() << "V " << I << "\n");
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)) {
1562 // There's a loop backedge from a block that's dominated by this
1563 // scope to the entry block.
1564 CHR_DEBUG(dbgs() << "V " << I << "\n");
1565 CHR_DEBUG(dbgs()
1566 << "Used at entry block (for a back edge) by a phi user "
1567 << *UI << "\n");
1568 Users.push_back(UI);
1569 }
1570 }
1571 }
1572 if (Users.size() > 0) {
1573 // Insert a trivial phi for I (phi [&I, P0], [&I, P1], ...) at
1574 // ExitBlock. Replace I with the new phi in UI unless UI is another
1575 // phi at ExitBlock.
1576 PHINode *PN = PHINode::Create(I.getType(), pred_size(ExitBlock), "");
1577 PN->insertBefore(ExitBlock->begin());
1578 for (BasicBlock *Pred : predecessors(ExitBlock)) {
1579 PN->addIncoming(&I, Pred);
1580 }
1581 TrivialPHIs.insert(PN);
1582 CHR_DEBUG(dbgs() << "Insert phi " << *PN << "\n");
1583 bool FoundLifetimeAnnotation = false;
1584 for (Instruction *UI : Users) {
1585 // If we found a lifetime annotation, remove it, but set a flag
1586 // to ensure that we remove all other lifetime annotations attached
1587 // to the alloca.
1588 if (UI->isLifetimeStartOrEnd()) {
1589 UI->eraseFromParent();
1590 FoundLifetimeAnnotation = true;
1591 continue;
1592 }
1593 for (unsigned J = 0, NumOps = UI->getNumOperands(); J < NumOps; ++J) {
1594 if (UI->getOperand(J) == &I) {
1595 UI->setOperand(J, PN);
1596 }
1597 }
1598 CHR_DEBUG(dbgs() << "Updated user " << *UI << "\n");
1599 }
1600 // Erase any leftover lifetime annotations for a dynamic alloca.
1601 if (FoundLifetimeAnnotation) {
1602 for (User *U : make_early_inc_range(I.users())) {
1603 if (auto *UI = dyn_cast<Instruction>(U))
1604 if (UI->isLifetimeStartOrEnd())
1605 UI->eraseFromParent();
1606 }
1607 }
1608 }
1609 }
1610 }
1611}
1612
1613// Assert that all the CHR regions of the scope have a biased branch or select.
1614[[maybe_unused]] static void
1616#ifndef NDEBUG
1617 auto HasBiasedBranchOrSelect = [](RegInfo &RI, CHRScope *Scope) {
1618 if (Scope->TrueBiasedRegions.count(RI.R) ||
1619 Scope->FalseBiasedRegions.count(RI.R))
1620 return true;
1621 for (SelectInst *SI : RI.Selects)
1622 if (Scope->TrueBiasedSelects.count(SI) ||
1623 Scope->FalseBiasedSelects.count(SI))
1624 return true;
1625 return false;
1626 };
1627 for (RegInfo &RI : Scope->CHRRegions) {
1628 assert(HasBiasedBranchOrSelect(RI, Scope) &&
1629 "Must have biased branch or select");
1630 }
1631#endif
1632}
1633
1634// Assert that all the condition values of the biased branches and selects have
1635// been hoisted to the pre-entry block or outside of the scope.
1636[[maybe_unused]] static void
1638 BasicBlock *PreEntryBlock) {
1639 CHR_DEBUG(dbgs() << "Biased regions condition values \n");
1640 for (RegInfo &RI : Scope->CHRRegions) {
1641 Region *R = RI.R;
1642 bool IsTrueBiased = Scope->TrueBiasedRegions.count(R);
1643 bool IsFalseBiased = Scope->FalseBiasedRegions.count(R);
1644 if (RI.HasBranch && (IsTrueBiased || IsFalseBiased)) {
1645 auto *BI = cast<CondBrInst>(R->getEntry()->getTerminator());
1646 Value *V = BI->getCondition();
1647 CHR_DEBUG(dbgs() << *V << "\n");
1648 if (auto *I = dyn_cast<Instruction>(V)) {
1649 (void)(I); // Unused in release build.
1650 assert((I->getParent() == PreEntryBlock ||
1651 !Scope->contains(I)) &&
1652 "Must have been hoisted to PreEntryBlock or outside the scope");
1653 }
1654 }
1655 for (SelectInst *SI : RI.Selects) {
1656 bool IsTrueBiased = Scope->TrueBiasedSelects.count(SI);
1657 bool IsFalseBiased = Scope->FalseBiasedSelects.count(SI);
1658 if (!(IsTrueBiased || IsFalseBiased))
1659 continue;
1660 Value *V = SI->getCondition();
1661 CHR_DEBUG(dbgs() << *V << "\n");
1662 if (auto *I = dyn_cast<Instruction>(V)) {
1663 (void)(I); // Unused in release build.
1664 assert((I->getParent() == PreEntryBlock ||
1665 !Scope->contains(I)) &&
1666 "Must have been hoisted to PreEntryBlock or outside the scope");
1667 }
1668 }
1669 }
1670}
1671
1672void CHR::transformScopes(CHRScope *Scope, DenseSet<PHINode *> &TrivialPHIs) {
1673 CHR_DEBUG(dbgs() << "transformScopes " << *Scope << "\n");
1674
1675 assert(Scope->RegInfos.size() >= 1 && "Should have at least one Region");
1676
1677 for (RegInfo &RI : Scope->RegInfos) {
1678 const Region *R = RI.R;
1679 unsigned Duplication = getRegionDuplicationCount(R);
1680 CHR_DEBUG(dbgs() << "Dup count for R=" << R << " is " << Duplication
1681 << "\n");
1682 if (Duplication >= Opts.chr_dup_threshold) {
1683 CHR_DEBUG(dbgs() << "Reached the dup threshold of " << Duplication
1684 << " for this region");
1685 ORE.emit([&]() {
1686 return OptimizationRemarkMissed(DEBUG_TYPE, "DupThresholdReached",
1687 R->getEntry()->getTerminator())
1688 << "Reached the duplication threshold for the region";
1689 });
1690 return;
1691 }
1692 }
1693 for (RegInfo &RI : Scope->RegInfos) {
1694 DuplicationCount[RI.R]++;
1695 }
1696
1697 Region *FirstRegion = Scope->RegInfos[0].R;
1698 BasicBlock *EntryBlock = FirstRegion->getEntry();
1699 Region *LastRegion = Scope->RegInfos[Scope->RegInfos.size() - 1].R;
1700 BasicBlock *ExitBlock = LastRegion->getExit();
1701 std::optional<uint64_t> ProfileCount = BFI.getBlockProfileCount(EntryBlock);
1702
1703 SmallVector<AllocaInst *> StaticAllocas;
1704 for (Instruction &I : *EntryBlock) {
1705 if (auto *AI = dyn_cast<AllocaInst>(&I)) {
1706 if (AI->isStaticAlloca())
1707 StaticAllocas.push_back(AI);
1708 }
1709 }
1710
1711 // Split the entry block of the first region. The new block becomes the new
1712 // entry block of the first region. The old entry block becomes the block to
1713 // insert the CHR branch into. Note DT gets updated. Since DT gets updated
1714 // through the split, we update the entry of the first region after the split,
1715 // and Region only points to the entry and the exit blocks, rather than
1716 // keeping everything in a list or set, the blocks membership and the
1717 // entry/exit blocks of the region are still valid after the split.
1718 CHR_DEBUG(dbgs() << "Splitting entry block " << EntryBlock->getName()
1719 << " at " << *Scope->BranchInsertPoint << "\n");
1720 BasicBlock *NewEntryBlock =
1721 SplitBlock(EntryBlock, Scope->BranchInsertPoint, &DT);
1722 assert(NewEntryBlock->getSinglePredecessor() == EntryBlock &&
1723 "NewEntryBlock's only pred must be EntryBlock");
1724 FirstRegion->replaceEntryRecursive(NewEntryBlock);
1725 BasicBlock *PreEntryBlock = EntryBlock;
1726
1727 // Move static allocas into the pre-entry block so they stay static.
1728 for (AllocaInst *AI : StaticAllocas)
1729 AI->moveBefore(EntryBlock->begin());
1730
1731 if (ExitBlock) {
1732 // Insert a trivial phi at the exit block (where the CHR hot path and the
1733 // cold path merges) for a value that's defined in the scope but used
1734 // outside it (meaning it's alive at the exit block). We will add the
1735 // incoming values for the CHR cold paths to it below. Without this, we'd
1736 // miss updating phi's for such values unless there happens to already be a
1737 // phi for that value there.
1738 insertTrivialPHIs(Scope, EntryBlock, ExitBlock, TrivialPHIs);
1739 }
1740
1741 ValueToValueMapTy VMap;
1742 // Clone the blocks in the scope (excluding the PreEntryBlock) to split into a
1743 // hot path (originals) and a cold path (clones) and update the PHIs at the
1744 // exit block.
1745 cloneScopeBlocks(Scope, PreEntryBlock, ExitBlock, LastRegion, VMap);
1746
1747 // Replace the old (placeholder) branch with the new (merged) conditional
1748 // branch.
1749 CondBrInst *MergedBr =
1750 createMergedBranch(PreEntryBlock, EntryBlock, NewEntryBlock, VMap);
1751
1752#ifndef NDEBUG
1754#endif
1755
1756 // Hoist the conditional values of the branches/selects.
1757 hoistScopeConditions(Scope, PreEntryBlock->getTerminator(), TrivialPHIs, DT);
1758
1759#ifndef NDEBUG
1760 assertBranchOrSelectConditionHoisted(Scope, PreEntryBlock);
1761#endif
1762
1763 // Create the combined branch condition and constant-fold the branches/selects
1764 // in the hot path.
1765 fixupBranchesAndSelects(Scope, PreEntryBlock, MergedBr,
1766 ProfileCount.value_or(0));
1767}
1768
1769// A helper for transformScopes. Clone the blocks in the scope (excluding the
1770// PreEntryBlock) to split into a hot path and a cold path and update the PHIs
1771// at the exit block.
1772void CHR::cloneScopeBlocks(CHRScope *Scope,
1773 BasicBlock *PreEntryBlock,
1774 BasicBlock *ExitBlock,
1775 Region *LastRegion,
1776 ValueToValueMapTy &VMap) {
1777 // Clone all the blocks. The original blocks will be the hot-path
1778 // CHR-optimized code and the cloned blocks will be the original unoptimized
1779 // code. This is so that the block pointers from the
1780 // CHRScope/Region/RegionInfo can stay valid in pointing to the hot-path code
1781 // which CHR should apply to.
1782 SmallVector<BasicBlock*, 8> NewBlocks;
1783 for (RegInfo &RI : Scope->RegInfos)
1784 for (BasicBlock *BB : RI.R->blocks()) { // This includes the blocks in the
1785 // sub-Scopes.
1786 assert(BB != PreEntryBlock && "Don't copy the preetntry block");
1787 BasicBlock *NewBB = CloneBasicBlock(BB, VMap, ".nonchr", &F);
1788 NewBlocks.push_back(NewBB);
1789 VMap[BB] = NewBB;
1790
1791 // Unreachable predecessors will not be cloned and will not have an edge
1792 // to the cloned block. As such, also remove them from any phi nodes.
1793 for (PHINode &PN : make_early_inc_range(NewBB->phis()))
1794 PN.removeIncomingValueIf([&](unsigned Idx) {
1795 return !DT.isReachableFromEntry(PN.getIncomingBlock(Idx));
1796 });
1797 }
1798
1799 // Place the cloned blocks right after the original blocks (right before the
1800 // exit block of.)
1801 if (ExitBlock)
1802 F.splice(ExitBlock->getIterator(), &F, NewBlocks[0]->getIterator(),
1803 F.end());
1804
1805 // Update the cloned blocks/instructions to refer to themselves.
1806 for (BasicBlock *NewBB : NewBlocks)
1807 for (Instruction &I : *NewBB)
1808 RemapInstruction(&I, VMap,
1810
1811 // Add the cloned blocks to the PHIs of the exit blocks. ExitBlock is null for
1812 // the top-level region but we don't need to add PHIs. The trivial PHIs
1813 // inserted above will be updated here.
1814 if (ExitBlock)
1815 for (PHINode &PN : ExitBlock->phis())
1816 for (unsigned I = 0, NumOps = PN.getNumIncomingValues(); I < NumOps;
1817 ++I) {
1818 BasicBlock *Pred = PN.getIncomingBlock(I);
1819 if (LastRegion->contains(Pred)) {
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");
1824 PN.addIncoming(V, cast<BasicBlock>(VMap[Pred]));
1825 }
1826 }
1827}
1828
1829// A helper for transformScope. Replace the old (placeholder) branch with the
1830// new (merged) conditional branch.
1831CondBrInst *CHR::createMergedBranch(BasicBlock *PreEntryBlock,
1832 BasicBlock *EntryBlock,
1833 BasicBlock *NewEntryBlock,
1834 ValueToValueMapTy &VMap) {
1835 UncondBrInst *OldBR = cast<UncondBrInst>(PreEntryBlock->getTerminator());
1836 assert(OldBR->getSuccessor() == NewEntryBlock &&
1837 "SplitBlock did not work correctly!");
1838 assert(NewEntryBlock->getSinglePredecessor() == EntryBlock &&
1839 "NewEntryBlock's only pred must be EntryBlock");
1840 assert(VMap.find(NewEntryBlock) != VMap.end() &&
1841 "NewEntryBlock must have been copied");
1842 OldBR->dropAllReferences();
1843 OldBR->eraseFromParent();
1844 // The true predicate is a placeholder. It will be replaced later in
1845 // fixupBranchesAndSelects().
1846 CondBrInst *NewBR =
1847 CondBrInst::Create(ConstantInt::getTrue(F.getContext()), NewEntryBlock,
1848 cast<BasicBlock>(VMap[NewEntryBlock]));
1849 NewBR->insertInto(PreEntryBlock, PreEntryBlock->end());
1850 assert(NewEntryBlock->getSinglePredecessor() == EntryBlock &&
1851 "NewEntryBlock's only pred must be EntryBlock");
1852 return NewBR;
1853}
1854
1855// A helper for transformScopes. Create the combined branch condition and
1856// constant-fold the branches/selects in the hot path.
1857void CHR::fixupBranchesAndSelects(CHRScope *Scope, BasicBlock *PreEntryBlock,
1858 CondBrInst *MergedBR, uint64_t ProfileCount) {
1859 Value *MergedCondition = ConstantInt::getTrue(F.getContext());
1860 BranchProbability CHRBranchBias(1, 1);
1861 uint64_t NumCHRedBranches = 0;
1862 IRBuilder<> IRB(PreEntryBlock->getTerminator());
1863 for (RegInfo &RI : Scope->CHRRegions) {
1864 Region *R = RI.R;
1865 if (RI.HasBranch) {
1866 fixupBranch(R, Scope, IRB, MergedCondition, CHRBranchBias);
1867 ++NumCHRedBranches;
1868 }
1869 for (SelectInst *SI : RI.Selects) {
1870 fixupSelect(SI, Scope, IRB, MergedCondition, CHRBranchBias);
1871 ++NumCHRedBranches;
1872 }
1873 }
1874 assert(NumCHRedBranches > 0);
1875 Stats.NumBranchesDelta += NumCHRedBranches - 1;
1876 Stats.WeightedNumBranchesDelta += (NumCHRedBranches - 1) * ProfileCount;
1877 ORE.emit([&]() {
1878 return OptimizationRemark(DEBUG_TYPE,
1879 "CHR",
1880 // Refer to the hot (original) path
1881 MergedBR->getSuccessor(0)->getTerminator())
1882 << "Merged " << ore::NV("NumCHRedBranches", NumCHRedBranches)
1883 << " branches or selects";
1884 });
1885 MergedBR->setCondition(MergedCondition);
1886 uint32_t Weights[] = {
1887 static_cast<uint32_t>(CHRBranchBias.scale(1000)),
1888 static_cast<uint32_t>(CHRBranchBias.getCompl().scale(1000)),
1889 };
1890 setBranchWeights(*MergedBR, Weights, /*IsExpected=*/false);
1891 CHR_DEBUG(dbgs() << "CHR branch bias " << Weights[0] << ":" << Weights[1]
1892 << "\n");
1893}
1894
1895// A helper for fixupBranchesAndSelects. Add to the combined branch condition
1896// and constant-fold a branch in the hot path.
1897void CHR::fixupBranch(Region *R, CHRScope *Scope,
1898 IRBuilder<> &IRB,
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");
1904 auto *BI = cast<CondBrInst>(R->getEntry()->getTerminator());
1905 assert(BranchBiasMap.contains(R) && "Must be in the bias map");
1906 BranchProbability Bias = BranchBiasMap[R];
1907 assert(Bias >= getCHRBiasThreshold(Opts) && "Must be highly biased");
1908 // Take the min.
1909 if (CHRBranchBias > Bias)
1910 CHRBranchBias = Bias;
1911 BasicBlock *IfThen = BI->getSuccessor(1);
1912 BasicBlock *IfElse = BI->getSuccessor(0);
1913 BasicBlock *RegionExitBlock = R->getExit();
1914 assert(RegionExitBlock && "Null ExitBlock");
1915 assert((IfThen == RegionExitBlock || IfElse == RegionExitBlock) &&
1916 IfThen != IfElse && "Invariant from findScopes");
1917 if (IfThen == RegionExitBlock) {
1918 // Swap them so that IfThen means going into it and IfElse means skipping
1919 // it.
1920 std::swap(IfThen, IfElse);
1921 }
1922 CHR_DEBUG(dbgs() << "IfThen " << IfThen->getName()
1923 << " IfElse " << IfElse->getName() << "\n");
1924 Value *Cond = BI->getCondition();
1925 BasicBlock *HotTarget = IsTrueBiased ? IfThen : IfElse;
1926 bool ConditionTrue = HotTarget == BI->getSuccessor(0);
1927 addToMergedCondition(ConditionTrue, Cond, BI, Scope, IRB,
1928 MergedCondition);
1929 // Constant-fold the branch at ClonedEntryBlock.
1930 assert(ConditionTrue == (HotTarget == BI->getSuccessor(0)) &&
1931 "The successor shouldn't change");
1932 Value *NewCondition = ConditionTrue ?
1933 ConstantInt::getTrue(F.getContext()) :
1934 ConstantInt::getFalse(F.getContext());
1935 BI->setCondition(NewCondition);
1936}
1937
1938// A helper for fixupBranchesAndSelects. Add to the combined branch condition
1939// and constant-fold a select in the hot path.
1940void CHR::fixupSelect(SelectInst *SI, CHRScope *Scope,
1941 IRBuilder<> &IRB,
1942 Value *&MergedCondition,
1943 BranchProbability &CHRBranchBias) {
1944 bool IsTrueBiased = Scope->TrueBiasedSelects.count(SI);
1945 assert((IsTrueBiased ||
1946 Scope->FalseBiasedSelects.count(SI)) && "Must be biased");
1947 assert(SelectBiasMap.contains(SI) && "Must be in the bias map");
1948 BranchProbability Bias = SelectBiasMap[SI];
1949 assert(Bias >= getCHRBiasThreshold(Opts) && "Must be highly biased");
1950 // Take the min.
1951 if (CHRBranchBias > Bias)
1952 CHRBranchBias = Bias;
1953 Value *Cond = SI->getCondition();
1954 addToMergedCondition(IsTrueBiased, Cond, SI, Scope, IRB,
1955 MergedCondition);
1956 Value *NewCondition = IsTrueBiased ?
1957 ConstantInt::getTrue(F.getContext()) :
1958 ConstantInt::getFalse(F.getContext());
1959 SI->setCondition(NewCondition);
1960}
1961
1962// A helper for fixupBranch/fixupSelect. Add a branch condition to the merged
1963// condition.
1964void CHR::addToMergedCondition(bool IsTrueBiased, Value *Cond,
1965 Instruction *BranchOrSelect, CHRScope *Scope,
1966 IRBuilder<> &IRB, Value *&MergedCondition) {
1967 if (!IsTrueBiased) {
1968 // If Cond is an icmp and all users of V except for BranchOrSelect is a
1969 // branch, negate the icmp predicate and swap the branch targets and avoid
1970 // inserting an Xor to negate Cond.
1971 auto *ICmp = dyn_cast<ICmpInst>(Cond);
1972 if (!ICmp ||
1973 !negateICmpIfUsedByBranchOrSelectOnly(ICmp, BranchOrSelect, Scope))
1974 Cond = IRB.CreateXor(ConstantInt::getTrue(F.getContext()), Cond);
1975 }
1976
1977 // Freeze potentially poisonous conditions.
1979 Cond = IRB.CreateFreeze(Cond);
1980
1981 // Use logical and to avoid propagating poison from later conditions.
1982 MergedCondition = IRB.CreateLogicalAnd(MergedCondition, Cond);
1983 if (auto *MergedInst = dyn_cast<Instruction>(MergedCondition))
1985}
1986
1987void CHR::transformScopes(SmallVectorImpl<CHRScope *> &CHRScopes) {
1988 unsigned I = 0;
1989 DenseSet<PHINode *> TrivialPHIs;
1990 for (CHRScope *Scope : CHRScopes) {
1991 transformScopes(Scope, TrivialPHIs);
1992 CHR_DEBUG(
1993 std::ostringstream oss;
1994 oss << " after transformScopes " << I++;
1995 dumpIR(F, oss.str().c_str(), nullptr));
1996 (void)I;
1997 }
1998}
1999
2000[[maybe_unused]] static void dumpScopes(SmallVectorImpl<CHRScope *> &Scopes,
2001 const char *Label) {
2002 dbgs() << Label << " " << Scopes.size() << "\n";
2003 for (CHRScope *Scope : Scopes) {
2004 dbgs() << *Scope << "\n";
2005 }
2006}
2007
2008bool CHR::run() {
2009 if (!shouldApply(Opts, F, PSI))
2010 return false;
2011
2012 CHR_DEBUG(dumpIR(F, "before", nullptr));
2013
2014 bool Changed = false;
2015 {
2016 CHR_DEBUG(
2017 dbgs() << "RegionInfo:\n";
2018 RI.print(dbgs()));
2019
2020 // Recursively traverse the region tree and find regions that have biased
2021 // branches and/or selects and create scopes.
2023 findScopes(AllScopes);
2024 CHR_DEBUG(dumpScopes(AllScopes, "All scopes"));
2025
2026 // Split the scopes if 1) the conditional values of the biased
2027 // branches/selects of the inner/lower scope can't be hoisted up to the
2028 // outermost/uppermost scope entry, or 2) the condition values of the biased
2029 // branches/selects in a scope (including subscopes) don't share at least
2030 // one common value.
2031 SmallVector<CHRScope *, 8> SplitScopes;
2032 splitScopes(AllScopes, SplitScopes);
2033 CHR_DEBUG(dumpScopes(SplitScopes, "Split scopes"));
2034
2035 // After splitting, set the biased regions and selects of a scope (a tree
2036 // root) that include those of the subscopes.
2037 classifyBiasedScopes(SplitScopes);
2038 CHR_DEBUG(dbgs() << "Set per-scope bias " << SplitScopes.size() << "\n");
2039
2040 // Filter out the scopes that has only one biased region or select (CHR
2041 // isn't useful in such a case).
2042 SmallVector<CHRScope *, 8> FilteredScopes;
2043 filterScopes(SplitScopes, FilteredScopes);
2044 CHR_DEBUG(dumpScopes(FilteredScopes, "Filtered scopes"));
2045
2046 // Set the regions to be CHR'ed and their hoist stops for each scope.
2048 setCHRRegions(FilteredScopes, SetScopes);
2049 CHR_DEBUG(dumpScopes(SetScopes, "Set CHR regions"));
2050
2051 // Sort CHRScopes by the depth so that outer CHRScopes comes before inner
2052 // ones. We need to apply CHR from outer to inner so that we apply CHR only
2053 // to the hot path, rather than both hot and cold paths.
2054 SmallVector<CHRScope *, 8> SortedScopes;
2055 sortScopes(SetScopes, SortedScopes);
2056 CHR_DEBUG(dumpScopes(SortedScopes, "Sorted scopes"));
2057
2058 CHR_DEBUG(
2059 dbgs() << "RegionInfo:\n";
2060 RI.print(dbgs()));
2061
2062 // Apply the CHR transformation.
2063 if (!SortedScopes.empty()) {
2064 transformScopes(SortedScopes);
2065 Changed = true;
2066 }
2067 }
2068
2069 if (Changed) {
2070 CHR_DEBUG(dumpIR(F, "after", &Stats));
2071 ORE.emit([&]() {
2072 return OptimizationRemark(DEBUG_TYPE, "Stats", &F)
2073 << ore::NV("Function", &F) << " "
2074 << "Reduced the number of branches in hot paths by "
2075 << ore::NV("NumBranchesDelta", Stats.NumBranchesDelta)
2076 << " (static) and "
2077 << ore::NV("WeightedNumBranchesDelta", Stats.WeightedNumBranchesDelta)
2078 << " (weighted by PGO count)";
2079 });
2080 }
2081
2082 return Changed;
2083}
2084
2088
2090 Function &F,
2092 auto &MAMProxy = FAM.getResult<ModuleAnalysisManagerFunctionProxy>(F);
2093 auto PPSI = MAMProxy.getCachedResult<ProfileSummaryAnalysis>(*F.getParent());
2094 // If there is no profile summary, we should not do CHR.
2095 if (!PPSI || !PPSI->hasProfileSummary())
2096 return PreservedAnalyses::all();
2097 auto &PSI = *PPSI;
2098 auto &BFI = FAM.getResult<BlockFrequencyAnalysis>(F);
2099 auto &DT = FAM.getResult<DominatorTreeAnalysis>(F);
2100 auto &RI = FAM.getResult<RegionInfoAnalysis>(F);
2101 auto &ORE = FAM.getResult<OptimizationRemarkEmitterAnalysis>(F);
2102 bool Changed =
2103 CHR(InstrumentationOptions::Global, F, BFI, DT, PSI, RI, ORE).run();
2104 if (!Changed)
2105 return PreservedAnalyses::all();
2106 return PreservedAnalyses::none();
2107}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
unsigned uint64_t
constexpr LLT S1
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)
#define CHR_DEBUG(X)
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.
#define DEBUG_TYPE
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
Definition IVUsers.cpp:48
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
#define F(x, y, z)
Definition MD5.cpp:54
#define I(x, y, z)
Definition MD5.cpp:57
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)
Definition Value.cpp:484
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),...
Definition ArrayRef.h:40
LLVM Basic Block Representation.
Definition BasicBlock.h:62
iterator end()
Definition BasicBlock.h:459
iterator begin()
Instruction iterator methods.
Definition BasicBlock.h:446
iterator_range< const_phi_iterator > phis() const
Returns a range that iterates over the phis in the basic block.
Definition BasicBlock.h:515
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.
Definition BasicBlock.h:237
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.
Definition InstrTypes.h:831
Predicate getInversePredicate() const
For example, EQ -> NE, UGT -> ULE, SLT -> SGE, OEQ -> UNE, UGT -> OLE, OLT -> UGE,...
Definition InstrTypes.h:852
Predicate getPredicate() const
Return the predicate for this instruction.
Definition InstrTypes.h:828
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)
Definition DenseMap.h:767
iterator end()
Definition DenseMap.h:687
Implements a dense probed hash-table based set.
Definition DenseSet.h:281
Analysis pass which computes a DominatorTree.
Definition Dominators.h:241
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.
Definition Dominators.h:122
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="")
Definition IRBuilder.h:2744
Value * CreateLogicalAnd(Value *Cond1, Value *Cond2, const Twine &Name="", Instruction *MDFrom=nullptr)
Definition IRBuilder.h:1775
Value * CreateXor(Value *LHS, Value *RHS, const Twine &Name="")
Definition IRBuilder.h:1627
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,...
LLVM_ABI void emit(DiagnosticInfoOptimizationBase &OptDiag)
Output the remark via the diagnostic handler and to the optimization record file.
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.
Definition Analysis.h:112
static PreservedAnalyses none()
Convenience factory function for the empty preserved set.
Definition Analysis.h:115
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
Definition Analysis.h:118
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.
Definition RegionInfo.h:357
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.
Definition RegionInfo.h:320
Analysis pass that exposes the RegionInfo for a function.
Definition RegionInfo.h:971
This class represents the LLVM 'select' instruction.
bool contains(const_arg_type key) const
Check if the SetVector contains the given key.
Definition SetVector.h:258
bool insert(const value_type &X)
Insert a new element into the SetVector.
Definition SetVector.h:157
A SetVector that performs no allocations if smaller than a certain size.
Definition SetVector.h:345
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
iterator erase(const_iterator CI)
void resize(size_type N)
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.
Definition StringRef.h:56
std::pair< StringRef, StringRef > split(char Separator) const
Split into two substrings around the first occurrence of a separator character.
Definition StringRef.h:736
StringSet - A wrapper for StringMap that provides set-like functionality.
Definition StringSet.h:25
BasicBlock * getSuccessor(unsigned i=0) const
void dropAllReferences()
Drop all references to operands.
Definition User.h:324
iterator find(const KeyT &Val)
Definition ValueMap.h:160
iterator end()
Definition ValueMap.h:139
LLVM Value Representation.
Definition Value.h:75
LLVM_ABI StringRef getName() const
Return a constant reference to the value's name.
Definition Value.cpp:319
std::pair< iterator, bool > insert(const ValueT &V)
Definition DenseSet.h:209
bool contains(const_arg_type_t< ValueT > V) const
Check if the set contains the given element.
Definition DenseSet.h:182
void insert_range(Range &&R)
Definition DenseSet.h:235
size_type count(const_arg_type_t< ValueT > V) const
Return 1 if the specified key is in the set, 0 otherwise.
Definition DenseSet.h:187
const ParentTy * getParent() const
Definition ilist_node.h:34
self_iterator getIterator()
Definition ilist_node.h:123
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition raw_ostream.h:53
Changed
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ Entry
Definition COFF.h:862
@ Tail
Attemps to make calls as fast as possible while guaranteeing that tail call optimization can always b...
Definition CallingConv.h:76
@ BasicBlock
Various leaf nodes.
Definition ISDOpcodes.h:83
PointerTypeMap run(const Module &M)
Compute the PointerTypeMap for the module M.
DiagnosticInfoOptimizationBase::Argument NV
friend class Instruction
Iterator for Instructions in a `BasicBlock.
Definition BasicBlock.h:73
LLVM_ABI void append(SmallVectorImpl< char > &path, const Twine &a, const Twine &b="", const Twine &c="", const Twine &d="")
Append to path.
Definition Path.cpp:467
This is an optimization pass for GlobalISel generic memory operations.
void stable_sort(R &&Range)
Definition STLExtras.h:2132
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.
Definition Casting.h:643
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.
Definition STLExtras.h:2224
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...
Definition STLExtras.h:649
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
Definition InstrProf.h:143
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,...
Definition ValueMapper.h:98
@ RF_NoModuleLevelChanges
If this flag is set, the remapper knows that only local values within a function (such as an instruct...
Definition ValueMapper.h:80
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition Debug.cpp:209
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...
Definition Casting.h:547
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
Definition InstrProf.h:145
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)
Definition STLExtras.h:1901
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.
Definition Casting.h:559
auto find_if(R &&Range, UnaryPredicate P)
Provide wrappers to std::find_if which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1788
void erase_if(Container &C, UnaryPredicate P)
Provide a container algorithm similar to C++ Library Fundamentals v2's erase_if which is equivalent t...
Definition STLExtras.h:2208
auto predecessors(const MachineBasicBlock *BB)
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Next
Definition InstrProf.h:147
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.
Definition BitVector.h:880