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