123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219 |
- //===--- Utils.cpp - Utility functions for the code generation --*- C++ -*-===//
- //
- // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
- // See https://llvm.org/LICENSE.txt for license information.
- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
- //
- //===----------------------------------------------------------------------===//
- //
- // This file contains utility functions for the code generation.
- //
- //===----------------------------------------------------------------------===//
- #include "polly/CodeGen/Utils.h"
- #include "polly/CodeGen/IRBuilder.h"
- #include "polly/ScopInfo.h"
- #include "llvm/Analysis/LoopInfo.h"
- #include "llvm/Analysis/RegionInfo.h"
- #include "llvm/Transforms/Utils/BasicBlockUtils.h"
- using namespace llvm;
- // Alternative to llvm::SplitCriticalEdge.
- //
- // Creates a new block which branches to Succ. The edge to split is redirected
- // to the new block.
- //
- // The issue with llvm::SplitCriticalEdge is that it does nothing if the edge is
- // not critical.
- // The issue with llvm::SplitEdge is that it does not always create the middle
- // block, but reuses Prev/Succ if it can. We always want a new middle block.
- static BasicBlock *splitEdge(BasicBlock *Prev, BasicBlock *Succ,
- const char *Suffix, DominatorTree *DT,
- LoopInfo *LI, RegionInfo *RI) {
- assert(Prev && Succ);
- // Before:
- // \ / / //
- // Prev / //
- // | \___/ //
- // | ___ //
- // | / \ //
- // Succ \ //
- // / \ \ //
- // The algorithm to update DominatorTree and LoopInfo of
- // llvm::SplitCriticalEdge is more efficient than
- // llvm::SplitBlockPredecessors, which is more general. In the future we might
- // either modify llvm::SplitCriticalEdge to allow skipping the critical edge
- // check; or Copy&Pase it here.
- BasicBlock *MiddleBlock = SplitBlockPredecessors(
- Succ, ArrayRef<BasicBlock *>(Prev), Suffix, DT, LI);
- if (RI) {
- Region *PrevRegion = RI->getRegionFor(Prev);
- Region *SuccRegion = RI->getRegionFor(Succ);
- if (PrevRegion->contains(MiddleBlock)) {
- RI->setRegionFor(MiddleBlock, PrevRegion);
- } else {
- RI->setRegionFor(MiddleBlock, SuccRegion);
- }
- }
- // After:
- // \ / / //
- // Prev / //
- // | \___/ //
- // | //
- // MiddleBlock //
- // | ___ //
- // | / \ //
- // Succ \ //
- // / \ \ //
- return MiddleBlock;
- }
- std::pair<polly::BBPair, BranchInst *>
- polly::executeScopConditionally(Scop &S, Value *RTC, DominatorTree &DT,
- RegionInfo &RI, LoopInfo &LI) {
- Region &R = S.getRegion();
- PollyIRBuilder Builder(S.getEntry());
- // Before:
- //
- // \ / //
- // EnteringBB //
- // _____|_____ //
- // / EntryBB \ //
- // | (region) | //
- // \_ExitingBB_/ //
- // | //
- // ExitBB //
- // / \ //
- // Create a fork block.
- BasicBlock *EnteringBB = S.getEnteringBlock();
- BasicBlock *EntryBB = S.getEntry();
- assert(EnteringBB && "Must be a simple region");
- BasicBlock *SplitBlock =
- splitEdge(EnteringBB, EntryBB, ".split_new_and_old", &DT, &LI, &RI);
- SplitBlock->setName("polly.split_new_and_old");
- // If EntryBB is the exit block of the region that includes Prev, exclude
- // SplitBlock from that region by making it itself the exit block. This is
- // trivially possible because there is just one edge to EnteringBB.
- // This is necessary because we will add an outgoing edge from SplitBlock,
- // which would violate the single exit block requirement of PrevRegion.
- Region *PrevRegion = RI.getRegionFor(EnteringBB);
- while (PrevRegion->getExit() == EntryBB) {
- PrevRegion->replaceExit(SplitBlock);
- PrevRegion = PrevRegion->getParent();
- }
- RI.setRegionFor(SplitBlock, PrevRegion);
- // Create a join block
- BasicBlock *ExitingBB = S.getExitingBlock();
- BasicBlock *ExitBB = S.getExit();
- assert(ExitingBB && "Must be a simple region");
- BasicBlock *MergeBlock =
- splitEdge(ExitingBB, ExitBB, ".merge_new_and_old", &DT, &LI, &RI);
- MergeBlock->setName("polly.merge_new_and_old");
- // Exclude the join block from the region.
- R.replaceExitRecursive(MergeBlock);
- RI.setRegionFor(MergeBlock, R.getParent());
- // \ / //
- // EnteringBB //
- // | //
- // SplitBlock //
- // _____|_____ //
- // / EntryBB \ //
- // | (region) | //
- // \_ExitingBB_/ //
- // | //
- // MergeBlock //
- // | //
- // ExitBB //
- // / \ //
- // Create the start and exiting block.
- Function *F = SplitBlock->getParent();
- BasicBlock *StartBlock =
- BasicBlock::Create(F->getContext(), "polly.start", F);
- BasicBlock *ExitingBlock =
- BasicBlock::Create(F->getContext(), "polly.exiting", F);
- SplitBlock->getTerminator()->eraseFromParent();
- Builder.SetInsertPoint(SplitBlock);
- BranchInst *CondBr = Builder.CreateCondBr(RTC, StartBlock, S.getEntry());
- if (Loop *L = LI.getLoopFor(SplitBlock)) {
- L->addBasicBlockToLoop(StartBlock, LI);
- L->addBasicBlockToLoop(ExitingBlock, LI);
- }
- DT.addNewBlock(StartBlock, SplitBlock);
- DT.addNewBlock(ExitingBlock, StartBlock);
- RI.setRegionFor(StartBlock, RI.getRegionFor(SplitBlock));
- RI.setRegionFor(ExitingBlock, RI.getRegionFor(SplitBlock));
- // \ / //
- // EnteringBB //
- // | //
- // SplitBlock---------\ //
- // _____|_____ | //
- // / EntryBB \ StartBlock //
- // | (region) | | //
- // \_ExitingBB_/ ExitingBlock //
- // | //
- // MergeBlock //
- // | //
- // ExitBB //
- // / \ //
- // Connect start block to exiting block.
- Builder.SetInsertPoint(StartBlock);
- Builder.CreateBr(ExitingBlock);
- DT.changeImmediateDominator(ExitingBlock, StartBlock);
- // Connect exiting block to join block.
- Builder.SetInsertPoint(ExitingBlock);
- Builder.CreateBr(MergeBlock);
- DT.changeImmediateDominator(MergeBlock, SplitBlock);
- // \ / //
- // EnteringBB //
- // | //
- // SplitBlock---------\ //
- // _____|_____ | //
- // / EntryBB \ StartBlock //
- // | (region) | | //
- // \_ExitingBB_/ ExitingBlock //
- // | | //
- // MergeBlock---------/ //
- // | //
- // ExitBB //
- // / \ //
- //
- // Split the edge between SplitBlock and EntryBB, to avoid a critical edge.
- splitEdge(SplitBlock, EntryBB, ".pre_entry_bb", &DT, &LI, &RI);
- // \ / //
- // EnteringBB //
- // | //
- // SplitBlock---------\ //
- // | | //
- // PreEntryBB | //
- // _____|_____ | //
- // / EntryBB \ StartBlock //
- // | (region) | | //
- // \_ExitingBB_/ ExitingBlock //
- // | | //
- // MergeBlock---------/ //
- // | //
- // ExitBB //
- // / \ //
- return std::make_pair(std::make_pair(StartBlock, ExitingBlock), CondBr);
- }
|