[PATCH] D50658: Hot cold splitting pass
Sebastian Pop via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Thu Aug 16 13:34:39 PDT 2018
sebpop added inline comments.
================
Comment at: lib/Transforms/IPO/HotColdSplitting.cpp:209
+ // Get cold region
+ BasicBlock *Exit = PDT[BB]->getIDom()->getBlock();
+ SmallVector<BasicBlock *, 4> Region;
----------------
hiraditya wrote:
> kparzysz wrote:
> > Another thing for the future development would be to find the largest cold section of the code: for example, if there are two adjacent loops that are both in a cold side of an if-statement, both of them could be outlined into the same function.
> That's a good idea! Thanks. I'll work on that. Another improvement I'm thinking of is to outline multiple regions from a function.
find cold blocks like this:
```
+ bool unlikelyExecuted(BasicBlock &BB) {
+ if (blockEndsInUnreachable(&BB))
+ return true;
+ // Exception handling blocks are unlikely executed.
+ if (BB.isEHPad())
+ return true;
+ for (const Instruction &I : BB)
+ if (const CallInst *CI = dyn_cast<CallInst>(&I)) {
+ // The block is cold if it calls functions tagged as cold or noreturn.
+ if (CI->hasFnAttr(Attribute::Cold) ||
+ CI->hasFnAttr(Attribute::NoReturn))
+ return true;
+
+ // Assume that inline assembly is hot code.
+ if (isa<InlineAsm>(CI->getCalledValue()))
+ return false;
+ }
```
and then propagate the cold block property to all the blocks only reachable from the cold blocks:
```
+ DenseMap<const BasicBlock *, bool> ColdBlock;
+ // First mark all function basic blocks as hot or cold.
+ for (BasicBlock &BB : *F)
+ ColdBlock[&BB] = unlikelyExecuted(BB);
+
+ // Then adjust the hot/cold partitions by adding to the cold partition all the
+ // blocks that are only reachable from cold blocks.
+ forwardPropagation(ColdBlock, F);
+
```
```
+static void
+forwardPropagation(DenseMap<const BasicBlock *, bool> &ColdBlock,
+ Function *F) {
+ SmallVector<BasicBlock *, 8> WL;
+ DenseMap<const BasicBlock *, bool> Visited;
+ for (BasicBlock &BB : *F)
+ Visited[&BB] = false;
+
+ BasicBlock *It = &F->front();
+ if (!ColdBlock[It]) {
+ Visited[It] = true;
+ WL.push_back(It);
+ while (WL.size() > 0) {
+ It = WL.pop_back_val();
+ for (BasicBlock *Succ : It->successors())
+ // Do not visit blocks that are cold.
+ if (!ColdBlock[Succ] && !Visited[Succ]) {
+ Visited[Succ] = true;
+ WL.push_back(Succ);
+ }
+ }
+ }
+
+ // Mark all the blocks that were not visited as cold.
+ for (MachineBasicBlock &BB : *F)
+ if (!Visited[&BB])
+ ColdBlock[&BB] = true;
+}
```
https://reviews.llvm.org/D50658
More information about the llvm-commits
mailing list