aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/CodeGen/BasicBlockSections.cpp
diff options
context:
space:
mode:
authorSnehasish Kumar <snehasishk@google.com>2020-08-05 15:34:31 -0700
committerSnehasish Kumar <snehasishk@google.com>2020-08-28 11:10:14 -0700
commit94faadaca4e1704f674d2e9d4a1d25643b9ca52c (patch)
tree2838a645b079079538e845291ea8185cb6266bbc /llvm/lib/CodeGen/BasicBlockSections.cpp
parent064981f0cee47b140e94ca7df6c24102514af6f0 (diff)
downloadllvm-94faadaca4e1704f674d2e9d4a1d25643b9ca52c.zip
llvm-94faadaca4e1704f674d2e9d4a1d25643b9ca52c.tar.gz
llvm-94faadaca4e1704f674d2e9d4a1d25643b9ca52c.tar.bz2
[llvm][CodeGen] Machine Function Splitter
We introduce a codegen optimization pass which splits functions into hot and cold parts. This pass leverages the basic block sections feature recently introduced in LLVM from the Propeller project. The pass targets functions with profile coverage, identifies cold blocks and moves them to a separate section. The linker groups all cold blocks across functions together, decreasing fragmentation and improving icache and itlb utilization. We evaluated the Machine Function Splitter pass on clang bootstrap and SPECInt 2017. For clang bootstrap we observe a mean 2.33% runtime improvement with a ~32% reduction in itlb and stlb misses. Additionally, L1 icache misses reduced by 9.5% while L2 instruction misses reduced by 20%. For SPECInt we report the change in IntRate the C/C++ benchmarks. All benchmarks apart from mcf and x264 improve, on average by 0.6% with the max for deepsjeng at 1.6%. Benchmark % Change 500.perlbench_r 0.78 502.gcc_r 0.82 505.mcf_r -0.30 520.omnetpp_r 0.18 523.xalancbmk_r 0.37 525.x264_r -0.46 531.deepsjeng_r 1.61 541.leela_r 0.83 557.xz_r 0.15 Differential Revision: https://reviews.llvm.org/D85368
Diffstat (limited to 'llvm/lib/CodeGen/BasicBlockSections.cpp')
-rw-r--r--llvm/lib/CodeGen/BasicBlockSections.cpp87
1 files changed, 47 insertions, 40 deletions
diff --git a/llvm/lib/CodeGen/BasicBlockSections.cpp b/llvm/lib/CodeGen/BasicBlockSections.cpp
index cd8173eb..a3c3660 100644
--- a/llvm/lib/CodeGen/BasicBlockSections.cpp
+++ b/llvm/lib/CodeGen/BasicBlockSections.cpp
@@ -69,6 +69,7 @@
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringRef.h"
+#include "llvm/CodeGen/BasicBlockSectionUtils.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/CodeGen/MachineModuleInfo.h"
@@ -226,9 +227,9 @@ static bool getBBClusterInfoForFunction(
// and "Cold" succeeding all other clusters.
// FuncBBClusterInfo represent the cluster information for basic blocks. If this
// is empty, it means unique sections for all basic blocks in the function.
-static bool assignSectionsAndSortBasicBlocks(
- MachineFunction &MF,
- const std::vector<Optional<BBClusterInfo>> &FuncBBClusterInfo) {
+static void
+assignSections(MachineFunction &MF,
+ const std::vector<Optional<BBClusterInfo>> &FuncBBClusterInfo) {
assert(MF.hasBBSections() && "BB Sections is not set for function.");
// This variable stores the section ID of the cluster containing eh_pads (if
// all eh_pads are one cluster). If more than one cluster contain eh_pads, we
@@ -271,12 +272,51 @@ static bool assignSectionsAndSortBasicBlocks(
for (auto &MBB : MF)
if (MBB.isEHPad())
MBB.setSectionID(EHPadsSectionID.getValue());
+}
+void llvm::sortBasicBlocksAndUpdateBranches(
+ MachineFunction &MF, MachineBasicBlockComparator MBBCmp) {
SmallVector<MachineBasicBlock *, 4> PreLayoutFallThroughs(
MF.getNumBlockIDs());
for (auto &MBB : MF)
PreLayoutFallThroughs[MBB.getNumber()] = MBB.getFallThrough();
+ MF.sort(MBBCmp);
+
+ // Set IsBeginSection and IsEndSection according to the assigned section IDs.
+ MF.assignBeginEndSections();
+
+ // After reordering basic blocks, we must update basic block branches to
+ // insert explicit fallthrough branches when required and optimize branches
+ // when possible.
+ updateBranches(MF, PreLayoutFallThroughs);
+}
+
+bool BasicBlockSections::runOnMachineFunction(MachineFunction &MF) {
+ auto BBSectionsType = MF.getTarget().getBBSectionsType();
+ assert(BBSectionsType != BasicBlockSection::None &&
+ "BB Sections not enabled!");
+ // Renumber blocks before sorting them for basic block sections. This is
+ // useful during sorting, basic blocks in the same section will retain the
+ // default order. This renumbering should also be done for basic block
+ // labels to match the profiles with the correct blocks.
+ MF.RenumberBlocks();
+
+ if (BBSectionsType == BasicBlockSection::Labels) {
+ MF.setBBSectionsType(BBSectionsType);
+ MF.createBBLabels();
+ return true;
+ }
+
+ std::vector<Optional<BBClusterInfo>> FuncBBClusterInfo;
+ if (BBSectionsType == BasicBlockSection::List &&
+ !getBBClusterInfoForFunction(MF, FuncAliasMap, ProgramBBClusterInfo,
+ FuncBBClusterInfo))
+ return true;
+ MF.setBBSectionsType(BBSectionsType);
+ MF.createBBLabels();
+ assignSections(MF, FuncBBClusterInfo);
+
// We make sure that the cluster including the entry basic block precedes all
// other clusters.
auto EntryBBSectionID = MF.front().getSectionID();
@@ -300,7 +340,8 @@ static bool assignSectionsAndSortBasicBlocks(
// contiguous and ordered accordingly. Furthermore, clusters are ordered in
// increasing order of their section IDs, with the exception and the
// cold section placed at the end of the function.
- MF.sort([&](MachineBasicBlock &X, MachineBasicBlock &Y) {
+ auto Comparator = [&](const MachineBasicBlock &X,
+ const MachineBasicBlock &Y) {
auto XSectionID = X.getSectionID();
auto YSectionID = Y.getSectionID();
if (XSectionID != YSectionID)
@@ -311,43 +352,9 @@ static bool assignSectionsAndSortBasicBlocks(
return FuncBBClusterInfo[X.getNumber()]->PositionInCluster <
FuncBBClusterInfo[Y.getNumber()]->PositionInCluster;
return X.getNumber() < Y.getNumber();
- });
-
- // Set IsBeginSection and IsEndSection according to the assigned section IDs.
- MF.assignBeginEndSections();
-
- // After reordering basic blocks, we must update basic block branches to
- // insert explicit fallthrough branches when required and optimize branches
- // when possible.
- updateBranches(MF, PreLayoutFallThroughs);
-
- return true;
-}
-
-bool BasicBlockSections::runOnMachineFunction(MachineFunction &MF) {
- auto BBSectionsType = MF.getTarget().getBBSectionsType();
- assert(BBSectionsType != BasicBlockSection::None &&
- "BB Sections not enabled!");
- // Renumber blocks before sorting them for basic block sections. This is
- // useful during sorting, basic blocks in the same section will retain the
- // default order. This renumbering should also be done for basic block
- // labels to match the profiles with the correct blocks.
- MF.RenumberBlocks();
-
- if (BBSectionsType == BasicBlockSection::Labels) {
- MF.setBBSectionsType(BBSectionsType);
- MF.createBBLabels();
- return true;
- }
+ };
- std::vector<Optional<BBClusterInfo>> FuncBBClusterInfo;
- if (BBSectionsType == BasicBlockSection::List &&
- !getBBClusterInfoForFunction(MF, FuncAliasMap, ProgramBBClusterInfo,
- FuncBBClusterInfo))
- return true;
- MF.setBBSectionsType(BBSectionsType);
- MF.createBBLabels();
- assignSectionsAndSortBasicBlocks(MF, FuncBBClusterInfo);
+ sortBasicBlocksAndUpdateBranches(MF, Comparator);
return true;
}