19775a620SHiroshi Yamauchi //===-- ControlHeightReduction.cpp - Control Height Reduction -------------===//
29775a620SHiroshi Yamauchi //
32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
69775a620SHiroshi Yamauchi //
79775a620SHiroshi Yamauchi //===----------------------------------------------------------------------===//
89775a620SHiroshi Yamauchi //
99775a620SHiroshi Yamauchi // This pass merges conditional blocks of code and reduces the number of
109775a620SHiroshi Yamauchi // conditional branches in the hot paths based on profiles.
119775a620SHiroshi Yamauchi //
129775a620SHiroshi Yamauchi //===----------------------------------------------------------------------===//
139775a620SHiroshi Yamauchi
149775a620SHiroshi Yamauchi #include "llvm/Transforms/Instrumentation/ControlHeightReduction.h"
159775a620SHiroshi Yamauchi #include "llvm/ADT/DenseMap.h"
169775a620SHiroshi Yamauchi #include "llvm/ADT/DenseSet.h"
179775a620SHiroshi Yamauchi #include "llvm/ADT/SmallVector.h"
189775a620SHiroshi Yamauchi #include "llvm/ADT/StringSet.h"
199775a620SHiroshi Yamauchi #include "llvm/Analysis/BlockFrequencyInfo.h"
209abad481SBenjamin Kramer #include "llvm/Analysis/GlobalsModRef.h"
21fd2c699dSHiroshi Yamauchi #include "llvm/Analysis/OptimizationRemarkEmitter.h"
229775a620SHiroshi Yamauchi #include "llvm/Analysis/ProfileSummaryInfo.h"
239775a620SHiroshi Yamauchi #include "llvm/Analysis/RegionInfo.h"
249775a620SHiroshi Yamauchi #include "llvm/Analysis/RegionIterator.h"
259775a620SHiroshi Yamauchi #include "llvm/Analysis/ValueTracking.h"
269775a620SHiroshi Yamauchi #include "llvm/IR/CFG.h"
279775a620SHiroshi Yamauchi #include "llvm/IR/Dominators.h"
289775a620SHiroshi Yamauchi #include "llvm/IR/IRBuilder.h"
2926a0d53bSWei Wang #include "llvm/IR/IntrinsicInst.h"
309775a620SHiroshi Yamauchi #include "llvm/IR/MDBuilder.h"
316b9524a0SArthur Eubanks #include "llvm/IR/PassManager.h"
3205da2fe5SReid Kleckner #include "llvm/InitializePasses.h"
339775a620SHiroshi Yamauchi #include "llvm/Support/BranchProbability.h"
344c1a1d3cSReid Kleckner #include "llvm/Support/CommandLine.h"
359775a620SHiroshi Yamauchi #include "llvm/Support/MemoryBuffer.h"
369abad481SBenjamin Kramer #include "llvm/Transforms/Utils.h"
379abad481SBenjamin Kramer #include "llvm/Transforms/Utils/BasicBlockUtils.h"
389abad481SBenjamin Kramer #include "llvm/Transforms/Utils/Cloning.h"
399abad481SBenjamin Kramer #include "llvm/Transforms/Utils/ValueMapper.h"
409775a620SHiroshi Yamauchi
419775a620SHiroshi Yamauchi #include <set>
429775a620SHiroshi Yamauchi #include <sstream>
439775a620SHiroshi Yamauchi
449775a620SHiroshi Yamauchi using namespace llvm;
459775a620SHiroshi Yamauchi
469775a620SHiroshi Yamauchi #define DEBUG_TYPE "chr"
479775a620SHiroshi Yamauchi
489775a620SHiroshi Yamauchi #define CHR_DEBUG(X) LLVM_DEBUG(X)
499775a620SHiroshi Yamauchi
509775a620SHiroshi Yamauchi static cl::opt<bool> ForceCHR("force-chr", cl::init(false), cl::Hidden,
519775a620SHiroshi Yamauchi cl::desc("Apply CHR for all functions"));
529775a620SHiroshi Yamauchi
539775a620SHiroshi Yamauchi static cl::opt<double> CHRBiasThreshold(
549775a620SHiroshi Yamauchi "chr-bias-threshold", cl::init(0.99), cl::Hidden,
559775a620SHiroshi Yamauchi cl::desc("CHR considers a branch bias greater than this ratio as biased"));
569775a620SHiroshi Yamauchi
579775a620SHiroshi Yamauchi static cl::opt<unsigned> CHRMergeThreshold(
589775a620SHiroshi Yamauchi "chr-merge-threshold", cl::init(2), cl::Hidden,
599775a620SHiroshi Yamauchi cl::desc("CHR merges a group of N branches/selects where N >= this value"));
609775a620SHiroshi Yamauchi
619775a620SHiroshi Yamauchi static cl::opt<std::string> CHRModuleList(
629775a620SHiroshi Yamauchi "chr-module-list", cl::init(""), cl::Hidden,
639775a620SHiroshi Yamauchi cl::desc("Specify file to retrieve the list of modules to apply CHR to"));
649775a620SHiroshi Yamauchi
659775a620SHiroshi Yamauchi static cl::opt<std::string> CHRFunctionList(
669775a620SHiroshi Yamauchi "chr-function-list", cl::init(""), cl::Hidden,
679775a620SHiroshi Yamauchi cl::desc("Specify file to retrieve the list of functions to apply CHR to"));
689775a620SHiroshi Yamauchi
699775a620SHiroshi Yamauchi static StringSet<> CHRModules;
709775a620SHiroshi Yamauchi static StringSet<> CHRFunctions;
719775a620SHiroshi Yamauchi
parseCHRFilterFiles()72b3b61de0SFangrui Song static void parseCHRFilterFiles() {
739775a620SHiroshi Yamauchi if (!CHRModuleList.empty()) {
749775a620SHiroshi Yamauchi auto FileOrErr = MemoryBuffer::getFile(CHRModuleList);
759775a620SHiroshi Yamauchi if (!FileOrErr) {
769775a620SHiroshi Yamauchi errs() << "Error: Couldn't read the chr-module-list file " << CHRModuleList << "\n";
779775a620SHiroshi Yamauchi std::exit(1);
789775a620SHiroshi Yamauchi }
799775a620SHiroshi Yamauchi StringRef Buf = FileOrErr->get()->getBuffer();
809775a620SHiroshi Yamauchi SmallVector<StringRef, 0> Lines;
819775a620SHiroshi Yamauchi Buf.split(Lines, '\n');
829775a620SHiroshi Yamauchi for (StringRef Line : Lines) {
839775a620SHiroshi Yamauchi Line = Line.trim();
849775a620SHiroshi Yamauchi if (!Line.empty())
859775a620SHiroshi Yamauchi CHRModules.insert(Line);
869775a620SHiroshi Yamauchi }
879775a620SHiroshi Yamauchi }
889775a620SHiroshi Yamauchi if (!CHRFunctionList.empty()) {
899775a620SHiroshi Yamauchi auto FileOrErr = MemoryBuffer::getFile(CHRFunctionList);
909775a620SHiroshi Yamauchi if (!FileOrErr) {
919775a620SHiroshi Yamauchi errs() << "Error: Couldn't read the chr-function-list file " << CHRFunctionList << "\n";
929775a620SHiroshi Yamauchi std::exit(1);
939775a620SHiroshi Yamauchi }
949775a620SHiroshi Yamauchi StringRef Buf = FileOrErr->get()->getBuffer();
959775a620SHiroshi Yamauchi SmallVector<StringRef, 0> Lines;
969775a620SHiroshi Yamauchi Buf.split(Lines, '\n');
979775a620SHiroshi Yamauchi for (StringRef Line : Lines) {
989775a620SHiroshi Yamauchi Line = Line.trim();
999775a620SHiroshi Yamauchi if (!Line.empty())
1009775a620SHiroshi Yamauchi CHRFunctions.insert(Line);
1019775a620SHiroshi Yamauchi }
1029775a620SHiroshi Yamauchi }
1039775a620SHiroshi Yamauchi }
1049775a620SHiroshi Yamauchi
1059775a620SHiroshi Yamauchi namespace {
1069775a620SHiroshi Yamauchi
1079775a620SHiroshi Yamauchi struct CHRStats {
108fda6a1adSKazu Hirata CHRStats() = default;
print__anonfd3f65480111::CHRStats1099775a620SHiroshi Yamauchi void print(raw_ostream &OS) const {
1109775a620SHiroshi Yamauchi OS << "CHRStats: NumBranches " << NumBranches
1119775a620SHiroshi Yamauchi << " NumBranchesDelta " << NumBranchesDelta
1129775a620SHiroshi Yamauchi << " WeightedNumBranchesDelta " << WeightedNumBranchesDelta;
1139775a620SHiroshi Yamauchi }
114fda6a1adSKazu Hirata // The original number of conditional branches / selects
115fda6a1adSKazu Hirata uint64_t NumBranches = 0;
116fda6a1adSKazu Hirata // The decrease of the number of conditional branches / selects in the hot
117fda6a1adSKazu Hirata // paths due to CHR.
118fda6a1adSKazu Hirata uint64_t NumBranchesDelta = 0;
119fda6a1adSKazu Hirata // NumBranchesDelta weighted by the profile count at the scope entry.
120fda6a1adSKazu Hirata uint64_t WeightedNumBranchesDelta = 0;
1219775a620SHiroshi Yamauchi };
1229775a620SHiroshi Yamauchi
1239775a620SHiroshi Yamauchi // RegInfo - some properties of a Region.
1249775a620SHiroshi Yamauchi struct RegInfo {
125df792bcbSKazu Hirata RegInfo() = default;
RegInfo__anonfd3f65480111::RegInfo126df792bcbSKazu Hirata RegInfo(Region *RegionIn) : R(RegionIn) {}
127df792bcbSKazu Hirata Region *R = nullptr;
128df792bcbSKazu Hirata bool HasBranch = false;
1299775a620SHiroshi Yamauchi SmallVector<SelectInst *, 8> Selects;
1309775a620SHiroshi Yamauchi };
1319775a620SHiroshi Yamauchi
1329775a620SHiroshi Yamauchi typedef DenseMap<Region *, DenseSet<Instruction *>> HoistStopMapTy;
1339775a620SHiroshi Yamauchi
1349775a620SHiroshi Yamauchi // CHRScope - a sequence of regions to CHR together. It corresponds to a
1359775a620SHiroshi Yamauchi // sequence of conditional blocks. It can have subscopes which correspond to
1369775a620SHiroshi Yamauchi // nested conditional blocks. Nested CHRScopes form a tree.
1379775a620SHiroshi Yamauchi class CHRScope {
1389775a620SHiroshi Yamauchi public:
CHRScope(RegInfo RI)1399775a620SHiroshi Yamauchi CHRScope(RegInfo RI) : BranchInsertPoint(nullptr) {
1409775a620SHiroshi Yamauchi assert(RI.R && "Null RegionIn");
1419775a620SHiroshi Yamauchi RegInfos.push_back(RI);
1429775a620SHiroshi Yamauchi }
1439775a620SHiroshi Yamauchi
getParentRegion()1449775a620SHiroshi Yamauchi Region *getParentRegion() {
1459775a620SHiroshi Yamauchi assert(RegInfos.size() > 0 && "Empty CHRScope");
1469775a620SHiroshi Yamauchi Region *Parent = RegInfos[0].R->getParent();
1479775a620SHiroshi Yamauchi assert(Parent && "Unexpected to call this on the top-level region");
1489775a620SHiroshi Yamauchi return Parent;
1499775a620SHiroshi Yamauchi }
1509775a620SHiroshi Yamauchi
getEntryBlock()1519775a620SHiroshi Yamauchi BasicBlock *getEntryBlock() {
1529775a620SHiroshi Yamauchi assert(RegInfos.size() > 0 && "Empty CHRScope");
1539775a620SHiroshi Yamauchi return RegInfos.front().R->getEntry();
1549775a620SHiroshi Yamauchi }
1559775a620SHiroshi Yamauchi
getExitBlock()1569775a620SHiroshi Yamauchi BasicBlock *getExitBlock() {
1579775a620SHiroshi Yamauchi assert(RegInfos.size() > 0 && "Empty CHRScope");
1589775a620SHiroshi Yamauchi return RegInfos.back().R->getExit();
1599775a620SHiroshi Yamauchi }
1609775a620SHiroshi Yamauchi
appendable(CHRScope * Next)1619775a620SHiroshi Yamauchi bool appendable(CHRScope *Next) {
1629775a620SHiroshi Yamauchi // The next scope is appendable only if this scope is directly connected to
1639775a620SHiroshi Yamauchi // it (which implies it post-dominates this scope) and this scope dominates
1649775a620SHiroshi Yamauchi // it (no edge to the next scope outside this scope).
1659775a620SHiroshi Yamauchi BasicBlock *NextEntry = Next->getEntryBlock();
1669775a620SHiroshi Yamauchi if (getExitBlock() != NextEntry)
1679775a620SHiroshi Yamauchi // Not directly connected.
1689775a620SHiroshi Yamauchi return false;
1699775a620SHiroshi Yamauchi Region *LastRegion = RegInfos.back().R;
1709775a620SHiroshi Yamauchi for (BasicBlock *Pred : predecessors(NextEntry))
1719775a620SHiroshi Yamauchi if (!LastRegion->contains(Pred))
1729775a620SHiroshi Yamauchi // There's an edge going into the entry of the next scope from outside
1739775a620SHiroshi Yamauchi // of this scope.
1749775a620SHiroshi Yamauchi return false;
1759775a620SHiroshi Yamauchi return true;
1769775a620SHiroshi Yamauchi }
1779775a620SHiroshi Yamauchi
append(CHRScope * Next)1789775a620SHiroshi Yamauchi void append(CHRScope *Next) {
1799775a620SHiroshi Yamauchi assert(RegInfos.size() > 0 && "Empty CHRScope");
1809775a620SHiroshi Yamauchi assert(Next->RegInfos.size() > 0 && "Empty CHRScope");
1819775a620SHiroshi Yamauchi assert(getParentRegion() == Next->getParentRegion() &&
1829775a620SHiroshi Yamauchi "Must be siblings");
1839775a620SHiroshi Yamauchi assert(getExitBlock() == Next->getEntryBlock() &&
1849775a620SHiroshi Yamauchi "Must be adjacent");
185f1542efdSBenjamin Kramer RegInfos.append(Next->RegInfos.begin(), Next->RegInfos.end());
186f1542efdSBenjamin Kramer Subs.append(Next->Subs.begin(), Next->Subs.end());
1879775a620SHiroshi Yamauchi }
1889775a620SHiroshi Yamauchi
addSub(CHRScope * SubIn)1899775a620SHiroshi Yamauchi void addSub(CHRScope *SubIn) {
1909775a620SHiroshi Yamauchi #ifndef NDEBUG
191b3b61de0SFangrui Song bool IsChild = false;
1929775a620SHiroshi Yamauchi for (RegInfo &RI : RegInfos)
1939775a620SHiroshi Yamauchi if (RI.R == SubIn->getParentRegion()) {
194b3b61de0SFangrui Song IsChild = true;
1959775a620SHiroshi Yamauchi break;
1969775a620SHiroshi Yamauchi }
197b3b61de0SFangrui Song assert(IsChild && "Must be a child");
1989775a620SHiroshi Yamauchi #endif
1999775a620SHiroshi Yamauchi Subs.push_back(SubIn);
2009775a620SHiroshi Yamauchi }
2019775a620SHiroshi Yamauchi
2029775a620SHiroshi Yamauchi // Split this scope at the boundary region into two, which will belong to the
2039775a620SHiroshi Yamauchi // tail and returns the tail.
split(Region * Boundary)2049775a620SHiroshi Yamauchi CHRScope *split(Region *Boundary) {
2059775a620SHiroshi Yamauchi assert(Boundary && "Boundary null");
2069775a620SHiroshi Yamauchi assert(RegInfos.begin()->R != Boundary &&
2079775a620SHiroshi Yamauchi "Can't be split at beginning");
208f1542efdSBenjamin Kramer auto BoundaryIt = llvm::find_if(
209f1542efdSBenjamin Kramer RegInfos, [&Boundary](const RegInfo &RI) { return Boundary == RI.R; });
2109775a620SHiroshi Yamauchi if (BoundaryIt == RegInfos.end())
2119775a620SHiroshi Yamauchi return nullptr;
212f1542efdSBenjamin Kramer ArrayRef<RegInfo> TailRegInfos(BoundaryIt, RegInfos.end());
2139775a620SHiroshi Yamauchi DenseSet<Region *> TailRegionSet;
214f1542efdSBenjamin Kramer for (const RegInfo &RI : TailRegInfos)
2159775a620SHiroshi Yamauchi TailRegionSet.insert(RI.R);
216f1542efdSBenjamin Kramer
217f1542efdSBenjamin Kramer auto TailIt =
218f1542efdSBenjamin Kramer std::stable_partition(Subs.begin(), Subs.end(), [&](CHRScope *Sub) {
2199775a620SHiroshi Yamauchi assert(Sub && "null Sub");
2209775a620SHiroshi Yamauchi Region *Parent = Sub->getParentRegion();
221f1542efdSBenjamin Kramer if (TailRegionSet.count(Parent))
222f1542efdSBenjamin Kramer return false;
223f1542efdSBenjamin Kramer
224df812115SKazu Hirata assert(llvm::any_of(
225df812115SKazu Hirata RegInfos,
226df812115SKazu Hirata [&Parent](const RegInfo &RI) { return Parent == RI.R; }) &&
2279775a620SHiroshi Yamauchi "Must be in head");
228f1542efdSBenjamin Kramer return true;
229f1542efdSBenjamin Kramer });
230f1542efdSBenjamin Kramer ArrayRef<CHRScope *> TailSubs(TailIt, Subs.end());
231f1542efdSBenjamin Kramer
2329775a620SHiroshi Yamauchi assert(HoistStopMap.empty() && "MapHoistStops must be empty");
233f1542efdSBenjamin Kramer auto *Scope = new CHRScope(TailRegInfos, TailSubs);
234f1542efdSBenjamin Kramer RegInfos.erase(BoundaryIt, RegInfos.end());
235f1542efdSBenjamin Kramer Subs.erase(TailIt, Subs.end());
236f1542efdSBenjamin Kramer return Scope;
2379775a620SHiroshi Yamauchi }
2389775a620SHiroshi Yamauchi
contains(Instruction * I) const2399775a620SHiroshi Yamauchi bool contains(Instruction *I) const {
2409775a620SHiroshi Yamauchi BasicBlock *Parent = I->getParent();
2419775a620SHiroshi Yamauchi for (const RegInfo &RI : RegInfos)
2429775a620SHiroshi Yamauchi if (RI.R->contains(Parent))
2439775a620SHiroshi Yamauchi return true;
2449775a620SHiroshi Yamauchi return false;
2459775a620SHiroshi Yamauchi }
2469775a620SHiroshi Yamauchi
2479775a620SHiroshi Yamauchi void print(raw_ostream &OS) const;
2489775a620SHiroshi Yamauchi
2499775a620SHiroshi Yamauchi SmallVector<RegInfo, 8> RegInfos; // Regions that belong to this scope
2509775a620SHiroshi Yamauchi SmallVector<CHRScope *, 8> Subs; // Subscopes.
2519775a620SHiroshi Yamauchi
2529775a620SHiroshi Yamauchi // The instruction at which to insert the CHR conditional branch (and hoist
2539775a620SHiroshi Yamauchi // the dependent condition values).
2549775a620SHiroshi Yamauchi Instruction *BranchInsertPoint;
2559775a620SHiroshi Yamauchi
2569775a620SHiroshi Yamauchi // True-biased and false-biased regions (conditional blocks),
2579775a620SHiroshi Yamauchi // respectively. Used only for the outermost scope and includes regions in
2589775a620SHiroshi Yamauchi // subscopes. The rest are unbiased.
2599775a620SHiroshi Yamauchi DenseSet<Region *> TrueBiasedRegions;
2609775a620SHiroshi Yamauchi DenseSet<Region *> FalseBiasedRegions;
2619775a620SHiroshi Yamauchi // Among the biased regions, the regions that get CHRed.
2629775a620SHiroshi Yamauchi SmallVector<RegInfo, 8> CHRRegions;
2639775a620SHiroshi Yamauchi
2649775a620SHiroshi Yamauchi // True-biased and false-biased selects, respectively. Used only for the
2659775a620SHiroshi Yamauchi // outermost scope and includes ones in subscopes.
2669775a620SHiroshi Yamauchi DenseSet<SelectInst *> TrueBiasedSelects;
2679775a620SHiroshi Yamauchi DenseSet<SelectInst *> FalseBiasedSelects;
2689775a620SHiroshi Yamauchi
2699775a620SHiroshi Yamauchi // Map from one of the above regions to the instructions to stop
2709775a620SHiroshi Yamauchi // hoisting instructions at through use-def chains.
2719775a620SHiroshi Yamauchi HoistStopMapTy HoistStopMap;
2729775a620SHiroshi Yamauchi
2739775a620SHiroshi Yamauchi private:
CHRScope(ArrayRef<RegInfo> RegInfosIn,ArrayRef<CHRScope * > SubsIn)274f1542efdSBenjamin Kramer CHRScope(ArrayRef<RegInfo> RegInfosIn, ArrayRef<CHRScope *> SubsIn)
275f1542efdSBenjamin Kramer : RegInfos(RegInfosIn.begin(), RegInfosIn.end()),
276f1542efdSBenjamin Kramer Subs(SubsIn.begin(), SubsIn.end()), BranchInsertPoint(nullptr) {}
2779775a620SHiroshi Yamauchi };
2789775a620SHiroshi Yamauchi
2799775a620SHiroshi Yamauchi class CHR {
2809775a620SHiroshi Yamauchi public:
CHR(Function & Fin,BlockFrequencyInfo & BFIin,DominatorTree & DTin,ProfileSummaryInfo & PSIin,RegionInfo & RIin,OptimizationRemarkEmitter & OREin)2819775a620SHiroshi Yamauchi CHR(Function &Fin, BlockFrequencyInfo &BFIin, DominatorTree &DTin,
282fd2c699dSHiroshi Yamauchi ProfileSummaryInfo &PSIin, RegionInfo &RIin,
283fd2c699dSHiroshi Yamauchi OptimizationRemarkEmitter &OREin)
284fd2c699dSHiroshi Yamauchi : F(Fin), BFI(BFIin), DT(DTin), PSI(PSIin), RI(RIin), ORE(OREin) {}
2859775a620SHiroshi Yamauchi
~CHR()2869775a620SHiroshi Yamauchi ~CHR() {
2879775a620SHiroshi Yamauchi for (CHRScope *Scope : Scopes) {
2889775a620SHiroshi Yamauchi delete Scope;
2899775a620SHiroshi Yamauchi }
2909775a620SHiroshi Yamauchi }
2919775a620SHiroshi Yamauchi
2929775a620SHiroshi Yamauchi bool run();
2939775a620SHiroshi Yamauchi
2949775a620SHiroshi Yamauchi private:
2959775a620SHiroshi Yamauchi // See the comments in CHR::run() for the high level flow of the algorithm and
2969775a620SHiroshi Yamauchi // what the following functions do.
2979775a620SHiroshi Yamauchi
findScopes(SmallVectorImpl<CHRScope * > & Output)2989775a620SHiroshi Yamauchi void findScopes(SmallVectorImpl<CHRScope *> &Output) {
2999775a620SHiroshi Yamauchi Region *R = RI.getTopLevelRegion();
300f1542efdSBenjamin Kramer if (CHRScope *Scope = findScopes(R, nullptr, nullptr, Output)) {
3019775a620SHiroshi Yamauchi Output.push_back(Scope);
3029775a620SHiroshi Yamauchi }
3039775a620SHiroshi Yamauchi }
3049775a620SHiroshi Yamauchi CHRScope *findScopes(Region *R, Region *NextRegion, Region *ParentRegion,
3059775a620SHiroshi Yamauchi SmallVectorImpl<CHRScope *> &Scopes);
3069775a620SHiroshi Yamauchi CHRScope *findScope(Region *R);
3079775a620SHiroshi Yamauchi void checkScopeHoistable(CHRScope *Scope);
3089775a620SHiroshi Yamauchi
3099775a620SHiroshi Yamauchi void splitScopes(SmallVectorImpl<CHRScope *> &Input,
3109775a620SHiroshi Yamauchi SmallVectorImpl<CHRScope *> &Output);
3119775a620SHiroshi Yamauchi SmallVector<CHRScope *, 8> splitScope(CHRScope *Scope,
3129775a620SHiroshi Yamauchi CHRScope *Outer,
3139775a620SHiroshi Yamauchi DenseSet<Value *> *OuterConditionValues,
3149775a620SHiroshi Yamauchi Instruction *OuterInsertPoint,
3159775a620SHiroshi Yamauchi SmallVectorImpl<CHRScope *> &Output,
3169775a620SHiroshi Yamauchi DenseSet<Instruction *> &Unhoistables);
3179775a620SHiroshi Yamauchi
3189775a620SHiroshi Yamauchi void classifyBiasedScopes(SmallVectorImpl<CHRScope *> &Scopes);
3199775a620SHiroshi Yamauchi void classifyBiasedScopes(CHRScope *Scope, CHRScope *OutermostScope);
3209775a620SHiroshi Yamauchi
3219775a620SHiroshi Yamauchi void filterScopes(SmallVectorImpl<CHRScope *> &Input,
3229775a620SHiroshi Yamauchi SmallVectorImpl<CHRScope *> &Output);
3239775a620SHiroshi Yamauchi
3249775a620SHiroshi Yamauchi void setCHRRegions(SmallVectorImpl<CHRScope *> &Input,
3259775a620SHiroshi Yamauchi SmallVectorImpl<CHRScope *> &Output);
3269775a620SHiroshi Yamauchi void setCHRRegions(CHRScope *Scope, CHRScope *OutermostScope);
3279775a620SHiroshi Yamauchi
3289775a620SHiroshi Yamauchi void sortScopes(SmallVectorImpl<CHRScope *> &Input,
3299775a620SHiroshi Yamauchi SmallVectorImpl<CHRScope *> &Output);
3309775a620SHiroshi Yamauchi
3319775a620SHiroshi Yamauchi void transformScopes(SmallVectorImpl<CHRScope *> &CHRScopes);
3329775a620SHiroshi Yamauchi void transformScopes(CHRScope *Scope, DenseSet<PHINode *> &TrivialPHIs);
3339775a620SHiroshi Yamauchi void cloneScopeBlocks(CHRScope *Scope,
3349775a620SHiroshi Yamauchi BasicBlock *PreEntryBlock,
3359775a620SHiroshi Yamauchi BasicBlock *ExitBlock,
3369775a620SHiroshi Yamauchi Region *LastRegion,
3379775a620SHiroshi Yamauchi ValueToValueMapTy &VMap);
3389775a620SHiroshi Yamauchi BranchInst *createMergedBranch(BasicBlock *PreEntryBlock,
3399775a620SHiroshi Yamauchi BasicBlock *EntryBlock,
3409775a620SHiroshi Yamauchi BasicBlock *NewEntryBlock,
3419775a620SHiroshi Yamauchi ValueToValueMapTy &VMap);
3429775a620SHiroshi Yamauchi void fixupBranchesAndSelects(CHRScope *Scope,
3439775a620SHiroshi Yamauchi BasicBlock *PreEntryBlock,
3449775a620SHiroshi Yamauchi BranchInst *MergedBR,
3459775a620SHiroshi Yamauchi uint64_t ProfileCount);
3469775a620SHiroshi Yamauchi void fixupBranch(Region *R,
3479775a620SHiroshi Yamauchi CHRScope *Scope,
3489775a620SHiroshi Yamauchi IRBuilder<> &IRB,
3499775a620SHiroshi Yamauchi Value *&MergedCondition, BranchProbability &CHRBranchBias);
3509775a620SHiroshi Yamauchi void fixupSelect(SelectInst* SI,
3519775a620SHiroshi Yamauchi CHRScope *Scope,
3529775a620SHiroshi Yamauchi IRBuilder<> &IRB,
3539775a620SHiroshi Yamauchi Value *&MergedCondition, BranchProbability &CHRBranchBias);
3549775a620SHiroshi Yamauchi void addToMergedCondition(bool IsTrueBiased, Value *Cond,
3559775a620SHiroshi Yamauchi Instruction *BranchOrSelect,
3569775a620SHiroshi Yamauchi CHRScope *Scope,
3579775a620SHiroshi Yamauchi IRBuilder<> &IRB,
3589775a620SHiroshi Yamauchi Value *&MergedCondition);
3599775a620SHiroshi Yamauchi
3609775a620SHiroshi Yamauchi Function &F;
3619775a620SHiroshi Yamauchi BlockFrequencyInfo &BFI;
3629775a620SHiroshi Yamauchi DominatorTree &DT;
3639775a620SHiroshi Yamauchi ProfileSummaryInfo &PSI;
3649775a620SHiroshi Yamauchi RegionInfo &RI;
365fd2c699dSHiroshi Yamauchi OptimizationRemarkEmitter &ORE;
3669775a620SHiroshi Yamauchi CHRStats Stats;
3679775a620SHiroshi Yamauchi
3689775a620SHiroshi Yamauchi // All the true-biased regions in the function
3699775a620SHiroshi Yamauchi DenseSet<Region *> TrueBiasedRegionsGlobal;
3709775a620SHiroshi Yamauchi // All the false-biased regions in the function
3719775a620SHiroshi Yamauchi DenseSet<Region *> FalseBiasedRegionsGlobal;
3729775a620SHiroshi Yamauchi // All the true-biased selects in the function
3739775a620SHiroshi Yamauchi DenseSet<SelectInst *> TrueBiasedSelectsGlobal;
3749775a620SHiroshi Yamauchi // All the false-biased selects in the function
3759775a620SHiroshi Yamauchi DenseSet<SelectInst *> FalseBiasedSelectsGlobal;
3769775a620SHiroshi Yamauchi // A map from biased regions to their branch bias
3779775a620SHiroshi Yamauchi DenseMap<Region *, BranchProbability> BranchBiasMap;
3789775a620SHiroshi Yamauchi // A map from biased selects to their branch bias
3799775a620SHiroshi Yamauchi DenseMap<SelectInst *, BranchProbability> SelectBiasMap;
3809775a620SHiroshi Yamauchi // All the scopes.
3819775a620SHiroshi Yamauchi DenseSet<CHRScope *> Scopes;
3829775a620SHiroshi Yamauchi };
3839775a620SHiroshi Yamauchi
3849775a620SHiroshi Yamauchi } // end anonymous namespace
3859775a620SHiroshi Yamauchi
3865fb509b7SHiroshi Yamauchi static inline
operator <<(raw_ostream & OS,const CHRStats & Stats)3875fb509b7SHiroshi Yamauchi raw_ostream LLVM_ATTRIBUTE_UNUSED &operator<<(raw_ostream &OS,
3885fb509b7SHiroshi Yamauchi const CHRStats &Stats) {
3895fb509b7SHiroshi Yamauchi Stats.print(OS);
3905fb509b7SHiroshi Yamauchi return OS;
3915fb509b7SHiroshi Yamauchi }
3925fb509b7SHiroshi Yamauchi
3935fb509b7SHiroshi Yamauchi static inline
operator <<(raw_ostream & OS,const CHRScope & Scope)3945fb509b7SHiroshi Yamauchi raw_ostream &operator<<(raw_ostream &OS, const CHRScope &Scope) {
3955fb509b7SHiroshi Yamauchi Scope.print(OS);
3965fb509b7SHiroshi Yamauchi return OS;
3975fb509b7SHiroshi Yamauchi }
3985fb509b7SHiroshi Yamauchi
shouldApply(Function & F,ProfileSummaryInfo & PSI)3999775a620SHiroshi Yamauchi static bool shouldApply(Function &F, ProfileSummaryInfo& PSI) {
4009775a620SHiroshi Yamauchi if (ForceCHR)
4019775a620SHiroshi Yamauchi return true;
4029775a620SHiroshi Yamauchi
4039775a620SHiroshi Yamauchi if (!CHRModuleList.empty() || !CHRFunctionList.empty()) {
4049775a620SHiroshi Yamauchi if (CHRModules.count(F.getParent()->getName()))
4059775a620SHiroshi Yamauchi return true;
4065fb509b7SHiroshi Yamauchi return CHRFunctions.count(F.getName());
4079775a620SHiroshi Yamauchi }
4089775a620SHiroshi Yamauchi
4099775a620SHiroshi Yamauchi assert(PSI.hasProfileSummary() && "Empty PSI?");
4109775a620SHiroshi Yamauchi return PSI.isFunctionEntryHot(&F);
4119775a620SHiroshi Yamauchi }
4129775a620SHiroshi Yamauchi
dumpIR(Function & F,const char * Label,CHRStats * Stats)413c8f348cbSFangrui Song static void LLVM_ATTRIBUTE_UNUSED dumpIR(Function &F, const char *Label,
414c8f348cbSFangrui Song CHRStats *Stats) {
4155fb509b7SHiroshi Yamauchi StringRef FuncName = F.getName();
4165fb509b7SHiroshi Yamauchi StringRef ModuleName = F.getParent()->getName();
41706650941SHiroshi Yamauchi (void)(FuncName); // Unused in release build.
41806650941SHiroshi Yamauchi (void)(ModuleName); // Unused in release build.
4199775a620SHiroshi Yamauchi CHR_DEBUG(dbgs() << "CHR IR dump " << Label << " " << ModuleName << " "
4205fb509b7SHiroshi Yamauchi << FuncName);
4219775a620SHiroshi Yamauchi if (Stats)
4229775a620SHiroshi Yamauchi CHR_DEBUG(dbgs() << " " << *Stats);
4239775a620SHiroshi Yamauchi CHR_DEBUG(dbgs() << "\n");
4249775a620SHiroshi Yamauchi CHR_DEBUG(F.dump());
4259775a620SHiroshi Yamauchi }
4269775a620SHiroshi Yamauchi
print(raw_ostream & OS) const4279775a620SHiroshi Yamauchi void CHRScope::print(raw_ostream &OS) const {
4289775a620SHiroshi Yamauchi assert(RegInfos.size() > 0 && "Empty CHRScope");
4299775a620SHiroshi Yamauchi OS << "CHRScope[";
4309775a620SHiroshi Yamauchi OS << RegInfos.size() << ", Regions[";
4319775a620SHiroshi Yamauchi for (const RegInfo &RI : RegInfos) {
4329775a620SHiroshi Yamauchi OS << RI.R->getNameStr();
4339775a620SHiroshi Yamauchi if (RI.HasBranch)
4349775a620SHiroshi Yamauchi OS << " B";
4359775a620SHiroshi Yamauchi if (RI.Selects.size() > 0)
4369775a620SHiroshi Yamauchi OS << " S" << RI.Selects.size();
4379775a620SHiroshi Yamauchi OS << ", ";
4389775a620SHiroshi Yamauchi }
4399775a620SHiroshi Yamauchi if (RegInfos[0].R->getParent()) {
4409775a620SHiroshi Yamauchi OS << "], Parent " << RegInfos[0].R->getParent()->getNameStr();
4419775a620SHiroshi Yamauchi } else {
4429775a620SHiroshi Yamauchi // top level region
4439775a620SHiroshi Yamauchi OS << "]";
4449775a620SHiroshi Yamauchi }
4459775a620SHiroshi Yamauchi OS << ", Subs[";
4469775a620SHiroshi Yamauchi for (CHRScope *Sub : Subs) {
4479775a620SHiroshi Yamauchi OS << *Sub << ", ";
4489775a620SHiroshi Yamauchi }
4499775a620SHiroshi Yamauchi OS << "]]";
4509775a620SHiroshi Yamauchi }
4519775a620SHiroshi Yamauchi
4529775a620SHiroshi Yamauchi // Return true if the given instruction type can be hoisted by CHR.
isHoistableInstructionType(Instruction * I)4539775a620SHiroshi Yamauchi static bool isHoistableInstructionType(Instruction *I) {
4549775a620SHiroshi Yamauchi return isa<BinaryOperator>(I) || isa<CastInst>(I) || isa<SelectInst>(I) ||
4559775a620SHiroshi Yamauchi isa<GetElementPtrInst>(I) || isa<CmpInst>(I) ||
4569775a620SHiroshi Yamauchi isa<InsertElementInst>(I) || isa<ExtractElementInst>(I) ||
4579775a620SHiroshi Yamauchi isa<ShuffleVectorInst>(I) || isa<ExtractValueInst>(I) ||
4589775a620SHiroshi Yamauchi isa<InsertValueInst>(I);
4599775a620SHiroshi Yamauchi }
4609775a620SHiroshi Yamauchi
4619775a620SHiroshi Yamauchi // Return true if the given instruction can be hoisted by CHR.
isHoistable(Instruction * I,DominatorTree & DT)4629775a620SHiroshi Yamauchi static bool isHoistable(Instruction *I, DominatorTree &DT) {
4639775a620SHiroshi Yamauchi if (!isHoistableInstructionType(I))
4649775a620SHiroshi Yamauchi return false;
4659775a620SHiroshi Yamauchi return isSafeToSpeculativelyExecute(I, nullptr, &DT);
4669775a620SHiroshi Yamauchi }
4679775a620SHiroshi Yamauchi
4689775a620SHiroshi Yamauchi // Recursively traverse the use-def chains of the given value and return a set
4699775a620SHiroshi Yamauchi // of the unhoistable base values defined within the scope (excluding the
4709775a620SHiroshi Yamauchi // first-region entry block) or the (hoistable or unhoistable) base values that
4719775a620SHiroshi Yamauchi // are defined outside (including the first-region entry block) of the
4729775a620SHiroshi Yamauchi // scope. The returned set doesn't include constants.
473f1542efdSBenjamin Kramer static const std::set<Value *> &
getBaseValues(Value * V,DominatorTree & DT,DenseMap<Value *,std::set<Value * >> & Visited)474f1542efdSBenjamin Kramer getBaseValues(Value *V, DominatorTree &DT,
475d842f2eeSHiroshi Yamauchi DenseMap<Value *, std::set<Value *>> &Visited) {
476f1542efdSBenjamin Kramer auto It = Visited.find(V);
477f1542efdSBenjamin Kramer if (It != Visited.end()) {
478f1542efdSBenjamin Kramer return It->second;
479d842f2eeSHiroshi Yamauchi }
4809775a620SHiroshi Yamauchi std::set<Value *> Result;
4819775a620SHiroshi Yamauchi if (auto *I = dyn_cast<Instruction>(V)) {
482f1542efdSBenjamin Kramer // We don't stop at a block that's not in the Scope because we would miss
483f1542efdSBenjamin Kramer // some instructions that are based on the same base values if we stop
484f1542efdSBenjamin Kramer // there.
4859775a620SHiroshi Yamauchi if (!isHoistable(I, DT)) {
4869775a620SHiroshi Yamauchi Result.insert(I);
487f1542efdSBenjamin Kramer return Visited.insert(std::make_pair(V, std::move(Result))).first->second;
4889775a620SHiroshi Yamauchi }
4899775a620SHiroshi Yamauchi // I is hoistable above the Scope.
4909775a620SHiroshi Yamauchi for (Value *Op : I->operands()) {
491f1542efdSBenjamin Kramer const std::set<Value *> &OpResult = getBaseValues(Op, DT, Visited);
4929775a620SHiroshi Yamauchi Result.insert(OpResult.begin(), OpResult.end());
4939775a620SHiroshi Yamauchi }
494f1542efdSBenjamin Kramer return Visited.insert(std::make_pair(V, std::move(Result))).first->second;
4959775a620SHiroshi Yamauchi }
4969775a620SHiroshi Yamauchi if (isa<Argument>(V)) {
4979775a620SHiroshi Yamauchi Result.insert(V);
4989775a620SHiroshi Yamauchi }
4999775a620SHiroshi Yamauchi // We don't include others like constants because those won't lead to any
5009775a620SHiroshi Yamauchi // chance of folding of conditions (eg two bit checks merged into one check)
5019775a620SHiroshi Yamauchi // after CHR.
502f1542efdSBenjamin Kramer return Visited.insert(std::make_pair(V, std::move(Result))).first->second;
5039775a620SHiroshi Yamauchi }
5049775a620SHiroshi Yamauchi
5059775a620SHiroshi Yamauchi // Return true if V is already hoisted or can be hoisted (along with its
5069775a620SHiroshi Yamauchi // operands) above the insert point. When it returns true and HoistStops is
5079775a620SHiroshi Yamauchi // non-null, the instructions to stop hoisting at through the use-def chains are
5089775a620SHiroshi Yamauchi // inserted into HoistStops.
5099775a620SHiroshi Yamauchi static bool
checkHoistValue(Value * V,Instruction * InsertPoint,DominatorTree & DT,DenseSet<Instruction * > & Unhoistables,DenseSet<Instruction * > * HoistStops,DenseMap<Instruction *,bool> & Visited)5109775a620SHiroshi Yamauchi checkHoistValue(Value *V, Instruction *InsertPoint, DominatorTree &DT,
5119775a620SHiroshi Yamauchi DenseSet<Instruction *> &Unhoistables,
512dfeb7974SHiroshi Yamauchi DenseSet<Instruction *> *HoistStops,
513dfeb7974SHiroshi Yamauchi DenseMap<Instruction *, bool> &Visited) {
5149775a620SHiroshi Yamauchi assert(InsertPoint && "Null InsertPoint");
5159775a620SHiroshi Yamauchi if (auto *I = dyn_cast<Instruction>(V)) {
516f1542efdSBenjamin Kramer auto It = Visited.find(I);
517f1542efdSBenjamin Kramer if (It != Visited.end()) {
518f1542efdSBenjamin Kramer return It->second;
519dfeb7974SHiroshi Yamauchi }
5209775a620SHiroshi Yamauchi assert(DT.getNode(I->getParent()) && "DT must contain I's parent block");
5219775a620SHiroshi Yamauchi assert(DT.getNode(InsertPoint->getParent()) && "DT must contain Destination");
5229775a620SHiroshi Yamauchi if (Unhoistables.count(I)) {
5239775a620SHiroshi Yamauchi // Don't hoist if they are not to be hoisted.
524dfeb7974SHiroshi Yamauchi Visited[I] = false;
5259775a620SHiroshi Yamauchi return false;
5269775a620SHiroshi Yamauchi }
5279775a620SHiroshi Yamauchi if (DT.dominates(I, InsertPoint)) {
5289775a620SHiroshi Yamauchi // We are already above the insert point. Stop here.
5299775a620SHiroshi Yamauchi if (HoistStops)
5309775a620SHiroshi Yamauchi HoistStops->insert(I);
531dfeb7974SHiroshi Yamauchi Visited[I] = true;
5329775a620SHiroshi Yamauchi return true;
5339775a620SHiroshi Yamauchi }
5349775a620SHiroshi Yamauchi // We aren't not above the insert point, check if we can hoist it above the
5359775a620SHiroshi Yamauchi // insert point.
5369775a620SHiroshi Yamauchi if (isHoistable(I, DT)) {
5379775a620SHiroshi Yamauchi // Check operands first.
5389775a620SHiroshi Yamauchi DenseSet<Instruction *> OpsHoistStops;
5399775a620SHiroshi Yamauchi bool AllOpsHoisted = true;
5409775a620SHiroshi Yamauchi for (Value *Op : I->operands()) {
541dfeb7974SHiroshi Yamauchi if (!checkHoistValue(Op, InsertPoint, DT, Unhoistables, &OpsHoistStops,
542dfeb7974SHiroshi Yamauchi Visited)) {
5439775a620SHiroshi Yamauchi AllOpsHoisted = false;
5449775a620SHiroshi Yamauchi break;
5459775a620SHiroshi Yamauchi }
5469775a620SHiroshi Yamauchi }
5479775a620SHiroshi Yamauchi if (AllOpsHoisted) {
5489775a620SHiroshi Yamauchi CHR_DEBUG(dbgs() << "checkHoistValue " << *I << "\n");
5499775a620SHiroshi Yamauchi if (HoistStops)
5509775a620SHiroshi Yamauchi HoistStops->insert(OpsHoistStops.begin(), OpsHoistStops.end());
551dfeb7974SHiroshi Yamauchi Visited[I] = true;
5529775a620SHiroshi Yamauchi return true;
5539775a620SHiroshi Yamauchi }
5549775a620SHiroshi Yamauchi }
555dfeb7974SHiroshi Yamauchi Visited[I] = false;
5569775a620SHiroshi Yamauchi return false;
5579775a620SHiroshi Yamauchi }
5589775a620SHiroshi Yamauchi // Non-instructions are considered hoistable.
5599775a620SHiroshi Yamauchi return true;
5609775a620SHiroshi Yamauchi }
5619775a620SHiroshi Yamauchi
5629775a620SHiroshi Yamauchi // Returns true and sets the true probability and false probability of an
5639775a620SHiroshi Yamauchi // MD_prof metadata if it's well-formed.
checkMDProf(MDNode * MD,BranchProbability & TrueProb,BranchProbability & FalseProb)564b3b61de0SFangrui Song static bool checkMDProf(MDNode *MD, BranchProbability &TrueProb,
5659775a620SHiroshi Yamauchi BranchProbability &FalseProb) {
5669775a620SHiroshi Yamauchi if (!MD) return false;
5679775a620SHiroshi Yamauchi MDString *MDName = cast<MDString>(MD->getOperand(0));
5689775a620SHiroshi Yamauchi if (MDName->getString() != "branch_weights" ||
5699775a620SHiroshi Yamauchi MD->getNumOperands() != 3)
5709775a620SHiroshi Yamauchi return false;
5719775a620SHiroshi Yamauchi ConstantInt *TrueWeight = mdconst::extract<ConstantInt>(MD->getOperand(1));
5729775a620SHiroshi Yamauchi ConstantInt *FalseWeight = mdconst::extract<ConstantInt>(MD->getOperand(2));
5739775a620SHiroshi Yamauchi if (!TrueWeight || !FalseWeight)
5749775a620SHiroshi Yamauchi return false;
57547c2bc58SRichard Trieu uint64_t TrueWt = TrueWeight->getValue().getZExtValue();
57647c2bc58SRichard Trieu uint64_t FalseWt = FalseWeight->getValue().getZExtValue();
57747c2bc58SRichard Trieu uint64_t SumWt = TrueWt + FalseWt;
57847c2bc58SRichard Trieu
57947c2bc58SRichard Trieu assert(SumWt >= TrueWt && SumWt >= FalseWt &&
58047c2bc58SRichard Trieu "Overflow calculating branch probabilities.");
58147c2bc58SRichard Trieu
5827b9f8e17SHiroshi Yamauchi // Guard against 0-to-0 branch weights to avoid a division-by-zero crash.
5837b9f8e17SHiroshi Yamauchi if (SumWt == 0)
5847b9f8e17SHiroshi Yamauchi return false;
5857b9f8e17SHiroshi Yamauchi
58647c2bc58SRichard Trieu TrueProb = BranchProbability::getBranchProbability(TrueWt, SumWt);
58747c2bc58SRichard Trieu FalseProb = BranchProbability::getBranchProbability(FalseWt, SumWt);
5889775a620SHiroshi Yamauchi return true;
5899775a620SHiroshi Yamauchi }
5909775a620SHiroshi Yamauchi
getCHRBiasThreshold()5919775a620SHiroshi Yamauchi static BranchProbability getCHRBiasThreshold() {
5929775a620SHiroshi Yamauchi return BranchProbability::getBranchProbability(
5939775a620SHiroshi Yamauchi static_cast<uint64_t>(CHRBiasThreshold * 1000000), 1000000);
5949775a620SHiroshi Yamauchi }
5959775a620SHiroshi Yamauchi
5969775a620SHiroshi Yamauchi // A helper for CheckBiasedBranch and CheckBiasedSelect. If TrueProb >=
5979775a620SHiroshi Yamauchi // CHRBiasThreshold, put Key into TrueSet and return true. If FalseProb >=
5989775a620SHiroshi Yamauchi // CHRBiasThreshold, put Key into FalseSet and return true. Otherwise, return
5999775a620SHiroshi Yamauchi // false.
6009775a620SHiroshi Yamauchi template <typename K, typename S, typename M>
checkBias(K * Key,BranchProbability TrueProb,BranchProbability FalseProb,S & TrueSet,S & FalseSet,M & BiasMap)601c55e9975SBenjamin Kramer static bool checkBias(K *Key, BranchProbability TrueProb,
602c55e9975SBenjamin Kramer BranchProbability FalseProb, S &TrueSet, S &FalseSet,
603c55e9975SBenjamin Kramer M &BiasMap) {
6049775a620SHiroshi Yamauchi BranchProbability Threshold = getCHRBiasThreshold();
6059775a620SHiroshi Yamauchi if (TrueProb >= Threshold) {
6069775a620SHiroshi Yamauchi TrueSet.insert(Key);
6079775a620SHiroshi Yamauchi BiasMap[Key] = TrueProb;
6089775a620SHiroshi Yamauchi return true;
6099775a620SHiroshi Yamauchi } else if (FalseProb >= Threshold) {
6109775a620SHiroshi Yamauchi FalseSet.insert(Key);
6119775a620SHiroshi Yamauchi BiasMap[Key] = FalseProb;
6129775a620SHiroshi Yamauchi return true;
6139775a620SHiroshi Yamauchi }
6149775a620SHiroshi Yamauchi return false;
6159775a620SHiroshi Yamauchi }
6169775a620SHiroshi Yamauchi
6179775a620SHiroshi Yamauchi // Returns true and insert a region into the right biased set and the map if the
6189775a620SHiroshi Yamauchi // branch of the region is biased.
checkBiasedBranch(BranchInst * BI,Region * R,DenseSet<Region * > & TrueBiasedRegionsGlobal,DenseSet<Region * > & FalseBiasedRegionsGlobal,DenseMap<Region *,BranchProbability> & BranchBiasMap)619b3b61de0SFangrui Song static bool checkBiasedBranch(BranchInst *BI, Region *R,
6209775a620SHiroshi Yamauchi DenseSet<Region *> &TrueBiasedRegionsGlobal,
6219775a620SHiroshi Yamauchi DenseSet<Region *> &FalseBiasedRegionsGlobal,
6229775a620SHiroshi Yamauchi DenseMap<Region *, BranchProbability> &BranchBiasMap) {
6239775a620SHiroshi Yamauchi if (!BI->isConditional())
6249775a620SHiroshi Yamauchi return false;
6259775a620SHiroshi Yamauchi BranchProbability ThenProb, ElseProb;
626b3b61de0SFangrui Song if (!checkMDProf(BI->getMetadata(LLVMContext::MD_prof),
6279775a620SHiroshi Yamauchi ThenProb, ElseProb))
6289775a620SHiroshi Yamauchi return false;
6299775a620SHiroshi Yamauchi BasicBlock *IfThen = BI->getSuccessor(0);
6309775a620SHiroshi Yamauchi BasicBlock *IfElse = BI->getSuccessor(1);
6319775a620SHiroshi Yamauchi assert((IfThen == R->getExit() || IfElse == R->getExit()) &&
6329775a620SHiroshi Yamauchi IfThen != IfElse &&
6339775a620SHiroshi Yamauchi "Invariant from findScopes");
6349775a620SHiroshi Yamauchi if (IfThen == R->getExit()) {
6359775a620SHiroshi Yamauchi // Swap them so that IfThen/ThenProb means going into the conditional code
6369775a620SHiroshi Yamauchi // and IfElse/ElseProb means skipping it.
6379775a620SHiroshi Yamauchi std::swap(IfThen, IfElse);
6389775a620SHiroshi Yamauchi std::swap(ThenProb, ElseProb);
6399775a620SHiroshi Yamauchi }
6409775a620SHiroshi Yamauchi CHR_DEBUG(dbgs() << "BI " << *BI << " ");
6419775a620SHiroshi Yamauchi CHR_DEBUG(dbgs() << "ThenProb " << ThenProb << " ");
6429775a620SHiroshi Yamauchi CHR_DEBUG(dbgs() << "ElseProb " << ElseProb << "\n");
643b3b61de0SFangrui Song return checkBias(R, ThenProb, ElseProb,
6449775a620SHiroshi Yamauchi TrueBiasedRegionsGlobal, FalseBiasedRegionsGlobal,
6459775a620SHiroshi Yamauchi BranchBiasMap);
6469775a620SHiroshi Yamauchi }
6479775a620SHiroshi Yamauchi
6489775a620SHiroshi Yamauchi // Returns true and insert a select into the right biased set and the map if the
6499775a620SHiroshi Yamauchi // select is biased.
checkBiasedSelect(SelectInst * SI,Region * R,DenseSet<SelectInst * > & TrueBiasedSelectsGlobal,DenseSet<SelectInst * > & FalseBiasedSelectsGlobal,DenseMap<SelectInst *,BranchProbability> & SelectBiasMap)650b3b61de0SFangrui Song static bool checkBiasedSelect(
6519775a620SHiroshi Yamauchi SelectInst *SI, Region *R,
6529775a620SHiroshi Yamauchi DenseSet<SelectInst *> &TrueBiasedSelectsGlobal,
6539775a620SHiroshi Yamauchi DenseSet<SelectInst *> &FalseBiasedSelectsGlobal,
6549775a620SHiroshi Yamauchi DenseMap<SelectInst *, BranchProbability> &SelectBiasMap) {
6559775a620SHiroshi Yamauchi BranchProbability TrueProb, FalseProb;
656b3b61de0SFangrui Song if (!checkMDProf(SI->getMetadata(LLVMContext::MD_prof),
6579775a620SHiroshi Yamauchi TrueProb, FalseProb))
6589775a620SHiroshi Yamauchi return false;
6599775a620SHiroshi Yamauchi CHR_DEBUG(dbgs() << "SI " << *SI << " ");
6609775a620SHiroshi Yamauchi CHR_DEBUG(dbgs() << "TrueProb " << TrueProb << " ");
6619775a620SHiroshi Yamauchi CHR_DEBUG(dbgs() << "FalseProb " << FalseProb << "\n");
662b3b61de0SFangrui Song return checkBias(SI, TrueProb, FalseProb,
6639775a620SHiroshi Yamauchi TrueBiasedSelectsGlobal, FalseBiasedSelectsGlobal,
6649775a620SHiroshi Yamauchi SelectBiasMap);
6659775a620SHiroshi Yamauchi }
6669775a620SHiroshi Yamauchi
6679775a620SHiroshi Yamauchi // Returns the instruction at which to hoist the dependent condition values and
6689775a620SHiroshi Yamauchi // insert the CHR branch for a region. This is the terminator branch in the
6699775a620SHiroshi Yamauchi // entry block or the first select in the entry block, if any.
getBranchInsertPoint(RegInfo & RI)6709775a620SHiroshi Yamauchi static Instruction* getBranchInsertPoint(RegInfo &RI) {
6719775a620SHiroshi Yamauchi Region *R = RI.R;
6729775a620SHiroshi Yamauchi BasicBlock *EntryBB = R->getEntry();
6739775a620SHiroshi Yamauchi // The hoist point is by default the terminator of the entry block, which is
6749775a620SHiroshi Yamauchi // the same as the branch instruction if RI.HasBranch is true.
6759775a620SHiroshi Yamauchi Instruction *HoistPoint = EntryBB->getTerminator();
6769775a620SHiroshi Yamauchi for (SelectInst *SI : RI.Selects) {
6779775a620SHiroshi Yamauchi if (SI->getParent() == EntryBB) {
6789775a620SHiroshi Yamauchi // Pick the first select in Selects in the entry block. Note Selects is
6799775a620SHiroshi Yamauchi // sorted in the instruction order within a block (asserted below).
6809775a620SHiroshi Yamauchi HoistPoint = SI;
6819775a620SHiroshi Yamauchi break;
6829775a620SHiroshi Yamauchi }
6839775a620SHiroshi Yamauchi }
6849775a620SHiroshi Yamauchi assert(HoistPoint && "Null HoistPoint");
6859775a620SHiroshi Yamauchi #ifndef NDEBUG
6869775a620SHiroshi Yamauchi // Check that HoistPoint is the first one in Selects in the entry block,
6879775a620SHiroshi Yamauchi // if any.
6889775a620SHiroshi Yamauchi DenseSet<Instruction *> EntryBlockSelectSet;
6899775a620SHiroshi Yamauchi for (SelectInst *SI : RI.Selects) {
6909775a620SHiroshi Yamauchi if (SI->getParent() == EntryBB) {
6919775a620SHiroshi Yamauchi EntryBlockSelectSet.insert(SI);
6929775a620SHiroshi Yamauchi }
6939775a620SHiroshi Yamauchi }
6949775a620SHiroshi Yamauchi for (Instruction &I : *EntryBB) {
69533bf1cadSKazu Hirata if (EntryBlockSelectSet.contains(&I)) {
6969775a620SHiroshi Yamauchi assert(&I == HoistPoint &&
6979775a620SHiroshi Yamauchi "HoistPoint must be the first one in Selects");
6989775a620SHiroshi Yamauchi break;
6999775a620SHiroshi Yamauchi }
7009775a620SHiroshi Yamauchi }
7019775a620SHiroshi Yamauchi #endif
7029775a620SHiroshi Yamauchi return HoistPoint;
7039775a620SHiroshi Yamauchi }
7049775a620SHiroshi Yamauchi
7059775a620SHiroshi Yamauchi // Find a CHR scope in the given region.
findScope(Region * R)7069775a620SHiroshi Yamauchi CHRScope * CHR::findScope(Region *R) {
7079775a620SHiroshi Yamauchi CHRScope *Result = nullptr;
7089775a620SHiroshi Yamauchi BasicBlock *Entry = R->getEntry();
7099775a620SHiroshi Yamauchi BasicBlock *Exit = R->getExit(); // null if top level.
7109775a620SHiroshi Yamauchi assert(Entry && "Entry must not be null");
7119775a620SHiroshi Yamauchi assert((Exit == nullptr) == (R->isTopLevelRegion()) &&
7129775a620SHiroshi Yamauchi "Only top level region has a null exit");
7139775a620SHiroshi Yamauchi if (Entry)
7149775a620SHiroshi Yamauchi CHR_DEBUG(dbgs() << "Entry " << Entry->getName() << "\n");
7159775a620SHiroshi Yamauchi else
7169775a620SHiroshi Yamauchi CHR_DEBUG(dbgs() << "Entry null\n");
7179775a620SHiroshi Yamauchi if (Exit)
7189775a620SHiroshi Yamauchi CHR_DEBUG(dbgs() << "Exit " << Exit->getName() << "\n");
7199775a620SHiroshi Yamauchi else
7209775a620SHiroshi Yamauchi CHR_DEBUG(dbgs() << "Exit null\n");
7219775a620SHiroshi Yamauchi // Exclude cases where Entry is part of a subregion (hence it doesn't belong
7229775a620SHiroshi Yamauchi // to this region).
7239775a620SHiroshi Yamauchi bool EntryInSubregion = RI.getRegionFor(Entry) != R;
7249775a620SHiroshi Yamauchi if (EntryInSubregion)
7259775a620SHiroshi Yamauchi return nullptr;
7269775a620SHiroshi Yamauchi // Exclude loops
7279775a620SHiroshi Yamauchi for (BasicBlock *Pred : predecessors(Entry))
7289775a620SHiroshi Yamauchi if (R->contains(Pred))
7299775a620SHiroshi Yamauchi return nullptr;
730fae7debaSXun Li // If any of the basic blocks have address taken, we must skip this region
731fae7debaSXun Li // because we cannot clone basic blocks that have address taken.
73226a0d53bSWei Wang for (BasicBlock *BB : R->blocks()) {
733fae7debaSXun Li if (BB->hasAddressTaken())
734fae7debaSXun Li return nullptr;
73526a0d53bSWei Wang // If we encounter llvm.coro.id, skip this region because if the basic block
73626a0d53bSWei Wang // is cloned, we end up inserting a token type PHI node to the block with
73726a0d53bSWei Wang // llvm.coro.begin.
73826a0d53bSWei Wang // FIXME: This could lead to less optimal codegen, because the region is
73926a0d53bSWei Wang // excluded, it can prevent CHR from merging adjacent regions into bigger
74026a0d53bSWei Wang // scope and hoisting more branches.
74126a0d53bSWei Wang for (Instruction &I : *BB)
74226a0d53bSWei Wang if (auto *II = dyn_cast<IntrinsicInst>(&I))
74326a0d53bSWei Wang if (II->getIntrinsicID() == Intrinsic::coro_id)
74426a0d53bSWei Wang return nullptr;
74526a0d53bSWei Wang }
74626a0d53bSWei Wang
7479775a620SHiroshi Yamauchi if (Exit) {
7489775a620SHiroshi Yamauchi // Try to find an if-then block (check if R is an if-then).
7499775a620SHiroshi Yamauchi // if (cond) {
7509775a620SHiroshi Yamauchi // ...
7519775a620SHiroshi Yamauchi // }
7529775a620SHiroshi Yamauchi auto *BI = dyn_cast<BranchInst>(Entry->getTerminator());
7539775a620SHiroshi Yamauchi if (BI)
7549775a620SHiroshi Yamauchi CHR_DEBUG(dbgs() << "BI.isConditional " << BI->isConditional() << "\n");
7559775a620SHiroshi Yamauchi else
7569775a620SHiroshi Yamauchi CHR_DEBUG(dbgs() << "BI null\n");
7579775a620SHiroshi Yamauchi if (BI && BI->isConditional()) {
7589775a620SHiroshi Yamauchi BasicBlock *S0 = BI->getSuccessor(0);
7599775a620SHiroshi Yamauchi BasicBlock *S1 = BI->getSuccessor(1);
7609775a620SHiroshi Yamauchi CHR_DEBUG(dbgs() << "S0 " << S0->getName() << "\n");
7619775a620SHiroshi Yamauchi CHR_DEBUG(dbgs() << "S1 " << S1->getName() << "\n");
7629775a620SHiroshi Yamauchi if (S0 != S1 && (S0 == Exit || S1 == Exit)) {
7639775a620SHiroshi Yamauchi RegInfo RI(R);
764b3b61de0SFangrui Song RI.HasBranch = checkBiasedBranch(
7659775a620SHiroshi Yamauchi BI, R, TrueBiasedRegionsGlobal, FalseBiasedRegionsGlobal,
7669775a620SHiroshi Yamauchi BranchBiasMap);
7679775a620SHiroshi Yamauchi Result = new CHRScope(RI);
7689775a620SHiroshi Yamauchi Scopes.insert(Result);
7699775a620SHiroshi Yamauchi CHR_DEBUG(dbgs() << "Found a region with a branch\n");
7709775a620SHiroshi Yamauchi ++Stats.NumBranches;
771fd2c699dSHiroshi Yamauchi if (!RI.HasBranch) {
772fd2c699dSHiroshi Yamauchi ORE.emit([&]() {
773fd2c699dSHiroshi Yamauchi return OptimizationRemarkMissed(DEBUG_TYPE, "BranchNotBiased", BI)
774fd2c699dSHiroshi Yamauchi << "Branch not biased";
775fd2c699dSHiroshi Yamauchi });
776fd2c699dSHiroshi Yamauchi }
7779775a620SHiroshi Yamauchi }
7789775a620SHiroshi Yamauchi }
7799775a620SHiroshi Yamauchi }
7809775a620SHiroshi Yamauchi {
7819775a620SHiroshi Yamauchi // Try to look for selects in the direct child blocks (as opposed to in
7829775a620SHiroshi Yamauchi // subregions) of R.
7839775a620SHiroshi Yamauchi // ...
7849775a620SHiroshi Yamauchi // if (..) { // Some subregion
7859775a620SHiroshi Yamauchi // ...
7869775a620SHiroshi Yamauchi // }
7879775a620SHiroshi Yamauchi // if (..) { // Some subregion
7889775a620SHiroshi Yamauchi // ...
7899775a620SHiroshi Yamauchi // }
7909775a620SHiroshi Yamauchi // ...
7919775a620SHiroshi Yamauchi // a = cond ? b : c;
7929775a620SHiroshi Yamauchi // ...
7939775a620SHiroshi Yamauchi SmallVector<SelectInst *, 8> Selects;
7949775a620SHiroshi Yamauchi for (RegionNode *E : R->elements()) {
7959775a620SHiroshi Yamauchi if (E->isSubRegion())
7969775a620SHiroshi Yamauchi continue;
7979775a620SHiroshi Yamauchi // This returns the basic block of E if E is a direct child of R (not a
7989775a620SHiroshi Yamauchi // subregion.)
7999775a620SHiroshi Yamauchi BasicBlock *BB = E->getEntry();
8009775a620SHiroshi Yamauchi // Need to push in the order to make it easier to find the first Select
8019775a620SHiroshi Yamauchi // later.
8029775a620SHiroshi Yamauchi for (Instruction &I : *BB) {
8039775a620SHiroshi Yamauchi if (auto *SI = dyn_cast<SelectInst>(&I)) {
8049775a620SHiroshi Yamauchi Selects.push_back(SI);
8059775a620SHiroshi Yamauchi ++Stats.NumBranches;
8069775a620SHiroshi Yamauchi }
8079775a620SHiroshi Yamauchi }
8089775a620SHiroshi Yamauchi }
8099775a620SHiroshi Yamauchi if (Selects.size() > 0) {
8109775a620SHiroshi Yamauchi auto AddSelects = [&](RegInfo &RI) {
8119775a620SHiroshi Yamauchi for (auto *SI : Selects)
812b3b61de0SFangrui Song if (checkBiasedSelect(SI, RI.R,
8139775a620SHiroshi Yamauchi TrueBiasedSelectsGlobal,
8149775a620SHiroshi Yamauchi FalseBiasedSelectsGlobal,
8159775a620SHiroshi Yamauchi SelectBiasMap))
8169775a620SHiroshi Yamauchi RI.Selects.push_back(SI);
817fd2c699dSHiroshi Yamauchi else
818fd2c699dSHiroshi Yamauchi ORE.emit([&]() {
819fd2c699dSHiroshi Yamauchi return OptimizationRemarkMissed(DEBUG_TYPE, "SelectNotBiased", SI)
820fd2c699dSHiroshi Yamauchi << "Select not biased";
821fd2c699dSHiroshi Yamauchi });
8229775a620SHiroshi Yamauchi };
8239775a620SHiroshi Yamauchi if (!Result) {
8249775a620SHiroshi Yamauchi CHR_DEBUG(dbgs() << "Found a select-only region\n");
8259775a620SHiroshi Yamauchi RegInfo RI(R);
8269775a620SHiroshi Yamauchi AddSelects(RI);
8279775a620SHiroshi Yamauchi Result = new CHRScope(RI);
8289775a620SHiroshi Yamauchi Scopes.insert(Result);
8299775a620SHiroshi Yamauchi } else {
8309775a620SHiroshi Yamauchi CHR_DEBUG(dbgs() << "Found select(s) in a region with a branch\n");
8319775a620SHiroshi Yamauchi AddSelects(Result->RegInfos[0]);
8329775a620SHiroshi Yamauchi }
8339775a620SHiroshi Yamauchi }
8349775a620SHiroshi Yamauchi }
8359775a620SHiroshi Yamauchi
8369775a620SHiroshi Yamauchi if (Result) {
8379775a620SHiroshi Yamauchi checkScopeHoistable(Result);
8389775a620SHiroshi Yamauchi }
8399775a620SHiroshi Yamauchi return Result;
8409775a620SHiroshi Yamauchi }
8419775a620SHiroshi Yamauchi
8429775a620SHiroshi Yamauchi // Check that any of the branch and the selects in the region could be
8439775a620SHiroshi Yamauchi // hoisted above the the CHR branch insert point (the most dominating of
8449775a620SHiroshi Yamauchi // them, either the branch (at the end of the first block) or the first
8459775a620SHiroshi Yamauchi // select in the first block). If the branch can't be hoisted, drop the
8469775a620SHiroshi Yamauchi // selects in the first blocks.
8479775a620SHiroshi Yamauchi //
8489775a620SHiroshi Yamauchi // For example, for the following scope/region with selects, we want to insert
8499775a620SHiroshi Yamauchi // the merged branch right before the first select in the first/entry block by
8509775a620SHiroshi Yamauchi // hoisting c1, c2, c3, and c4.
8519775a620SHiroshi Yamauchi //
8529775a620SHiroshi Yamauchi // // Branch insert point here.
8539775a620SHiroshi Yamauchi // a = c1 ? b : c; // Select 1
8549775a620SHiroshi Yamauchi // d = c2 ? e : f; // Select 2
8559775a620SHiroshi Yamauchi // if (c3) { // Branch
8569775a620SHiroshi Yamauchi // ...
8579775a620SHiroshi Yamauchi // c4 = foo() // A call.
8589775a620SHiroshi Yamauchi // g = c4 ? h : i; // Select 3
8599775a620SHiroshi Yamauchi // }
8609775a620SHiroshi Yamauchi //
8619775a620SHiroshi Yamauchi // But suppose we can't hoist c4 because it's dependent on the preceding
8629775a620SHiroshi Yamauchi // call. Then, we drop Select 3. Furthermore, if we can't hoist c2, we also drop
8639775a620SHiroshi Yamauchi // Select 2. If we can't hoist c3, we drop Selects 1 & 2.
checkScopeHoistable(CHRScope * Scope)8649775a620SHiroshi Yamauchi void CHR::checkScopeHoistable(CHRScope *Scope) {
8659775a620SHiroshi Yamauchi RegInfo &RI = Scope->RegInfos[0];
8669775a620SHiroshi Yamauchi Region *R = RI.R;
8679775a620SHiroshi Yamauchi BasicBlock *EntryBB = R->getEntry();
8689775a620SHiroshi Yamauchi auto *Branch = RI.HasBranch ?
8699775a620SHiroshi Yamauchi cast<BranchInst>(EntryBB->getTerminator()) : nullptr;
8709775a620SHiroshi Yamauchi SmallVector<SelectInst *, 8> &Selects = RI.Selects;
8719775a620SHiroshi Yamauchi if (RI.HasBranch || !Selects.empty()) {
8729775a620SHiroshi Yamauchi Instruction *InsertPoint = getBranchInsertPoint(RI);
8739775a620SHiroshi Yamauchi CHR_DEBUG(dbgs() << "InsertPoint " << *InsertPoint << "\n");
8749775a620SHiroshi Yamauchi // Avoid a data dependence from a select or a branch to a(nother)
8759775a620SHiroshi Yamauchi // select. Note no instruction can't data-depend on a branch (a branch
8769775a620SHiroshi Yamauchi // instruction doesn't produce a value).
8779775a620SHiroshi Yamauchi DenseSet<Instruction *> Unhoistables;
8789775a620SHiroshi Yamauchi // Initialize Unhoistables with the selects.
8799775a620SHiroshi Yamauchi for (SelectInst *SI : Selects) {
8809775a620SHiroshi Yamauchi Unhoistables.insert(SI);
8819775a620SHiroshi Yamauchi }
8829775a620SHiroshi Yamauchi // Remove Selects that can't be hoisted.
8839775a620SHiroshi Yamauchi for (auto it = Selects.begin(); it != Selects.end(); ) {
8849775a620SHiroshi Yamauchi SelectInst *SI = *it;
8859775a620SHiroshi Yamauchi if (SI == InsertPoint) {
8869775a620SHiroshi Yamauchi ++it;
8879775a620SHiroshi Yamauchi continue;
8889775a620SHiroshi Yamauchi }
889dfeb7974SHiroshi Yamauchi DenseMap<Instruction *, bool> Visited;
8909775a620SHiroshi Yamauchi bool IsHoistable = checkHoistValue(SI->getCondition(), InsertPoint,
891dfeb7974SHiroshi Yamauchi DT, Unhoistables, nullptr, Visited);
8929775a620SHiroshi Yamauchi if (!IsHoistable) {
8939775a620SHiroshi Yamauchi CHR_DEBUG(dbgs() << "Dropping select " << *SI << "\n");
894fd2c699dSHiroshi Yamauchi ORE.emit([&]() {
895fd2c699dSHiroshi Yamauchi return OptimizationRemarkMissed(DEBUG_TYPE,
896fd2c699dSHiroshi Yamauchi "DropUnhoistableSelect", SI)
897fd2c699dSHiroshi Yamauchi << "Dropped unhoistable select";
898fd2c699dSHiroshi Yamauchi });
8999775a620SHiroshi Yamauchi it = Selects.erase(it);
9009775a620SHiroshi Yamauchi // Since we are dropping the select here, we also drop it from
9019775a620SHiroshi Yamauchi // Unhoistables.
9029775a620SHiroshi Yamauchi Unhoistables.erase(SI);
9039775a620SHiroshi Yamauchi } else
9049775a620SHiroshi Yamauchi ++it;
9059775a620SHiroshi Yamauchi }
9069775a620SHiroshi Yamauchi // Update InsertPoint after potentially removing selects.
9079775a620SHiroshi Yamauchi InsertPoint = getBranchInsertPoint(RI);
9089775a620SHiroshi Yamauchi CHR_DEBUG(dbgs() << "InsertPoint " << *InsertPoint << "\n");
9099775a620SHiroshi Yamauchi if (RI.HasBranch && InsertPoint != Branch) {
910dfeb7974SHiroshi Yamauchi DenseMap<Instruction *, bool> Visited;
9119775a620SHiroshi Yamauchi bool IsHoistable = checkHoistValue(Branch->getCondition(), InsertPoint,
912dfeb7974SHiroshi Yamauchi DT, Unhoistables, nullptr, Visited);
9139775a620SHiroshi Yamauchi if (!IsHoistable) {
9149775a620SHiroshi Yamauchi // If the branch isn't hoistable, drop the selects in the entry
9159775a620SHiroshi Yamauchi // block, preferring the branch, which makes the branch the hoist
9169775a620SHiroshi Yamauchi // point.
9179775a620SHiroshi Yamauchi assert(InsertPoint != Branch && "Branch must not be the hoist point");
9189775a620SHiroshi Yamauchi CHR_DEBUG(dbgs() << "Dropping selects in entry block \n");
9199775a620SHiroshi Yamauchi CHR_DEBUG(
9209775a620SHiroshi Yamauchi for (SelectInst *SI : Selects) {
9219775a620SHiroshi Yamauchi dbgs() << "SI " << *SI << "\n";
9229775a620SHiroshi Yamauchi });
923fd2c699dSHiroshi Yamauchi for (SelectInst *SI : Selects) {
924fd2c699dSHiroshi Yamauchi ORE.emit([&]() {
925fd2c699dSHiroshi Yamauchi return OptimizationRemarkMissed(DEBUG_TYPE,
926fd2c699dSHiroshi Yamauchi "DropSelectUnhoistableBranch", SI)
927fd2c699dSHiroshi Yamauchi << "Dropped select due to unhoistable branch";
928fd2c699dSHiroshi Yamauchi });
929fd2c699dSHiroshi Yamauchi }
930b6211167SKazu Hirata llvm::erase_if(Selects, [EntryBB](SelectInst *SI) {
9319775a620SHiroshi Yamauchi return SI->getParent() == EntryBB;
932b6211167SKazu Hirata });
9339775a620SHiroshi Yamauchi Unhoistables.clear();
9349775a620SHiroshi Yamauchi InsertPoint = Branch;
9359775a620SHiroshi Yamauchi }
9369775a620SHiroshi Yamauchi }
9379775a620SHiroshi Yamauchi CHR_DEBUG(dbgs() << "InsertPoint " << *InsertPoint << "\n");
9389775a620SHiroshi Yamauchi #ifndef NDEBUG
9399775a620SHiroshi Yamauchi if (RI.HasBranch) {
9409775a620SHiroshi Yamauchi assert(!DT.dominates(Branch, InsertPoint) &&
9419775a620SHiroshi Yamauchi "Branch can't be already above the hoist point");
942dfeb7974SHiroshi Yamauchi DenseMap<Instruction *, bool> Visited;
9439775a620SHiroshi Yamauchi assert(checkHoistValue(Branch->getCondition(), InsertPoint,
944dfeb7974SHiroshi Yamauchi DT, Unhoistables, nullptr, Visited) &&
9459775a620SHiroshi Yamauchi "checkHoistValue for branch");
9469775a620SHiroshi Yamauchi }
9479775a620SHiroshi Yamauchi for (auto *SI : Selects) {
9489775a620SHiroshi Yamauchi assert(!DT.dominates(SI, InsertPoint) &&
9499775a620SHiroshi Yamauchi "SI can't be already above the hoist point");
950dfeb7974SHiroshi Yamauchi DenseMap<Instruction *, bool> Visited;
9519775a620SHiroshi Yamauchi assert(checkHoistValue(SI->getCondition(), InsertPoint, DT,
952dfeb7974SHiroshi Yamauchi Unhoistables, nullptr, Visited) &&
9539775a620SHiroshi Yamauchi "checkHoistValue for selects");
9549775a620SHiroshi Yamauchi }
9559775a620SHiroshi Yamauchi CHR_DEBUG(dbgs() << "Result\n");
9569775a620SHiroshi Yamauchi if (RI.HasBranch) {
9579775a620SHiroshi Yamauchi CHR_DEBUG(dbgs() << "BI " << *Branch << "\n");
9589775a620SHiroshi Yamauchi }
9599775a620SHiroshi Yamauchi for (auto *SI : Selects) {
9609775a620SHiroshi Yamauchi CHR_DEBUG(dbgs() << "SI " << *SI << "\n");
9619775a620SHiroshi Yamauchi }
9629775a620SHiroshi Yamauchi #endif
9639775a620SHiroshi Yamauchi }
9649775a620SHiroshi Yamauchi }
9659775a620SHiroshi Yamauchi
9669775a620SHiroshi Yamauchi // Traverse the region tree, find all nested scopes and merge them if possible.
findScopes(Region * R,Region * NextRegion,Region * ParentRegion,SmallVectorImpl<CHRScope * > & Scopes)9679775a620SHiroshi Yamauchi CHRScope * CHR::findScopes(Region *R, Region *NextRegion, Region *ParentRegion,
9689775a620SHiroshi Yamauchi SmallVectorImpl<CHRScope *> &Scopes) {
9699775a620SHiroshi Yamauchi CHR_DEBUG(dbgs() << "findScopes " << R->getNameStr() << "\n");
9709775a620SHiroshi Yamauchi CHRScope *Result = findScope(R);
9719775a620SHiroshi Yamauchi // Visit subscopes.
9729775a620SHiroshi Yamauchi CHRScope *ConsecutiveSubscope = nullptr;
9739775a620SHiroshi Yamauchi SmallVector<CHRScope *, 8> Subscopes;
9749775a620SHiroshi Yamauchi for (auto It = R->begin(); It != R->end(); ++It) {
9759775a620SHiroshi Yamauchi const std::unique_ptr<Region> &SubR = *It;
976b3b61de0SFangrui Song auto NextIt = std::next(It);
977b3b61de0SFangrui Song Region *NextSubR = NextIt != R->end() ? NextIt->get() : nullptr;
9789775a620SHiroshi Yamauchi CHR_DEBUG(dbgs() << "Looking at subregion " << SubR.get()->getNameStr()
9799775a620SHiroshi Yamauchi << "\n");
9809775a620SHiroshi Yamauchi CHRScope *SubCHRScope = findScopes(SubR.get(), NextSubR, R, Scopes);
9819775a620SHiroshi Yamauchi if (SubCHRScope) {
9829775a620SHiroshi Yamauchi CHR_DEBUG(dbgs() << "Subregion Scope " << *SubCHRScope << "\n");
9839775a620SHiroshi Yamauchi } else {
9849775a620SHiroshi Yamauchi CHR_DEBUG(dbgs() << "Subregion Scope null\n");
9859775a620SHiroshi Yamauchi }
9869775a620SHiroshi Yamauchi if (SubCHRScope) {
9879775a620SHiroshi Yamauchi if (!ConsecutiveSubscope)
9889775a620SHiroshi Yamauchi ConsecutiveSubscope = SubCHRScope;
9899775a620SHiroshi Yamauchi else if (!ConsecutiveSubscope->appendable(SubCHRScope)) {
9909775a620SHiroshi Yamauchi Subscopes.push_back(ConsecutiveSubscope);
9919775a620SHiroshi Yamauchi ConsecutiveSubscope = SubCHRScope;
9929775a620SHiroshi Yamauchi } else
9939775a620SHiroshi Yamauchi ConsecutiveSubscope->append(SubCHRScope);
9949775a620SHiroshi Yamauchi } else {
9959775a620SHiroshi Yamauchi if (ConsecutiveSubscope) {
9969775a620SHiroshi Yamauchi Subscopes.push_back(ConsecutiveSubscope);
9979775a620SHiroshi Yamauchi }
9989775a620SHiroshi Yamauchi ConsecutiveSubscope = nullptr;
9999775a620SHiroshi Yamauchi }
10009775a620SHiroshi Yamauchi }
10019775a620SHiroshi Yamauchi if (ConsecutiveSubscope) {
10029775a620SHiroshi Yamauchi Subscopes.push_back(ConsecutiveSubscope);
10039775a620SHiroshi Yamauchi }
10049775a620SHiroshi Yamauchi for (CHRScope *Sub : Subscopes) {
10059775a620SHiroshi Yamauchi if (Result) {
10069775a620SHiroshi Yamauchi // Combine it with the parent.
10079775a620SHiroshi Yamauchi Result->addSub(Sub);
10089775a620SHiroshi Yamauchi } else {
10099775a620SHiroshi Yamauchi // Push Subscopes as they won't be combined with the parent.
10109775a620SHiroshi Yamauchi Scopes.push_back(Sub);
10119775a620SHiroshi Yamauchi }
10129775a620SHiroshi Yamauchi }
10139775a620SHiroshi Yamauchi return Result;
10149775a620SHiroshi Yamauchi }
10159775a620SHiroshi Yamauchi
getCHRConditionValuesForRegion(RegInfo & RI)10169775a620SHiroshi Yamauchi static DenseSet<Value *> getCHRConditionValuesForRegion(RegInfo &RI) {
10179775a620SHiroshi Yamauchi DenseSet<Value *> ConditionValues;
10189775a620SHiroshi Yamauchi if (RI.HasBranch) {
10199775a620SHiroshi Yamauchi auto *BI = cast<BranchInst>(RI.R->getEntry()->getTerminator());
10209775a620SHiroshi Yamauchi ConditionValues.insert(BI->getCondition());
10219775a620SHiroshi Yamauchi }
10229775a620SHiroshi Yamauchi for (SelectInst *SI : RI.Selects) {
10239775a620SHiroshi Yamauchi ConditionValues.insert(SI->getCondition());
10249775a620SHiroshi Yamauchi }
10259775a620SHiroshi Yamauchi return ConditionValues;
10269775a620SHiroshi Yamauchi }
10279775a620SHiroshi Yamauchi
10289775a620SHiroshi Yamauchi
10299775a620SHiroshi Yamauchi // Determine whether to split a scope depending on the sets of the branch
10309775a620SHiroshi Yamauchi // condition values of the previous region and the current region. We split
10319775a620SHiroshi Yamauchi // (return true) it if 1) the condition values of the inner/lower scope can't be
10329775a620SHiroshi Yamauchi // hoisted up to the outer/upper scope, or 2) the two sets of the condition
10339775a620SHiroshi Yamauchi // values have an empty intersection (because the combined branch conditions
10349775a620SHiroshi Yamauchi // won't probably lead to a simpler combined condition).
shouldSplit(Instruction * InsertPoint,DenseSet<Value * > & PrevConditionValues,DenseSet<Value * > & ConditionValues,DominatorTree & DT,DenseSet<Instruction * > & Unhoistables)10359775a620SHiroshi Yamauchi static bool shouldSplit(Instruction *InsertPoint,
10369775a620SHiroshi Yamauchi DenseSet<Value *> &PrevConditionValues,
10379775a620SHiroshi Yamauchi DenseSet<Value *> &ConditionValues,
10389775a620SHiroshi Yamauchi DominatorTree &DT,
10399775a620SHiroshi Yamauchi DenseSet<Instruction *> &Unhoistables) {
10408262a5b7SDávid Bolvanský assert(InsertPoint && "Null InsertPoint");
10419775a620SHiroshi Yamauchi CHR_DEBUG(
10429775a620SHiroshi Yamauchi dbgs() << "shouldSplit " << *InsertPoint << " PrevConditionValues ";
10439775a620SHiroshi Yamauchi for (Value *V : PrevConditionValues) {
10449775a620SHiroshi Yamauchi dbgs() << *V << ", ";
10459775a620SHiroshi Yamauchi }
10469775a620SHiroshi Yamauchi dbgs() << " ConditionValues ";
10479775a620SHiroshi Yamauchi for (Value *V : ConditionValues) {
10489775a620SHiroshi Yamauchi dbgs() << *V << ", ";
10499775a620SHiroshi Yamauchi }
10509775a620SHiroshi Yamauchi dbgs() << "\n");
10519775a620SHiroshi Yamauchi // If any of Bases isn't hoistable to the hoist point, split.
10529775a620SHiroshi Yamauchi for (Value *V : ConditionValues) {
1053dfeb7974SHiroshi Yamauchi DenseMap<Instruction *, bool> Visited;
1054dfeb7974SHiroshi Yamauchi if (!checkHoistValue(V, InsertPoint, DT, Unhoistables, nullptr, Visited)) {
10559775a620SHiroshi Yamauchi CHR_DEBUG(dbgs() << "Split. checkHoistValue false " << *V << "\n");
10569775a620SHiroshi Yamauchi return true; // Not hoistable, split.
10579775a620SHiroshi Yamauchi }
10589775a620SHiroshi Yamauchi }
10599775a620SHiroshi Yamauchi // If PrevConditionValues or ConditionValues is empty, don't split to avoid
10609775a620SHiroshi Yamauchi // unnecessary splits at scopes with no branch/selects. If
10619775a620SHiroshi Yamauchi // PrevConditionValues and ConditionValues don't intersect at all, split.
10629775a620SHiroshi Yamauchi if (!PrevConditionValues.empty() && !ConditionValues.empty()) {
10639775a620SHiroshi Yamauchi // Use std::set as DenseSet doesn't work with set_intersection.
10649775a620SHiroshi Yamauchi std::set<Value *> PrevBases, Bases;
1065d842f2eeSHiroshi Yamauchi DenseMap<Value *, std::set<Value *>> Visited;
10669775a620SHiroshi Yamauchi for (Value *V : PrevConditionValues) {
1067f1542efdSBenjamin Kramer const std::set<Value *> &BaseValues = getBaseValues(V, DT, Visited);
10689775a620SHiroshi Yamauchi PrevBases.insert(BaseValues.begin(), BaseValues.end());
10699775a620SHiroshi Yamauchi }
10709775a620SHiroshi Yamauchi for (Value *V : ConditionValues) {
1071f1542efdSBenjamin Kramer const std::set<Value *> &BaseValues = getBaseValues(V, DT, Visited);
10729775a620SHiroshi Yamauchi Bases.insert(BaseValues.begin(), BaseValues.end());
10739775a620SHiroshi Yamauchi }
10749775a620SHiroshi Yamauchi CHR_DEBUG(
10759775a620SHiroshi Yamauchi dbgs() << "PrevBases ";
10769775a620SHiroshi Yamauchi for (Value *V : PrevBases) {
10779775a620SHiroshi Yamauchi dbgs() << *V << ", ";
10789775a620SHiroshi Yamauchi }
10799775a620SHiroshi Yamauchi dbgs() << " Bases ";
10809775a620SHiroshi Yamauchi for (Value *V : Bases) {
10819775a620SHiroshi Yamauchi dbgs() << *V << ", ";
10829775a620SHiroshi Yamauchi }
10839775a620SHiroshi Yamauchi dbgs() << "\n");
1084f1542efdSBenjamin Kramer std::vector<Value *> Intersection;
1085f1542efdSBenjamin Kramer std::set_intersection(PrevBases.begin(), PrevBases.end(), Bases.begin(),
1086f1542efdSBenjamin Kramer Bases.end(), std::back_inserter(Intersection));
10879775a620SHiroshi Yamauchi if (Intersection.empty()) {
10889775a620SHiroshi Yamauchi // Empty intersection, split.
10899775a620SHiroshi Yamauchi CHR_DEBUG(dbgs() << "Split. Intersection empty\n");
10909775a620SHiroshi Yamauchi return true;
10919775a620SHiroshi Yamauchi }
10929775a620SHiroshi Yamauchi }
10939775a620SHiroshi Yamauchi CHR_DEBUG(dbgs() << "No split\n");
10949775a620SHiroshi Yamauchi return false; // Don't split.
10959775a620SHiroshi Yamauchi }
10969775a620SHiroshi Yamauchi
getSelectsInScope(CHRScope * Scope,DenseSet<Instruction * > & Output)1097b3b61de0SFangrui Song static void getSelectsInScope(CHRScope *Scope,
10989775a620SHiroshi Yamauchi DenseSet<Instruction *> &Output) {
1099b3b61de0SFangrui Song for (RegInfo &RI : Scope->RegInfos)
1100b3b61de0SFangrui Song for (SelectInst *SI : RI.Selects)
11019775a620SHiroshi Yamauchi Output.insert(SI);
1102b3b61de0SFangrui Song for (CHRScope *Sub : Scope->Subs)
1103b3b61de0SFangrui Song getSelectsInScope(Sub, Output);
11049775a620SHiroshi Yamauchi }
11059775a620SHiroshi Yamauchi
splitScopes(SmallVectorImpl<CHRScope * > & Input,SmallVectorImpl<CHRScope * > & Output)11069775a620SHiroshi Yamauchi void CHR::splitScopes(SmallVectorImpl<CHRScope *> &Input,
11079775a620SHiroshi Yamauchi SmallVectorImpl<CHRScope *> &Output) {
11089775a620SHiroshi Yamauchi for (CHRScope *Scope : Input) {
11099775a620SHiroshi Yamauchi assert(!Scope->BranchInsertPoint &&
11109775a620SHiroshi Yamauchi "BranchInsertPoint must not be set");
11119775a620SHiroshi Yamauchi DenseSet<Instruction *> Unhoistables;
1112b3b61de0SFangrui Song getSelectsInScope(Scope, Unhoistables);
11139775a620SHiroshi Yamauchi splitScope(Scope, nullptr, nullptr, nullptr, Output, Unhoistables);
11149775a620SHiroshi Yamauchi }
11159775a620SHiroshi Yamauchi #ifndef NDEBUG
11169775a620SHiroshi Yamauchi for (CHRScope *Scope : Output) {
11179775a620SHiroshi Yamauchi assert(Scope->BranchInsertPoint && "BranchInsertPoint must be set");
11189775a620SHiroshi Yamauchi }
11199775a620SHiroshi Yamauchi #endif
11209775a620SHiroshi Yamauchi }
11219775a620SHiroshi Yamauchi
splitScope(CHRScope * Scope,CHRScope * Outer,DenseSet<Value * > * OuterConditionValues,Instruction * OuterInsertPoint,SmallVectorImpl<CHRScope * > & Output,DenseSet<Instruction * > & Unhoistables)11229775a620SHiroshi Yamauchi SmallVector<CHRScope *, 8> CHR::splitScope(
11239775a620SHiroshi Yamauchi CHRScope *Scope,
11249775a620SHiroshi Yamauchi CHRScope *Outer,
11259775a620SHiroshi Yamauchi DenseSet<Value *> *OuterConditionValues,
11269775a620SHiroshi Yamauchi Instruction *OuterInsertPoint,
11279775a620SHiroshi Yamauchi SmallVectorImpl<CHRScope *> &Output,
11289775a620SHiroshi Yamauchi DenseSet<Instruction *> &Unhoistables) {
11299775a620SHiroshi Yamauchi if (Outer) {
11309775a620SHiroshi Yamauchi assert(OuterConditionValues && "Null OuterConditionValues");
11319775a620SHiroshi Yamauchi assert(OuterInsertPoint && "Null OuterInsertPoint");
11329775a620SHiroshi Yamauchi }
11339775a620SHiroshi Yamauchi bool PrevSplitFromOuter = true;
11349775a620SHiroshi Yamauchi DenseSet<Value *> PrevConditionValues;
11359775a620SHiroshi Yamauchi Instruction *PrevInsertPoint = nullptr;
11369775a620SHiroshi Yamauchi SmallVector<CHRScope *, 8> Splits;
11379775a620SHiroshi Yamauchi SmallVector<bool, 8> SplitsSplitFromOuter;
11389775a620SHiroshi Yamauchi SmallVector<DenseSet<Value *>, 8> SplitsConditionValues;
11399775a620SHiroshi Yamauchi SmallVector<Instruction *, 8> SplitsInsertPoints;
11409775a620SHiroshi Yamauchi SmallVector<RegInfo, 8> RegInfos(Scope->RegInfos); // Copy
11419775a620SHiroshi Yamauchi for (RegInfo &RI : RegInfos) {
11429775a620SHiroshi Yamauchi Instruction *InsertPoint = getBranchInsertPoint(RI);
11439775a620SHiroshi Yamauchi DenseSet<Value *> ConditionValues = getCHRConditionValuesForRegion(RI);
11449775a620SHiroshi Yamauchi CHR_DEBUG(
11459775a620SHiroshi Yamauchi dbgs() << "ConditionValues ";
11469775a620SHiroshi Yamauchi for (Value *V : ConditionValues) {
11479775a620SHiroshi Yamauchi dbgs() << *V << ", ";
11489775a620SHiroshi Yamauchi }
11499775a620SHiroshi Yamauchi dbgs() << "\n");
11509775a620SHiroshi Yamauchi if (RI.R == RegInfos[0].R) {
11519775a620SHiroshi Yamauchi // First iteration. Check to see if we should split from the outer.
11529775a620SHiroshi Yamauchi if (Outer) {
11539775a620SHiroshi Yamauchi CHR_DEBUG(dbgs() << "Outer " << *Outer << "\n");
11549775a620SHiroshi Yamauchi CHR_DEBUG(dbgs() << "Should split from outer at "
11559775a620SHiroshi Yamauchi << RI.R->getNameStr() << "\n");
11569775a620SHiroshi Yamauchi if (shouldSplit(OuterInsertPoint, *OuterConditionValues,
11579775a620SHiroshi Yamauchi ConditionValues, DT, Unhoistables)) {
11589775a620SHiroshi Yamauchi PrevConditionValues = ConditionValues;
11599775a620SHiroshi Yamauchi PrevInsertPoint = InsertPoint;
1160fd2c699dSHiroshi Yamauchi ORE.emit([&]() {
1161fd2c699dSHiroshi Yamauchi return OptimizationRemarkMissed(DEBUG_TYPE,
1162fd2c699dSHiroshi Yamauchi "SplitScopeFromOuter",
1163fd2c699dSHiroshi Yamauchi RI.R->getEntry()->getTerminator())
1164fd2c699dSHiroshi Yamauchi << "Split scope from outer due to unhoistable branch/select "
1165fd2c699dSHiroshi Yamauchi << "and/or lack of common condition values";
1166fd2c699dSHiroshi Yamauchi });
11679775a620SHiroshi Yamauchi } else {
11689775a620SHiroshi Yamauchi // Not splitting from the outer. Use the outer bases and insert
11699775a620SHiroshi Yamauchi // point. Union the bases.
11709775a620SHiroshi Yamauchi PrevSplitFromOuter = false;
11719775a620SHiroshi Yamauchi PrevConditionValues = *OuterConditionValues;
11729775a620SHiroshi Yamauchi PrevConditionValues.insert(ConditionValues.begin(),
11739775a620SHiroshi Yamauchi ConditionValues.end());
11749775a620SHiroshi Yamauchi PrevInsertPoint = OuterInsertPoint;
11759775a620SHiroshi Yamauchi }
11769775a620SHiroshi Yamauchi } else {
11779775a620SHiroshi Yamauchi CHR_DEBUG(dbgs() << "Outer null\n");
11789775a620SHiroshi Yamauchi PrevConditionValues = ConditionValues;
11799775a620SHiroshi Yamauchi PrevInsertPoint = InsertPoint;
11809775a620SHiroshi Yamauchi }
11819775a620SHiroshi Yamauchi } else {
11829775a620SHiroshi Yamauchi CHR_DEBUG(dbgs() << "Should split from prev at "
11839775a620SHiroshi Yamauchi << RI.R->getNameStr() << "\n");
11849775a620SHiroshi Yamauchi if (shouldSplit(PrevInsertPoint, PrevConditionValues, ConditionValues,
11859775a620SHiroshi Yamauchi DT, Unhoistables)) {
11869775a620SHiroshi Yamauchi CHRScope *Tail = Scope->split(RI.R);
11879775a620SHiroshi Yamauchi Scopes.insert(Tail);
11889775a620SHiroshi Yamauchi Splits.push_back(Scope);
11899775a620SHiroshi Yamauchi SplitsSplitFromOuter.push_back(PrevSplitFromOuter);
11909775a620SHiroshi Yamauchi SplitsConditionValues.push_back(PrevConditionValues);
11919775a620SHiroshi Yamauchi SplitsInsertPoints.push_back(PrevInsertPoint);
11929775a620SHiroshi Yamauchi Scope = Tail;
11939775a620SHiroshi Yamauchi PrevConditionValues = ConditionValues;
11949775a620SHiroshi Yamauchi PrevInsertPoint = InsertPoint;
11959775a620SHiroshi Yamauchi PrevSplitFromOuter = true;
1196fd2c699dSHiroshi Yamauchi ORE.emit([&]() {
1197fd2c699dSHiroshi Yamauchi return OptimizationRemarkMissed(DEBUG_TYPE,
1198fd2c699dSHiroshi Yamauchi "SplitScopeFromPrev",
1199fd2c699dSHiroshi Yamauchi RI.R->getEntry()->getTerminator())
1200fd2c699dSHiroshi Yamauchi << "Split scope from previous due to unhoistable branch/select "
1201fd2c699dSHiroshi Yamauchi << "and/or lack of common condition values";
1202fd2c699dSHiroshi Yamauchi });
12039775a620SHiroshi Yamauchi } else {
12049775a620SHiroshi Yamauchi // Not splitting. Union the bases. Keep the hoist point.
12059775a620SHiroshi Yamauchi PrevConditionValues.insert(ConditionValues.begin(), ConditionValues.end());
12069775a620SHiroshi Yamauchi }
12079775a620SHiroshi Yamauchi }
12089775a620SHiroshi Yamauchi }
12099775a620SHiroshi Yamauchi Splits.push_back(Scope);
12109775a620SHiroshi Yamauchi SplitsSplitFromOuter.push_back(PrevSplitFromOuter);
12119775a620SHiroshi Yamauchi SplitsConditionValues.push_back(PrevConditionValues);
12129775a620SHiroshi Yamauchi assert(PrevInsertPoint && "Null PrevInsertPoint");
12139775a620SHiroshi Yamauchi SplitsInsertPoints.push_back(PrevInsertPoint);
12149775a620SHiroshi Yamauchi assert(Splits.size() == SplitsConditionValues.size() &&
12159775a620SHiroshi Yamauchi Splits.size() == SplitsSplitFromOuter.size() &&
12169775a620SHiroshi Yamauchi Splits.size() == SplitsInsertPoints.size() && "Mismatching sizes");
12179775a620SHiroshi Yamauchi for (size_t I = 0; I < Splits.size(); ++I) {
12189775a620SHiroshi Yamauchi CHRScope *Split = Splits[I];
12199775a620SHiroshi Yamauchi DenseSet<Value *> &SplitConditionValues = SplitsConditionValues[I];
12209775a620SHiroshi Yamauchi Instruction *SplitInsertPoint = SplitsInsertPoints[I];
12219775a620SHiroshi Yamauchi SmallVector<CHRScope *, 8> NewSubs;
12229775a620SHiroshi Yamauchi DenseSet<Instruction *> SplitUnhoistables;
1223b3b61de0SFangrui Song getSelectsInScope(Split, SplitUnhoistables);
12249775a620SHiroshi Yamauchi for (CHRScope *Sub : Split->Subs) {
12259775a620SHiroshi Yamauchi SmallVector<CHRScope *, 8> SubSplits = splitScope(
12269775a620SHiroshi Yamauchi Sub, Split, &SplitConditionValues, SplitInsertPoint, Output,
12279775a620SHiroshi Yamauchi SplitUnhoistables);
12288299fb8fSKazu Hirata llvm::append_range(NewSubs, SubSplits);
12299775a620SHiroshi Yamauchi }
12309775a620SHiroshi Yamauchi Split->Subs = NewSubs;
12319775a620SHiroshi Yamauchi }
12329775a620SHiroshi Yamauchi SmallVector<CHRScope *, 8> Result;
12339775a620SHiroshi Yamauchi for (size_t I = 0; I < Splits.size(); ++I) {
12349775a620SHiroshi Yamauchi CHRScope *Split = Splits[I];
12359775a620SHiroshi Yamauchi if (SplitsSplitFromOuter[I]) {
12369775a620SHiroshi Yamauchi // Split from the outer.
12379775a620SHiroshi Yamauchi Output.push_back(Split);
12389775a620SHiroshi Yamauchi Split->BranchInsertPoint = SplitsInsertPoints[I];
12399775a620SHiroshi Yamauchi CHR_DEBUG(dbgs() << "BranchInsertPoint " << *SplitsInsertPoints[I]
12409775a620SHiroshi Yamauchi << "\n");
12419775a620SHiroshi Yamauchi } else {
12429775a620SHiroshi Yamauchi // Connected to the outer.
12439775a620SHiroshi Yamauchi Result.push_back(Split);
12449775a620SHiroshi Yamauchi }
12459775a620SHiroshi Yamauchi }
12469775a620SHiroshi Yamauchi if (!Outer)
12479775a620SHiroshi Yamauchi assert(Result.empty() &&
12489775a620SHiroshi Yamauchi "If no outer (top-level), must return no nested ones");
12499775a620SHiroshi Yamauchi return Result;
12509775a620SHiroshi Yamauchi }
12519775a620SHiroshi Yamauchi
classifyBiasedScopes(SmallVectorImpl<CHRScope * > & Scopes)12529775a620SHiroshi Yamauchi void CHR::classifyBiasedScopes(SmallVectorImpl<CHRScope *> &Scopes) {
12539775a620SHiroshi Yamauchi for (CHRScope *Scope : Scopes) {
12549775a620SHiroshi Yamauchi assert(Scope->TrueBiasedRegions.empty() && Scope->FalseBiasedRegions.empty() && "Empty");
12559775a620SHiroshi Yamauchi classifyBiasedScopes(Scope, Scope);
12569775a620SHiroshi Yamauchi CHR_DEBUG(
12579775a620SHiroshi Yamauchi dbgs() << "classifyBiasedScopes " << *Scope << "\n";
12589775a620SHiroshi Yamauchi dbgs() << "TrueBiasedRegions ";
12599775a620SHiroshi Yamauchi for (Region *R : Scope->TrueBiasedRegions) {
12609775a620SHiroshi Yamauchi dbgs() << R->getNameStr() << ", ";
12619775a620SHiroshi Yamauchi }
12629775a620SHiroshi Yamauchi dbgs() << "\n";
12639775a620SHiroshi Yamauchi dbgs() << "FalseBiasedRegions ";
12649775a620SHiroshi Yamauchi for (Region *R : Scope->FalseBiasedRegions) {
12659775a620SHiroshi Yamauchi dbgs() << R->getNameStr() << ", ";
12669775a620SHiroshi Yamauchi }
12679775a620SHiroshi Yamauchi dbgs() << "\n";
12689775a620SHiroshi Yamauchi dbgs() << "TrueBiasedSelects ";
12699775a620SHiroshi Yamauchi for (SelectInst *SI : Scope->TrueBiasedSelects) {
12709775a620SHiroshi Yamauchi dbgs() << *SI << ", ";
12719775a620SHiroshi Yamauchi }
12729775a620SHiroshi Yamauchi dbgs() << "\n";
12739775a620SHiroshi Yamauchi dbgs() << "FalseBiasedSelects ";
12749775a620SHiroshi Yamauchi for (SelectInst *SI : Scope->FalseBiasedSelects) {
12759775a620SHiroshi Yamauchi dbgs() << *SI << ", ";
12769775a620SHiroshi Yamauchi }
12779775a620SHiroshi Yamauchi dbgs() << "\n";);
12789775a620SHiroshi Yamauchi }
12799775a620SHiroshi Yamauchi }
12809775a620SHiroshi Yamauchi
classifyBiasedScopes(CHRScope * Scope,CHRScope * OutermostScope)12819775a620SHiroshi Yamauchi void CHR::classifyBiasedScopes(CHRScope *Scope, CHRScope *OutermostScope) {
12829775a620SHiroshi Yamauchi for (RegInfo &RI : Scope->RegInfos) {
12839775a620SHiroshi Yamauchi if (RI.HasBranch) {
12849775a620SHiroshi Yamauchi Region *R = RI.R;
128533bf1cadSKazu Hirata if (TrueBiasedRegionsGlobal.contains(R))
12869775a620SHiroshi Yamauchi OutermostScope->TrueBiasedRegions.insert(R);
128733bf1cadSKazu Hirata else if (FalseBiasedRegionsGlobal.contains(R))
12889775a620SHiroshi Yamauchi OutermostScope->FalseBiasedRegions.insert(R);
12899775a620SHiroshi Yamauchi else
12909775a620SHiroshi Yamauchi llvm_unreachable("Must be biased");
12919775a620SHiroshi Yamauchi }
12929775a620SHiroshi Yamauchi for (SelectInst *SI : RI.Selects) {
129333bf1cadSKazu Hirata if (TrueBiasedSelectsGlobal.contains(SI))
12949775a620SHiroshi Yamauchi OutermostScope->TrueBiasedSelects.insert(SI);
129533bf1cadSKazu Hirata else if (FalseBiasedSelectsGlobal.contains(SI))
12969775a620SHiroshi Yamauchi OutermostScope->FalseBiasedSelects.insert(SI);
12979775a620SHiroshi Yamauchi else
12989775a620SHiroshi Yamauchi llvm_unreachable("Must be biased");
12999775a620SHiroshi Yamauchi }
13009775a620SHiroshi Yamauchi }
13019775a620SHiroshi Yamauchi for (CHRScope *Sub : Scope->Subs) {
13029775a620SHiroshi Yamauchi classifyBiasedScopes(Sub, OutermostScope);
13039775a620SHiroshi Yamauchi }
13049775a620SHiroshi Yamauchi }
13059775a620SHiroshi Yamauchi
hasAtLeastTwoBiasedBranches(CHRScope * Scope)13069775a620SHiroshi Yamauchi static bool hasAtLeastTwoBiasedBranches(CHRScope *Scope) {
13079775a620SHiroshi Yamauchi unsigned NumBiased = Scope->TrueBiasedRegions.size() +
13089775a620SHiroshi Yamauchi Scope->FalseBiasedRegions.size() +
13099775a620SHiroshi Yamauchi Scope->TrueBiasedSelects.size() +
13109775a620SHiroshi Yamauchi Scope->FalseBiasedSelects.size();
13119775a620SHiroshi Yamauchi return NumBiased >= CHRMergeThreshold;
13129775a620SHiroshi Yamauchi }
13139775a620SHiroshi Yamauchi
filterScopes(SmallVectorImpl<CHRScope * > & Input,SmallVectorImpl<CHRScope * > & Output)13149775a620SHiroshi Yamauchi void CHR::filterScopes(SmallVectorImpl<CHRScope *> &Input,
13159775a620SHiroshi Yamauchi SmallVectorImpl<CHRScope *> &Output) {
13169775a620SHiroshi Yamauchi for (CHRScope *Scope : Input) {
13179775a620SHiroshi Yamauchi // Filter out the ones with only one region and no subs.
13189775a620SHiroshi Yamauchi if (!hasAtLeastTwoBiasedBranches(Scope)) {
13199775a620SHiroshi Yamauchi CHR_DEBUG(dbgs() << "Filtered out by biased branches truthy-regions "
13209775a620SHiroshi Yamauchi << Scope->TrueBiasedRegions.size()
13219775a620SHiroshi Yamauchi << " falsy-regions " << Scope->FalseBiasedRegions.size()
13229775a620SHiroshi Yamauchi << " true-selects " << Scope->TrueBiasedSelects.size()
13239775a620SHiroshi Yamauchi << " false-selects " << Scope->FalseBiasedSelects.size() << "\n");
1324fd2c699dSHiroshi Yamauchi ORE.emit([&]() {
1325fd2c699dSHiroshi Yamauchi return OptimizationRemarkMissed(
1326fd2c699dSHiroshi Yamauchi DEBUG_TYPE,
1327fd2c699dSHiroshi Yamauchi "DropScopeWithOneBranchOrSelect",
1328fd2c699dSHiroshi Yamauchi Scope->RegInfos[0].R->getEntry()->getTerminator())
1329fd2c699dSHiroshi Yamauchi << "Drop scope with < "
1330fd2c699dSHiroshi Yamauchi << ore::NV("CHRMergeThreshold", CHRMergeThreshold)
1331fd2c699dSHiroshi Yamauchi << " biased branch(es) or select(s)";
1332fd2c699dSHiroshi Yamauchi });
13339775a620SHiroshi Yamauchi continue;
13349775a620SHiroshi Yamauchi }
13359775a620SHiroshi Yamauchi Output.push_back(Scope);
13369775a620SHiroshi Yamauchi }
13379775a620SHiroshi Yamauchi }
13389775a620SHiroshi Yamauchi
setCHRRegions(SmallVectorImpl<CHRScope * > & Input,SmallVectorImpl<CHRScope * > & Output)13399775a620SHiroshi Yamauchi void CHR::setCHRRegions(SmallVectorImpl<CHRScope *> &Input,
13409775a620SHiroshi Yamauchi SmallVectorImpl<CHRScope *> &Output) {
13419775a620SHiroshi Yamauchi for (CHRScope *Scope : Input) {
13429775a620SHiroshi Yamauchi assert(Scope->HoistStopMap.empty() && Scope->CHRRegions.empty() &&
13439775a620SHiroshi Yamauchi "Empty");
13449775a620SHiroshi Yamauchi setCHRRegions(Scope, Scope);
13459775a620SHiroshi Yamauchi Output.push_back(Scope);
13469775a620SHiroshi Yamauchi CHR_DEBUG(
13479775a620SHiroshi Yamauchi dbgs() << "setCHRRegions HoistStopMap " << *Scope << "\n";
13489775a620SHiroshi Yamauchi for (auto pair : Scope->HoistStopMap) {
13499775a620SHiroshi Yamauchi Region *R = pair.first;
13509775a620SHiroshi Yamauchi dbgs() << "Region " << R->getNameStr() << "\n";
13519775a620SHiroshi Yamauchi for (Instruction *I : pair.second) {
13529775a620SHiroshi Yamauchi dbgs() << "HoistStop " << *I << "\n";
13539775a620SHiroshi Yamauchi }
13549775a620SHiroshi Yamauchi }
13559775a620SHiroshi Yamauchi dbgs() << "CHRRegions" << "\n";
13569775a620SHiroshi Yamauchi for (RegInfo &RI : Scope->CHRRegions) {
13579775a620SHiroshi Yamauchi dbgs() << RI.R->getNameStr() << "\n";
13589775a620SHiroshi Yamauchi });
13599775a620SHiroshi Yamauchi }
13609775a620SHiroshi Yamauchi }
13619775a620SHiroshi Yamauchi
setCHRRegions(CHRScope * Scope,CHRScope * OutermostScope)13629775a620SHiroshi Yamauchi void CHR::setCHRRegions(CHRScope *Scope, CHRScope *OutermostScope) {
13639775a620SHiroshi Yamauchi DenseSet<Instruction *> Unhoistables;
13649775a620SHiroshi Yamauchi // Put the biased selects in Unhoistables because they should stay where they
13659775a620SHiroshi Yamauchi // are and constant-folded after CHR (in case one biased select or a branch
13669775a620SHiroshi Yamauchi // can depend on another biased select.)
13679775a620SHiroshi Yamauchi for (RegInfo &RI : Scope->RegInfos) {
13689775a620SHiroshi Yamauchi for (SelectInst *SI : RI.Selects) {
13699775a620SHiroshi Yamauchi Unhoistables.insert(SI);
13709775a620SHiroshi Yamauchi }
13719775a620SHiroshi Yamauchi }
13729775a620SHiroshi Yamauchi Instruction *InsertPoint = OutermostScope->BranchInsertPoint;
13739775a620SHiroshi Yamauchi for (RegInfo &RI : Scope->RegInfos) {
13749775a620SHiroshi Yamauchi Region *R = RI.R;
13759775a620SHiroshi Yamauchi DenseSet<Instruction *> HoistStops;
13769775a620SHiroshi Yamauchi bool IsHoisted = false;
13779775a620SHiroshi Yamauchi if (RI.HasBranch) {
137833bf1cadSKazu Hirata assert((OutermostScope->TrueBiasedRegions.contains(R) ||
137933bf1cadSKazu Hirata OutermostScope->FalseBiasedRegions.contains(R)) &&
13809775a620SHiroshi Yamauchi "Must be truthy or falsy");
13819775a620SHiroshi Yamauchi auto *BI = cast<BranchInst>(R->getEntry()->getTerminator());
13829775a620SHiroshi Yamauchi // Note checkHoistValue fills in HoistStops.
1383dfeb7974SHiroshi Yamauchi DenseMap<Instruction *, bool> Visited;
13849775a620SHiroshi Yamauchi bool IsHoistable = checkHoistValue(BI->getCondition(), InsertPoint, DT,
1385dfeb7974SHiroshi Yamauchi Unhoistables, &HoistStops, Visited);
13869775a620SHiroshi Yamauchi assert(IsHoistable && "Must be hoistable");
13879775a620SHiroshi Yamauchi (void)(IsHoistable); // Unused in release build
13889775a620SHiroshi Yamauchi IsHoisted = true;
13899775a620SHiroshi Yamauchi }
13909775a620SHiroshi Yamauchi for (SelectInst *SI : RI.Selects) {
139133bf1cadSKazu Hirata assert((OutermostScope->TrueBiasedSelects.contains(SI) ||
139233bf1cadSKazu Hirata OutermostScope->FalseBiasedSelects.contains(SI)) &&
13939775a620SHiroshi Yamauchi "Must be true or false biased");
13949775a620SHiroshi Yamauchi // Note checkHoistValue fills in HoistStops.
1395dfeb7974SHiroshi Yamauchi DenseMap<Instruction *, bool> Visited;
13969775a620SHiroshi Yamauchi bool IsHoistable = checkHoistValue(SI->getCondition(), InsertPoint, DT,
1397dfeb7974SHiroshi Yamauchi Unhoistables, &HoistStops, Visited);
13989775a620SHiroshi Yamauchi assert(IsHoistable && "Must be hoistable");
13999775a620SHiroshi Yamauchi (void)(IsHoistable); // Unused in release build
14009775a620SHiroshi Yamauchi IsHoisted = true;
14019775a620SHiroshi Yamauchi }
14029775a620SHiroshi Yamauchi if (IsHoisted) {
14039775a620SHiroshi Yamauchi OutermostScope->CHRRegions.push_back(RI);
14049775a620SHiroshi Yamauchi OutermostScope->HoistStopMap[R] = HoistStops;
14059775a620SHiroshi Yamauchi }
14069775a620SHiroshi Yamauchi }
14079775a620SHiroshi Yamauchi for (CHRScope *Sub : Scope->Subs)
14089775a620SHiroshi Yamauchi setCHRRegions(Sub, OutermostScope);
14099775a620SHiroshi Yamauchi }
14109775a620SHiroshi Yamauchi
CHRScopeSorter(CHRScope * Scope1,CHRScope * Scope2)1411f1542efdSBenjamin Kramer static bool CHRScopeSorter(CHRScope *Scope1, CHRScope *Scope2) {
14129775a620SHiroshi Yamauchi return Scope1->RegInfos[0].R->getDepth() < Scope2->RegInfos[0].R->getDepth();
14139775a620SHiroshi Yamauchi }
14149775a620SHiroshi Yamauchi
sortScopes(SmallVectorImpl<CHRScope * > & Input,SmallVectorImpl<CHRScope * > & Output)14159775a620SHiroshi Yamauchi void CHR::sortScopes(SmallVectorImpl<CHRScope *> &Input,
14169775a620SHiroshi Yamauchi SmallVectorImpl<CHRScope *> &Output) {
14179775a620SHiroshi Yamauchi Output.resize(Input.size());
141875709329SFangrui Song llvm::copy(Input, Output.begin());
1419efd94c56SFangrui Song llvm::stable_sort(Output, CHRScopeSorter);
14209775a620SHiroshi Yamauchi }
14219775a620SHiroshi Yamauchi
14229775a620SHiroshi Yamauchi // Return true if V is already hoisted or was hoisted (along with its operands)
14239775a620SHiroshi Yamauchi // to the insert point.
hoistValue(Value * V,Instruction * HoistPoint,Region * R,HoistStopMapTy & HoistStopMap,DenseSet<Instruction * > & HoistedSet,DenseSet<PHINode * > & TrivialPHIs,DominatorTree & DT)14249775a620SHiroshi Yamauchi static void hoistValue(Value *V, Instruction *HoistPoint, Region *R,
14259775a620SHiroshi Yamauchi HoistStopMapTy &HoistStopMap,
14269775a620SHiroshi Yamauchi DenseSet<Instruction *> &HoistedSet,
142716201040SHiroshi Yamauchi DenseSet<PHINode *> &TrivialPHIs,
142816201040SHiroshi Yamauchi DominatorTree &DT) {
14299775a620SHiroshi Yamauchi auto IT = HoistStopMap.find(R);
14309775a620SHiroshi Yamauchi assert(IT != HoistStopMap.end() && "Region must be in hoist stop map");
14319775a620SHiroshi Yamauchi DenseSet<Instruction *> &HoistStops = IT->second;
14329775a620SHiroshi Yamauchi if (auto *I = dyn_cast<Instruction>(V)) {
14339775a620SHiroshi Yamauchi if (I == HoistPoint)
14349775a620SHiroshi Yamauchi return;
14359775a620SHiroshi Yamauchi if (HoistStops.count(I))
14369775a620SHiroshi Yamauchi return;
14379775a620SHiroshi Yamauchi if (auto *PN = dyn_cast<PHINode>(I))
14389775a620SHiroshi Yamauchi if (TrivialPHIs.count(PN))
14399775a620SHiroshi Yamauchi // The trivial phi inserted by the previous CHR scope could replace a
14409775a620SHiroshi Yamauchi // non-phi in HoistStops. Note that since this phi is at the exit of a
14419775a620SHiroshi Yamauchi // previous CHR scope, which dominates this scope, it's safe to stop
14429775a620SHiroshi Yamauchi // hoisting there.
14439775a620SHiroshi Yamauchi return;
14449775a620SHiroshi Yamauchi if (HoistedSet.count(I))
14459775a620SHiroshi Yamauchi // Already hoisted, return.
14469775a620SHiroshi Yamauchi return;
14479775a620SHiroshi Yamauchi assert(isHoistableInstructionType(I) && "Unhoistable instruction type");
144816201040SHiroshi Yamauchi assert(DT.getNode(I->getParent()) && "DT must contain I's block");
144916201040SHiroshi Yamauchi assert(DT.getNode(HoistPoint->getParent()) &&
145016201040SHiroshi Yamauchi "DT must contain HoistPoint block");
145116201040SHiroshi Yamauchi if (DT.dominates(I, HoistPoint))
145216201040SHiroshi Yamauchi // We are already above the hoist point. Stop here. This may be necessary
145316201040SHiroshi Yamauchi // when multiple scopes would independently hoist the same
145416201040SHiroshi Yamauchi // instruction. Since an outer (dominating) scope would hoist it to its
145516201040SHiroshi Yamauchi // entry before an inner (dominated) scope would to its entry, the inner
145616201040SHiroshi Yamauchi // scope may see the instruction already hoisted, in which case it
145716201040SHiroshi Yamauchi // potentially wrong for the inner scope to hoist it and could cause bad
145816201040SHiroshi Yamauchi // IR (non-dominating def), but safe to skip hoisting it instead because
145916201040SHiroshi Yamauchi // it's already in a block that dominates the inner scope.
146016201040SHiroshi Yamauchi return;
14619775a620SHiroshi Yamauchi for (Value *Op : I->operands()) {
146216201040SHiroshi Yamauchi hoistValue(Op, HoistPoint, R, HoistStopMap, HoistedSet, TrivialPHIs, DT);
14639775a620SHiroshi Yamauchi }
14649775a620SHiroshi Yamauchi I->moveBefore(HoistPoint);
14659775a620SHiroshi Yamauchi HoistedSet.insert(I);
14669775a620SHiroshi Yamauchi CHR_DEBUG(dbgs() << "hoistValue " << *I << "\n");
14679775a620SHiroshi Yamauchi }
14689775a620SHiroshi Yamauchi }
14699775a620SHiroshi Yamauchi
14709775a620SHiroshi Yamauchi // Hoist the dependent condition values of the branches and the selects in the
14719775a620SHiroshi Yamauchi // scope to the insert point.
hoistScopeConditions(CHRScope * Scope,Instruction * HoistPoint,DenseSet<PHINode * > & TrivialPHIs,DominatorTree & DT)14729775a620SHiroshi Yamauchi static void hoistScopeConditions(CHRScope *Scope, Instruction *HoistPoint,
147316201040SHiroshi Yamauchi DenseSet<PHINode *> &TrivialPHIs,
147416201040SHiroshi Yamauchi DominatorTree &DT) {
14759775a620SHiroshi Yamauchi DenseSet<Instruction *> HoistedSet;
14769775a620SHiroshi Yamauchi for (const RegInfo &RI : Scope->CHRRegions) {
14779775a620SHiroshi Yamauchi Region *R = RI.R;
14789775a620SHiroshi Yamauchi bool IsTrueBiased = Scope->TrueBiasedRegions.count(R);
14799775a620SHiroshi Yamauchi bool IsFalseBiased = Scope->FalseBiasedRegions.count(R);
14809775a620SHiroshi Yamauchi if (RI.HasBranch && (IsTrueBiased || IsFalseBiased)) {
14819775a620SHiroshi Yamauchi auto *BI = cast<BranchInst>(R->getEntry()->getTerminator());
14829775a620SHiroshi Yamauchi hoistValue(BI->getCondition(), HoistPoint, R, Scope->HoistStopMap,
148316201040SHiroshi Yamauchi HoistedSet, TrivialPHIs, DT);
14849775a620SHiroshi Yamauchi }
14859775a620SHiroshi Yamauchi for (SelectInst *SI : RI.Selects) {
14869775a620SHiroshi Yamauchi bool IsTrueBiased = Scope->TrueBiasedSelects.count(SI);
14879775a620SHiroshi Yamauchi bool IsFalseBiased = Scope->FalseBiasedSelects.count(SI);
14889775a620SHiroshi Yamauchi if (!(IsTrueBiased || IsFalseBiased))
14899775a620SHiroshi Yamauchi continue;
14909775a620SHiroshi Yamauchi hoistValue(SI->getCondition(), HoistPoint, R, Scope->HoistStopMap,
149116201040SHiroshi Yamauchi HoistedSet, TrivialPHIs, DT);
14929775a620SHiroshi Yamauchi }
14939775a620SHiroshi Yamauchi }
14949775a620SHiroshi Yamauchi }
14959775a620SHiroshi Yamauchi
14969775a620SHiroshi Yamauchi // Negate the predicate if an ICmp if it's used only by branches or selects by
14979775a620SHiroshi Yamauchi // swapping the operands of the branches or the selects. Returns true if success.
negateICmpIfUsedByBranchOrSelectOnly(ICmpInst * ICmp,Instruction * ExcludedUser,CHRScope * Scope)1498b3b61de0SFangrui Song static bool negateICmpIfUsedByBranchOrSelectOnly(ICmpInst *ICmp,
14999775a620SHiroshi Yamauchi Instruction *ExcludedUser,
15009775a620SHiroshi Yamauchi CHRScope *Scope) {
15019775a620SHiroshi Yamauchi for (User *U : ICmp->users()) {
15029775a620SHiroshi Yamauchi if (U == ExcludedUser)
15039775a620SHiroshi Yamauchi continue;
15049775a620SHiroshi Yamauchi if (isa<BranchInst>(U) && cast<BranchInst>(U)->isConditional())
15059775a620SHiroshi Yamauchi continue;
15069775a620SHiroshi Yamauchi if (isa<SelectInst>(U) && cast<SelectInst>(U)->getCondition() == ICmp)
15079775a620SHiroshi Yamauchi continue;
15089775a620SHiroshi Yamauchi return false;
15099775a620SHiroshi Yamauchi }
15109775a620SHiroshi Yamauchi for (User *U : ICmp->users()) {
15119775a620SHiroshi Yamauchi if (U == ExcludedUser)
15129775a620SHiroshi Yamauchi continue;
15139775a620SHiroshi Yamauchi if (auto *BI = dyn_cast<BranchInst>(U)) {
15149775a620SHiroshi Yamauchi assert(BI->isConditional() && "Must be conditional");
15159775a620SHiroshi Yamauchi BI->swapSuccessors();
15169775a620SHiroshi Yamauchi // Don't need to swap this in terms of
15179775a620SHiroshi Yamauchi // TrueBiasedRegions/FalseBiasedRegions because true-based/false-based
15189775a620SHiroshi Yamauchi // mean whehter the branch is likely go into the if-then rather than
15199775a620SHiroshi Yamauchi // successor0/successor1 and because we can tell which edge is the then or
15209775a620SHiroshi Yamauchi // the else one by comparing the destination to the region exit block.
15219775a620SHiroshi Yamauchi continue;
15229775a620SHiroshi Yamauchi }
15239775a620SHiroshi Yamauchi if (auto *SI = dyn_cast<SelectInst>(U)) {
15249775a620SHiroshi Yamauchi // Swap operands
15250efeaa81SRoman Lebedev SI->swapValues();
15269775a620SHiroshi Yamauchi SI->swapProfMetadata();
15279775a620SHiroshi Yamauchi if (Scope->TrueBiasedSelects.count(SI)) {
1528c714da2cSKazu Hirata assert(!Scope->FalseBiasedSelects.contains(SI) &&
15299775a620SHiroshi Yamauchi "Must not be already in");
15309775a620SHiroshi Yamauchi Scope->FalseBiasedSelects.insert(SI);
15319775a620SHiroshi Yamauchi } else if (Scope->FalseBiasedSelects.count(SI)) {
1532c714da2cSKazu Hirata assert(!Scope->TrueBiasedSelects.contains(SI) &&
15339775a620SHiroshi Yamauchi "Must not be already in");
15349775a620SHiroshi Yamauchi Scope->TrueBiasedSelects.insert(SI);
15359775a620SHiroshi Yamauchi }
15369775a620SHiroshi Yamauchi continue;
15379775a620SHiroshi Yamauchi }
15389775a620SHiroshi Yamauchi llvm_unreachable("Must be a branch or a select");
15399775a620SHiroshi Yamauchi }
15409775a620SHiroshi Yamauchi ICmp->setPredicate(CmpInst::getInversePredicate(ICmp->getPredicate()));
15419775a620SHiroshi Yamauchi return true;
15429775a620SHiroshi Yamauchi }
15439775a620SHiroshi Yamauchi
15449775a620SHiroshi Yamauchi // A helper for transformScopes. Insert a trivial phi at the scope exit block
15459775a620SHiroshi Yamauchi // for a value that's defined in the scope but used outside it (meaning it's
15469775a620SHiroshi Yamauchi // alive at the exit block).
insertTrivialPHIs(CHRScope * Scope,BasicBlock * EntryBlock,BasicBlock * ExitBlock,DenseSet<PHINode * > & TrivialPHIs)15479775a620SHiroshi Yamauchi static void insertTrivialPHIs(CHRScope *Scope,
15489775a620SHiroshi Yamauchi BasicBlock *EntryBlock, BasicBlock *ExitBlock,
15499775a620SHiroshi Yamauchi DenseSet<PHINode *> &TrivialPHIs) {
1550f1542efdSBenjamin Kramer SmallSetVector<BasicBlock *, 8> BlocksInScope;
15519775a620SHiroshi Yamauchi for (RegInfo &RI : Scope->RegInfos) {
15529775a620SHiroshi Yamauchi for (BasicBlock *BB : RI.R->blocks()) { // This includes the blocks in the
15539775a620SHiroshi Yamauchi // sub-Scopes.
1554f1542efdSBenjamin Kramer BlocksInScope.insert(BB);
15559775a620SHiroshi Yamauchi }
15569775a620SHiroshi Yamauchi }
1557f1542efdSBenjamin Kramer CHR_DEBUG({
1558f1542efdSBenjamin Kramer dbgs() << "Inserting redundant phis\n";
1559f1542efdSBenjamin Kramer for (BasicBlock *BB : BlocksInScope)
15609775a620SHiroshi Yamauchi dbgs() << "BlockInScope " << BB->getName() << "\n";
15619775a620SHiroshi Yamauchi });
1562f1542efdSBenjamin Kramer for (BasicBlock *BB : BlocksInScope) {
15639775a620SHiroshi Yamauchi for (Instruction &I : *BB) {
15649775a620SHiroshi Yamauchi SmallVector<Instruction *, 8> Users;
15659775a620SHiroshi Yamauchi for (User *U : I.users()) {
15669775a620SHiroshi Yamauchi if (auto *UI = dyn_cast<Instruction>(U)) {
1567c714da2cSKazu Hirata if (!BlocksInScope.contains(UI->getParent()) &&
15689775a620SHiroshi Yamauchi // Unless there's already a phi for I at the exit block.
15699775a620SHiroshi Yamauchi !(isa<PHINode>(UI) && UI->getParent() == ExitBlock)) {
15709775a620SHiroshi Yamauchi CHR_DEBUG(dbgs() << "V " << I << "\n");
15719775a620SHiroshi Yamauchi CHR_DEBUG(dbgs() << "Used outside scope by user " << *UI << "\n");
15729775a620SHiroshi Yamauchi Users.push_back(UI);
15739775a620SHiroshi Yamauchi } else if (UI->getParent() == EntryBlock && isa<PHINode>(UI)) {
15749775a620SHiroshi Yamauchi // There's a loop backedge from a block that's dominated by this
15759775a620SHiroshi Yamauchi // scope to the entry block.
15769775a620SHiroshi Yamauchi CHR_DEBUG(dbgs() << "V " << I << "\n");
15779775a620SHiroshi Yamauchi CHR_DEBUG(dbgs()
15789775a620SHiroshi Yamauchi << "Used at entry block (for a back edge) by a phi user "
15799775a620SHiroshi Yamauchi << *UI << "\n");
15809775a620SHiroshi Yamauchi Users.push_back(UI);
15819775a620SHiroshi Yamauchi }
15829775a620SHiroshi Yamauchi }
15839775a620SHiroshi Yamauchi }
15849775a620SHiroshi Yamauchi if (Users.size() > 0) {
15859775a620SHiroshi Yamauchi // Insert a trivial phi for I (phi [&I, P0], [&I, P1], ...) at
15869775a620SHiroshi Yamauchi // ExitBlock. Replace I with the new phi in UI unless UI is another
15879775a620SHiroshi Yamauchi // phi at ExitBlock.
15881c82d320SKazu Hirata PHINode *PN = PHINode::Create(I.getType(), pred_size(ExitBlock), "",
15899775a620SHiroshi Yamauchi &ExitBlock->front());
15909775a620SHiroshi Yamauchi for (BasicBlock *Pred : predecessors(ExitBlock)) {
15919775a620SHiroshi Yamauchi PN->addIncoming(&I, Pred);
15929775a620SHiroshi Yamauchi }
15939775a620SHiroshi Yamauchi TrivialPHIs.insert(PN);
15949775a620SHiroshi Yamauchi CHR_DEBUG(dbgs() << "Insert phi " << *PN << "\n");
15959775a620SHiroshi Yamauchi for (Instruction *UI : Users) {
15969775a620SHiroshi Yamauchi for (unsigned J = 0, NumOps = UI->getNumOperands(); J < NumOps; ++J) {
15979775a620SHiroshi Yamauchi if (UI->getOperand(J) == &I) {
15989775a620SHiroshi Yamauchi UI->setOperand(J, PN);
15999775a620SHiroshi Yamauchi }
16009775a620SHiroshi Yamauchi }
16019775a620SHiroshi Yamauchi CHR_DEBUG(dbgs() << "Updated user " << *UI << "\n");
16029775a620SHiroshi Yamauchi }
16039775a620SHiroshi Yamauchi }
16049775a620SHiroshi Yamauchi }
16059775a620SHiroshi Yamauchi }
16069775a620SHiroshi Yamauchi }
16079775a620SHiroshi Yamauchi
16089775a620SHiroshi Yamauchi // Assert that all the CHR regions of the scope have a biased branch or select.
1609c8f348cbSFangrui Song static void LLVM_ATTRIBUTE_UNUSED
assertCHRRegionsHaveBiasedBranchOrSelect(CHRScope * Scope)1610c8f348cbSFangrui Song assertCHRRegionsHaveBiasedBranchOrSelect(CHRScope *Scope) {
16119775a620SHiroshi Yamauchi #ifndef NDEBUG
16129775a620SHiroshi Yamauchi auto HasBiasedBranchOrSelect = [](RegInfo &RI, CHRScope *Scope) {
16139775a620SHiroshi Yamauchi if (Scope->TrueBiasedRegions.count(RI.R) ||
16149775a620SHiroshi Yamauchi Scope->FalseBiasedRegions.count(RI.R))
16159775a620SHiroshi Yamauchi return true;
16169775a620SHiroshi Yamauchi for (SelectInst *SI : RI.Selects)
16179775a620SHiroshi Yamauchi if (Scope->TrueBiasedSelects.count(SI) ||
16189775a620SHiroshi Yamauchi Scope->FalseBiasedSelects.count(SI))
16199775a620SHiroshi Yamauchi return true;
16209775a620SHiroshi Yamauchi return false;
16219775a620SHiroshi Yamauchi };
16229775a620SHiroshi Yamauchi for (RegInfo &RI : Scope->CHRRegions) {
16239775a620SHiroshi Yamauchi assert(HasBiasedBranchOrSelect(RI, Scope) &&
16249775a620SHiroshi Yamauchi "Must have biased branch or select");
16259775a620SHiroshi Yamauchi }
16269775a620SHiroshi Yamauchi #endif
16279775a620SHiroshi Yamauchi }
16289775a620SHiroshi Yamauchi
16299775a620SHiroshi Yamauchi // Assert that all the condition values of the biased branches and selects have
16309775a620SHiroshi Yamauchi // been hoisted to the pre-entry block or outside of the scope.
assertBranchOrSelectConditionHoisted(CHRScope * Scope,BasicBlock * PreEntryBlock)1631c8f348cbSFangrui Song static void LLVM_ATTRIBUTE_UNUSED assertBranchOrSelectConditionHoisted(
1632c8f348cbSFangrui Song CHRScope *Scope, BasicBlock *PreEntryBlock) {
16339775a620SHiroshi Yamauchi CHR_DEBUG(dbgs() << "Biased regions condition values \n");
16349775a620SHiroshi Yamauchi for (RegInfo &RI : Scope->CHRRegions) {
16359775a620SHiroshi Yamauchi Region *R = RI.R;
16369775a620SHiroshi Yamauchi bool IsTrueBiased = Scope->TrueBiasedRegions.count(R);
16379775a620SHiroshi Yamauchi bool IsFalseBiased = Scope->FalseBiasedRegions.count(R);
16389775a620SHiroshi Yamauchi if (RI.HasBranch && (IsTrueBiased || IsFalseBiased)) {
16399775a620SHiroshi Yamauchi auto *BI = cast<BranchInst>(R->getEntry()->getTerminator());
16409775a620SHiroshi Yamauchi Value *V = BI->getCondition();
16419775a620SHiroshi Yamauchi CHR_DEBUG(dbgs() << *V << "\n");
16429775a620SHiroshi Yamauchi if (auto *I = dyn_cast<Instruction>(V)) {
164372ee6d60SHiroshi Yamauchi (void)(I); // Unused in release build.
16449775a620SHiroshi Yamauchi assert((I->getParent() == PreEntryBlock ||
16459775a620SHiroshi Yamauchi !Scope->contains(I)) &&
16469775a620SHiroshi Yamauchi "Must have been hoisted to PreEntryBlock or outside the scope");
16479775a620SHiroshi Yamauchi }
16489775a620SHiroshi Yamauchi }
16499775a620SHiroshi Yamauchi for (SelectInst *SI : RI.Selects) {
16509775a620SHiroshi Yamauchi bool IsTrueBiased = Scope->TrueBiasedSelects.count(SI);
16519775a620SHiroshi Yamauchi bool IsFalseBiased = Scope->FalseBiasedSelects.count(SI);
16529775a620SHiroshi Yamauchi if (!(IsTrueBiased || IsFalseBiased))
16539775a620SHiroshi Yamauchi continue;
16549775a620SHiroshi Yamauchi Value *V = SI->getCondition();
16559775a620SHiroshi Yamauchi CHR_DEBUG(dbgs() << *V << "\n");
16569775a620SHiroshi Yamauchi if (auto *I = dyn_cast<Instruction>(V)) {
165772ee6d60SHiroshi Yamauchi (void)(I); // Unused in release build.
16589775a620SHiroshi Yamauchi assert((I->getParent() == PreEntryBlock ||
16599775a620SHiroshi Yamauchi !Scope->contains(I)) &&
16609775a620SHiroshi Yamauchi "Must have been hoisted to PreEntryBlock or outside the scope");
16619775a620SHiroshi Yamauchi }
16629775a620SHiroshi Yamauchi }
16639775a620SHiroshi Yamauchi }
16649775a620SHiroshi Yamauchi }
16659775a620SHiroshi Yamauchi
transformScopes(CHRScope * Scope,DenseSet<PHINode * > & TrivialPHIs)16669775a620SHiroshi Yamauchi void CHR::transformScopes(CHRScope *Scope, DenseSet<PHINode *> &TrivialPHIs) {
16679775a620SHiroshi Yamauchi CHR_DEBUG(dbgs() << "transformScopes " << *Scope << "\n");
16689775a620SHiroshi Yamauchi
16699775a620SHiroshi Yamauchi assert(Scope->RegInfos.size() >= 1 && "Should have at least one Region");
16709775a620SHiroshi Yamauchi Region *FirstRegion = Scope->RegInfos[0].R;
16719775a620SHiroshi Yamauchi BasicBlock *EntryBlock = FirstRegion->getEntry();
16729775a620SHiroshi Yamauchi Region *LastRegion = Scope->RegInfos[Scope->RegInfos.size() - 1].R;
16739775a620SHiroshi Yamauchi BasicBlock *ExitBlock = LastRegion->getExit();
16749775a620SHiroshi Yamauchi Optional<uint64_t> ProfileCount = BFI.getBlockProfileCount(EntryBlock);
16759775a620SHiroshi Yamauchi
16769775a620SHiroshi Yamauchi if (ExitBlock) {
16779775a620SHiroshi Yamauchi // Insert a trivial phi at the exit block (where the CHR hot path and the
16789775a620SHiroshi Yamauchi // cold path merges) for a value that's defined in the scope but used
16799775a620SHiroshi Yamauchi // outside it (meaning it's alive at the exit block). We will add the
16809775a620SHiroshi Yamauchi // incoming values for the CHR cold paths to it below. Without this, we'd
16819775a620SHiroshi Yamauchi // miss updating phi's for such values unless there happens to already be a
16829775a620SHiroshi Yamauchi // phi for that value there.
16839775a620SHiroshi Yamauchi insertTrivialPHIs(Scope, EntryBlock, ExitBlock, TrivialPHIs);
16849775a620SHiroshi Yamauchi }
16859775a620SHiroshi Yamauchi
16869775a620SHiroshi Yamauchi // Split the entry block of the first region. The new block becomes the new
16879775a620SHiroshi Yamauchi // entry block of the first region. The old entry block becomes the block to
16889775a620SHiroshi Yamauchi // insert the CHR branch into. Note DT gets updated. Since DT gets updated
16899775a620SHiroshi Yamauchi // through the split, we update the entry of the first region after the split,
16909775a620SHiroshi Yamauchi // and Region only points to the entry and the exit blocks, rather than
16919775a620SHiroshi Yamauchi // keeping everything in a list or set, the blocks membership and the
16929775a620SHiroshi Yamauchi // entry/exit blocks of the region are still valid after the split.
16939775a620SHiroshi Yamauchi CHR_DEBUG(dbgs() << "Splitting entry block " << EntryBlock->getName()
16949775a620SHiroshi Yamauchi << " at " << *Scope->BranchInsertPoint << "\n");
16959775a620SHiroshi Yamauchi BasicBlock *NewEntryBlock =
16969775a620SHiroshi Yamauchi SplitBlock(EntryBlock, Scope->BranchInsertPoint, &DT);
16979775a620SHiroshi Yamauchi assert(NewEntryBlock->getSinglePredecessor() == EntryBlock &&
16989775a620SHiroshi Yamauchi "NewEntryBlock's only pred must be EntryBlock");
16999775a620SHiroshi Yamauchi FirstRegion->replaceEntryRecursive(NewEntryBlock);
17009775a620SHiroshi Yamauchi BasicBlock *PreEntryBlock = EntryBlock;
17019775a620SHiroshi Yamauchi
17029775a620SHiroshi Yamauchi ValueToValueMapTy VMap;
17039775a620SHiroshi Yamauchi // Clone the blocks in the scope (excluding the PreEntryBlock) to split into a
17049775a620SHiroshi Yamauchi // hot path (originals) and a cold path (clones) and update the PHIs at the
17059775a620SHiroshi Yamauchi // exit block.
17069775a620SHiroshi Yamauchi cloneScopeBlocks(Scope, PreEntryBlock, ExitBlock, LastRegion, VMap);
17079775a620SHiroshi Yamauchi
17089775a620SHiroshi Yamauchi // Replace the old (placeholder) branch with the new (merged) conditional
17099775a620SHiroshi Yamauchi // branch.
17109775a620SHiroshi Yamauchi BranchInst *MergedBr = createMergedBranch(PreEntryBlock, EntryBlock,
17119775a620SHiroshi Yamauchi NewEntryBlock, VMap);
17129775a620SHiroshi Yamauchi
17139775a620SHiroshi Yamauchi #ifndef NDEBUG
17149775a620SHiroshi Yamauchi assertCHRRegionsHaveBiasedBranchOrSelect(Scope);
17159775a620SHiroshi Yamauchi #endif
17169775a620SHiroshi Yamauchi
17179775a620SHiroshi Yamauchi // Hoist the conditional values of the branches/selects.
171816201040SHiroshi Yamauchi hoistScopeConditions(Scope, PreEntryBlock->getTerminator(), TrivialPHIs, DT);
17199775a620SHiroshi Yamauchi
17209775a620SHiroshi Yamauchi #ifndef NDEBUG
17219775a620SHiroshi Yamauchi assertBranchOrSelectConditionHoisted(Scope, PreEntryBlock);
17229775a620SHiroshi Yamauchi #endif
17239775a620SHiroshi Yamauchi
17249775a620SHiroshi Yamauchi // Create the combined branch condition and constant-fold the branches/selects
17259775a620SHiroshi Yamauchi // in the hot path.
17269775a620SHiroshi Yamauchi fixupBranchesAndSelects(Scope, PreEntryBlock, MergedBr,
1727*129b531cSKazu Hirata ProfileCount.value_or(0));
17289775a620SHiroshi Yamauchi }
17299775a620SHiroshi Yamauchi
17309775a620SHiroshi Yamauchi // A helper for transformScopes. Clone the blocks in the scope (excluding the
17319775a620SHiroshi Yamauchi // PreEntryBlock) to split into a hot path and a cold path and update the PHIs
17329775a620SHiroshi Yamauchi // at the exit block.
cloneScopeBlocks(CHRScope * Scope,BasicBlock * PreEntryBlock,BasicBlock * ExitBlock,Region * LastRegion,ValueToValueMapTy & VMap)17339775a620SHiroshi Yamauchi void CHR::cloneScopeBlocks(CHRScope *Scope,
17349775a620SHiroshi Yamauchi BasicBlock *PreEntryBlock,
17359775a620SHiroshi Yamauchi BasicBlock *ExitBlock,
17369775a620SHiroshi Yamauchi Region *LastRegion,
17379775a620SHiroshi Yamauchi ValueToValueMapTy &VMap) {
17389775a620SHiroshi Yamauchi // Clone all the blocks. The original blocks will be the hot-path
17399775a620SHiroshi Yamauchi // CHR-optimized code and the cloned blocks will be the original unoptimized
17409775a620SHiroshi Yamauchi // code. This is so that the block pointers from the
17419775a620SHiroshi Yamauchi // CHRScope/Region/RegionInfo can stay valid in pointing to the hot-path code
17429775a620SHiroshi Yamauchi // which CHR should apply to.
17439775a620SHiroshi Yamauchi SmallVector<BasicBlock*, 8> NewBlocks;
17449775a620SHiroshi Yamauchi for (RegInfo &RI : Scope->RegInfos)
17459775a620SHiroshi Yamauchi for (BasicBlock *BB : RI.R->blocks()) { // This includes the blocks in the
17469775a620SHiroshi Yamauchi // sub-Scopes.
17479775a620SHiroshi Yamauchi assert(BB != PreEntryBlock && "Don't copy the preetntry block");
17489775a620SHiroshi Yamauchi BasicBlock *NewBB = CloneBasicBlock(BB, VMap, ".nonchr", &F);
17499775a620SHiroshi Yamauchi NewBlocks.push_back(NewBB);
17509775a620SHiroshi Yamauchi VMap[BB] = NewBB;
17519775a620SHiroshi Yamauchi }
17529775a620SHiroshi Yamauchi
17539775a620SHiroshi Yamauchi // Place the cloned blocks right after the original blocks (right before the
17549775a620SHiroshi Yamauchi // exit block of.)
17559775a620SHiroshi Yamauchi if (ExitBlock)
17569775a620SHiroshi Yamauchi F.getBasicBlockList().splice(ExitBlock->getIterator(),
17579775a620SHiroshi Yamauchi F.getBasicBlockList(),
17589775a620SHiroshi Yamauchi NewBlocks[0]->getIterator(), F.end());
17599775a620SHiroshi Yamauchi
17609775a620SHiroshi Yamauchi // Update the cloned blocks/instructions to refer to themselves.
17619775a620SHiroshi Yamauchi for (unsigned i = 0, e = NewBlocks.size(); i != e; ++i)
17629775a620SHiroshi Yamauchi for (Instruction &I : *NewBlocks[i])
17639775a620SHiroshi Yamauchi RemapInstruction(&I, VMap,
17649775a620SHiroshi Yamauchi RF_NoModuleLevelChanges | RF_IgnoreMissingLocals);
17659775a620SHiroshi Yamauchi
17669775a620SHiroshi Yamauchi // Add the cloned blocks to the PHIs of the exit blocks. ExitBlock is null for
17679775a620SHiroshi Yamauchi // the top-level region but we don't need to add PHIs. The trivial PHIs
17689775a620SHiroshi Yamauchi // inserted above will be updated here.
17699775a620SHiroshi Yamauchi if (ExitBlock)
17709775a620SHiroshi Yamauchi for (PHINode &PN : ExitBlock->phis())
17719775a620SHiroshi Yamauchi for (unsigned I = 0, NumOps = PN.getNumIncomingValues(); I < NumOps;
17729775a620SHiroshi Yamauchi ++I) {
17739775a620SHiroshi Yamauchi BasicBlock *Pred = PN.getIncomingBlock(I);
17749775a620SHiroshi Yamauchi if (LastRegion->contains(Pred)) {
17759775a620SHiroshi Yamauchi Value *V = PN.getIncomingValue(I);
17769775a620SHiroshi Yamauchi auto It = VMap.find(V);
17779775a620SHiroshi Yamauchi if (It != VMap.end()) V = It->second;
17789775a620SHiroshi Yamauchi assert(VMap.find(Pred) != VMap.end() && "Pred must have been cloned");
17799775a620SHiroshi Yamauchi PN.addIncoming(V, cast<BasicBlock>(VMap[Pred]));
17809775a620SHiroshi Yamauchi }
17819775a620SHiroshi Yamauchi }
17829775a620SHiroshi Yamauchi }
17839775a620SHiroshi Yamauchi
17849775a620SHiroshi Yamauchi // A helper for transformScope. Replace the old (placeholder) branch with the
17859775a620SHiroshi Yamauchi // new (merged) conditional branch.
createMergedBranch(BasicBlock * PreEntryBlock,BasicBlock * EntryBlock,BasicBlock * NewEntryBlock,ValueToValueMapTy & VMap)17869775a620SHiroshi Yamauchi BranchInst *CHR::createMergedBranch(BasicBlock *PreEntryBlock,
17879775a620SHiroshi Yamauchi BasicBlock *EntryBlock,
17889775a620SHiroshi Yamauchi BasicBlock *NewEntryBlock,
17899775a620SHiroshi Yamauchi ValueToValueMapTy &VMap) {
17909775a620SHiroshi Yamauchi BranchInst *OldBR = cast<BranchInst>(PreEntryBlock->getTerminator());
17919775a620SHiroshi Yamauchi assert(OldBR->isUnconditional() && OldBR->getSuccessor(0) == NewEntryBlock &&
17929775a620SHiroshi Yamauchi "SplitBlock did not work correctly!");
17939775a620SHiroshi Yamauchi assert(NewEntryBlock->getSinglePredecessor() == EntryBlock &&
17949775a620SHiroshi Yamauchi "NewEntryBlock's only pred must be EntryBlock");
17959775a620SHiroshi Yamauchi assert(VMap.find(NewEntryBlock) != VMap.end() &&
17969775a620SHiroshi Yamauchi "NewEntryBlock must have been copied");
17979775a620SHiroshi Yamauchi OldBR->dropAllReferences();
1798bd897a02SHiroshi Yamauchi OldBR->eraseFromParent();
17999775a620SHiroshi Yamauchi // The true predicate is a placeholder. It will be replaced later in
18009775a620SHiroshi Yamauchi // fixupBranchesAndSelects().
18019775a620SHiroshi Yamauchi BranchInst *NewBR = BranchInst::Create(NewEntryBlock,
18029775a620SHiroshi Yamauchi cast<BasicBlock>(VMap[NewEntryBlock]),
18039775a620SHiroshi Yamauchi ConstantInt::getTrue(F.getContext()));
18049775a620SHiroshi Yamauchi PreEntryBlock->getInstList().push_back(NewBR);
18059775a620SHiroshi Yamauchi assert(NewEntryBlock->getSinglePredecessor() == EntryBlock &&
18069775a620SHiroshi Yamauchi "NewEntryBlock's only pred must be EntryBlock");
18079775a620SHiroshi Yamauchi return NewBR;
18089775a620SHiroshi Yamauchi }
18099775a620SHiroshi Yamauchi
18109775a620SHiroshi Yamauchi // A helper for transformScopes. Create the combined branch condition and
18119775a620SHiroshi Yamauchi // constant-fold the branches/selects in the hot path.
fixupBranchesAndSelects(CHRScope * Scope,BasicBlock * PreEntryBlock,BranchInst * MergedBR,uint64_t ProfileCount)18129775a620SHiroshi Yamauchi void CHR::fixupBranchesAndSelects(CHRScope *Scope,
18139775a620SHiroshi Yamauchi BasicBlock *PreEntryBlock,
18149775a620SHiroshi Yamauchi BranchInst *MergedBR,
18159775a620SHiroshi Yamauchi uint64_t ProfileCount) {
18169775a620SHiroshi Yamauchi Value *MergedCondition = ConstantInt::getTrue(F.getContext());
18179775a620SHiroshi Yamauchi BranchProbability CHRBranchBias(1, 1);
18189775a620SHiroshi Yamauchi uint64_t NumCHRedBranches = 0;
18199775a620SHiroshi Yamauchi IRBuilder<> IRB(PreEntryBlock->getTerminator());
18209775a620SHiroshi Yamauchi for (RegInfo &RI : Scope->CHRRegions) {
18219775a620SHiroshi Yamauchi Region *R = RI.R;
18229775a620SHiroshi Yamauchi if (RI.HasBranch) {
18239775a620SHiroshi Yamauchi fixupBranch(R, Scope, IRB, MergedCondition, CHRBranchBias);
18249775a620SHiroshi Yamauchi ++NumCHRedBranches;
18259775a620SHiroshi Yamauchi }
18269775a620SHiroshi Yamauchi for (SelectInst *SI : RI.Selects) {
18279775a620SHiroshi Yamauchi fixupSelect(SI, Scope, IRB, MergedCondition, CHRBranchBias);
18289775a620SHiroshi Yamauchi ++NumCHRedBranches;
18299775a620SHiroshi Yamauchi }
18309775a620SHiroshi Yamauchi }
18319775a620SHiroshi Yamauchi Stats.NumBranchesDelta += NumCHRedBranches - 1;
18329775a620SHiroshi Yamauchi Stats.WeightedNumBranchesDelta += (NumCHRedBranches - 1) * ProfileCount;
1833fd2c699dSHiroshi Yamauchi ORE.emit([&]() {
1834fd2c699dSHiroshi Yamauchi return OptimizationRemark(DEBUG_TYPE,
1835fd2c699dSHiroshi Yamauchi "CHR",
1836fd2c699dSHiroshi Yamauchi // Refer to the hot (original) path
1837fd2c699dSHiroshi Yamauchi MergedBR->getSuccessor(0)->getTerminator())
1838fd2c699dSHiroshi Yamauchi << "Merged " << ore::NV("NumCHRedBranches", NumCHRedBranches)
1839fd2c699dSHiroshi Yamauchi << " branches or selects";
1840fd2c699dSHiroshi Yamauchi });
18419775a620SHiroshi Yamauchi MergedBR->setCondition(MergedCondition);
18425c31b8b9SArthur Eubanks uint32_t Weights[] = {
18435c31b8b9SArthur Eubanks static_cast<uint32_t>(CHRBranchBias.scale(1000)),
18445c31b8b9SArthur Eubanks static_cast<uint32_t>(CHRBranchBias.getCompl().scale(1000)),
1845f1542efdSBenjamin Kramer };
18469775a620SHiroshi Yamauchi MDBuilder MDB(F.getContext());
18479775a620SHiroshi Yamauchi MergedBR->setMetadata(LLVMContext::MD_prof, MDB.createBranchWeights(Weights));
18489775a620SHiroshi Yamauchi CHR_DEBUG(dbgs() << "CHR branch bias " << Weights[0] << ":" << Weights[1]
18499775a620SHiroshi Yamauchi << "\n");
18509775a620SHiroshi Yamauchi }
18519775a620SHiroshi Yamauchi
18529775a620SHiroshi Yamauchi // A helper for fixupBranchesAndSelects. Add to the combined branch condition
18539775a620SHiroshi Yamauchi // and constant-fold a branch in the hot path.
fixupBranch(Region * R,CHRScope * Scope,IRBuilder<> & IRB,Value * & MergedCondition,BranchProbability & CHRBranchBias)18549775a620SHiroshi Yamauchi void CHR::fixupBranch(Region *R, CHRScope *Scope,
18559775a620SHiroshi Yamauchi IRBuilder<> &IRB,
18569775a620SHiroshi Yamauchi Value *&MergedCondition,
18579775a620SHiroshi Yamauchi BranchProbability &CHRBranchBias) {
18589775a620SHiroshi Yamauchi bool IsTrueBiased = Scope->TrueBiasedRegions.count(R);
18599775a620SHiroshi Yamauchi assert((IsTrueBiased || Scope->FalseBiasedRegions.count(R)) &&
18609775a620SHiroshi Yamauchi "Must be truthy or falsy");
18619775a620SHiroshi Yamauchi auto *BI = cast<BranchInst>(R->getEntry()->getTerminator());
18629775a620SHiroshi Yamauchi assert(BranchBiasMap.find(R) != BranchBiasMap.end() &&
18639775a620SHiroshi Yamauchi "Must be in the bias map");
18649775a620SHiroshi Yamauchi BranchProbability Bias = BranchBiasMap[R];
18659775a620SHiroshi Yamauchi assert(Bias >= getCHRBiasThreshold() && "Must be highly biased");
18669775a620SHiroshi Yamauchi // Take the min.
18679775a620SHiroshi Yamauchi if (CHRBranchBias > Bias)
18689775a620SHiroshi Yamauchi CHRBranchBias = Bias;
18699775a620SHiroshi Yamauchi BasicBlock *IfThen = BI->getSuccessor(1);
18709775a620SHiroshi Yamauchi BasicBlock *IfElse = BI->getSuccessor(0);
18719775a620SHiroshi Yamauchi BasicBlock *RegionExitBlock = R->getExit();
18729775a620SHiroshi Yamauchi assert(RegionExitBlock && "Null ExitBlock");
18739775a620SHiroshi Yamauchi assert((IfThen == RegionExitBlock || IfElse == RegionExitBlock) &&
18749775a620SHiroshi Yamauchi IfThen != IfElse && "Invariant from findScopes");
18759775a620SHiroshi Yamauchi if (IfThen == RegionExitBlock) {
18769775a620SHiroshi Yamauchi // Swap them so that IfThen means going into it and IfElse means skipping
18779775a620SHiroshi Yamauchi // it.
18789775a620SHiroshi Yamauchi std::swap(IfThen, IfElse);
18799775a620SHiroshi Yamauchi }
18809775a620SHiroshi Yamauchi CHR_DEBUG(dbgs() << "IfThen " << IfThen->getName()
18819775a620SHiroshi Yamauchi << " IfElse " << IfElse->getName() << "\n");
18829775a620SHiroshi Yamauchi Value *Cond = BI->getCondition();
18839775a620SHiroshi Yamauchi BasicBlock *HotTarget = IsTrueBiased ? IfThen : IfElse;
18849775a620SHiroshi Yamauchi bool ConditionTrue = HotTarget == BI->getSuccessor(0);
18859775a620SHiroshi Yamauchi addToMergedCondition(ConditionTrue, Cond, BI, Scope, IRB,
18869775a620SHiroshi Yamauchi MergedCondition);
18879775a620SHiroshi Yamauchi // Constant-fold the branch at ClonedEntryBlock.
18889775a620SHiroshi Yamauchi assert(ConditionTrue == (HotTarget == BI->getSuccessor(0)) &&
18899775a620SHiroshi Yamauchi "The successor shouldn't change");
18909775a620SHiroshi Yamauchi Value *NewCondition = ConditionTrue ?
18919775a620SHiroshi Yamauchi ConstantInt::getTrue(F.getContext()) :
18929775a620SHiroshi Yamauchi ConstantInt::getFalse(F.getContext());
18939775a620SHiroshi Yamauchi BI->setCondition(NewCondition);
18949775a620SHiroshi Yamauchi }
18959775a620SHiroshi Yamauchi
18969775a620SHiroshi Yamauchi // A helper for fixupBranchesAndSelects. Add to the combined branch condition
18979775a620SHiroshi Yamauchi // and constant-fold a select in the hot path.
fixupSelect(SelectInst * SI,CHRScope * Scope,IRBuilder<> & IRB,Value * & MergedCondition,BranchProbability & CHRBranchBias)18989775a620SHiroshi Yamauchi void CHR::fixupSelect(SelectInst *SI, CHRScope *Scope,
18999775a620SHiroshi Yamauchi IRBuilder<> &IRB,
19009775a620SHiroshi Yamauchi Value *&MergedCondition,
19019775a620SHiroshi Yamauchi BranchProbability &CHRBranchBias) {
19029775a620SHiroshi Yamauchi bool IsTrueBiased = Scope->TrueBiasedSelects.count(SI);
19039775a620SHiroshi Yamauchi assert((IsTrueBiased ||
19049775a620SHiroshi Yamauchi Scope->FalseBiasedSelects.count(SI)) && "Must be biased");
19059775a620SHiroshi Yamauchi assert(SelectBiasMap.find(SI) != SelectBiasMap.end() &&
19069775a620SHiroshi Yamauchi "Must be in the bias map");
19079775a620SHiroshi Yamauchi BranchProbability Bias = SelectBiasMap[SI];
19089775a620SHiroshi Yamauchi assert(Bias >= getCHRBiasThreshold() && "Must be highly biased");
19099775a620SHiroshi Yamauchi // Take the min.
19109775a620SHiroshi Yamauchi if (CHRBranchBias > Bias)
19119775a620SHiroshi Yamauchi CHRBranchBias = Bias;
19129775a620SHiroshi Yamauchi Value *Cond = SI->getCondition();
19139775a620SHiroshi Yamauchi addToMergedCondition(IsTrueBiased, Cond, SI, Scope, IRB,
19149775a620SHiroshi Yamauchi MergedCondition);
19159775a620SHiroshi Yamauchi Value *NewCondition = IsTrueBiased ?
19169775a620SHiroshi Yamauchi ConstantInt::getTrue(F.getContext()) :
19179775a620SHiroshi Yamauchi ConstantInt::getFalse(F.getContext());
19189775a620SHiroshi Yamauchi SI->setCondition(NewCondition);
19199775a620SHiroshi Yamauchi }
19209775a620SHiroshi Yamauchi
19219775a620SHiroshi Yamauchi // A helper for fixupBranch/fixupSelect. Add a branch condition to the merged
19229775a620SHiroshi Yamauchi // condition.
addToMergedCondition(bool IsTrueBiased,Value * Cond,Instruction * BranchOrSelect,CHRScope * Scope,IRBuilder<> & IRB,Value * & MergedCondition)19239775a620SHiroshi Yamauchi void CHR::addToMergedCondition(bool IsTrueBiased, Value *Cond,
1924afc21c7eSNikita Popov Instruction *BranchOrSelect, CHRScope *Scope,
1925afc21c7eSNikita Popov IRBuilder<> &IRB, Value *&MergedCondition) {
1926afc21c7eSNikita Popov if (!IsTrueBiased) {
19279775a620SHiroshi Yamauchi // If Cond is an icmp and all users of V except for BranchOrSelect is a
19289775a620SHiroshi Yamauchi // branch, negate the icmp predicate and swap the branch targets and avoid
19299775a620SHiroshi Yamauchi // inserting an Xor to negate Cond.
1930afc21c7eSNikita Popov auto *ICmp = dyn_cast<ICmpInst>(Cond);
1931afc21c7eSNikita Popov if (!ICmp ||
1932afc21c7eSNikita Popov !negateICmpIfUsedByBranchOrSelectOnly(ICmp, BranchOrSelect, Scope))
1933afc21c7eSNikita Popov Cond = IRB.CreateXor(ConstantInt::getTrue(F.getContext()), Cond);
1934afc21c7eSNikita Popov }
1935afc21c7eSNikita Popov
19367ba48466SNikita Popov // Select conditions can be poison, while branching on poison is immediate
19377ba48466SNikita Popov // undefined behavior. As such, we need to freeze potentially poisonous
19387ba48466SNikita Popov // conditions derived from selects.
19397ba48466SNikita Popov if (isa<SelectInst>(BranchOrSelect) &&
19407ba48466SNikita Popov !isGuaranteedNotToBeUndefOrPoison(Cond))
19417ba48466SNikita Popov Cond = IRB.CreateFreeze(Cond);
19427ba48466SNikita Popov
1943c8eb83f2SNikita Popov // Use logical and to avoid propagating poison from later conditions.
1944c8eb83f2SNikita Popov MergedCondition = IRB.CreateLogicalAnd(MergedCondition, Cond);
19459775a620SHiroshi Yamauchi }
19469775a620SHiroshi Yamauchi
transformScopes(SmallVectorImpl<CHRScope * > & CHRScopes)19479775a620SHiroshi Yamauchi void CHR::transformScopes(SmallVectorImpl<CHRScope *> &CHRScopes) {
1948b3b61de0SFangrui Song unsigned I = 0;
19499775a620SHiroshi Yamauchi DenseSet<PHINode *> TrivialPHIs;
19509775a620SHiroshi Yamauchi for (CHRScope *Scope : CHRScopes) {
19519775a620SHiroshi Yamauchi transformScopes(Scope, TrivialPHIs);
19529775a620SHiroshi Yamauchi CHR_DEBUG(
19539775a620SHiroshi Yamauchi std::ostringstream oss;
1954b3b61de0SFangrui Song oss << " after transformScopes " << I++;
19559775a620SHiroshi Yamauchi dumpIR(F, oss.str().c_str(), nullptr));
1956b3b61de0SFangrui Song (void)I;
19579775a620SHiroshi Yamauchi }
19589775a620SHiroshi Yamauchi }
19599775a620SHiroshi Yamauchi
1960c8f348cbSFangrui Song static void LLVM_ATTRIBUTE_UNUSED
dumpScopes(SmallVectorImpl<CHRScope * > & Scopes,const char * Label)1961c8f348cbSFangrui Song dumpScopes(SmallVectorImpl<CHRScope *> &Scopes, const char *Label) {
19629775a620SHiroshi Yamauchi dbgs() << Label << " " << Scopes.size() << "\n";
19639775a620SHiroshi Yamauchi for (CHRScope *Scope : Scopes) {
19649775a620SHiroshi Yamauchi dbgs() << *Scope << "\n";
19659775a620SHiroshi Yamauchi }
19669775a620SHiroshi Yamauchi }
19679775a620SHiroshi Yamauchi
run()19689775a620SHiroshi Yamauchi bool CHR::run() {
19699775a620SHiroshi Yamauchi if (!shouldApply(F, PSI))
19709775a620SHiroshi Yamauchi return false;
19719775a620SHiroshi Yamauchi
19729775a620SHiroshi Yamauchi CHR_DEBUG(dumpIR(F, "before", nullptr));
19739775a620SHiroshi Yamauchi
19749775a620SHiroshi Yamauchi bool Changed = false;
19759775a620SHiroshi Yamauchi {
19769775a620SHiroshi Yamauchi CHR_DEBUG(
19779775a620SHiroshi Yamauchi dbgs() << "RegionInfo:\n";
19789775a620SHiroshi Yamauchi RI.print(dbgs()));
19799775a620SHiroshi Yamauchi
19809775a620SHiroshi Yamauchi // Recursively traverse the region tree and find regions that have biased
19819775a620SHiroshi Yamauchi // branches and/or selects and create scopes.
19829775a620SHiroshi Yamauchi SmallVector<CHRScope *, 8> AllScopes;
19839775a620SHiroshi Yamauchi findScopes(AllScopes);
19849775a620SHiroshi Yamauchi CHR_DEBUG(dumpScopes(AllScopes, "All scopes"));
19859775a620SHiroshi Yamauchi
19869775a620SHiroshi Yamauchi // Split the scopes if 1) the conditiona values of the biased
19879775a620SHiroshi Yamauchi // branches/selects of the inner/lower scope can't be hoisted up to the
19889775a620SHiroshi Yamauchi // outermost/uppermost scope entry, or 2) the condition values of the biased
19899775a620SHiroshi Yamauchi // branches/selects in a scope (including subscopes) don't share at least
19909775a620SHiroshi Yamauchi // one common value.
19919775a620SHiroshi Yamauchi SmallVector<CHRScope *, 8> SplitScopes;
19929775a620SHiroshi Yamauchi splitScopes(AllScopes, SplitScopes);
19939775a620SHiroshi Yamauchi CHR_DEBUG(dumpScopes(SplitScopes, "Split scopes"));
19949775a620SHiroshi Yamauchi
19959775a620SHiroshi Yamauchi // After splitting, set the biased regions and selects of a scope (a tree
19969775a620SHiroshi Yamauchi // root) that include those of the subscopes.
19979775a620SHiroshi Yamauchi classifyBiasedScopes(SplitScopes);
19989775a620SHiroshi Yamauchi CHR_DEBUG(dbgs() << "Set per-scope bias " << SplitScopes.size() << "\n");
19999775a620SHiroshi Yamauchi
20009775a620SHiroshi Yamauchi // Filter out the scopes that has only one biased region or select (CHR
20019775a620SHiroshi Yamauchi // isn't useful in such a case).
20029775a620SHiroshi Yamauchi SmallVector<CHRScope *, 8> FilteredScopes;
20039775a620SHiroshi Yamauchi filterScopes(SplitScopes, FilteredScopes);
20049775a620SHiroshi Yamauchi CHR_DEBUG(dumpScopes(FilteredScopes, "Filtered scopes"));
20059775a620SHiroshi Yamauchi
20069775a620SHiroshi Yamauchi // Set the regions to be CHR'ed and their hoist stops for each scope.
20079775a620SHiroshi Yamauchi SmallVector<CHRScope *, 8> SetScopes;
20089775a620SHiroshi Yamauchi setCHRRegions(FilteredScopes, SetScopes);
20099775a620SHiroshi Yamauchi CHR_DEBUG(dumpScopes(SetScopes, "Set CHR regions"));
20109775a620SHiroshi Yamauchi
20119775a620SHiroshi Yamauchi // Sort CHRScopes by the depth so that outer CHRScopes comes before inner
20129775a620SHiroshi Yamauchi // ones. We need to apply CHR from outer to inner so that we apply CHR only
20139775a620SHiroshi Yamauchi // to the hot path, rather than both hot and cold paths.
20149775a620SHiroshi Yamauchi SmallVector<CHRScope *, 8> SortedScopes;
20159775a620SHiroshi Yamauchi sortScopes(SetScopes, SortedScopes);
20169775a620SHiroshi Yamauchi CHR_DEBUG(dumpScopes(SortedScopes, "Sorted scopes"));
20179775a620SHiroshi Yamauchi
20189775a620SHiroshi Yamauchi CHR_DEBUG(
20199775a620SHiroshi Yamauchi dbgs() << "RegionInfo:\n";
20209775a620SHiroshi Yamauchi RI.print(dbgs()));
20219775a620SHiroshi Yamauchi
20229775a620SHiroshi Yamauchi // Apply the CHR transformation.
20239775a620SHiroshi Yamauchi if (!SortedScopes.empty()) {
20249775a620SHiroshi Yamauchi transformScopes(SortedScopes);
20259775a620SHiroshi Yamauchi Changed = true;
20269775a620SHiroshi Yamauchi }
20279775a620SHiroshi Yamauchi }
20289775a620SHiroshi Yamauchi
2029fd2c699dSHiroshi Yamauchi if (Changed) {
20309775a620SHiroshi Yamauchi CHR_DEBUG(dumpIR(F, "after", &Stats));
2031fd2c699dSHiroshi Yamauchi ORE.emit([&]() {
2032fd2c699dSHiroshi Yamauchi return OptimizationRemark(DEBUG_TYPE, "Stats", &F)
2033fd2c699dSHiroshi Yamauchi << ore::NV("Function", &F) << " "
2034fd2c699dSHiroshi Yamauchi << "Reduced the number of branches in hot paths by "
2035fd2c699dSHiroshi Yamauchi << ore::NV("NumBranchesDelta", Stats.NumBranchesDelta)
2036fd2c699dSHiroshi Yamauchi << " (static) and "
2037fd2c699dSHiroshi Yamauchi << ore::NV("WeightedNumBranchesDelta", Stats.WeightedNumBranchesDelta)
2038fd2c699dSHiroshi Yamauchi << " (weighted by PGO count)";
2039fd2c699dSHiroshi Yamauchi });
2040fd2c699dSHiroshi Yamauchi }
20419775a620SHiroshi Yamauchi
20429775a620SHiroshi Yamauchi return Changed;
20439775a620SHiroshi Yamauchi }
20449775a620SHiroshi Yamauchi
20459775a620SHiroshi Yamauchi namespace llvm {
20469775a620SHiroshi Yamauchi
ControlHeightReductionPass()20479775a620SHiroshi Yamauchi ControlHeightReductionPass::ControlHeightReductionPass() {
2048b3b61de0SFangrui Song parseCHRFilterFiles();
20499775a620SHiroshi Yamauchi }
20509775a620SHiroshi Yamauchi
run(Function & F,FunctionAnalysisManager & FAM)20519775a620SHiroshi Yamauchi PreservedAnalyses ControlHeightReductionPass::run(
20529775a620SHiroshi Yamauchi Function &F,
20539775a620SHiroshi Yamauchi FunctionAnalysisManager &FAM) {
20549775a620SHiroshi Yamauchi auto &BFI = FAM.getResult<BlockFrequencyAnalysis>(F);
20559775a620SHiroshi Yamauchi auto &DT = FAM.getResult<DominatorTreeAnalysis>(F);
20569775a620SHiroshi Yamauchi auto &MAMProxy = FAM.getResult<ModuleAnalysisManagerFunctionProxy>(F);
2057bd541b21SAlina Sbirlea auto &PSI = *MAMProxy.getCachedResult<ProfileSummaryAnalysis>(*F.getParent());
20589775a620SHiroshi Yamauchi auto &RI = FAM.getResult<RegionInfoAnalysis>(F);
2059fd2c699dSHiroshi Yamauchi auto &ORE = FAM.getResult<OptimizationRemarkEmitterAnalysis>(F);
2060fd2c699dSHiroshi Yamauchi bool Changed = CHR(F, BFI, DT, PSI, RI, ORE).run();
20619775a620SHiroshi Yamauchi if (!Changed)
20629775a620SHiroshi Yamauchi return PreservedAnalyses::all();
20636b9524a0SArthur Eubanks return PreservedAnalyses::none();
20649775a620SHiroshi Yamauchi }
20659775a620SHiroshi Yamauchi
20669775a620SHiroshi Yamauchi } // namespace llvm
2067