aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Transforms/Instrumentation/ControlHeightReduction.cpp
diff options
context:
space:
mode:
authorRong Xu <xur@google.com>2022-11-22 11:22:38 -0800
committerRong Xu <xur@google.com>2022-11-22 11:36:40 -0800
commit6327d263f5e2a18645979fac2525b574866adbe5 (patch)
treeed667adadbf5be277b9b396f3b1eba98163bcab2 /llvm/lib/Transforms/Instrumentation/ControlHeightReduction.cpp
parentb816b526741c409e9f5de74508bf134589ded638 (diff)
downloadllvm-6327d263f5e2a18645979fac2525b574866adbe5.zip
llvm-6327d263f5e2a18645979fac2525b574866adbe5.tar.gz
llvm-6327d263f5e2a18645979fac2525b574866adbe5.tar.bz2
[CHR] Add a threshold for the code duplication
ControlHeightReduction (CHR) clones the code region to reduce the branches in the hot code path. The number of clones is linear to the depth of the region. Currently it does not have control over the code size increase. We are seeing one ~9000 BB functions get expanded to ~250000 BBs, an 25x increase. This creates a big compile time issue for the downstream optimizations. This patch adds a cap for number of clones for one region. Differential Revision: https://reviews.llvm.org/D138333
Diffstat (limited to 'llvm/lib/Transforms/Instrumentation/ControlHeightReduction.cpp')
-rw-r--r--llvm/lib/Transforms/Instrumentation/ControlHeightReduction.cpp66
1 files changed, 51 insertions, 15 deletions
diff --git a/llvm/lib/Transforms/Instrumentation/ControlHeightReduction.cpp b/llvm/lib/Transforms/Instrumentation/ControlHeightReduction.cpp
index 8ecf2cf..aee9718 100644
--- a/llvm/lib/Transforms/Instrumentation/ControlHeightReduction.cpp
+++ b/llvm/lib/Transforms/Instrumentation/ControlHeightReduction.cpp
@@ -47,6 +47,9 @@ using namespace llvm;
#define CHR_DEBUG(X) LLVM_DEBUG(X)
+static cl::opt<bool> DisableCHR("disable-chr", cl::init(false), cl::Hidden,
+ cl::desc("Disable CHR for all functions"));
+
static cl::opt<bool> ForceCHR("force-chr", cl::init(false), cl::Hidden,
cl::desc("Apply CHR for all functions"));
@@ -66,6 +69,10 @@ static cl::opt<std::string> CHRFunctionList(
"chr-function-list", cl::init(""), cl::Hidden,
cl::desc("Specify file to retrieve the list of functions to apply CHR to"));
+static cl::opt<unsigned> CHRDupThreshsold(
+ "chr-dup-threshold", cl::init(3), cl::Hidden,
+ cl::desc("Max number of duplications by CHR for a region"));
+
static StringSet<> CHRModules;
static StringSet<> CHRFunctions;
@@ -339,23 +346,27 @@ class CHR {
BasicBlock *EntryBlock,
BasicBlock *NewEntryBlock,
ValueToValueMapTy &VMap);
- void fixupBranchesAndSelects(CHRScope *Scope,
- BasicBlock *PreEntryBlock,
- BranchInst *MergedBR,
- uint64_t ProfileCount);
- void fixupBranch(Region *R,
- CHRScope *Scope,
- IRBuilder<> &IRB,
+ void fixupBranchesAndSelects(CHRScope *Scope, BasicBlock *PreEntryBlock,
+ BranchInst *MergedBR, uint64_t ProfileCount);
+ void fixupBranch(Region *R, CHRScope *Scope, IRBuilder<> &IRB,
Value *&MergedCondition, BranchProbability &CHRBranchBias);
- void fixupSelect(SelectInst* SI,
- CHRScope *Scope,
- IRBuilder<> &IRB,
+ void fixupSelect(SelectInst *SI, CHRScope *Scope, IRBuilder<> &IRB,
Value *&MergedCondition, BranchProbability &CHRBranchBias);
void addToMergedCondition(bool IsTrueBiased, Value *Cond,
- Instruction *BranchOrSelect,
- CHRScope *Scope,
- IRBuilder<> &IRB,
- Value *&MergedCondition);
+ Instruction *BranchOrSelect, CHRScope *Scope,
+ IRBuilder<> &IRB, Value *&MergedCondition);
+ unsigned getRegionDuplicationCount(const Region *R) {
+ unsigned Count = 0;
+ // Find out how many times region R is cloned. Note that if the parent
+ // of R is cloned, R is also cloned, but R's clone count is not updated
+ // from the clone of the parent. We need to accumlate all the counts
+ // from the ancestors to get the clone count.
+ while (R) {
+ Count += DuplicationCount[R];
+ R = R->getParent();
+ }
+ return Count;
+ }
Function &F;
BlockFrequencyInfo &BFI;
@@ -379,6 +390,8 @@ class CHR {
DenseMap<SelectInst *, BranchProbability> SelectBiasMap;
// All the scopes.
DenseSet<CHRScope *> Scopes;
+ // This maps records how many times this region is cloned.
+ DenseMap<const Region *, unsigned> DuplicationCount;
};
} // end anonymous namespace
@@ -396,7 +409,10 @@ raw_ostream &operator<<(raw_ostream &OS, const CHRScope &Scope) {
return OS;
}
-static bool shouldApply(Function &F, ProfileSummaryInfo& PSI) {
+static bool shouldApply(Function &F, ProfileSummaryInfo &PSI) {
+ if (DisableCHR)
+ return false;
+
if (ForceCHR)
return true;
@@ -1666,6 +1682,26 @@ void CHR::transformScopes(CHRScope *Scope, DenseSet<PHINode *> &TrivialPHIs) {
CHR_DEBUG(dbgs() << "transformScopes " << *Scope << "\n");
assert(Scope->RegInfos.size() >= 1 && "Should have at least one Region");
+
+ for (RegInfo &RI : Scope->RegInfos) {
+ const Region *R = RI.R;
+ unsigned Duplication = getRegionDuplicationCount(R);
+ dbgs() << "Dup count for R=" << R << " is " << Duplication << "\n";
+ if (Duplication >= CHRDupThreshsold) {
+ CHR_DEBUG(dbgs() << "Reached the dup threshold of " << Duplication
+ << " for this region");
+ ORE.emit([&]() {
+ return OptimizationRemarkMissed(DEBUG_TYPE, "DupThresholdReached",
+ R->getEntry()->getTerminator())
+ << "Reached the duplication threshold for the region";
+ });
+ return;
+ }
+ }
+ for (RegInfo &RI : Scope->RegInfos) {
+ DuplicationCount[RI.R]++;
+ }
+
Region *FirstRegion = Scope->RegInfos[0].R;
BasicBlock *EntryBlock = FirstRegion->getEntry();
Region *LastRegion = Scope->RegInfos[Scope->RegInfos.size() - 1].R;