13a275d20STobias Grosser //===--- Utils.cpp - Utility functions for the code generation --*- C++ -*-===//
23a275d20STobias Grosser //
3*2946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*2946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
5*2946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
63a275d20STobias Grosser //
73a275d20STobias Grosser //===----------------------------------------------------------------------===//
83a275d20STobias Grosser //
93a275d20STobias Grosser // This file contains utility functions for the code generation.
103a275d20STobias Grosser //
113a275d20STobias Grosser //===----------------------------------------------------------------------===//
123a275d20STobias Grosser
133a275d20STobias Grosser #include "polly/CodeGen/Utils.h"
145103ba7cSTobias Grosser #include "polly/CodeGen/IRBuilder.h"
153a275d20STobias Grosser #include "polly/ScopInfo.h"
16472d3b70STobias Grosser #include "llvm/Analysis/LoopInfo.h"
17f32d651dSJohannes Doerfert #include "llvm/Analysis/RegionInfo.h"
183a275d20STobias Grosser #include "llvm/Transforms/Utils/BasicBlockUtils.h"
193a275d20STobias Grosser
203a275d20STobias Grosser using namespace llvm;
213a275d20STobias Grosser
2222370884SMichael Kruse // Alternative to llvm::SplitCriticalEdge.
2322370884SMichael Kruse //
2422370884SMichael Kruse // Creates a new block which branches to Succ. The edge to split is redirected
2522370884SMichael Kruse // to the new block.
2622370884SMichael Kruse //
2722370884SMichael Kruse // The issue with llvm::SplitCriticalEdge is that it does nothing if the edge is
2822370884SMichael Kruse // not critical.
2922370884SMichael Kruse // The issue with llvm::SplitEdge is that it does not always create the middle
3022370884SMichael Kruse // block, but reuses Prev/Succ if it can. We always want a new middle block.
splitEdge(BasicBlock * Prev,BasicBlock * Succ,const char * Suffix,DominatorTree * DT,LoopInfo * LI,RegionInfo * RI)3122370884SMichael Kruse static BasicBlock *splitEdge(BasicBlock *Prev, BasicBlock *Succ,
3222370884SMichael Kruse const char *Suffix, DominatorTree *DT,
3322370884SMichael Kruse LoopInfo *LI, RegionInfo *RI) {
3422370884SMichael Kruse assert(Prev && Succ);
3522370884SMichael Kruse
3622370884SMichael Kruse // Before:
3722370884SMichael Kruse // \ / / //
3822370884SMichael Kruse // Prev / //
3922370884SMichael Kruse // | \___/ //
4022370884SMichael Kruse // | ___ //
4122370884SMichael Kruse // | / \ //
4222370884SMichael Kruse // Succ \ //
4322370884SMichael Kruse // / \ \ //
4422370884SMichael Kruse
4522370884SMichael Kruse // The algorithm to update DominatorTree and LoopInfo of
4622370884SMichael Kruse // llvm::SplitCriticalEdge is more efficient than
4722370884SMichael Kruse // llvm::SplitBlockPredecessors, which is more general. In the future we might
4822370884SMichael Kruse // either modify llvm::SplitCriticalEdge to allow skipping the critical edge
4922370884SMichael Kruse // check; or Copy&Pase it here.
5022370884SMichael Kruse BasicBlock *MiddleBlock = SplitBlockPredecessors(
5122370884SMichael Kruse Succ, ArrayRef<BasicBlock *>(Prev), Suffix, DT, LI);
5222370884SMichael Kruse
5322370884SMichael Kruse if (RI) {
5422370884SMichael Kruse Region *PrevRegion = RI->getRegionFor(Prev);
5522370884SMichael Kruse Region *SuccRegion = RI->getRegionFor(Succ);
5622370884SMichael Kruse if (PrevRegion->contains(MiddleBlock)) {
5722370884SMichael Kruse RI->setRegionFor(MiddleBlock, PrevRegion);
5822370884SMichael Kruse } else {
5922370884SMichael Kruse RI->setRegionFor(MiddleBlock, SuccRegion);
6022370884SMichael Kruse }
6122370884SMichael Kruse }
6222370884SMichael Kruse
6322370884SMichael Kruse // After:
6422370884SMichael Kruse // \ / / //
6522370884SMichael Kruse // Prev / //
6622370884SMichael Kruse // | \___/ //
6722370884SMichael Kruse // | //
6822370884SMichael Kruse // MiddleBlock //
6922370884SMichael Kruse // | ___ //
7022370884SMichael Kruse // | / \ //
7122370884SMichael Kruse // Succ \ //
7222370884SMichael Kruse // / \ \ //
7322370884SMichael Kruse
7422370884SMichael Kruse return MiddleBlock;
7522370884SMichael Kruse }
7622370884SMichael Kruse
7703346c27SSiddharth Bhat std::pair<polly::BBPair, BranchInst *>
executeScopConditionally(Scop & S,Value * RTC,DominatorTree & DT,RegionInfo & RI,LoopInfo & LI)7803346c27SSiddharth Bhat polly::executeScopConditionally(Scop &S, Value *RTC, DominatorTree &DT,
7903346c27SSiddharth Bhat RegionInfo &RI, LoopInfo &LI) {
803a275d20STobias Grosser Region &R = S.getRegion();
81ef74443cSJohannes Doerfert PollyIRBuilder Builder(S.getEntry());
823a275d20STobias Grosser
8322370884SMichael Kruse // Before:
8422370884SMichael Kruse //
8522370884SMichael Kruse // \ / //
8622370884SMichael Kruse // EnteringBB //
8722370884SMichael Kruse // _____|_____ //
8822370884SMichael Kruse // / EntryBB \ //
8922370884SMichael Kruse // | (region) | //
9022370884SMichael Kruse // \_ExitingBB_/ //
9122370884SMichael Kruse // | //
9222370884SMichael Kruse // ExitBB //
9322370884SMichael Kruse // / \ //
943a275d20STobias Grosser
9522370884SMichael Kruse // Create a fork block.
96ef74443cSJohannes Doerfert BasicBlock *EnteringBB = S.getEnteringBlock();
97ef74443cSJohannes Doerfert BasicBlock *EntryBB = S.getEntry();
9822370884SMichael Kruse assert(EnteringBB && "Must be a simple region");
9922370884SMichael Kruse BasicBlock *SplitBlock =
10022370884SMichael Kruse splitEdge(EnteringBB, EntryBB, ".split_new_and_old", &DT, &LI, &RI);
1013a275d20STobias Grosser SplitBlock->setName("polly.split_new_and_old");
10222370884SMichael Kruse
103d2b03601SMichael Kruse // If EntryBB is the exit block of the region that includes Prev, exclude
104d2b03601SMichael Kruse // SplitBlock from that region by making it itself the exit block. This is
105d2b03601SMichael Kruse // trivially possible because there is just one edge to EnteringBB.
106d2b03601SMichael Kruse // This is necessary because we will add an outgoing edge from SplitBlock,
107d2b03601SMichael Kruse // which would violate the single exit block requirement of PrevRegion.
108d2b03601SMichael Kruse Region *PrevRegion = RI.getRegionFor(EnteringBB);
109d2b03601SMichael Kruse while (PrevRegion->getExit() == EntryBB) {
110d2b03601SMichael Kruse PrevRegion->replaceExit(SplitBlock);
111d2b03601SMichael Kruse PrevRegion = PrevRegion->getParent();
112d2b03601SMichael Kruse }
113d2b03601SMichael Kruse RI.setRegionFor(SplitBlock, PrevRegion);
114d2b03601SMichael Kruse
11522370884SMichael Kruse // Create a join block
116ef74443cSJohannes Doerfert BasicBlock *ExitingBB = S.getExitingBlock();
117ef74443cSJohannes Doerfert BasicBlock *ExitBB = S.getExit();
11822370884SMichael Kruse assert(ExitingBB && "Must be a simple region");
11922370884SMichael Kruse BasicBlock *MergeBlock =
12022370884SMichael Kruse splitEdge(ExitingBB, ExitBB, ".merge_new_and_old", &DT, &LI, &RI);
12122370884SMichael Kruse MergeBlock->setName("polly.merge_new_and_old");
12222370884SMichael Kruse
12322370884SMichael Kruse // Exclude the join block from the region.
12422370884SMichael Kruse R.replaceExitRecursive(MergeBlock);
12522370884SMichael Kruse RI.setRegionFor(MergeBlock, R.getParent());
12622370884SMichael Kruse
12722370884SMichael Kruse // \ / //
12822370884SMichael Kruse // EnteringBB //
12922370884SMichael Kruse // | //
13022370884SMichael Kruse // SplitBlock //
13122370884SMichael Kruse // _____|_____ //
13222370884SMichael Kruse // / EntryBB \ //
13322370884SMichael Kruse // | (region) | //
13422370884SMichael Kruse // \_ExitingBB_/ //
13522370884SMichael Kruse // | //
13622370884SMichael Kruse // MergeBlock //
13722370884SMichael Kruse // | //
13822370884SMichael Kruse // ExitBB //
13922370884SMichael Kruse // / \ //
14022370884SMichael Kruse
1412d3d4ec8STobias Grosser // Create the start and exiting block.
1423a275d20STobias Grosser Function *F = SplitBlock->getParent();
14322370884SMichael Kruse BasicBlock *StartBlock =
14422370884SMichael Kruse BasicBlock::Create(F->getContext(), "polly.start", F);
1452d3d4ec8STobias Grosser BasicBlock *ExitingBlock =
1462d3d4ec8STobias Grosser BasicBlock::Create(F->getContext(), "polly.exiting", F);
1473a275d20STobias Grosser SplitBlock->getTerminator()->eraseFromParent();
1483a275d20STobias Grosser Builder.SetInsertPoint(SplitBlock);
14903346c27SSiddharth Bhat BranchInst *CondBr = Builder.CreateCondBr(RTC, StartBlock, S.getEntry());
15003346c27SSiddharth Bhat
1512d3d4ec8STobias Grosser if (Loop *L = LI.getLoopFor(SplitBlock)) {
1526adcf56bSChandler Carruth L->addBasicBlockToLoop(StartBlock, LI);
1532d3d4ec8STobias Grosser L->addBasicBlockToLoop(ExitingBlock, LI);
1542d3d4ec8STobias Grosser }
1553a275d20STobias Grosser DT.addNewBlock(StartBlock, SplitBlock);
1562d3d4ec8STobias Grosser DT.addNewBlock(ExitingBlock, StartBlock);
15722370884SMichael Kruse RI.setRegionFor(StartBlock, RI.getRegionFor(SplitBlock));
1582d3d4ec8STobias Grosser RI.setRegionFor(ExitingBlock, RI.getRegionFor(SplitBlock));
15922370884SMichael Kruse
16022370884SMichael Kruse // \ / //
16122370884SMichael Kruse // EnteringBB //
16222370884SMichael Kruse // | //
16322370884SMichael Kruse // SplitBlock---------\ //
16422370884SMichael Kruse // _____|_____ | //
16522370884SMichael Kruse // / EntryBB \ StartBlock //
1662d3d4ec8STobias Grosser // | (region) | | //
1672d3d4ec8STobias Grosser // \_ExitingBB_/ ExitingBlock //
16822370884SMichael Kruse // | //
16922370884SMichael Kruse // MergeBlock //
17022370884SMichael Kruse // | //
17122370884SMichael Kruse // ExitBB //
17222370884SMichael Kruse // / \ //
17322370884SMichael Kruse
1742d3d4ec8STobias Grosser // Connect start block to exiting block.
1753a275d20STobias Grosser Builder.SetInsertPoint(StartBlock);
1762d3d4ec8STobias Grosser Builder.CreateBr(ExitingBlock);
1772d3d4ec8STobias Grosser DT.changeImmediateDominator(ExitingBlock, StartBlock);
1782d3d4ec8STobias Grosser
1792d3d4ec8STobias Grosser // Connect exiting block to join block.
1802d3d4ec8STobias Grosser Builder.SetInsertPoint(ExitingBlock);
1813a275d20STobias Grosser Builder.CreateBr(MergeBlock);
1823a275d20STobias Grosser DT.changeImmediateDominator(MergeBlock, SplitBlock);
18322370884SMichael Kruse
18422370884SMichael Kruse // \ / //
18522370884SMichael Kruse // EnteringBB //
18622370884SMichael Kruse // | //
18722370884SMichael Kruse // SplitBlock---------\ //
18822370884SMichael Kruse // _____|_____ | //
18922370884SMichael Kruse // / EntryBB \ StartBlock //
19022370884SMichael Kruse // | (region) | | //
1912d3d4ec8STobias Grosser // \_ExitingBB_/ ExitingBlock //
19222370884SMichael Kruse // | | //
19322370884SMichael Kruse // MergeBlock---------/ //
19422370884SMichael Kruse // | //
19522370884SMichael Kruse // ExitBB //
19622370884SMichael Kruse // / \ //
197acf80064SEli Friedman //
198acf80064SEli Friedman
199acf80064SEli Friedman // Split the edge between SplitBlock and EntryBB, to avoid a critical edge.
200acf80064SEli Friedman splitEdge(SplitBlock, EntryBB, ".pre_entry_bb", &DT, &LI, &RI);
201acf80064SEli Friedman
202acf80064SEli Friedman // \ / //
203acf80064SEli Friedman // EnteringBB //
204acf80064SEli Friedman // | //
205acf80064SEli Friedman // SplitBlock---------\ //
206acf80064SEli Friedman // | | //
207acf80064SEli Friedman // PreEntryBB | //
208acf80064SEli Friedman // _____|_____ | //
209acf80064SEli Friedman // / EntryBB \ StartBlock //
210acf80064SEli Friedman // | (region) | | //
211acf80064SEli Friedman // \_ExitingBB_/ ExitingBlock //
212acf80064SEli Friedman // | | //
213acf80064SEli Friedman // MergeBlock---------/ //
214acf80064SEli Friedman // | //
215acf80064SEli Friedman // ExitBB //
216acf80064SEli Friedman // / \ //
21722370884SMichael Kruse
21803346c27SSiddharth Bhat return std::make_pair(std::make_pair(StartBlock, ExitingBlock), CondBr);
2193a275d20STobias Grosser }
220