1f22ef01cSRoman Divacky //===- CodeExtractor.cpp - Pull code region into a new function -----------===// 2f22ef01cSRoman Divacky // 3f22ef01cSRoman Divacky // The LLVM Compiler Infrastructure 4f22ef01cSRoman Divacky // 5f22ef01cSRoman Divacky // This file is distributed under the University of Illinois Open Source 6f22ef01cSRoman Divacky // License. See LICENSE.TXT for details. 7f22ef01cSRoman Divacky // 8f22ef01cSRoman Divacky //===----------------------------------------------------------------------===// 9f22ef01cSRoman Divacky // 10f22ef01cSRoman Divacky // This file implements the interface to tear out a code region, such as an 11f22ef01cSRoman Divacky // individual loop or a parallel section, into a new function, replacing it with 12f22ef01cSRoman Divacky // a call to the new function. 13f22ef01cSRoman Divacky // 14f22ef01cSRoman Divacky //===----------------------------------------------------------------------===// 15f22ef01cSRoman Divacky 167ae0e2c9SDimitry Andric #include "llvm/Transforms/Utils/CodeExtractor.h" 172cab237bSDimitry Andric #include "llvm/ADT/ArrayRef.h" 182cab237bSDimitry Andric #include "llvm/ADT/DenseMap.h" 192cab237bSDimitry Andric #include "llvm/ADT/Optional.h" 20139f7f9bSDimitry Andric #include "llvm/ADT/STLExtras.h" 2191bc56edSDimitry Andric #include "llvm/ADT/SetVector.h" 222cab237bSDimitry Andric #include "llvm/ADT/SmallPtrSet.h" 232cab237bSDimitry Andric #include "llvm/ADT/SmallVector.h" 24d88c1a5aSDimitry Andric #include "llvm/Analysis/BlockFrequencyInfo.h" 25d88c1a5aSDimitry Andric #include "llvm/Analysis/BlockFrequencyInfoImpl.h" 26d88c1a5aSDimitry Andric #include "llvm/Analysis/BranchProbabilityInfo.h" 27f22ef01cSRoman Divacky #include "llvm/Analysis/LoopInfo.h" 282cab237bSDimitry Andric #include "llvm/IR/Argument.h" 292cab237bSDimitry Andric #include "llvm/IR/Attributes.h" 302cab237bSDimitry Andric #include "llvm/IR/BasicBlock.h" 312cab237bSDimitry Andric #include "llvm/IR/CFG.h" 322cab237bSDimitry Andric #include "llvm/IR/Constant.h" 33139f7f9bSDimitry Andric #include "llvm/IR/Constants.h" 342cab237bSDimitry Andric #include "llvm/IR/DataLayout.h" 35139f7f9bSDimitry Andric #include "llvm/IR/DerivedTypes.h" 3691bc56edSDimitry Andric #include "llvm/IR/Dominators.h" 372cab237bSDimitry Andric #include "llvm/IR/Function.h" 382cab237bSDimitry Andric #include "llvm/IR/GlobalValue.h" 392cab237bSDimitry Andric #include "llvm/IR/InstrTypes.h" 402cab237bSDimitry Andric #include "llvm/IR/Instruction.h" 41139f7f9bSDimitry Andric #include "llvm/IR/Instructions.h" 42f9448bf3SDimitry Andric #include "llvm/IR/IntrinsicInst.h" 43139f7f9bSDimitry Andric #include "llvm/IR/Intrinsics.h" 44139f7f9bSDimitry Andric #include "llvm/IR/LLVMContext.h" 45d88c1a5aSDimitry Andric #include "llvm/IR/MDBuilder.h" 46139f7f9bSDimitry Andric #include "llvm/IR/Module.h" 472cab237bSDimitry Andric #include "llvm/IR/Type.h" 482cab237bSDimitry Andric #include "llvm/IR/User.h" 492cab237bSDimitry Andric #include "llvm/IR/Value.h" 5091bc56edSDimitry Andric #include "llvm/IR/Verifier.h" 51139f7f9bSDimitry Andric #include "llvm/Pass.h" 52d88c1a5aSDimitry Andric #include "llvm/Support/BlockFrequency.h" 532cab237bSDimitry Andric #include "llvm/Support/BranchProbability.h" 542cab237bSDimitry Andric #include "llvm/Support/Casting.h" 55f22ef01cSRoman Divacky #include "llvm/Support/CommandLine.h" 56f22ef01cSRoman Divacky #include "llvm/Support/Debug.h" 57f22ef01cSRoman Divacky #include "llvm/Support/ErrorHandling.h" 58f22ef01cSRoman Divacky #include "llvm/Support/raw_ostream.h" 59139f7f9bSDimitry Andric #include "llvm/Transforms/Utils/BasicBlockUtils.h" 602cab237bSDimitry Andric #include <cassert> 612cab237bSDimitry Andric #include <cstdint> 622cab237bSDimitry Andric #include <iterator> 632cab237bSDimitry Andric #include <map> 64f22ef01cSRoman Divacky #include <set> 652cab237bSDimitry Andric #include <utility> 662cab237bSDimitry Andric #include <vector> 672cab237bSDimitry Andric 68f22ef01cSRoman Divacky using namespace llvm; 69f22ef01cSRoman Divacky 7091bc56edSDimitry Andric #define DEBUG_TYPE "code-extractor" 7191bc56edSDimitry Andric 72f22ef01cSRoman Divacky // Provide a command-line option to aggregate function arguments into a struct 73f22ef01cSRoman Divacky // for functions produced by the code extractor. This is useful when converting 74f22ef01cSRoman Divacky // extracted functions to pthread-based code, as only one argument (void*) can 75f22ef01cSRoman Divacky // be passed in to pthread_create(). 76f22ef01cSRoman Divacky static cl::opt<bool> 77f22ef01cSRoman Divacky AggregateArgsOpt("aggregate-extracted-args", cl::Hidden, 78f22ef01cSRoman Divacky cl::desc("Aggregate arguments to code-extracted functions")); 79f22ef01cSRoman Divacky 807ae0e2c9SDimitry Andric /// \brief Test whether a block is valid for extraction. 812cab237bSDimitry Andric bool CodeExtractor::isBlockValidForExtraction(const BasicBlock &BB, 822cab237bSDimitry Andric bool AllowVarArgs) { 837ae0e2c9SDimitry Andric // Landing pads must be in the function where they were inserted for cleanup. 847d523365SDimitry Andric if (BB.isEHPad()) 857ae0e2c9SDimitry Andric return false; 86a580b014SDimitry Andric // taking the address of a basic block moved to another function is illegal 87a580b014SDimitry Andric if (BB.hasAddressTaken()) 88a580b014SDimitry Andric return false; 89a580b014SDimitry Andric 90a580b014SDimitry Andric // don't hoist code that uses another basicblock address, as it's likely to 91a580b014SDimitry Andric // lead to unexpected behavior, like cross-function jumps 92a580b014SDimitry Andric SmallPtrSet<User const *, 16> Visited; 93a580b014SDimitry Andric SmallVector<User const *, 16> ToVisit; 94a580b014SDimitry Andric 95a580b014SDimitry Andric for (Instruction const &Inst : BB) 96a580b014SDimitry Andric ToVisit.push_back(&Inst); 97a580b014SDimitry Andric 98a580b014SDimitry Andric while (!ToVisit.empty()) { 99a580b014SDimitry Andric User const *Curr = ToVisit.pop_back_val(); 100a580b014SDimitry Andric if (!Visited.insert(Curr).second) 101a580b014SDimitry Andric continue; 102a580b014SDimitry Andric if (isa<BlockAddress const>(Curr)) 103a580b014SDimitry Andric return false; // even a reference to self is likely to be not compatible 104a580b014SDimitry Andric 105a580b014SDimitry Andric if (isa<Instruction>(Curr) && cast<Instruction>(Curr)->getParent() != &BB) 106a580b014SDimitry Andric continue; 107a580b014SDimitry Andric 108a580b014SDimitry Andric for (auto const &U : Curr->operands()) { 109a580b014SDimitry Andric if (auto *UU = dyn_cast<User>(U)) 110a580b014SDimitry Andric ToVisit.push_back(UU); 111a580b014SDimitry Andric } 112a580b014SDimitry Andric } 113f22ef01cSRoman Divacky 1142cab237bSDimitry Andric // Don't hoist code containing allocas or invokes. If explicitly requested, 1152cab237bSDimitry Andric // allow vastart. 1167ae0e2c9SDimitry Andric for (BasicBlock::const_iterator I = BB.begin(), E = BB.end(); I != E; ++I) { 1177ae0e2c9SDimitry Andric if (isa<AllocaInst>(I) || isa<InvokeInst>(I)) 1187ae0e2c9SDimitry Andric return false; 1197ae0e2c9SDimitry Andric if (const CallInst *CI = dyn_cast<CallInst>(I)) 1207ae0e2c9SDimitry Andric if (const Function *F = CI->getCalledFunction()) 1212cab237bSDimitry Andric if (F->getIntrinsicID() == Intrinsic::vastart) { 1222cab237bSDimitry Andric if (AllowVarArgs) 1232cab237bSDimitry Andric continue; 1242cab237bSDimitry Andric else 1257ae0e2c9SDimitry Andric return false; 1267ae0e2c9SDimitry Andric } 1272cab237bSDimitry Andric } 128f22ef01cSRoman Divacky 1297ae0e2c9SDimitry Andric return true; 1307ae0e2c9SDimitry Andric } 131f22ef01cSRoman Divacky 1327ae0e2c9SDimitry Andric /// \brief Build a set of blocks to extract if the input blocks are viable. 13351690af2SDimitry Andric static SetVector<BasicBlock *> 1342cab237bSDimitry Andric buildExtractionBlockSet(ArrayRef<BasicBlock *> BBs, DominatorTree *DT, 1352cab237bSDimitry Andric bool AllowVarArgs) { 13651690af2SDimitry Andric assert(!BBs.empty() && "The set of blocks to extract must be non-empty"); 1377ae0e2c9SDimitry Andric SetVector<BasicBlock *> Result; 1387ae0e2c9SDimitry Andric 1397ae0e2c9SDimitry Andric // Loop over the blocks, adding them to our set-vector, and aborting with an 1407ae0e2c9SDimitry Andric // empty set if we encounter invalid blocks. 14151690af2SDimitry Andric for (BasicBlock *BB : BBs) { 14251690af2SDimitry Andric // If this block is dead, don't process it. 14351690af2SDimitry Andric if (DT && !DT->isReachableFromEntry(BB)) 14451690af2SDimitry Andric continue; 14551690af2SDimitry Andric 14651690af2SDimitry Andric if (!Result.insert(BB)) 14751690af2SDimitry Andric llvm_unreachable("Repeated basic blocks in extraction input"); 1482cab237bSDimitry Andric if (!CodeExtractor::isBlockValidForExtraction(*BB, AllowVarArgs)) { 1497ae0e2c9SDimitry Andric Result.clear(); 1507ae0e2c9SDimitry Andric return Result; 1517ae0e2c9SDimitry Andric } 15251690af2SDimitry Andric } 1537ae0e2c9SDimitry Andric 1547ae0e2c9SDimitry Andric #ifndef NDEBUG 15591bc56edSDimitry Andric for (SetVector<BasicBlock *>::iterator I = std::next(Result.begin()), 1567ae0e2c9SDimitry Andric E = Result.end(); 1577ae0e2c9SDimitry Andric I != E; ++I) 1587ae0e2c9SDimitry Andric for (pred_iterator PI = pred_begin(*I), PE = pred_end(*I); 1597ae0e2c9SDimitry Andric PI != PE; ++PI) 1607ae0e2c9SDimitry Andric assert(Result.count(*PI) && 1617ae0e2c9SDimitry Andric "No blocks in this region may have entries from outside the region" 1627ae0e2c9SDimitry Andric " except for the first block!"); 1637ae0e2c9SDimitry Andric #endif 1647ae0e2c9SDimitry Andric 1657ae0e2c9SDimitry Andric return Result; 1667ae0e2c9SDimitry Andric } 1677ae0e2c9SDimitry Andric 1687ae0e2c9SDimitry Andric CodeExtractor::CodeExtractor(ArrayRef<BasicBlock *> BBs, DominatorTree *DT, 169d88c1a5aSDimitry Andric bool AggregateArgs, BlockFrequencyInfo *BFI, 1702cab237bSDimitry Andric BranchProbabilityInfo *BPI, bool AllowVarArgs) 171d88c1a5aSDimitry Andric : DT(DT), AggregateArgs(AggregateArgs || AggregateArgsOpt), BFI(BFI), 1722cab237bSDimitry Andric BPI(BPI), AllowVarArgs(AllowVarArgs), 1732cab237bSDimitry Andric Blocks(buildExtractionBlockSet(BBs, DT, AllowVarArgs)) {} 1747ae0e2c9SDimitry Andric 175d88c1a5aSDimitry Andric CodeExtractor::CodeExtractor(DominatorTree &DT, Loop &L, bool AggregateArgs, 176d88c1a5aSDimitry Andric BlockFrequencyInfo *BFI, 177d88c1a5aSDimitry Andric BranchProbabilityInfo *BPI) 178d88c1a5aSDimitry Andric : DT(&DT), AggregateArgs(AggregateArgs || AggregateArgsOpt), BFI(BFI), 1792cab237bSDimitry Andric BPI(BPI), AllowVarArgs(false), 1802cab237bSDimitry Andric Blocks(buildExtractionBlockSet(L.getBlocks(), &DT, 1812cab237bSDimitry Andric /* AllowVarArgs */ false)) {} 1827ae0e2c9SDimitry Andric 183f22ef01cSRoman Divacky /// definedInRegion - Return true if the specified value is defined in the 184f22ef01cSRoman Divacky /// extracted region. 1857ae0e2c9SDimitry Andric static bool definedInRegion(const SetVector<BasicBlock *> &Blocks, Value *V) { 186f22ef01cSRoman Divacky if (Instruction *I = dyn_cast<Instruction>(V)) 1877ae0e2c9SDimitry Andric if (Blocks.count(I->getParent())) 188f22ef01cSRoman Divacky return true; 189f22ef01cSRoman Divacky return false; 190f22ef01cSRoman Divacky } 191f22ef01cSRoman Divacky 192f22ef01cSRoman Divacky /// definedInCaller - Return true if the specified value is defined in the 193f22ef01cSRoman Divacky /// function being code extracted, but not in the region being extracted. 194f22ef01cSRoman Divacky /// These values must be passed in as live-ins to the function. 1957ae0e2c9SDimitry Andric static bool definedInCaller(const SetVector<BasicBlock *> &Blocks, Value *V) { 196f22ef01cSRoman Divacky if (isa<Argument>(V)) return true; 197f22ef01cSRoman Divacky if (Instruction *I = dyn_cast<Instruction>(V)) 1987ae0e2c9SDimitry Andric if (!Blocks.count(I->getParent())) 199f22ef01cSRoman Divacky return true; 200f22ef01cSRoman Divacky return false; 201f22ef01cSRoman Divacky } 202f22ef01cSRoman Divacky 20324d58133SDimitry Andric static BasicBlock *getCommonExitBlock(const SetVector<BasicBlock *> &Blocks) { 20424d58133SDimitry Andric BasicBlock *CommonExitBlock = nullptr; 20524d58133SDimitry Andric auto hasNonCommonExitSucc = [&](BasicBlock *Block) { 20624d58133SDimitry Andric for (auto *Succ : successors(Block)) { 20724d58133SDimitry Andric // Internal edges, ok. 20824d58133SDimitry Andric if (Blocks.count(Succ)) 20924d58133SDimitry Andric continue; 21024d58133SDimitry Andric if (!CommonExitBlock) { 21124d58133SDimitry Andric CommonExitBlock = Succ; 21224d58133SDimitry Andric continue; 21324d58133SDimitry Andric } 21424d58133SDimitry Andric if (CommonExitBlock == Succ) 21524d58133SDimitry Andric continue; 21624d58133SDimitry Andric 21724d58133SDimitry Andric return true; 21824d58133SDimitry Andric } 21924d58133SDimitry Andric return false; 22024d58133SDimitry Andric }; 22124d58133SDimitry Andric 22224d58133SDimitry Andric if (any_of(Blocks, hasNonCommonExitSucc)) 22324d58133SDimitry Andric return nullptr; 22424d58133SDimitry Andric 22524d58133SDimitry Andric return CommonExitBlock; 22624d58133SDimitry Andric } 22724d58133SDimitry Andric 22824d58133SDimitry Andric bool CodeExtractor::isLegalToShrinkwrapLifetimeMarkers( 22924d58133SDimitry Andric Instruction *Addr) const { 23024d58133SDimitry Andric AllocaInst *AI = cast<AllocaInst>(Addr->stripInBoundsConstantOffsets()); 231f9448bf3SDimitry Andric Function *Func = (*Blocks.begin())->getParent(); 232f9448bf3SDimitry Andric for (BasicBlock &BB : *Func) { 233f9448bf3SDimitry Andric if (Blocks.count(&BB)) 234f9448bf3SDimitry Andric continue; 235f9448bf3SDimitry Andric for (Instruction &II : BB) { 23624d58133SDimitry Andric if (isa<DbgInfoIntrinsic>(II)) 23724d58133SDimitry Andric continue; 23824d58133SDimitry Andric 23924d58133SDimitry Andric unsigned Opcode = II.getOpcode(); 24024d58133SDimitry Andric Value *MemAddr = nullptr; 24124d58133SDimitry Andric switch (Opcode) { 24224d58133SDimitry Andric case Instruction::Store: 24324d58133SDimitry Andric case Instruction::Load: { 24424d58133SDimitry Andric if (Opcode == Instruction::Store) { 24524d58133SDimitry Andric StoreInst *SI = cast<StoreInst>(&II); 24624d58133SDimitry Andric MemAddr = SI->getPointerOperand(); 24724d58133SDimitry Andric } else { 24824d58133SDimitry Andric LoadInst *LI = cast<LoadInst>(&II); 24924d58133SDimitry Andric MemAddr = LI->getPointerOperand(); 25024d58133SDimitry Andric } 25124d58133SDimitry Andric // Global variable can not be aliased with locals. 25224d58133SDimitry Andric if (dyn_cast<Constant>(MemAddr)) 25324d58133SDimitry Andric break; 25424d58133SDimitry Andric Value *Base = MemAddr->stripInBoundsConstantOffsets(); 25524d58133SDimitry Andric if (!dyn_cast<AllocaInst>(Base) || Base == AI) 25624d58133SDimitry Andric return false; 25724d58133SDimitry Andric break; 25824d58133SDimitry Andric } 25924d58133SDimitry Andric default: { 26024d58133SDimitry Andric IntrinsicInst *IntrInst = dyn_cast<IntrinsicInst>(&II); 26124d58133SDimitry Andric if (IntrInst) { 26224d58133SDimitry Andric if (IntrInst->getIntrinsicID() == Intrinsic::lifetime_start || 26324d58133SDimitry Andric IntrInst->getIntrinsicID() == Intrinsic::lifetime_end) 26424d58133SDimitry Andric break; 26524d58133SDimitry Andric return false; 26624d58133SDimitry Andric } 26724d58133SDimitry Andric // Treat all the other cases conservatively if it has side effects. 26824d58133SDimitry Andric if (II.mayHaveSideEffects()) 26924d58133SDimitry Andric return false; 27024d58133SDimitry Andric } 27124d58133SDimitry Andric } 27224d58133SDimitry Andric } 27324d58133SDimitry Andric } 27424d58133SDimitry Andric 27524d58133SDimitry Andric return true; 27624d58133SDimitry Andric } 27724d58133SDimitry Andric 27824d58133SDimitry Andric BasicBlock * 27924d58133SDimitry Andric CodeExtractor::findOrCreateBlockForHoisting(BasicBlock *CommonExitBlock) { 28024d58133SDimitry Andric BasicBlock *SinglePredFromOutlineRegion = nullptr; 28124d58133SDimitry Andric assert(!Blocks.count(CommonExitBlock) && 28224d58133SDimitry Andric "Expect a block outside the region!"); 28324d58133SDimitry Andric for (auto *Pred : predecessors(CommonExitBlock)) { 28424d58133SDimitry Andric if (!Blocks.count(Pred)) 28524d58133SDimitry Andric continue; 28624d58133SDimitry Andric if (!SinglePredFromOutlineRegion) { 28724d58133SDimitry Andric SinglePredFromOutlineRegion = Pred; 28824d58133SDimitry Andric } else if (SinglePredFromOutlineRegion != Pred) { 28924d58133SDimitry Andric SinglePredFromOutlineRegion = nullptr; 29024d58133SDimitry Andric break; 29124d58133SDimitry Andric } 29224d58133SDimitry Andric } 29324d58133SDimitry Andric 29424d58133SDimitry Andric if (SinglePredFromOutlineRegion) 29524d58133SDimitry Andric return SinglePredFromOutlineRegion; 29624d58133SDimitry Andric 29724d58133SDimitry Andric #ifndef NDEBUG 29824d58133SDimitry Andric auto getFirstPHI = [](BasicBlock *BB) { 29924d58133SDimitry Andric BasicBlock::iterator I = BB->begin(); 30024d58133SDimitry Andric PHINode *FirstPhi = nullptr; 30124d58133SDimitry Andric while (I != BB->end()) { 30224d58133SDimitry Andric PHINode *Phi = dyn_cast<PHINode>(I); 30324d58133SDimitry Andric if (!Phi) 30424d58133SDimitry Andric break; 30524d58133SDimitry Andric if (!FirstPhi) { 30624d58133SDimitry Andric FirstPhi = Phi; 30724d58133SDimitry Andric break; 30824d58133SDimitry Andric } 30924d58133SDimitry Andric } 31024d58133SDimitry Andric return FirstPhi; 31124d58133SDimitry Andric }; 31224d58133SDimitry Andric // If there are any phi nodes, the single pred either exists or has already 31324d58133SDimitry Andric // be created before code extraction. 31424d58133SDimitry Andric assert(!getFirstPHI(CommonExitBlock) && "Phi not expected"); 31524d58133SDimitry Andric #endif 31624d58133SDimitry Andric 31724d58133SDimitry Andric BasicBlock *NewExitBlock = CommonExitBlock->splitBasicBlock( 31824d58133SDimitry Andric CommonExitBlock->getFirstNonPHI()->getIterator()); 31924d58133SDimitry Andric 3202cab237bSDimitry Andric for (auto PI = pred_begin(CommonExitBlock), PE = pred_end(CommonExitBlock); 3212cab237bSDimitry Andric PI != PE;) { 3222cab237bSDimitry Andric BasicBlock *Pred = *PI++; 32324d58133SDimitry Andric if (Blocks.count(Pred)) 32424d58133SDimitry Andric continue; 32524d58133SDimitry Andric Pred->getTerminator()->replaceUsesOfWith(CommonExitBlock, NewExitBlock); 32624d58133SDimitry Andric } 32724d58133SDimitry Andric // Now add the old exit block to the outline region. 32824d58133SDimitry Andric Blocks.insert(CommonExitBlock); 32924d58133SDimitry Andric return CommonExitBlock; 33024d58133SDimitry Andric } 33124d58133SDimitry Andric 33224d58133SDimitry Andric void CodeExtractor::findAllocas(ValueSet &SinkCands, ValueSet &HoistCands, 33324d58133SDimitry Andric BasicBlock *&ExitBlock) const { 33424d58133SDimitry Andric Function *Func = (*Blocks.begin())->getParent(); 33524d58133SDimitry Andric ExitBlock = getCommonExitBlock(Blocks); 33624d58133SDimitry Andric 33724d58133SDimitry Andric for (BasicBlock &BB : *Func) { 33824d58133SDimitry Andric if (Blocks.count(&BB)) 33924d58133SDimitry Andric continue; 34024d58133SDimitry Andric for (Instruction &II : BB) { 341f9448bf3SDimitry Andric auto *AI = dyn_cast<AllocaInst>(&II); 342f9448bf3SDimitry Andric if (!AI) 343f9448bf3SDimitry Andric continue; 344f9448bf3SDimitry Andric 34524d58133SDimitry Andric // Find the pair of life time markers for address 'Addr' that are either 34624d58133SDimitry Andric // defined inside the outline region or can legally be shrinkwrapped into 34724d58133SDimitry Andric // the outline region. If there are not other untracked uses of the 34824d58133SDimitry Andric // address, return the pair of markers if found; otherwise return a pair 34924d58133SDimitry Andric // of nullptr. 35024d58133SDimitry Andric auto GetLifeTimeMarkers = 35124d58133SDimitry Andric [&](Instruction *Addr, bool &SinkLifeStart, 35224d58133SDimitry Andric bool &HoistLifeEnd) -> std::pair<Instruction *, Instruction *> { 353f9448bf3SDimitry Andric Instruction *LifeStart = nullptr, *LifeEnd = nullptr; 354f9448bf3SDimitry Andric 35524d58133SDimitry Andric for (User *U : Addr->users()) { 356f9448bf3SDimitry Andric IntrinsicInst *IntrInst = dyn_cast<IntrinsicInst>(U); 357f9448bf3SDimitry Andric if (IntrInst) { 35824d58133SDimitry Andric if (IntrInst->getIntrinsicID() == Intrinsic::lifetime_start) { 35924d58133SDimitry Andric // Do not handle the case where AI has multiple start markers. 36024d58133SDimitry Andric if (LifeStart) 36124d58133SDimitry Andric return std::make_pair<Instruction *>(nullptr, nullptr); 362f9448bf3SDimitry Andric LifeStart = IntrInst; 36324d58133SDimitry Andric } 36424d58133SDimitry Andric if (IntrInst->getIntrinsicID() == Intrinsic::lifetime_end) { 36524d58133SDimitry Andric if (LifeEnd) 36624d58133SDimitry Andric return std::make_pair<Instruction *>(nullptr, nullptr); 367f9448bf3SDimitry Andric LifeEnd = IntrInst; 368f9448bf3SDimitry Andric } 36924d58133SDimitry Andric continue; 370f9448bf3SDimitry Andric } 37124d58133SDimitry Andric // Find untracked uses of the address, bail. 37224d58133SDimitry Andric if (!definedInRegion(Blocks, U)) 37324d58133SDimitry Andric return std::make_pair<Instruction *>(nullptr, nullptr); 37424d58133SDimitry Andric } 37524d58133SDimitry Andric 37624d58133SDimitry Andric if (!LifeStart || !LifeEnd) 37724d58133SDimitry Andric return std::make_pair<Instruction *>(nullptr, nullptr); 37824d58133SDimitry Andric 37924d58133SDimitry Andric SinkLifeStart = !definedInRegion(Blocks, LifeStart); 38024d58133SDimitry Andric HoistLifeEnd = !definedInRegion(Blocks, LifeEnd); 38124d58133SDimitry Andric // Do legality Check. 38224d58133SDimitry Andric if ((SinkLifeStart || HoistLifeEnd) && 38324d58133SDimitry Andric !isLegalToShrinkwrapLifetimeMarkers(Addr)) 38424d58133SDimitry Andric return std::make_pair<Instruction *>(nullptr, nullptr); 38524d58133SDimitry Andric 38624d58133SDimitry Andric // Check to see if we have a place to do hoisting, if not, bail. 38724d58133SDimitry Andric if (HoistLifeEnd && !ExitBlock) 38824d58133SDimitry Andric return std::make_pair<Instruction *>(nullptr, nullptr); 38924d58133SDimitry Andric 39024d58133SDimitry Andric return std::make_pair(LifeStart, LifeEnd); 391f9448bf3SDimitry Andric }; 392f9448bf3SDimitry Andric 39324d58133SDimitry Andric bool SinkLifeStart = false, HoistLifeEnd = false; 39424d58133SDimitry Andric auto Markers = GetLifeTimeMarkers(AI, SinkLifeStart, HoistLifeEnd); 39524d58133SDimitry Andric 39624d58133SDimitry Andric if (Markers.first) { 39724d58133SDimitry Andric if (SinkLifeStart) 39824d58133SDimitry Andric SinkCands.insert(Markers.first); 399f9448bf3SDimitry Andric SinkCands.insert(AI); 40024d58133SDimitry Andric if (HoistLifeEnd) 40124d58133SDimitry Andric HoistCands.insert(Markers.second); 402f9448bf3SDimitry Andric continue; 403f9448bf3SDimitry Andric } 404f9448bf3SDimitry Andric 40524d58133SDimitry Andric // Follow the bitcast. 406f9448bf3SDimitry Andric Instruction *MarkerAddr = nullptr; 407f9448bf3SDimitry Andric for (User *U : AI->users()) { 40824d58133SDimitry Andric if (U->stripInBoundsConstantOffsets() == AI) { 40924d58133SDimitry Andric SinkLifeStart = false; 41024d58133SDimitry Andric HoistLifeEnd = false; 411f9448bf3SDimitry Andric Instruction *Bitcast = cast<Instruction>(U); 41224d58133SDimitry Andric Markers = GetLifeTimeMarkers(Bitcast, SinkLifeStart, HoistLifeEnd); 41324d58133SDimitry Andric if (Markers.first) { 414f9448bf3SDimitry Andric MarkerAddr = Bitcast; 415f9448bf3SDimitry Andric continue; 416f9448bf3SDimitry Andric } 417f9448bf3SDimitry Andric } 41824d58133SDimitry Andric 41924d58133SDimitry Andric // Found unknown use of AI. 420f9448bf3SDimitry Andric if (!definedInRegion(Blocks, U)) { 421f9448bf3SDimitry Andric MarkerAddr = nullptr; 422f9448bf3SDimitry Andric break; 423f9448bf3SDimitry Andric } 424f9448bf3SDimitry Andric } 42524d58133SDimitry Andric 426f9448bf3SDimitry Andric if (MarkerAddr) { 42724d58133SDimitry Andric if (SinkLifeStart) 42824d58133SDimitry Andric SinkCands.insert(Markers.first); 429f9448bf3SDimitry Andric if (!definedInRegion(Blocks, MarkerAddr)) 430f9448bf3SDimitry Andric SinkCands.insert(MarkerAddr); 431f9448bf3SDimitry Andric SinkCands.insert(AI); 43224d58133SDimitry Andric if (HoistLifeEnd) 43324d58133SDimitry Andric HoistCands.insert(Markers.second); 434f9448bf3SDimitry Andric } 435f9448bf3SDimitry Andric } 436f9448bf3SDimitry Andric } 437f9448bf3SDimitry Andric } 438f9448bf3SDimitry Andric 439f9448bf3SDimitry Andric void CodeExtractor::findInputsOutputs(ValueSet &Inputs, ValueSet &Outputs, 440f9448bf3SDimitry Andric const ValueSet &SinkCands) const { 4413ca95b02SDimitry Andric for (BasicBlock *BB : Blocks) { 4427ae0e2c9SDimitry Andric // If a used value is defined outside the region, it's an input. If an 4437ae0e2c9SDimitry Andric // instruction is used outside the region, it's an output. 4443ca95b02SDimitry Andric for (Instruction &II : *BB) { 4453ca95b02SDimitry Andric for (User::op_iterator OI = II.op_begin(), OE = II.op_end(); OI != OE; 446f9448bf3SDimitry Andric ++OI) { 447f9448bf3SDimitry Andric Value *V = *OI; 448f9448bf3SDimitry Andric if (!SinkCands.count(V) && definedInCaller(Blocks, V)) 449f9448bf3SDimitry Andric Inputs.insert(V); 450f9448bf3SDimitry Andric } 451f22ef01cSRoman Divacky 4523ca95b02SDimitry Andric for (User *U : II.users()) 45391bc56edSDimitry Andric if (!definedInRegion(Blocks, U)) { 4543ca95b02SDimitry Andric Outputs.insert(&II); 4557ae0e2c9SDimitry Andric break; 4567ae0e2c9SDimitry Andric } 4577ae0e2c9SDimitry Andric } 4587ae0e2c9SDimitry Andric } 459f22ef01cSRoman Divacky } 460f22ef01cSRoman Divacky 461f22ef01cSRoman Divacky /// severSplitPHINodes - If a PHI node has multiple inputs from outside of the 462f22ef01cSRoman Divacky /// region, we need to split the entry block of the region so that the PHI node 463f22ef01cSRoman Divacky /// is easier to deal with. 464f22ef01cSRoman Divacky void CodeExtractor::severSplitPHINodes(BasicBlock *&Header) { 4653b0f4066SDimitry Andric unsigned NumPredsFromRegion = 0; 466f22ef01cSRoman Divacky unsigned NumPredsOutsideRegion = 0; 467f22ef01cSRoman Divacky 468f22ef01cSRoman Divacky if (Header != &Header->getParent()->getEntryBlock()) { 469f22ef01cSRoman Divacky PHINode *PN = dyn_cast<PHINode>(Header->begin()); 470f22ef01cSRoman Divacky if (!PN) return; // No PHI nodes. 471f22ef01cSRoman Divacky 472f22ef01cSRoman Divacky // If the header node contains any PHI nodes, check to see if there is more 473f22ef01cSRoman Divacky // than one entry from outside the region. If so, we need to sever the 474f22ef01cSRoman Divacky // header block into two. 475f22ef01cSRoman Divacky for (unsigned i = 0, e = PN->getNumIncomingValues(); i != e; ++i) 4767ae0e2c9SDimitry Andric if (Blocks.count(PN->getIncomingBlock(i))) 4773b0f4066SDimitry Andric ++NumPredsFromRegion; 478f22ef01cSRoman Divacky else 479f22ef01cSRoman Divacky ++NumPredsOutsideRegion; 480f22ef01cSRoman Divacky 481f22ef01cSRoman Divacky // If there is one (or fewer) predecessor from outside the region, we don't 482f22ef01cSRoman Divacky // need to do anything special. 483f22ef01cSRoman Divacky if (NumPredsOutsideRegion <= 1) return; 484f22ef01cSRoman Divacky } 485f22ef01cSRoman Divacky 486f22ef01cSRoman Divacky // Otherwise, we need to split the header block into two pieces: one 487f22ef01cSRoman Divacky // containing PHI nodes merging values from outside of the region, and a 488f22ef01cSRoman Divacky // second that contains all of the code for the block and merges back any 489f22ef01cSRoman Divacky // incoming values from inside of the region. 4902cab237bSDimitry Andric BasicBlock *NewBB = SplitBlock(Header, Header->getFirstNonPHI(), DT); 491f22ef01cSRoman Divacky 492f22ef01cSRoman Divacky // We only want to code extract the second block now, and it becomes the new 493f22ef01cSRoman Divacky // header of the region. 494f22ef01cSRoman Divacky BasicBlock *OldPred = Header; 4957ae0e2c9SDimitry Andric Blocks.remove(OldPred); 4967ae0e2c9SDimitry Andric Blocks.insert(NewBB); 497f22ef01cSRoman Divacky Header = NewBB; 498f22ef01cSRoman Divacky 499f22ef01cSRoman Divacky // Okay, now we need to adjust the PHI nodes and any branches from within the 500f22ef01cSRoman Divacky // region to go to the new header block instead of the old header block. 5013b0f4066SDimitry Andric if (NumPredsFromRegion) { 502f22ef01cSRoman Divacky PHINode *PN = cast<PHINode>(OldPred->begin()); 503f22ef01cSRoman Divacky // Loop over all of the predecessors of OldPred that are in the region, 504f22ef01cSRoman Divacky // changing them to branch to NewBB instead. 505f22ef01cSRoman Divacky for (unsigned i = 0, e = PN->getNumIncomingValues(); i != e; ++i) 5067ae0e2c9SDimitry Andric if (Blocks.count(PN->getIncomingBlock(i))) { 507f22ef01cSRoman Divacky TerminatorInst *TI = PN->getIncomingBlock(i)->getTerminator(); 508f22ef01cSRoman Divacky TI->replaceUsesOfWith(OldPred, NewBB); 509f22ef01cSRoman Divacky } 510f22ef01cSRoman Divacky 5113b0f4066SDimitry Andric // Okay, everything within the region is now branching to the right block, we 512f22ef01cSRoman Divacky // just have to update the PHI nodes now, inserting PHI nodes into NewBB. 51351690af2SDimitry Andric BasicBlock::iterator AfterPHIs; 514f22ef01cSRoman Divacky for (AfterPHIs = OldPred->begin(); isa<PHINode>(AfterPHIs); ++AfterPHIs) { 515f22ef01cSRoman Divacky PHINode *PN = cast<PHINode>(AfterPHIs); 516f22ef01cSRoman Divacky // Create a new PHI node in the new region, which has an incoming value 517f22ef01cSRoman Divacky // from OldPred of PN. 5183b0f4066SDimitry Andric PHINode *NewPN = PHINode::Create(PN->getType(), 1 + NumPredsFromRegion, 5197d523365SDimitry Andric PN->getName() + ".ce", &NewBB->front()); 52051690af2SDimitry Andric PN->replaceAllUsesWith(NewPN); 521f22ef01cSRoman Divacky NewPN->addIncoming(PN, OldPred); 522f22ef01cSRoman Divacky 523f22ef01cSRoman Divacky // Loop over all of the incoming value in PN, moving them to NewPN if they 524f22ef01cSRoman Divacky // are from the extracted region. 525f22ef01cSRoman Divacky for (unsigned i = 0; i != PN->getNumIncomingValues(); ++i) { 5267ae0e2c9SDimitry Andric if (Blocks.count(PN->getIncomingBlock(i))) { 527f22ef01cSRoman Divacky NewPN->addIncoming(PN->getIncomingValue(i), PN->getIncomingBlock(i)); 528f22ef01cSRoman Divacky PN->removeIncomingValue(i); 529f22ef01cSRoman Divacky --i; 530f22ef01cSRoman Divacky } 531f22ef01cSRoman Divacky } 532f22ef01cSRoman Divacky } 533f22ef01cSRoman Divacky } 534f22ef01cSRoman Divacky } 535f22ef01cSRoman Divacky 536f22ef01cSRoman Divacky void CodeExtractor::splitReturnBlocks() { 5373ca95b02SDimitry Andric for (BasicBlock *Block : Blocks) 5383ca95b02SDimitry Andric if (ReturnInst *RI = dyn_cast<ReturnInst>(Block->getTerminator())) { 5397d523365SDimitry Andric BasicBlock *New = 5403ca95b02SDimitry Andric Block->splitBasicBlock(RI->getIterator(), Block->getName() + ".ret"); 541f22ef01cSRoman Divacky if (DT) { 5422754fe60SDimitry Andric // Old dominates New. New node dominates all other nodes dominated 543f22ef01cSRoman Divacky // by Old. 5443ca95b02SDimitry Andric DomTreeNode *OldNode = DT->getNode(Block); 5453ca95b02SDimitry Andric SmallVector<DomTreeNode *, 8> Children(OldNode->begin(), 5463ca95b02SDimitry Andric OldNode->end()); 547f22ef01cSRoman Divacky 5483ca95b02SDimitry Andric DomTreeNode *NewNode = DT->addNewBlock(New, Block); 549f22ef01cSRoman Divacky 5503ca95b02SDimitry Andric for (DomTreeNode *I : Children) 5513ca95b02SDimitry Andric DT->changeImmediateDominator(I, NewNode); 552f22ef01cSRoman Divacky } 553f22ef01cSRoman Divacky } 554f22ef01cSRoman Divacky } 555f22ef01cSRoman Divacky 556f22ef01cSRoman Divacky /// constructFunction - make a function based on inputs and outputs, as follows: 557f22ef01cSRoman Divacky /// f(in0, ..., inN, out0, ..., outN) 5587ae0e2c9SDimitry Andric Function *CodeExtractor::constructFunction(const ValueSet &inputs, 5597ae0e2c9SDimitry Andric const ValueSet &outputs, 560f22ef01cSRoman Divacky BasicBlock *header, 561f22ef01cSRoman Divacky BasicBlock *newRootNode, 562f22ef01cSRoman Divacky BasicBlock *newHeader, 563f22ef01cSRoman Divacky Function *oldFunction, 564f22ef01cSRoman Divacky Module *M) { 565f22ef01cSRoman Divacky DEBUG(dbgs() << "inputs: " << inputs.size() << "\n"); 566f22ef01cSRoman Divacky DEBUG(dbgs() << "outputs: " << outputs.size() << "\n"); 567f22ef01cSRoman Divacky 568f22ef01cSRoman Divacky // This function returns unsigned, outputs will go back by reference. 569f22ef01cSRoman Divacky switch (NumExitBlocks) { 570f22ef01cSRoman Divacky case 0: 571f22ef01cSRoman Divacky case 1: RetTy = Type::getVoidTy(header->getContext()); break; 572f22ef01cSRoman Divacky case 2: RetTy = Type::getInt1Ty(header->getContext()); break; 573f22ef01cSRoman Divacky default: RetTy = Type::getInt16Ty(header->getContext()); break; 574f22ef01cSRoman Divacky } 575f22ef01cSRoman Divacky 57617a519f9SDimitry Andric std::vector<Type *> paramTy; 577f22ef01cSRoman Divacky 578f22ef01cSRoman Divacky // Add the types of the input values to the function's argument list 5793ca95b02SDimitry Andric for (Value *value : inputs) { 580f22ef01cSRoman Divacky DEBUG(dbgs() << "value used in func: " << *value << "\n"); 581f22ef01cSRoman Divacky paramTy.push_back(value->getType()); 582f22ef01cSRoman Divacky } 583f22ef01cSRoman Divacky 584f22ef01cSRoman Divacky // Add the types of the output values to the function's argument list. 5853ca95b02SDimitry Andric for (Value *output : outputs) { 5863ca95b02SDimitry Andric DEBUG(dbgs() << "instr used in func: " << *output << "\n"); 587f22ef01cSRoman Divacky if (AggregateArgs) 5883ca95b02SDimitry Andric paramTy.push_back(output->getType()); 589f22ef01cSRoman Divacky else 5903ca95b02SDimitry Andric paramTy.push_back(PointerType::getUnqual(output->getType())); 591f22ef01cSRoman Divacky } 592f22ef01cSRoman Divacky 5933ca95b02SDimitry Andric DEBUG({ 5943ca95b02SDimitry Andric dbgs() << "Function type: " << *RetTy << " f("; 5953ca95b02SDimitry Andric for (Type *i : paramTy) 5963ca95b02SDimitry Andric dbgs() << *i << ", "; 5973ca95b02SDimitry Andric dbgs() << ")\n"; 5983ca95b02SDimitry Andric }); 599f22ef01cSRoman Divacky 600ff0cc061SDimitry Andric StructType *StructTy; 601f22ef01cSRoman Divacky if (AggregateArgs && (inputs.size() + outputs.size() > 0)) { 602ff0cc061SDimitry Andric StructTy = StructType::get(M->getContext(), paramTy); 603f22ef01cSRoman Divacky paramTy.clear(); 604ff0cc061SDimitry Andric paramTy.push_back(PointerType::getUnqual(StructTy)); 605f22ef01cSRoman Divacky } 6066122f3e6SDimitry Andric FunctionType *funcType = 6072cab237bSDimitry Andric FunctionType::get(RetTy, paramTy, 6082cab237bSDimitry Andric AllowVarArgs && oldFunction->isVarArg()); 609f22ef01cSRoman Divacky 610f22ef01cSRoman Divacky // Create the new function 611f22ef01cSRoman Divacky Function *newFunction = Function::Create(funcType, 612f22ef01cSRoman Divacky GlobalValue::InternalLinkage, 613f22ef01cSRoman Divacky oldFunction->getName() + "_" + 614f22ef01cSRoman Divacky header->getName(), M); 615f22ef01cSRoman Divacky // If the old function is no-throw, so is the new one. 616f22ef01cSRoman Divacky if (oldFunction->doesNotThrow()) 6173861d79fSDimitry Andric newFunction->setDoesNotThrow(); 618f22ef01cSRoman Divacky 619d88c1a5aSDimitry Andric // Inherit the uwtable attribute if we need to. 620d88c1a5aSDimitry Andric if (oldFunction->hasUWTable()) 621d88c1a5aSDimitry Andric newFunction->setHasUWTable(); 622d88c1a5aSDimitry Andric 623d88c1a5aSDimitry Andric // Inherit all of the target dependent attributes. 624d88c1a5aSDimitry Andric // (e.g. If the extracted region contains a call to an x86.sse 625d88c1a5aSDimitry Andric // instruction we need to make sure that the extracted region has the 626d88c1a5aSDimitry Andric // "target-features" attribute allowing it to be lowered. 627d88c1a5aSDimitry Andric // FIXME: This should be changed to check to see if a specific 628d88c1a5aSDimitry Andric // attribute can not be inherited. 6297a7e6055SDimitry Andric AttrBuilder AB(oldFunction->getAttributes().getFnAttributes()); 6307a7e6055SDimitry Andric for (const auto &Attr : AB.td_attrs()) 631d88c1a5aSDimitry Andric newFunction->addFnAttr(Attr.first, Attr.second); 632d88c1a5aSDimitry Andric 633f22ef01cSRoman Divacky newFunction->getBasicBlockList().push_back(newRootNode); 634f22ef01cSRoman Divacky 635f22ef01cSRoman Divacky // Create an iterator to name all of the arguments we inserted. 636f22ef01cSRoman Divacky Function::arg_iterator AI = newFunction->arg_begin(); 637f22ef01cSRoman Divacky 638f22ef01cSRoman Divacky // Rewrite all users of the inputs in the extracted region to use the 639f22ef01cSRoman Divacky // arguments (or appropriate addressing into struct) instead. 640f22ef01cSRoman Divacky for (unsigned i = 0, e = inputs.size(); i != e; ++i) { 641f22ef01cSRoman Divacky Value *RewriteVal; 642f22ef01cSRoman Divacky if (AggregateArgs) { 643f22ef01cSRoman Divacky Value *Idx[2]; 644f22ef01cSRoman Divacky Idx[0] = Constant::getNullValue(Type::getInt32Ty(header->getContext())); 645f22ef01cSRoman Divacky Idx[1] = ConstantInt::get(Type::getInt32Ty(header->getContext()), i); 646f22ef01cSRoman Divacky TerminatorInst *TI = newFunction->begin()->getTerminator(); 647ff0cc061SDimitry Andric GetElementPtrInst *GEP = GetElementPtrInst::Create( 6487d523365SDimitry Andric StructTy, &*AI, Idx, "gep_" + inputs[i]->getName(), TI); 649f22ef01cSRoman Divacky RewriteVal = new LoadInst(GEP, "loadgep_" + inputs[i]->getName(), TI); 650f22ef01cSRoman Divacky } else 6517d523365SDimitry Andric RewriteVal = &*AI++; 652f22ef01cSRoman Divacky 65391bc56edSDimitry Andric std::vector<User *> Users(inputs[i]->user_begin(), inputs[i]->user_end()); 6543ca95b02SDimitry Andric for (User *use : Users) 6553ca95b02SDimitry Andric if (Instruction *inst = dyn_cast<Instruction>(use)) 6567ae0e2c9SDimitry Andric if (Blocks.count(inst->getParent())) 657f22ef01cSRoman Divacky inst->replaceUsesOfWith(inputs[i], RewriteVal); 658f22ef01cSRoman Divacky } 659f22ef01cSRoman Divacky 660f22ef01cSRoman Divacky // Set names for input and output arguments. 661f22ef01cSRoman Divacky if (!AggregateArgs) { 662f22ef01cSRoman Divacky AI = newFunction->arg_begin(); 663f22ef01cSRoman Divacky for (unsigned i = 0, e = inputs.size(); i != e; ++i, ++AI) 664f22ef01cSRoman Divacky AI->setName(inputs[i]->getName()); 665f22ef01cSRoman Divacky for (unsigned i = 0, e = outputs.size(); i != e; ++i, ++AI) 666f22ef01cSRoman Divacky AI->setName(outputs[i]->getName()+".out"); 667f22ef01cSRoman Divacky } 668f22ef01cSRoman Divacky 669f22ef01cSRoman Divacky // Rewrite branches to basic blocks outside of the loop to new dummy blocks 670f22ef01cSRoman Divacky // within the new function. This must be done before we lose track of which 671f22ef01cSRoman Divacky // blocks were originally in the code region. 67291bc56edSDimitry Andric std::vector<User *> Users(header->user_begin(), header->user_end()); 673f22ef01cSRoman Divacky for (unsigned i = 0, e = Users.size(); i != e; ++i) 674f22ef01cSRoman Divacky // The BasicBlock which contains the branch is not in the region 675f22ef01cSRoman Divacky // modify the branch target to a new block 676f22ef01cSRoman Divacky if (TerminatorInst *TI = dyn_cast<TerminatorInst>(Users[i])) 6777ae0e2c9SDimitry Andric if (!Blocks.count(TI->getParent()) && 678f22ef01cSRoman Divacky TI->getParent()->getParent() == oldFunction) 679f22ef01cSRoman Divacky TI->replaceUsesOfWith(header, newHeader); 680f22ef01cSRoman Divacky 681f22ef01cSRoman Divacky return newFunction; 682f22ef01cSRoman Divacky } 683f22ef01cSRoman Divacky 684f22ef01cSRoman Divacky /// emitCallAndSwitchStatement - This method sets up the caller side by adding 685f22ef01cSRoman Divacky /// the call instruction, splitting any PHI nodes in the header block as 686f22ef01cSRoman Divacky /// necessary. 687f22ef01cSRoman Divacky void CodeExtractor:: 688f22ef01cSRoman Divacky emitCallAndSwitchStatement(Function *newFunction, BasicBlock *codeReplacer, 6897ae0e2c9SDimitry Andric ValueSet &inputs, ValueSet &outputs) { 690f22ef01cSRoman Divacky // Emit a call to the new function, passing in: *pointer to struct (if 691f22ef01cSRoman Divacky // aggregating parameters), or plan inputs and allocated memory for outputs 692f22ef01cSRoman Divacky std::vector<Value *> params, StructValues, ReloadOutputs, Reloads; 693f22ef01cSRoman Divacky 6947a7e6055SDimitry Andric Module *M = newFunction->getParent(); 6957a7e6055SDimitry Andric LLVMContext &Context = M->getContext(); 6967a7e6055SDimitry Andric const DataLayout &DL = M->getDataLayout(); 697f22ef01cSRoman Divacky 698f22ef01cSRoman Divacky // Add inputs as params, or to be filled into the struct 6993ca95b02SDimitry Andric for (Value *input : inputs) 700f22ef01cSRoman Divacky if (AggregateArgs) 7013ca95b02SDimitry Andric StructValues.push_back(input); 702f22ef01cSRoman Divacky else 7033ca95b02SDimitry Andric params.push_back(input); 704f22ef01cSRoman Divacky 705f22ef01cSRoman Divacky // Create allocas for the outputs 7063ca95b02SDimitry Andric for (Value *output : outputs) { 707f22ef01cSRoman Divacky if (AggregateArgs) { 7083ca95b02SDimitry Andric StructValues.push_back(output); 709f22ef01cSRoman Divacky } else { 710f22ef01cSRoman Divacky AllocaInst *alloca = 7117a7e6055SDimitry Andric new AllocaInst(output->getType(), DL.getAllocaAddrSpace(), 7127a7e6055SDimitry Andric nullptr, output->getName() + ".loc", 7137d523365SDimitry Andric &codeReplacer->getParent()->front().front()); 714f22ef01cSRoman Divacky ReloadOutputs.push_back(alloca); 715f22ef01cSRoman Divacky params.push_back(alloca); 716f22ef01cSRoman Divacky } 717f22ef01cSRoman Divacky } 718f22ef01cSRoman Divacky 719ff0cc061SDimitry Andric StructType *StructArgTy = nullptr; 72091bc56edSDimitry Andric AllocaInst *Struct = nullptr; 721f22ef01cSRoman Divacky if (AggregateArgs && (inputs.size() + outputs.size() > 0)) { 72217a519f9SDimitry Andric std::vector<Type *> ArgTypes; 7237ae0e2c9SDimitry Andric for (ValueSet::iterator v = StructValues.begin(), 724f22ef01cSRoman Divacky ve = StructValues.end(); v != ve; ++v) 725f22ef01cSRoman Divacky ArgTypes.push_back((*v)->getType()); 726f22ef01cSRoman Divacky 727f22ef01cSRoman Divacky // Allocate a struct at the beginning of this function 728ff0cc061SDimitry Andric StructArgTy = StructType::get(newFunction->getContext(), ArgTypes); 7297a7e6055SDimitry Andric Struct = new AllocaInst(StructArgTy, DL.getAllocaAddrSpace(), nullptr, 7307a7e6055SDimitry Andric "structArg", 7317d523365SDimitry Andric &codeReplacer->getParent()->front().front()); 732f22ef01cSRoman Divacky params.push_back(Struct); 733f22ef01cSRoman Divacky 734f22ef01cSRoman Divacky for (unsigned i = 0, e = inputs.size(); i != e; ++i) { 735f22ef01cSRoman Divacky Value *Idx[2]; 736f22ef01cSRoman Divacky Idx[0] = Constant::getNullValue(Type::getInt32Ty(Context)); 737f22ef01cSRoman Divacky Idx[1] = ConstantInt::get(Type::getInt32Ty(Context), i); 738ff0cc061SDimitry Andric GetElementPtrInst *GEP = GetElementPtrInst::Create( 739ff0cc061SDimitry Andric StructArgTy, Struct, Idx, "gep_" + StructValues[i]->getName()); 740f22ef01cSRoman Divacky codeReplacer->getInstList().push_back(GEP); 741f22ef01cSRoman Divacky StoreInst *SI = new StoreInst(StructValues[i], GEP); 742f22ef01cSRoman Divacky codeReplacer->getInstList().push_back(SI); 743f22ef01cSRoman Divacky } 744f22ef01cSRoman Divacky } 745f22ef01cSRoman Divacky 746f22ef01cSRoman Divacky // Emit the call to the function 74717a519f9SDimitry Andric CallInst *call = CallInst::Create(newFunction, params, 748f22ef01cSRoman Divacky NumExitBlocks > 1 ? "targetBlock" : ""); 7492cab237bSDimitry Andric // Add debug location to the new call, if the original function has debug 7502cab237bSDimitry Andric // info. In that case, the terminator of the entry block of the extracted 7512cab237bSDimitry Andric // function contains the first debug location of the extracted function, 7522cab237bSDimitry Andric // set in extractCodeRegion. 7532cab237bSDimitry Andric if (codeReplacer->getParent()->getSubprogram()) { 7542cab237bSDimitry Andric if (auto DL = newFunction->getEntryBlock().getTerminator()->getDebugLoc()) 7552cab237bSDimitry Andric call->setDebugLoc(DL); 7562cab237bSDimitry Andric } 757f22ef01cSRoman Divacky codeReplacer->getInstList().push_back(call); 758f22ef01cSRoman Divacky 759f22ef01cSRoman Divacky Function::arg_iterator OutputArgBegin = newFunction->arg_begin(); 760f22ef01cSRoman Divacky unsigned FirstOut = inputs.size(); 761f22ef01cSRoman Divacky if (!AggregateArgs) 762f22ef01cSRoman Divacky std::advance(OutputArgBegin, inputs.size()); 763f22ef01cSRoman Divacky 7642cab237bSDimitry Andric // Reload the outputs passed in by reference. 7652cab237bSDimitry Andric Function::arg_iterator OAI = OutputArgBegin; 766f22ef01cSRoman Divacky for (unsigned i = 0, e = outputs.size(); i != e; ++i) { 76791bc56edSDimitry Andric Value *Output = nullptr; 768f22ef01cSRoman Divacky if (AggregateArgs) { 769f22ef01cSRoman Divacky Value *Idx[2]; 770f22ef01cSRoman Divacky Idx[0] = Constant::getNullValue(Type::getInt32Ty(Context)); 771f22ef01cSRoman Divacky Idx[1] = ConstantInt::get(Type::getInt32Ty(Context), FirstOut + i); 772ff0cc061SDimitry Andric GetElementPtrInst *GEP = GetElementPtrInst::Create( 773ff0cc061SDimitry Andric StructArgTy, Struct, Idx, "gep_reload_" + outputs[i]->getName()); 774f22ef01cSRoman Divacky codeReplacer->getInstList().push_back(GEP); 775f22ef01cSRoman Divacky Output = GEP; 776f22ef01cSRoman Divacky } else { 777f22ef01cSRoman Divacky Output = ReloadOutputs[i]; 778f22ef01cSRoman Divacky } 779f22ef01cSRoman Divacky LoadInst *load = new LoadInst(Output, outputs[i]->getName()+".reload"); 780f22ef01cSRoman Divacky Reloads.push_back(load); 781f22ef01cSRoman Divacky codeReplacer->getInstList().push_back(load); 78291bc56edSDimitry Andric std::vector<User *> Users(outputs[i]->user_begin(), outputs[i]->user_end()); 783f22ef01cSRoman Divacky for (unsigned u = 0, e = Users.size(); u != e; ++u) { 784f22ef01cSRoman Divacky Instruction *inst = cast<Instruction>(Users[u]); 7857ae0e2c9SDimitry Andric if (!Blocks.count(inst->getParent())) 786f22ef01cSRoman Divacky inst->replaceUsesOfWith(outputs[i], load); 787f22ef01cSRoman Divacky } 7882cab237bSDimitry Andric 7892cab237bSDimitry Andric // Store to argument right after the definition of output value. 7902cab237bSDimitry Andric auto *OutI = dyn_cast<Instruction>(outputs[i]); 7912cab237bSDimitry Andric if (!OutI) 7922cab237bSDimitry Andric continue; 7932cab237bSDimitry Andric // Find proper insertion point. 7942cab237bSDimitry Andric Instruction *InsertPt = OutI->getNextNode(); 7952cab237bSDimitry Andric // Let's assume that there is no other guy interleave non-PHI in PHIs. 7962cab237bSDimitry Andric if (isa<PHINode>(InsertPt)) 7972cab237bSDimitry Andric InsertPt = InsertPt->getParent()->getFirstNonPHI(); 7982cab237bSDimitry Andric 7992cab237bSDimitry Andric assert(OAI != newFunction->arg_end() && 8002cab237bSDimitry Andric "Number of output arguments should match " 8012cab237bSDimitry Andric "the amount of defined values"); 8022cab237bSDimitry Andric if (AggregateArgs) { 8032cab237bSDimitry Andric Value *Idx[2]; 8042cab237bSDimitry Andric Idx[0] = Constant::getNullValue(Type::getInt32Ty(Context)); 8052cab237bSDimitry Andric Idx[1] = ConstantInt::get(Type::getInt32Ty(Context), FirstOut + i); 8062cab237bSDimitry Andric GetElementPtrInst *GEP = GetElementPtrInst::Create( 8072cab237bSDimitry Andric StructArgTy, &*OAI, Idx, "gep_" + outputs[i]->getName(), InsertPt); 8082cab237bSDimitry Andric new StoreInst(outputs[i], GEP, InsertPt); 8092cab237bSDimitry Andric // Since there should be only one struct argument aggregating 8102cab237bSDimitry Andric // all the output values, we shouldn't increment OAI, which always 8112cab237bSDimitry Andric // points to the struct argument, in this case. 8122cab237bSDimitry Andric } else { 8132cab237bSDimitry Andric new StoreInst(outputs[i], &*OAI, InsertPt); 8142cab237bSDimitry Andric ++OAI; 8152cab237bSDimitry Andric } 816f22ef01cSRoman Divacky } 817f22ef01cSRoman Divacky 818f22ef01cSRoman Divacky // Now we can emit a switch statement using the call as a value. 819f22ef01cSRoman Divacky SwitchInst *TheSwitch = 820f22ef01cSRoman Divacky SwitchInst::Create(Constant::getNullValue(Type::getInt16Ty(Context)), 821f22ef01cSRoman Divacky codeReplacer, 0, codeReplacer); 822f22ef01cSRoman Divacky 823f22ef01cSRoman Divacky // Since there may be multiple exits from the original region, make the new 824f22ef01cSRoman Divacky // function return an unsigned, switch on that number. This loop iterates 825f22ef01cSRoman Divacky // over all of the blocks in the extracted region, updating any terminator 826f22ef01cSRoman Divacky // instructions in the to-be-extracted region that branch to blocks that are 827f22ef01cSRoman Divacky // not in the region to be extracted. 828f22ef01cSRoman Divacky std::map<BasicBlock *, BasicBlock *> ExitBlockMap; 829f22ef01cSRoman Divacky 830f22ef01cSRoman Divacky unsigned switchVal = 0; 8313ca95b02SDimitry Andric for (BasicBlock *Block : Blocks) { 8323ca95b02SDimitry Andric TerminatorInst *TI = Block->getTerminator(); 833f22ef01cSRoman Divacky for (unsigned i = 0, e = TI->getNumSuccessors(); i != e; ++i) 8347ae0e2c9SDimitry Andric if (!Blocks.count(TI->getSuccessor(i))) { 835f22ef01cSRoman Divacky BasicBlock *OldTarget = TI->getSuccessor(i); 836f22ef01cSRoman Divacky // add a new basic block which returns the appropriate value 837f22ef01cSRoman Divacky BasicBlock *&NewTarget = ExitBlockMap[OldTarget]; 838f22ef01cSRoman Divacky if (!NewTarget) { 839f22ef01cSRoman Divacky // If we don't already have an exit stub for this non-extracted 840f22ef01cSRoman Divacky // destination, create one now! 841f22ef01cSRoman Divacky NewTarget = BasicBlock::Create(Context, 842f22ef01cSRoman Divacky OldTarget->getName() + ".exitStub", 843f22ef01cSRoman Divacky newFunction); 844f22ef01cSRoman Divacky unsigned SuccNum = switchVal++; 845f22ef01cSRoman Divacky 84691bc56edSDimitry Andric Value *brVal = nullptr; 847f22ef01cSRoman Divacky switch (NumExitBlocks) { 848f22ef01cSRoman Divacky case 0: 849f22ef01cSRoman Divacky case 1: break; // No value needed. 850f22ef01cSRoman Divacky case 2: // Conditional branch, return a bool 851f22ef01cSRoman Divacky brVal = ConstantInt::get(Type::getInt1Ty(Context), !SuccNum); 852f22ef01cSRoman Divacky break; 853f22ef01cSRoman Divacky default: 854f22ef01cSRoman Divacky brVal = ConstantInt::get(Type::getInt16Ty(Context), SuccNum); 855f22ef01cSRoman Divacky break; 856f22ef01cSRoman Divacky } 857f22ef01cSRoman Divacky 8582cab237bSDimitry Andric ReturnInst::Create(Context, brVal, NewTarget); 859f22ef01cSRoman Divacky 860f22ef01cSRoman Divacky // Update the switch instruction. 861f22ef01cSRoman Divacky TheSwitch->addCase(ConstantInt::get(Type::getInt16Ty(Context), 862f22ef01cSRoman Divacky SuccNum), 863f22ef01cSRoman Divacky OldTarget); 864f22ef01cSRoman Divacky } 865f22ef01cSRoman Divacky 866f22ef01cSRoman Divacky // rewrite the original branch instruction with this new target 867f22ef01cSRoman Divacky TI->setSuccessor(i, NewTarget); 868f22ef01cSRoman Divacky } 869f22ef01cSRoman Divacky } 870f22ef01cSRoman Divacky 871f22ef01cSRoman Divacky // Now that we've done the deed, simplify the switch instruction. 8726122f3e6SDimitry Andric Type *OldFnRetTy = TheSwitch->getParent()->getParent()->getReturnType(); 873f22ef01cSRoman Divacky switch (NumExitBlocks) { 874f22ef01cSRoman Divacky case 0: 875f22ef01cSRoman Divacky // There are no successors (the block containing the switch itself), which 876f22ef01cSRoman Divacky // means that previously this was the last part of the function, and hence 877f22ef01cSRoman Divacky // this should be rewritten as a `ret' 878f22ef01cSRoman Divacky 879f22ef01cSRoman Divacky // Check if the function should return a value 880f22ef01cSRoman Divacky if (OldFnRetTy->isVoidTy()) { 88191bc56edSDimitry Andric ReturnInst::Create(Context, nullptr, TheSwitch); // Return void 882f22ef01cSRoman Divacky } else if (OldFnRetTy == TheSwitch->getCondition()->getType()) { 883f22ef01cSRoman Divacky // return what we have 884f22ef01cSRoman Divacky ReturnInst::Create(Context, TheSwitch->getCondition(), TheSwitch); 885f22ef01cSRoman Divacky } else { 886f22ef01cSRoman Divacky // Otherwise we must have code extracted an unwind or something, just 887f22ef01cSRoman Divacky // return whatever we want. 888f22ef01cSRoman Divacky ReturnInst::Create(Context, 889f22ef01cSRoman Divacky Constant::getNullValue(OldFnRetTy), TheSwitch); 890f22ef01cSRoman Divacky } 891f22ef01cSRoman Divacky 892f22ef01cSRoman Divacky TheSwitch->eraseFromParent(); 893f22ef01cSRoman Divacky break; 894f22ef01cSRoman Divacky case 1: 895f22ef01cSRoman Divacky // Only a single destination, change the switch into an unconditional 896f22ef01cSRoman Divacky // branch. 897f22ef01cSRoman Divacky BranchInst::Create(TheSwitch->getSuccessor(1), TheSwitch); 898f22ef01cSRoman Divacky TheSwitch->eraseFromParent(); 899f22ef01cSRoman Divacky break; 900f22ef01cSRoman Divacky case 2: 901f22ef01cSRoman Divacky BranchInst::Create(TheSwitch->getSuccessor(1), TheSwitch->getSuccessor(2), 902f22ef01cSRoman Divacky call, TheSwitch); 903f22ef01cSRoman Divacky TheSwitch->eraseFromParent(); 904f22ef01cSRoman Divacky break; 905f22ef01cSRoman Divacky default: 906f22ef01cSRoman Divacky // Otherwise, make the default destination of the switch instruction be one 907f22ef01cSRoman Divacky // of the other successors. 908dff0c46cSDimitry Andric TheSwitch->setCondition(call); 909dff0c46cSDimitry Andric TheSwitch->setDefaultDest(TheSwitch->getSuccessor(NumExitBlocks)); 910dff0c46cSDimitry Andric // Remove redundant case 911f785676fSDimitry Andric TheSwitch->removeCase(SwitchInst::CaseIt(TheSwitch, NumExitBlocks-1)); 912f22ef01cSRoman Divacky break; 913f22ef01cSRoman Divacky } 914f22ef01cSRoman Divacky } 915f22ef01cSRoman Divacky 916f22ef01cSRoman Divacky void CodeExtractor::moveCodeToFunction(Function *newFunction) { 9177ae0e2c9SDimitry Andric Function *oldFunc = (*Blocks.begin())->getParent(); 918f22ef01cSRoman Divacky Function::BasicBlockListType &oldBlocks = oldFunc->getBasicBlockList(); 919f22ef01cSRoman Divacky Function::BasicBlockListType &newBlocks = newFunction->getBasicBlockList(); 920f22ef01cSRoman Divacky 9213ca95b02SDimitry Andric for (BasicBlock *Block : Blocks) { 922f22ef01cSRoman Divacky // Delete the basic block from the old function, and the list of blocks 9233ca95b02SDimitry Andric oldBlocks.remove(Block); 924f22ef01cSRoman Divacky 925f22ef01cSRoman Divacky // Insert this basic block into the new function 9263ca95b02SDimitry Andric newBlocks.push_back(Block); 927f22ef01cSRoman Divacky } 928f22ef01cSRoman Divacky } 929f22ef01cSRoman Divacky 930d88c1a5aSDimitry Andric void CodeExtractor::calculateNewCallTerminatorWeights( 931d88c1a5aSDimitry Andric BasicBlock *CodeReplacer, 932d88c1a5aSDimitry Andric DenseMap<BasicBlock *, BlockFrequency> &ExitWeights, 933d88c1a5aSDimitry Andric BranchProbabilityInfo *BPI) { 9342cab237bSDimitry Andric using Distribution = BlockFrequencyInfoImplBase::Distribution; 9352cab237bSDimitry Andric using BlockNode = BlockFrequencyInfoImplBase::BlockNode; 936d88c1a5aSDimitry Andric 937d88c1a5aSDimitry Andric // Update the branch weights for the exit block. 938d88c1a5aSDimitry Andric TerminatorInst *TI = CodeReplacer->getTerminator(); 939d88c1a5aSDimitry Andric SmallVector<unsigned, 8> BranchWeights(TI->getNumSuccessors(), 0); 940d88c1a5aSDimitry Andric 941d88c1a5aSDimitry Andric // Block Frequency distribution with dummy node. 942d88c1a5aSDimitry Andric Distribution BranchDist; 943d88c1a5aSDimitry Andric 944d88c1a5aSDimitry Andric // Add each of the frequencies of the successors. 945d88c1a5aSDimitry Andric for (unsigned i = 0, e = TI->getNumSuccessors(); i < e; ++i) { 946d88c1a5aSDimitry Andric BlockNode ExitNode(i); 947d88c1a5aSDimitry Andric uint64_t ExitFreq = ExitWeights[TI->getSuccessor(i)].getFrequency(); 948d88c1a5aSDimitry Andric if (ExitFreq != 0) 949d88c1a5aSDimitry Andric BranchDist.addExit(ExitNode, ExitFreq); 950d88c1a5aSDimitry Andric else 951d88c1a5aSDimitry Andric BPI->setEdgeProbability(CodeReplacer, i, BranchProbability::getZero()); 952d88c1a5aSDimitry Andric } 953d88c1a5aSDimitry Andric 954d88c1a5aSDimitry Andric // Check for no total weight. 955d88c1a5aSDimitry Andric if (BranchDist.Total == 0) 956d88c1a5aSDimitry Andric return; 957d88c1a5aSDimitry Andric 958d88c1a5aSDimitry Andric // Normalize the distribution so that they can fit in unsigned. 959d88c1a5aSDimitry Andric BranchDist.normalize(); 960d88c1a5aSDimitry Andric 961d88c1a5aSDimitry Andric // Create normalized branch weights and set the metadata. 962d88c1a5aSDimitry Andric for (unsigned I = 0, E = BranchDist.Weights.size(); I < E; ++I) { 963d88c1a5aSDimitry Andric const auto &Weight = BranchDist.Weights[I]; 964d88c1a5aSDimitry Andric 965d88c1a5aSDimitry Andric // Get the weight and update the current BFI. 966d88c1a5aSDimitry Andric BranchWeights[Weight.TargetNode.Index] = Weight.Amount; 967d88c1a5aSDimitry Andric BranchProbability BP(Weight.Amount, BranchDist.Total); 968d88c1a5aSDimitry Andric BPI->setEdgeProbability(CodeReplacer, Weight.TargetNode.Index, BP); 969d88c1a5aSDimitry Andric } 970d88c1a5aSDimitry Andric TI->setMetadata( 971d88c1a5aSDimitry Andric LLVMContext::MD_prof, 972d88c1a5aSDimitry Andric MDBuilder(TI->getContext()).createBranchWeights(BranchWeights)); 973d88c1a5aSDimitry Andric } 974d88c1a5aSDimitry Andric 9757ae0e2c9SDimitry Andric Function *CodeExtractor::extractCodeRegion() { 9767ae0e2c9SDimitry Andric if (!isEligible()) 97791bc56edSDimitry Andric return nullptr; 978f22ef01cSRoman Divacky 979f22ef01cSRoman Divacky // Assumption: this is a single-entry code region, and the header is the first 980f22ef01cSRoman Divacky // block in the region. 9817ae0e2c9SDimitry Andric BasicBlock *header = *Blocks.begin(); 9822cab237bSDimitry Andric Function *oldFunction = header->getParent(); 9832cab237bSDimitry Andric 9842cab237bSDimitry Andric // For functions with varargs, check that varargs handling is only done in the 9852cab237bSDimitry Andric // outlined function, i.e vastart and vaend are only used in outlined blocks. 9862cab237bSDimitry Andric if (AllowVarArgs && oldFunction->getFunctionType()->isVarArg()) { 9872cab237bSDimitry Andric auto containsVarArgIntrinsic = [](Instruction &I) { 9882cab237bSDimitry Andric if (const CallInst *CI = dyn_cast<CallInst>(&I)) 9892cab237bSDimitry Andric if (const Function *F = CI->getCalledFunction()) 9902cab237bSDimitry Andric return F->getIntrinsicID() == Intrinsic::vastart || 9912cab237bSDimitry Andric F->getIntrinsicID() == Intrinsic::vaend; 9922cab237bSDimitry Andric return false; 9932cab237bSDimitry Andric }; 9942cab237bSDimitry Andric 9952cab237bSDimitry Andric for (auto &BB : *oldFunction) { 9962cab237bSDimitry Andric if (Blocks.count(&BB)) 9972cab237bSDimitry Andric continue; 9982cab237bSDimitry Andric if (llvm::any_of(BB, containsVarArgIntrinsic)) 9992cab237bSDimitry Andric return nullptr; 10002cab237bSDimitry Andric } 10012cab237bSDimitry Andric } 10022cab237bSDimitry Andric ValueSet inputs, outputs, SinkingCands, HoistingCands; 10032cab237bSDimitry Andric BasicBlock *CommonExit = nullptr; 1004f22ef01cSRoman Divacky 1005d88c1a5aSDimitry Andric // Calculate the entry frequency of the new function before we change the root 1006d88c1a5aSDimitry Andric // block. 1007d88c1a5aSDimitry Andric BlockFrequency EntryFreq; 1008d88c1a5aSDimitry Andric if (BFI) { 1009d88c1a5aSDimitry Andric assert(BPI && "Both BPI and BFI are required to preserve profile info"); 1010d88c1a5aSDimitry Andric for (BasicBlock *Pred : predecessors(header)) { 1011d88c1a5aSDimitry Andric if (Blocks.count(Pred)) 1012d88c1a5aSDimitry Andric continue; 1013d88c1a5aSDimitry Andric EntryFreq += 1014d88c1a5aSDimitry Andric BFI->getBlockFreq(Pred) * BPI->getEdgeProbability(Pred, header); 1015d88c1a5aSDimitry Andric } 1016d88c1a5aSDimitry Andric } 1017d88c1a5aSDimitry Andric 1018f22ef01cSRoman Divacky // If we have to split PHI nodes or the entry block, do so now. 1019f22ef01cSRoman Divacky severSplitPHINodes(header); 1020f22ef01cSRoman Divacky 1021f22ef01cSRoman Divacky // If we have any return instructions in the region, split those blocks so 1022f22ef01cSRoman Divacky // that the return is not in the region. 1023f22ef01cSRoman Divacky splitReturnBlocks(); 1024f22ef01cSRoman Divacky 1025f22ef01cSRoman Divacky // This takes place of the original loop 1026f22ef01cSRoman Divacky BasicBlock *codeReplacer = BasicBlock::Create(header->getContext(), 1027f22ef01cSRoman Divacky "codeRepl", oldFunction, 1028f22ef01cSRoman Divacky header); 1029f22ef01cSRoman Divacky 1030f22ef01cSRoman Divacky // The new function needs a root node because other nodes can branch to the 1031f22ef01cSRoman Divacky // head of the region, but the entry node of a function cannot have preds. 1032f22ef01cSRoman Divacky BasicBlock *newFuncRoot = BasicBlock::Create(header->getContext(), 1033f22ef01cSRoman Divacky "newFuncRoot"); 10342cab237bSDimitry Andric auto *BranchI = BranchInst::Create(header); 10352cab237bSDimitry Andric // If the original function has debug info, we have to add a debug location 10362cab237bSDimitry Andric // to the new branch instruction from the artificial entry block. 10372cab237bSDimitry Andric // We use the debug location of the first instruction in the extracted 10382cab237bSDimitry Andric // blocks, as there is no other equivalent line in the source code. 10392cab237bSDimitry Andric if (oldFunction->getSubprogram()) { 10402cab237bSDimitry Andric any_of(Blocks, [&BranchI](const BasicBlock *BB) { 10412cab237bSDimitry Andric return any_of(*BB, [&BranchI](const Instruction &I) { 10422cab237bSDimitry Andric if (!I.getDebugLoc()) 10432cab237bSDimitry Andric return false; 10442cab237bSDimitry Andric BranchI->setDebugLoc(I.getDebugLoc()); 10452cab237bSDimitry Andric return true; 10462cab237bSDimitry Andric }); 10472cab237bSDimitry Andric }); 10482cab237bSDimitry Andric } 10492cab237bSDimitry Andric newFuncRoot->getInstList().push_back(BranchI); 1050f22ef01cSRoman Divacky 105124d58133SDimitry Andric findAllocas(SinkingCands, HoistingCands, CommonExit); 105224d58133SDimitry Andric assert(HoistingCands.empty() || CommonExit); 1053f9448bf3SDimitry Andric 1054f22ef01cSRoman Divacky // Find inputs to, outputs from the code region. 1055f9448bf3SDimitry Andric findInputsOutputs(inputs, outputs, SinkingCands); 1056f9448bf3SDimitry Andric 1057f9448bf3SDimitry Andric // Now sink all instructions which only have non-phi uses inside the region 1058f9448bf3SDimitry Andric for (auto *II : SinkingCands) 1059f9448bf3SDimitry Andric cast<Instruction>(II)->moveBefore(*newFuncRoot, 1060f9448bf3SDimitry Andric newFuncRoot->getFirstInsertionPt()); 1061f22ef01cSRoman Divacky 106224d58133SDimitry Andric if (!HoistingCands.empty()) { 106324d58133SDimitry Andric auto *HoistToBlock = findOrCreateBlockForHoisting(CommonExit); 106424d58133SDimitry Andric Instruction *TI = HoistToBlock->getTerminator(); 106524d58133SDimitry Andric for (auto *II : HoistingCands) 106624d58133SDimitry Andric cast<Instruction>(II)->moveBefore(TI); 106724d58133SDimitry Andric } 106824d58133SDimitry Andric 1069d88c1a5aSDimitry Andric // Calculate the exit blocks for the extracted region and the total exit 1070d88c1a5aSDimitry Andric // weights for each of those blocks. 1071d88c1a5aSDimitry Andric DenseMap<BasicBlock *, BlockFrequency> ExitWeights; 10727ae0e2c9SDimitry Andric SmallPtrSet<BasicBlock *, 1> ExitBlocks; 1073d88c1a5aSDimitry Andric for (BasicBlock *Block : Blocks) { 10743ca95b02SDimitry Andric for (succ_iterator SI = succ_begin(Block), SE = succ_end(Block); SI != SE; 1075d88c1a5aSDimitry Andric ++SI) { 1076d88c1a5aSDimitry Andric if (!Blocks.count(*SI)) { 1077d88c1a5aSDimitry Andric // Update the branch weight for this successor. 1078d88c1a5aSDimitry Andric if (BFI) { 1079d88c1a5aSDimitry Andric BlockFrequency &BF = ExitWeights[*SI]; 1080d88c1a5aSDimitry Andric BF += BFI->getBlockFreq(Block) * BPI->getEdgeProbability(Block, *SI); 1081d88c1a5aSDimitry Andric } 10827ae0e2c9SDimitry Andric ExitBlocks.insert(*SI); 1083d88c1a5aSDimitry Andric } 1084d88c1a5aSDimitry Andric } 1085d88c1a5aSDimitry Andric } 10867ae0e2c9SDimitry Andric NumExitBlocks = ExitBlocks.size(); 10877ae0e2c9SDimitry Andric 1088f22ef01cSRoman Divacky // Construct new function based on inputs/outputs & add allocas for all defs. 1089f22ef01cSRoman Divacky Function *newFunction = constructFunction(inputs, outputs, header, 1090f22ef01cSRoman Divacky newFuncRoot, 1091f22ef01cSRoman Divacky codeReplacer, oldFunction, 1092f22ef01cSRoman Divacky oldFunction->getParent()); 1093f22ef01cSRoman Divacky 1094d88c1a5aSDimitry Andric // Update the entry count of the function. 1095d88c1a5aSDimitry Andric if (BFI) { 1096d88c1a5aSDimitry Andric Optional<uint64_t> EntryCount = 1097d88c1a5aSDimitry Andric BFI->getProfileCountFromFreq(EntryFreq.getFrequency()); 1098d88c1a5aSDimitry Andric if (EntryCount.hasValue()) 1099d88c1a5aSDimitry Andric newFunction->setEntryCount(EntryCount.getValue()); 1100d88c1a5aSDimitry Andric BFI->setBlockFreq(codeReplacer, EntryFreq.getFrequency()); 1101d88c1a5aSDimitry Andric } 1102d88c1a5aSDimitry Andric 1103f22ef01cSRoman Divacky emitCallAndSwitchStatement(newFunction, codeReplacer, inputs, outputs); 1104f22ef01cSRoman Divacky 1105f22ef01cSRoman Divacky moveCodeToFunction(newFunction); 1106f22ef01cSRoman Divacky 1107d88c1a5aSDimitry Andric // Update the branch weights for the exit block. 1108d88c1a5aSDimitry Andric if (BFI && NumExitBlocks > 1) 1109d88c1a5aSDimitry Andric calculateNewCallTerminatorWeights(codeReplacer, ExitWeights, BPI); 1110d88c1a5aSDimitry Andric 1111f22ef01cSRoman Divacky // Loop over all of the PHI nodes in the header block, and change any 1112f22ef01cSRoman Divacky // references to the old incoming edge to be the new incoming edge. 1113f22ef01cSRoman Divacky for (BasicBlock::iterator I = header->begin(); isa<PHINode>(I); ++I) { 1114f22ef01cSRoman Divacky PHINode *PN = cast<PHINode>(I); 1115f22ef01cSRoman Divacky for (unsigned i = 0, e = PN->getNumIncomingValues(); i != e; ++i) 11167ae0e2c9SDimitry Andric if (!Blocks.count(PN->getIncomingBlock(i))) 1117f22ef01cSRoman Divacky PN->setIncomingBlock(i, newFuncRoot); 1118f22ef01cSRoman Divacky } 1119f22ef01cSRoman Divacky 1120f22ef01cSRoman Divacky // Look at all successors of the codeReplacer block. If any of these blocks 1121f22ef01cSRoman Divacky // had PHI nodes in them, we need to update the "from" block to be the code 1122f22ef01cSRoman Divacky // replacer, not the original block in the extracted region. 1123f22ef01cSRoman Divacky std::vector<BasicBlock *> Succs(succ_begin(codeReplacer), 1124f22ef01cSRoman Divacky succ_end(codeReplacer)); 1125f22ef01cSRoman Divacky for (unsigned i = 0, e = Succs.size(); i != e; ++i) 1126f22ef01cSRoman Divacky for (BasicBlock::iterator I = Succs[i]->begin(); isa<PHINode>(I); ++I) { 1127f22ef01cSRoman Divacky PHINode *PN = cast<PHINode>(I); 1128f22ef01cSRoman Divacky std::set<BasicBlock*> ProcessedPreds; 1129f22ef01cSRoman Divacky for (unsigned i = 0, e = PN->getNumIncomingValues(); i != e; ++i) 11307ae0e2c9SDimitry Andric if (Blocks.count(PN->getIncomingBlock(i))) { 1131f22ef01cSRoman Divacky if (ProcessedPreds.insert(PN->getIncomingBlock(i)).second) 1132f22ef01cSRoman Divacky PN->setIncomingBlock(i, codeReplacer); 1133f22ef01cSRoman Divacky else { 1134f22ef01cSRoman Divacky // There were multiple entries in the PHI for this block, now there 1135f22ef01cSRoman Divacky // is only one, so remove the duplicated entries. 1136f22ef01cSRoman Divacky PN->removeIncomingValue(i, false); 1137f22ef01cSRoman Divacky --i; --e; 1138f22ef01cSRoman Divacky } 1139f22ef01cSRoman Divacky } 1140f22ef01cSRoman Divacky } 1141f22ef01cSRoman Divacky 1142f22ef01cSRoman Divacky DEBUG(if (verifyFunction(*newFunction)) 1143f22ef01cSRoman Divacky report_fatal_error("verifyFunction failed!")); 1144f22ef01cSRoman Divacky return newFunction; 1145f22ef01cSRoman Divacky } 1146