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