2012-05-29 17:11:54 +08:00
|
|
|
//===--- Utils.cpp - Utility functions for the code generation --*- C++ -*-===//
|
|
|
|
//
|
|
|
|
// The LLVM Compiler Infrastructure
|
|
|
|
//
|
|
|
|
// This file is distributed under the University of Illinois Open Source
|
|
|
|
// License. See LICENSE.TXT for details.
|
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
//
|
|
|
|
// This file contains utility functions for the code generation.
|
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
|
|
|
#include "polly/CodeGen/Utils.h"
|
2014-03-04 22:58:49 +08:00
|
|
|
#include "polly/CodeGen/IRBuilder.h"
|
2012-05-29 17:11:54 +08:00
|
|
|
#include "polly/ScopInfo.h"
|
2014-02-24 08:50:49 +08:00
|
|
|
#include "llvm/Analysis/LoopInfo.h"
|
2015-03-02 02:45:58 +08:00
|
|
|
#include "llvm/Analysis/RegionInfo.h"
|
2012-05-29 17:11:54 +08:00
|
|
|
#include "llvm/Support/Debug.h"
|
|
|
|
#include "llvm/Transforms/Utils/BasicBlockUtils.h"
|
|
|
|
|
|
|
|
using namespace llvm;
|
|
|
|
|
2015-08-11 22:39:21 +08:00
|
|
|
// 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;
|
|
|
|
}
|
|
|
|
|
2014-09-10 22:50:23 +08:00
|
|
|
BasicBlock *polly::executeScopConditionally(Scop &S, Pass *P, Value *RTC) {
|
2012-05-29 17:11:54 +08:00
|
|
|
Region &R = S.getRegion();
|
2016-05-23 20:42:38 +08:00
|
|
|
PollyIRBuilder Builder(S.getEntry());
|
2014-09-10 22:50:23 +08:00
|
|
|
DominatorTree &DT = P->getAnalysis<DominatorTreeWrapperPass>().getDomTree();
|
|
|
|
RegionInfo &RI = P->getAnalysis<RegionInfoPass>().getRegionInfo();
|
2015-01-17 22:16:56 +08:00
|
|
|
LoopInfo &LI = P->getAnalysis<LoopInfoWrapperPass>().getLoopInfo();
|
2012-05-29 17:11:54 +08:00
|
|
|
|
2015-08-11 22:39:21 +08:00
|
|
|
// Before:
|
|
|
|
//
|
|
|
|
// \ / //
|
|
|
|
// EnteringBB //
|
|
|
|
// _____|_____ //
|
|
|
|
// / EntryBB \ //
|
|
|
|
// | (region) | //
|
|
|
|
// \_ExitingBB_/ //
|
|
|
|
// | //
|
|
|
|
// ExitBB //
|
|
|
|
// / \ //
|
2012-05-29 17:11:54 +08:00
|
|
|
|
2015-08-11 22:39:21 +08:00
|
|
|
// Create a fork block.
|
2016-05-23 20:42:38 +08:00
|
|
|
BasicBlock *EnteringBB = S.getEnteringBlock();
|
|
|
|
BasicBlock *EntryBB = S.getEntry();
|
2015-08-11 22:39:21 +08:00
|
|
|
assert(EnteringBB && "Must be a simple region");
|
|
|
|
BasicBlock *SplitBlock =
|
|
|
|
splitEdge(EnteringBB, EntryBB, ".split_new_and_old", &DT, &LI, &RI);
|
2012-05-29 17:11:54 +08:00
|
|
|
SplitBlock->setName("polly.split_new_and_old");
|
2015-08-11 22:39:21 +08:00
|
|
|
|
2015-08-18 21:14:42 +08:00
|
|
|
// 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);
|
|
|
|
|
2015-08-11 22:39:21 +08:00
|
|
|
// Create a join block
|
2016-05-23 20:42:38 +08:00
|
|
|
BasicBlock *ExitingBB = S.getExitingBlock();
|
|
|
|
BasicBlock *ExitBB = S.getExit();
|
2015-08-11 22:39:21 +08:00
|
|
|
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 //
|
|
|
|
// / \ //
|
|
|
|
|
2015-12-09 19:38:22 +08:00
|
|
|
// Create the start and exiting block.
|
2012-05-29 17:11:54 +08:00
|
|
|
Function *F = SplitBlock->getParent();
|
2015-08-11 22:39:21 +08:00
|
|
|
BasicBlock *StartBlock =
|
|
|
|
BasicBlock::Create(F->getContext(), "polly.start", F);
|
2015-12-09 19:38:22 +08:00
|
|
|
BasicBlock *ExitingBlock =
|
|
|
|
BasicBlock::Create(F->getContext(), "polly.exiting", F);
|
2012-05-29 17:11:54 +08:00
|
|
|
SplitBlock->getTerminator()->eraseFromParent();
|
|
|
|
Builder.SetInsertPoint(SplitBlock);
|
2016-05-23 20:42:38 +08:00
|
|
|
Builder.CreateCondBr(RTC, StartBlock, S.getEntry());
|
2015-12-09 19:38:22 +08:00
|
|
|
if (Loop *L = LI.getLoopFor(SplitBlock)) {
|
2015-01-18 09:47:30 +08:00
|
|
|
L->addBasicBlockToLoop(StartBlock, LI);
|
2015-12-09 19:38:22 +08:00
|
|
|
L->addBasicBlockToLoop(ExitingBlock, LI);
|
|
|
|
}
|
2012-05-29 17:11:54 +08:00
|
|
|
DT.addNewBlock(StartBlock, SplitBlock);
|
2015-12-09 19:38:22 +08:00
|
|
|
DT.addNewBlock(ExitingBlock, StartBlock);
|
2015-08-11 22:39:21 +08:00
|
|
|
RI.setRegionFor(StartBlock, RI.getRegionFor(SplitBlock));
|
2015-12-09 19:38:22 +08:00
|
|
|
RI.setRegionFor(ExitingBlock, RI.getRegionFor(SplitBlock));
|
2012-05-29 17:11:54 +08:00
|
|
|
|
2015-08-11 22:39:21 +08:00
|
|
|
// \ / //
|
|
|
|
// EnteringBB //
|
|
|
|
// | //
|
|
|
|
// SplitBlock---------\ //
|
|
|
|
// _____|_____ | //
|
|
|
|
// / EntryBB \ StartBlock //
|
2015-12-09 19:38:22 +08:00
|
|
|
// | (region) | | //
|
|
|
|
// \_ExitingBB_/ ExitingBlock //
|
2015-08-11 22:39:21 +08:00
|
|
|
// | //
|
|
|
|
// MergeBlock //
|
|
|
|
// | //
|
|
|
|
// ExitBB //
|
|
|
|
// / \ //
|
2012-05-29 17:11:54 +08:00
|
|
|
|
2015-12-09 19:38:22 +08:00
|
|
|
// Connect start block to exiting block.
|
2015-08-11 22:39:21 +08:00
|
|
|
Builder.SetInsertPoint(StartBlock);
|
2015-12-09 19:38:22 +08:00
|
|
|
Builder.CreateBr(ExitingBlock);
|
|
|
|
DT.changeImmediateDominator(ExitingBlock, StartBlock);
|
|
|
|
|
|
|
|
// Connect exiting block to join block.
|
|
|
|
Builder.SetInsertPoint(ExitingBlock);
|
2012-05-29 17:11:54 +08:00
|
|
|
Builder.CreateBr(MergeBlock);
|
2015-08-11 22:39:21 +08:00
|
|
|
DT.changeImmediateDominator(MergeBlock, SplitBlock);
|
|
|
|
|
|
|
|
// \ / //
|
|
|
|
// EnteringBB //
|
|
|
|
// | //
|
|
|
|
// SplitBlock---------\ //
|
|
|
|
// _____|_____ | //
|
|
|
|
// / EntryBB \ StartBlock //
|
|
|
|
// | (region) | | //
|
2015-12-09 19:38:22 +08:00
|
|
|
// \_ExitingBB_/ ExitingBlock //
|
2015-08-11 22:39:21 +08:00
|
|
|
// | | //
|
|
|
|
// MergeBlock---------/ //
|
|
|
|
// | //
|
|
|
|
// ExitBB //
|
|
|
|
// / \ //
|
2012-05-29 17:11:54 +08:00
|
|
|
|
|
|
|
return StartBlock;
|
|
|
|
}
|