10b57cec5SDimitry Andric //===- CodeExtractor.cpp - Pull code region into a new function -----------===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric // 90b57cec5SDimitry Andric // This file implements the interface to tear out a code region, such as an 100b57cec5SDimitry Andric // individual loop or a parallel section, into a new function, replacing it with 110b57cec5SDimitry Andric // a call to the new function. 120b57cec5SDimitry Andric // 130b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 140b57cec5SDimitry Andric 150b57cec5SDimitry Andric #include "llvm/Transforms/Utils/CodeExtractor.h" 160b57cec5SDimitry Andric #include "llvm/ADT/ArrayRef.h" 170b57cec5SDimitry Andric #include "llvm/ADT/DenseMap.h" 180b57cec5SDimitry Andric #include "llvm/ADT/STLExtras.h" 190b57cec5SDimitry Andric #include "llvm/ADT/SetVector.h" 200b57cec5SDimitry Andric #include "llvm/ADT/SmallPtrSet.h" 210b57cec5SDimitry Andric #include "llvm/ADT/SmallVector.h" 220b57cec5SDimitry Andric #include "llvm/Analysis/AssumptionCache.h" 230b57cec5SDimitry Andric #include "llvm/Analysis/BlockFrequencyInfo.h" 240b57cec5SDimitry Andric #include "llvm/Analysis/BlockFrequencyInfoImpl.h" 250b57cec5SDimitry Andric #include "llvm/Analysis/BranchProbabilityInfo.h" 260b57cec5SDimitry Andric #include "llvm/Analysis/LoopInfo.h" 270b57cec5SDimitry Andric #include "llvm/IR/Argument.h" 280b57cec5SDimitry Andric #include "llvm/IR/Attributes.h" 290b57cec5SDimitry Andric #include "llvm/IR/BasicBlock.h" 300b57cec5SDimitry Andric #include "llvm/IR/CFG.h" 310b57cec5SDimitry Andric #include "llvm/IR/Constant.h" 320b57cec5SDimitry Andric #include "llvm/IR/Constants.h" 335ffd83dbSDimitry Andric #include "llvm/IR/DIBuilder.h" 340b57cec5SDimitry Andric #include "llvm/IR/DataLayout.h" 351fd87a68SDimitry Andric #include "llvm/IR/DebugInfo.h" 365ffd83dbSDimitry Andric #include "llvm/IR/DebugInfoMetadata.h" 370b57cec5SDimitry Andric #include "llvm/IR/DerivedTypes.h" 380b57cec5SDimitry Andric #include "llvm/IR/Dominators.h" 390b57cec5SDimitry Andric #include "llvm/IR/Function.h" 400b57cec5SDimitry Andric #include "llvm/IR/GlobalValue.h" 415ffd83dbSDimitry Andric #include "llvm/IR/InstIterator.h" 420b57cec5SDimitry Andric #include "llvm/IR/InstrTypes.h" 430b57cec5SDimitry Andric #include "llvm/IR/Instruction.h" 440b57cec5SDimitry Andric #include "llvm/IR/Instructions.h" 450b57cec5SDimitry Andric #include "llvm/IR/IntrinsicInst.h" 460b57cec5SDimitry Andric #include "llvm/IR/Intrinsics.h" 470b57cec5SDimitry Andric #include "llvm/IR/LLVMContext.h" 480b57cec5SDimitry Andric #include "llvm/IR/MDBuilder.h" 490b57cec5SDimitry Andric #include "llvm/IR/Module.h" 500b57cec5SDimitry Andric #include "llvm/IR/PatternMatch.h" 510b57cec5SDimitry Andric #include "llvm/IR/Type.h" 520b57cec5SDimitry Andric #include "llvm/IR/User.h" 530b57cec5SDimitry Andric #include "llvm/IR/Value.h" 540b57cec5SDimitry Andric #include "llvm/IR/Verifier.h" 550b57cec5SDimitry Andric #include "llvm/Support/BlockFrequency.h" 560b57cec5SDimitry Andric #include "llvm/Support/BranchProbability.h" 570b57cec5SDimitry Andric #include "llvm/Support/Casting.h" 580b57cec5SDimitry Andric #include "llvm/Support/CommandLine.h" 590b57cec5SDimitry Andric #include "llvm/Support/Debug.h" 600b57cec5SDimitry Andric #include "llvm/Support/ErrorHandling.h" 610b57cec5SDimitry Andric #include "llvm/Support/raw_ostream.h" 620b57cec5SDimitry Andric #include "llvm/Transforms/Utils/BasicBlockUtils.h" 630b57cec5SDimitry Andric #include <cassert> 640b57cec5SDimitry Andric #include <cstdint> 650b57cec5SDimitry Andric #include <iterator> 660b57cec5SDimitry Andric #include <map> 670b57cec5SDimitry Andric #include <utility> 680b57cec5SDimitry Andric #include <vector> 690b57cec5SDimitry Andric 700b57cec5SDimitry Andric using namespace llvm; 710b57cec5SDimitry Andric using namespace llvm::PatternMatch; 720b57cec5SDimitry Andric using ProfileCount = Function::ProfileCount; 730b57cec5SDimitry Andric 740b57cec5SDimitry Andric #define DEBUG_TYPE "code-extractor" 750b57cec5SDimitry Andric 760b57cec5SDimitry Andric // Provide a command-line option to aggregate function arguments into a struct 770b57cec5SDimitry Andric // for functions produced by the code extractor. This is useful when converting 780b57cec5SDimitry Andric // extracted functions to pthread-based code, as only one argument (void*) can 790b57cec5SDimitry Andric // be passed in to pthread_create(). 800b57cec5SDimitry Andric static cl::opt<bool> 810b57cec5SDimitry Andric AggregateArgsOpt("aggregate-extracted-args", cl::Hidden, 820b57cec5SDimitry Andric cl::desc("Aggregate arguments to code-extracted functions")); 830b57cec5SDimitry Andric 840b57cec5SDimitry Andric /// Test whether a block is valid for extraction. 850b57cec5SDimitry Andric static bool isBlockValidForExtraction(const BasicBlock &BB, 860b57cec5SDimitry Andric const SetVector<BasicBlock *> &Result, 870b57cec5SDimitry Andric bool AllowVarArgs, bool AllowAlloca) { 880b57cec5SDimitry Andric // taking the address of a basic block moved to another function is illegal 890b57cec5SDimitry Andric if (BB.hasAddressTaken()) 900b57cec5SDimitry Andric return false; 910b57cec5SDimitry Andric 920b57cec5SDimitry Andric // don't hoist code that uses another basicblock address, as it's likely to 930b57cec5SDimitry Andric // lead to unexpected behavior, like cross-function jumps 940b57cec5SDimitry Andric SmallPtrSet<User const *, 16> Visited; 950b57cec5SDimitry Andric SmallVector<User const *, 16> ToVisit; 960b57cec5SDimitry Andric 970b57cec5SDimitry Andric for (Instruction const &Inst : BB) 980b57cec5SDimitry Andric ToVisit.push_back(&Inst); 990b57cec5SDimitry Andric 1000b57cec5SDimitry Andric while (!ToVisit.empty()) { 1010b57cec5SDimitry Andric User const *Curr = ToVisit.pop_back_val(); 1020b57cec5SDimitry Andric if (!Visited.insert(Curr).second) 1030b57cec5SDimitry Andric continue; 1040b57cec5SDimitry Andric if (isa<BlockAddress const>(Curr)) 1050b57cec5SDimitry Andric return false; // even a reference to self is likely to be not compatible 1060b57cec5SDimitry Andric 1070b57cec5SDimitry Andric if (isa<Instruction>(Curr) && cast<Instruction>(Curr)->getParent() != &BB) 1080b57cec5SDimitry Andric continue; 1090b57cec5SDimitry Andric 1100b57cec5SDimitry Andric for (auto const &U : Curr->operands()) { 1110b57cec5SDimitry Andric if (auto *UU = dyn_cast<User>(U)) 1120b57cec5SDimitry Andric ToVisit.push_back(UU); 1130b57cec5SDimitry Andric } 1140b57cec5SDimitry Andric } 1150b57cec5SDimitry Andric 1160b57cec5SDimitry Andric // If explicitly requested, allow vastart and alloca. For invoke instructions 1170b57cec5SDimitry Andric // verify that extraction is valid. 1180b57cec5SDimitry Andric for (BasicBlock::const_iterator I = BB.begin(), E = BB.end(); I != E; ++I) { 1190b57cec5SDimitry Andric if (isa<AllocaInst>(I)) { 1200b57cec5SDimitry Andric if (!AllowAlloca) 1210b57cec5SDimitry Andric return false; 1220b57cec5SDimitry Andric continue; 1230b57cec5SDimitry Andric } 1240b57cec5SDimitry Andric 1250b57cec5SDimitry Andric if (const auto *II = dyn_cast<InvokeInst>(I)) { 1260b57cec5SDimitry Andric // Unwind destination (either a landingpad, catchswitch, or cleanuppad) 1270b57cec5SDimitry Andric // must be a part of the subgraph which is being extracted. 1280b57cec5SDimitry Andric if (auto *UBB = II->getUnwindDest()) 1290b57cec5SDimitry Andric if (!Result.count(UBB)) 1300b57cec5SDimitry Andric return false; 1310b57cec5SDimitry Andric continue; 1320b57cec5SDimitry Andric } 1330b57cec5SDimitry Andric 1340b57cec5SDimitry Andric // All catch handlers of a catchswitch instruction as well as the unwind 1350b57cec5SDimitry Andric // destination must be in the subgraph. 1360b57cec5SDimitry Andric if (const auto *CSI = dyn_cast<CatchSwitchInst>(I)) { 1370b57cec5SDimitry Andric if (auto *UBB = CSI->getUnwindDest()) 1380b57cec5SDimitry Andric if (!Result.count(UBB)) 1390b57cec5SDimitry Andric return false; 140bdd1243dSDimitry Andric for (const auto *HBB : CSI->handlers()) 1410b57cec5SDimitry Andric if (!Result.count(const_cast<BasicBlock*>(HBB))) 1420b57cec5SDimitry Andric return false; 1430b57cec5SDimitry Andric continue; 1440b57cec5SDimitry Andric } 1450b57cec5SDimitry Andric 1460b57cec5SDimitry Andric // Make sure that entire catch handler is within subgraph. It is sufficient 1470b57cec5SDimitry Andric // to check that catch return's block is in the list. 1480b57cec5SDimitry Andric if (const auto *CPI = dyn_cast<CatchPadInst>(I)) { 1490b57cec5SDimitry Andric for (const auto *U : CPI->users()) 1500b57cec5SDimitry Andric if (const auto *CRI = dyn_cast<CatchReturnInst>(U)) 1510b57cec5SDimitry Andric if (!Result.count(const_cast<BasicBlock*>(CRI->getParent()))) 1520b57cec5SDimitry Andric return false; 1530b57cec5SDimitry Andric continue; 1540b57cec5SDimitry Andric } 1550b57cec5SDimitry Andric 1560b57cec5SDimitry Andric // And do similar checks for cleanup handler - the entire handler must be 1570b57cec5SDimitry Andric // in subgraph which is going to be extracted. For cleanup return should 1580b57cec5SDimitry Andric // additionally check that the unwind destination is also in the subgraph. 1590b57cec5SDimitry Andric if (const auto *CPI = dyn_cast<CleanupPadInst>(I)) { 1600b57cec5SDimitry Andric for (const auto *U : CPI->users()) 1610b57cec5SDimitry Andric if (const auto *CRI = dyn_cast<CleanupReturnInst>(U)) 1620b57cec5SDimitry Andric if (!Result.count(const_cast<BasicBlock*>(CRI->getParent()))) 1630b57cec5SDimitry Andric return false; 1640b57cec5SDimitry Andric continue; 1650b57cec5SDimitry Andric } 1660b57cec5SDimitry Andric if (const auto *CRI = dyn_cast<CleanupReturnInst>(I)) { 1670b57cec5SDimitry Andric if (auto *UBB = CRI->getUnwindDest()) 1680b57cec5SDimitry Andric if (!Result.count(UBB)) 1690b57cec5SDimitry Andric return false; 1700b57cec5SDimitry Andric continue; 1710b57cec5SDimitry Andric } 1720b57cec5SDimitry Andric 1730b57cec5SDimitry Andric if (const CallInst *CI = dyn_cast<CallInst>(I)) { 1740b57cec5SDimitry Andric if (const Function *F = CI->getCalledFunction()) { 1750b57cec5SDimitry Andric auto IID = F->getIntrinsicID(); 1760b57cec5SDimitry Andric if (IID == Intrinsic::vastart) { 1770b57cec5SDimitry Andric if (AllowVarArgs) 1780b57cec5SDimitry Andric continue; 1790b57cec5SDimitry Andric else 1800b57cec5SDimitry Andric return false; 1810b57cec5SDimitry Andric } 1820b57cec5SDimitry Andric 1830b57cec5SDimitry Andric // Currently, we miscompile outlined copies of eh_typid_for. There are 1840b57cec5SDimitry Andric // proposals for fixing this in llvm.org/PR39545. 1850b57cec5SDimitry Andric if (IID == Intrinsic::eh_typeid_for) 1860b57cec5SDimitry Andric return false; 1870b57cec5SDimitry Andric } 1880b57cec5SDimitry Andric } 1890b57cec5SDimitry Andric } 1900b57cec5SDimitry Andric 1910b57cec5SDimitry Andric return true; 1920b57cec5SDimitry Andric } 1930b57cec5SDimitry Andric 1940b57cec5SDimitry Andric /// Build a set of blocks to extract if the input blocks are viable. 1950b57cec5SDimitry Andric static SetVector<BasicBlock *> 1960b57cec5SDimitry Andric buildExtractionBlockSet(ArrayRef<BasicBlock *> BBs, DominatorTree *DT, 1970b57cec5SDimitry Andric bool AllowVarArgs, bool AllowAlloca) { 1980b57cec5SDimitry Andric assert(!BBs.empty() && "The set of blocks to extract must be non-empty"); 1990b57cec5SDimitry Andric SetVector<BasicBlock *> Result; 2000b57cec5SDimitry Andric 2010b57cec5SDimitry Andric // Loop over the blocks, adding them to our set-vector, and aborting with an 2020b57cec5SDimitry Andric // empty set if we encounter invalid blocks. 2030b57cec5SDimitry Andric for (BasicBlock *BB : BBs) { 2040b57cec5SDimitry Andric // If this block is dead, don't process it. 2050b57cec5SDimitry Andric if (DT && !DT->isReachableFromEntry(BB)) 2060b57cec5SDimitry Andric continue; 2070b57cec5SDimitry Andric 2080b57cec5SDimitry Andric if (!Result.insert(BB)) 2090b57cec5SDimitry Andric llvm_unreachable("Repeated basic blocks in extraction input"); 2100b57cec5SDimitry Andric } 2110b57cec5SDimitry Andric 2120b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "Region front block: " << Result.front()->getName() 2130b57cec5SDimitry Andric << '\n'); 2140b57cec5SDimitry Andric 2150b57cec5SDimitry Andric for (auto *BB : Result) { 2160b57cec5SDimitry Andric if (!isBlockValidForExtraction(*BB, Result, AllowVarArgs, AllowAlloca)) 2170b57cec5SDimitry Andric return {}; 2180b57cec5SDimitry Andric 2190b57cec5SDimitry Andric // Make sure that the first block is not a landing pad. 2200b57cec5SDimitry Andric if (BB == Result.front()) { 2210b57cec5SDimitry Andric if (BB->isEHPad()) { 2220b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "The first block cannot be an unwind block\n"); 2230b57cec5SDimitry Andric return {}; 2240b57cec5SDimitry Andric } 2250b57cec5SDimitry Andric continue; 2260b57cec5SDimitry Andric } 2270b57cec5SDimitry Andric 2280b57cec5SDimitry Andric // All blocks other than the first must not have predecessors outside of 2290b57cec5SDimitry Andric // the subgraph which is being extracted. 2300b57cec5SDimitry Andric for (auto *PBB : predecessors(BB)) 2310b57cec5SDimitry Andric if (!Result.count(PBB)) { 2320b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "No blocks in this region may have entries from " 2330b57cec5SDimitry Andric "outside the region except for the first block!\n" 2340b57cec5SDimitry Andric << "Problematic source BB: " << BB->getName() << "\n" 2350b57cec5SDimitry Andric << "Problematic destination BB: " << PBB->getName() 2360b57cec5SDimitry Andric << "\n"); 2370b57cec5SDimitry Andric return {}; 2380b57cec5SDimitry Andric } 2390b57cec5SDimitry Andric } 2400b57cec5SDimitry Andric 2410b57cec5SDimitry Andric return Result; 2420b57cec5SDimitry Andric } 2430b57cec5SDimitry Andric 2440b57cec5SDimitry Andric CodeExtractor::CodeExtractor(ArrayRef<BasicBlock *> BBs, DominatorTree *DT, 2450b57cec5SDimitry Andric bool AggregateArgs, BlockFrequencyInfo *BFI, 2460b57cec5SDimitry Andric BranchProbabilityInfo *BPI, AssumptionCache *AC, 2470b57cec5SDimitry Andric bool AllowVarArgs, bool AllowAlloca, 2485f757f3fSDimitry Andric BasicBlock *AllocationBlock, std::string Suffix, 2495f757f3fSDimitry Andric bool ArgsInZeroAddressSpace) 2500b57cec5SDimitry Andric : DT(DT), AggregateArgs(AggregateArgs || AggregateArgsOpt), BFI(BFI), 25181ad6265SDimitry Andric BPI(BPI), AC(AC), AllocationBlock(AllocationBlock), 25281ad6265SDimitry Andric AllowVarArgs(AllowVarArgs), 2530b57cec5SDimitry Andric Blocks(buildExtractionBlockSet(BBs, DT, AllowVarArgs, AllowAlloca)), 2545f757f3fSDimitry Andric Suffix(Suffix), ArgsInZeroAddressSpace(ArgsInZeroAddressSpace) {} 2550b57cec5SDimitry Andric 2560b57cec5SDimitry Andric CodeExtractor::CodeExtractor(DominatorTree &DT, Loop &L, bool AggregateArgs, 2570b57cec5SDimitry Andric BlockFrequencyInfo *BFI, 2580b57cec5SDimitry Andric BranchProbabilityInfo *BPI, AssumptionCache *AC, 2590b57cec5SDimitry Andric std::string Suffix) 2600b57cec5SDimitry Andric : DT(&DT), AggregateArgs(AggregateArgs || AggregateArgsOpt), BFI(BFI), 26181ad6265SDimitry Andric BPI(BPI), AC(AC), AllocationBlock(nullptr), AllowVarArgs(false), 2620b57cec5SDimitry Andric Blocks(buildExtractionBlockSet(L.getBlocks(), &DT, 2630b57cec5SDimitry Andric /* AllowVarArgs */ false, 2640b57cec5SDimitry Andric /* AllowAlloca */ false)), 2650b57cec5SDimitry Andric Suffix(Suffix) {} 2660b57cec5SDimitry Andric 2670b57cec5SDimitry Andric /// definedInRegion - Return true if the specified value is defined in the 2680b57cec5SDimitry Andric /// extracted region. 2690b57cec5SDimitry Andric static bool definedInRegion(const SetVector<BasicBlock *> &Blocks, Value *V) { 2700b57cec5SDimitry Andric if (Instruction *I = dyn_cast<Instruction>(V)) 2710b57cec5SDimitry Andric if (Blocks.count(I->getParent())) 2720b57cec5SDimitry Andric return true; 2730b57cec5SDimitry Andric return false; 2740b57cec5SDimitry Andric } 2750b57cec5SDimitry Andric 2760b57cec5SDimitry Andric /// definedInCaller - Return true if the specified value is defined in the 2770b57cec5SDimitry Andric /// function being code extracted, but not in the region being extracted. 2780b57cec5SDimitry Andric /// These values must be passed in as live-ins to the function. 2790b57cec5SDimitry Andric static bool definedInCaller(const SetVector<BasicBlock *> &Blocks, Value *V) { 2800b57cec5SDimitry Andric if (isa<Argument>(V)) return true; 2810b57cec5SDimitry Andric if (Instruction *I = dyn_cast<Instruction>(V)) 2820b57cec5SDimitry Andric if (!Blocks.count(I->getParent())) 2830b57cec5SDimitry Andric return true; 2840b57cec5SDimitry Andric return false; 2850b57cec5SDimitry Andric } 2860b57cec5SDimitry Andric 2870b57cec5SDimitry Andric static BasicBlock *getCommonExitBlock(const SetVector<BasicBlock *> &Blocks) { 2880b57cec5SDimitry Andric BasicBlock *CommonExitBlock = nullptr; 2890b57cec5SDimitry Andric auto hasNonCommonExitSucc = [&](BasicBlock *Block) { 2900b57cec5SDimitry Andric for (auto *Succ : successors(Block)) { 2910b57cec5SDimitry Andric // Internal edges, ok. 2920b57cec5SDimitry Andric if (Blocks.count(Succ)) 2930b57cec5SDimitry Andric continue; 2940b57cec5SDimitry Andric if (!CommonExitBlock) { 2950b57cec5SDimitry Andric CommonExitBlock = Succ; 2960b57cec5SDimitry Andric continue; 2970b57cec5SDimitry Andric } 2988bcb0991SDimitry Andric if (CommonExitBlock != Succ) 2990b57cec5SDimitry Andric return true; 3000b57cec5SDimitry Andric } 3010b57cec5SDimitry Andric return false; 3020b57cec5SDimitry Andric }; 3030b57cec5SDimitry Andric 3040b57cec5SDimitry Andric if (any_of(Blocks, hasNonCommonExitSucc)) 3050b57cec5SDimitry Andric return nullptr; 3060b57cec5SDimitry Andric 3070b57cec5SDimitry Andric return CommonExitBlock; 3080b57cec5SDimitry Andric } 3090b57cec5SDimitry Andric 3108bcb0991SDimitry Andric CodeExtractorAnalysisCache::CodeExtractorAnalysisCache(Function &F) { 3118bcb0991SDimitry Andric for (BasicBlock &BB : F) { 3128bcb0991SDimitry Andric for (Instruction &II : BB.instructionsWithoutDebug()) 3138bcb0991SDimitry Andric if (auto *AI = dyn_cast<AllocaInst>(&II)) 3148bcb0991SDimitry Andric Allocas.push_back(AI); 3150b57cec5SDimitry Andric 3168bcb0991SDimitry Andric findSideEffectInfoForBlock(BB); 3178bcb0991SDimitry Andric } 3188bcb0991SDimitry Andric } 3198bcb0991SDimitry Andric 3208bcb0991SDimitry Andric void CodeExtractorAnalysisCache::findSideEffectInfoForBlock(BasicBlock &BB) { 3218bcb0991SDimitry Andric for (Instruction &II : BB.instructionsWithoutDebug()) { 3220b57cec5SDimitry Andric unsigned Opcode = II.getOpcode(); 3230b57cec5SDimitry Andric Value *MemAddr = nullptr; 3240b57cec5SDimitry Andric switch (Opcode) { 3250b57cec5SDimitry Andric case Instruction::Store: 3260b57cec5SDimitry Andric case Instruction::Load: { 3270b57cec5SDimitry Andric if (Opcode == Instruction::Store) { 3280b57cec5SDimitry Andric StoreInst *SI = cast<StoreInst>(&II); 3290b57cec5SDimitry Andric MemAddr = SI->getPointerOperand(); 3300b57cec5SDimitry Andric } else { 3310b57cec5SDimitry Andric LoadInst *LI = cast<LoadInst>(&II); 3320b57cec5SDimitry Andric MemAddr = LI->getPointerOperand(); 3330b57cec5SDimitry Andric } 3340b57cec5SDimitry Andric // Global variable can not be aliased with locals. 335fe6060f1SDimitry Andric if (isa<Constant>(MemAddr)) 3360b57cec5SDimitry Andric break; 3370b57cec5SDimitry Andric Value *Base = MemAddr->stripInBoundsConstantOffsets(); 3388bcb0991SDimitry Andric if (!isa<AllocaInst>(Base)) { 3398bcb0991SDimitry Andric SideEffectingBlocks.insert(&BB); 3408bcb0991SDimitry Andric return; 3418bcb0991SDimitry Andric } 3428bcb0991SDimitry Andric BaseMemAddrs[&BB].insert(Base); 3430b57cec5SDimitry Andric break; 3440b57cec5SDimitry Andric } 3450b57cec5SDimitry Andric default: { 3460b57cec5SDimitry Andric IntrinsicInst *IntrInst = dyn_cast<IntrinsicInst>(&II); 3470b57cec5SDimitry Andric if (IntrInst) { 3480b57cec5SDimitry Andric if (IntrInst->isLifetimeStartOrEnd()) 3490b57cec5SDimitry Andric break; 3508bcb0991SDimitry Andric SideEffectingBlocks.insert(&BB); 3518bcb0991SDimitry Andric return; 3520b57cec5SDimitry Andric } 3530b57cec5SDimitry Andric // Treat all the other cases conservatively if it has side effects. 3548bcb0991SDimitry Andric if (II.mayHaveSideEffects()) { 3558bcb0991SDimitry Andric SideEffectingBlocks.insert(&BB); 3568bcb0991SDimitry Andric return; 3578bcb0991SDimitry Andric } 3580b57cec5SDimitry Andric } 3590b57cec5SDimitry Andric } 3600b57cec5SDimitry Andric } 3610b57cec5SDimitry Andric } 3620b57cec5SDimitry Andric 3638bcb0991SDimitry Andric bool CodeExtractorAnalysisCache::doesBlockContainClobberOfAddr( 3648bcb0991SDimitry Andric BasicBlock &BB, AllocaInst *Addr) const { 3658bcb0991SDimitry Andric if (SideEffectingBlocks.count(&BB)) 3668bcb0991SDimitry Andric return true; 3678bcb0991SDimitry Andric auto It = BaseMemAddrs.find(&BB); 3688bcb0991SDimitry Andric if (It != BaseMemAddrs.end()) 3698bcb0991SDimitry Andric return It->second.count(Addr); 3708bcb0991SDimitry Andric return false; 3718bcb0991SDimitry Andric } 3728bcb0991SDimitry Andric 3738bcb0991SDimitry Andric bool CodeExtractor::isLegalToShrinkwrapLifetimeMarkers( 3748bcb0991SDimitry Andric const CodeExtractorAnalysisCache &CEAC, Instruction *Addr) const { 3758bcb0991SDimitry Andric AllocaInst *AI = cast<AllocaInst>(Addr->stripInBoundsConstantOffsets()); 3768bcb0991SDimitry Andric Function *Func = (*Blocks.begin())->getParent(); 3778bcb0991SDimitry Andric for (BasicBlock &BB : *Func) { 3788bcb0991SDimitry Andric if (Blocks.count(&BB)) 3798bcb0991SDimitry Andric continue; 3808bcb0991SDimitry Andric if (CEAC.doesBlockContainClobberOfAddr(BB, AI)) 3818bcb0991SDimitry Andric return false; 3828bcb0991SDimitry Andric } 3830b57cec5SDimitry Andric return true; 3840b57cec5SDimitry Andric } 3850b57cec5SDimitry Andric 3860b57cec5SDimitry Andric BasicBlock * 3870b57cec5SDimitry Andric CodeExtractor::findOrCreateBlockForHoisting(BasicBlock *CommonExitBlock) { 3880b57cec5SDimitry Andric BasicBlock *SinglePredFromOutlineRegion = nullptr; 3890b57cec5SDimitry Andric assert(!Blocks.count(CommonExitBlock) && 3900b57cec5SDimitry Andric "Expect a block outside the region!"); 3910b57cec5SDimitry Andric for (auto *Pred : predecessors(CommonExitBlock)) { 3920b57cec5SDimitry Andric if (!Blocks.count(Pred)) 3930b57cec5SDimitry Andric continue; 3940b57cec5SDimitry Andric if (!SinglePredFromOutlineRegion) { 3950b57cec5SDimitry Andric SinglePredFromOutlineRegion = Pred; 3960b57cec5SDimitry Andric } else if (SinglePredFromOutlineRegion != Pred) { 3970b57cec5SDimitry Andric SinglePredFromOutlineRegion = nullptr; 3980b57cec5SDimitry Andric break; 3990b57cec5SDimitry Andric } 4000b57cec5SDimitry Andric } 4010b57cec5SDimitry Andric 4020b57cec5SDimitry Andric if (SinglePredFromOutlineRegion) 4030b57cec5SDimitry Andric return SinglePredFromOutlineRegion; 4040b57cec5SDimitry Andric 4050b57cec5SDimitry Andric #ifndef NDEBUG 4060b57cec5SDimitry Andric auto getFirstPHI = [](BasicBlock *BB) { 4070b57cec5SDimitry Andric BasicBlock::iterator I = BB->begin(); 4080b57cec5SDimitry Andric PHINode *FirstPhi = nullptr; 4090b57cec5SDimitry Andric while (I != BB->end()) { 4100b57cec5SDimitry Andric PHINode *Phi = dyn_cast<PHINode>(I); 4110b57cec5SDimitry Andric if (!Phi) 4120b57cec5SDimitry Andric break; 4130b57cec5SDimitry Andric if (!FirstPhi) { 4140b57cec5SDimitry Andric FirstPhi = Phi; 4150b57cec5SDimitry Andric break; 4160b57cec5SDimitry Andric } 4170b57cec5SDimitry Andric } 4180b57cec5SDimitry Andric return FirstPhi; 4190b57cec5SDimitry Andric }; 4200b57cec5SDimitry Andric // If there are any phi nodes, the single pred either exists or has already 4210b57cec5SDimitry Andric // be created before code extraction. 4220b57cec5SDimitry Andric assert(!getFirstPHI(CommonExitBlock) && "Phi not expected"); 4230b57cec5SDimitry Andric #endif 4240b57cec5SDimitry Andric 4250b57cec5SDimitry Andric BasicBlock *NewExitBlock = CommonExitBlock->splitBasicBlock( 4260b57cec5SDimitry Andric CommonExitBlock->getFirstNonPHI()->getIterator()); 4270b57cec5SDimitry Andric 428fe6060f1SDimitry Andric for (BasicBlock *Pred : 429fe6060f1SDimitry Andric llvm::make_early_inc_range(predecessors(CommonExitBlock))) { 4300b57cec5SDimitry Andric if (Blocks.count(Pred)) 4310b57cec5SDimitry Andric continue; 4320b57cec5SDimitry Andric Pred->getTerminator()->replaceUsesOfWith(CommonExitBlock, NewExitBlock); 4330b57cec5SDimitry Andric } 4340b57cec5SDimitry Andric // Now add the old exit block to the outline region. 4350b57cec5SDimitry Andric Blocks.insert(CommonExitBlock); 436349cc55cSDimitry Andric OldTargets.push_back(NewExitBlock); 4370b57cec5SDimitry Andric return CommonExitBlock; 4380b57cec5SDimitry Andric } 4390b57cec5SDimitry Andric 4400b57cec5SDimitry Andric // Find the pair of life time markers for address 'Addr' that are either 4410b57cec5SDimitry Andric // defined inside the outline region or can legally be shrinkwrapped into the 4420b57cec5SDimitry Andric // outline region. If there are not other untracked uses of the address, return 4430b57cec5SDimitry Andric // the pair of markers if found; otherwise return a pair of nullptr. 4440b57cec5SDimitry Andric CodeExtractor::LifetimeMarkerInfo 4458bcb0991SDimitry Andric CodeExtractor::getLifetimeMarkers(const CodeExtractorAnalysisCache &CEAC, 4468bcb0991SDimitry Andric Instruction *Addr, 4470b57cec5SDimitry Andric BasicBlock *ExitBlock) const { 4480b57cec5SDimitry Andric LifetimeMarkerInfo Info; 4490b57cec5SDimitry Andric 4500b57cec5SDimitry Andric for (User *U : Addr->users()) { 4510b57cec5SDimitry Andric IntrinsicInst *IntrInst = dyn_cast<IntrinsicInst>(U); 4520b57cec5SDimitry Andric if (IntrInst) { 4535ffd83dbSDimitry Andric // We don't model addresses with multiple start/end markers, but the 4545ffd83dbSDimitry Andric // markers do not need to be in the region. 4550b57cec5SDimitry Andric if (IntrInst->getIntrinsicID() == Intrinsic::lifetime_start) { 4560b57cec5SDimitry Andric if (Info.LifeStart) 4570b57cec5SDimitry Andric return {}; 4580b57cec5SDimitry Andric Info.LifeStart = IntrInst; 4595ffd83dbSDimitry Andric continue; 4600b57cec5SDimitry Andric } 4610b57cec5SDimitry Andric if (IntrInst->getIntrinsicID() == Intrinsic::lifetime_end) { 4620b57cec5SDimitry Andric if (Info.LifeEnd) 4630b57cec5SDimitry Andric return {}; 4640b57cec5SDimitry Andric Info.LifeEnd = IntrInst; 4655ffd83dbSDimitry Andric continue; 4660b57cec5SDimitry Andric } 4675ffd83dbSDimitry Andric // At this point, permit debug uses outside of the region. 4685ffd83dbSDimitry Andric // This is fixed in a later call to fixupDebugInfoPostExtraction(). 4695ffd83dbSDimitry Andric if (isa<DbgInfoIntrinsic>(IntrInst)) 4700b57cec5SDimitry Andric continue; 4710b57cec5SDimitry Andric } 4720b57cec5SDimitry Andric // Find untracked uses of the address, bail. 4730b57cec5SDimitry Andric if (!definedInRegion(Blocks, U)) 4740b57cec5SDimitry Andric return {}; 4750b57cec5SDimitry Andric } 4760b57cec5SDimitry Andric 4770b57cec5SDimitry Andric if (!Info.LifeStart || !Info.LifeEnd) 4780b57cec5SDimitry Andric return {}; 4790b57cec5SDimitry Andric 4800b57cec5SDimitry Andric Info.SinkLifeStart = !definedInRegion(Blocks, Info.LifeStart); 4810b57cec5SDimitry Andric Info.HoistLifeEnd = !definedInRegion(Blocks, Info.LifeEnd); 4820b57cec5SDimitry Andric // Do legality check. 4830b57cec5SDimitry Andric if ((Info.SinkLifeStart || Info.HoistLifeEnd) && 4848bcb0991SDimitry Andric !isLegalToShrinkwrapLifetimeMarkers(CEAC, Addr)) 4850b57cec5SDimitry Andric return {}; 4860b57cec5SDimitry Andric 4870b57cec5SDimitry Andric // Check to see if we have a place to do hoisting, if not, bail. 4880b57cec5SDimitry Andric if (Info.HoistLifeEnd && !ExitBlock) 4890b57cec5SDimitry Andric return {}; 4900b57cec5SDimitry Andric 4910b57cec5SDimitry Andric return Info; 4920b57cec5SDimitry Andric } 4930b57cec5SDimitry Andric 4948bcb0991SDimitry Andric void CodeExtractor::findAllocas(const CodeExtractorAnalysisCache &CEAC, 4958bcb0991SDimitry Andric ValueSet &SinkCands, ValueSet &HoistCands, 4960b57cec5SDimitry Andric BasicBlock *&ExitBlock) const { 4970b57cec5SDimitry Andric Function *Func = (*Blocks.begin())->getParent(); 4980b57cec5SDimitry Andric ExitBlock = getCommonExitBlock(Blocks); 4990b57cec5SDimitry Andric 5000b57cec5SDimitry Andric auto moveOrIgnoreLifetimeMarkers = 5010b57cec5SDimitry Andric [&](const LifetimeMarkerInfo &LMI) -> bool { 5020b57cec5SDimitry Andric if (!LMI.LifeStart) 5030b57cec5SDimitry Andric return false; 5040b57cec5SDimitry Andric if (LMI.SinkLifeStart) { 5050b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "Sinking lifetime.start: " << *LMI.LifeStart 5060b57cec5SDimitry Andric << "\n"); 5070b57cec5SDimitry Andric SinkCands.insert(LMI.LifeStart); 5080b57cec5SDimitry Andric } 5090b57cec5SDimitry Andric if (LMI.HoistLifeEnd) { 5100b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "Hoisting lifetime.end: " << *LMI.LifeEnd << "\n"); 5110b57cec5SDimitry Andric HoistCands.insert(LMI.LifeEnd); 5120b57cec5SDimitry Andric } 5130b57cec5SDimitry Andric return true; 5140b57cec5SDimitry Andric }; 5150b57cec5SDimitry Andric 5168bcb0991SDimitry Andric // Look up allocas in the original function in CodeExtractorAnalysisCache, as 5178bcb0991SDimitry Andric // this is much faster than walking all the instructions. 5188bcb0991SDimitry Andric for (AllocaInst *AI : CEAC.getAllocas()) { 5198bcb0991SDimitry Andric BasicBlock *BB = AI->getParent(); 5208bcb0991SDimitry Andric if (Blocks.count(BB)) 5210b57cec5SDimitry Andric continue; 5220b57cec5SDimitry Andric 5238bcb0991SDimitry Andric // As a prior call to extractCodeRegion() may have shrinkwrapped the alloca, 5248bcb0991SDimitry Andric // check whether it is actually still in the original function. 5258bcb0991SDimitry Andric Function *AIFunc = BB->getParent(); 5268bcb0991SDimitry Andric if (AIFunc != Func) 5278bcb0991SDimitry Andric continue; 5288bcb0991SDimitry Andric 5298bcb0991SDimitry Andric LifetimeMarkerInfo MarkerInfo = getLifetimeMarkers(CEAC, AI, ExitBlock); 5300b57cec5SDimitry Andric bool Moved = moveOrIgnoreLifetimeMarkers(MarkerInfo); 5310b57cec5SDimitry Andric if (Moved) { 5320b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "Sinking alloca: " << *AI << "\n"); 5330b57cec5SDimitry Andric SinkCands.insert(AI); 5340b57cec5SDimitry Andric continue; 5350b57cec5SDimitry Andric } 5360b57cec5SDimitry Andric 537e8d8bef9SDimitry Andric // Find bitcasts in the outlined region that have lifetime marker users 538e8d8bef9SDimitry Andric // outside that region. Replace the lifetime marker use with an 539e8d8bef9SDimitry Andric // outside region bitcast to avoid unnecessary alloca/reload instructions 540e8d8bef9SDimitry Andric // and extra lifetime markers. 541e8d8bef9SDimitry Andric SmallVector<Instruction *, 2> LifetimeBitcastUsers; 542e8d8bef9SDimitry Andric for (User *U : AI->users()) { 543e8d8bef9SDimitry Andric if (!definedInRegion(Blocks, U)) 544e8d8bef9SDimitry Andric continue; 545e8d8bef9SDimitry Andric 546e8d8bef9SDimitry Andric if (U->stripInBoundsConstantOffsets() != AI) 547e8d8bef9SDimitry Andric continue; 548e8d8bef9SDimitry Andric 549e8d8bef9SDimitry Andric Instruction *Bitcast = cast<Instruction>(U); 550e8d8bef9SDimitry Andric for (User *BU : Bitcast->users()) { 551e8d8bef9SDimitry Andric IntrinsicInst *IntrInst = dyn_cast<IntrinsicInst>(BU); 552e8d8bef9SDimitry Andric if (!IntrInst) 553e8d8bef9SDimitry Andric continue; 554e8d8bef9SDimitry Andric 555e8d8bef9SDimitry Andric if (!IntrInst->isLifetimeStartOrEnd()) 556e8d8bef9SDimitry Andric continue; 557e8d8bef9SDimitry Andric 558e8d8bef9SDimitry Andric if (definedInRegion(Blocks, IntrInst)) 559e8d8bef9SDimitry Andric continue; 560e8d8bef9SDimitry Andric 561e8d8bef9SDimitry Andric LLVM_DEBUG(dbgs() << "Replace use of extracted region bitcast" 562e8d8bef9SDimitry Andric << *Bitcast << " in out-of-region lifetime marker " 563e8d8bef9SDimitry Andric << *IntrInst << "\n"); 564e8d8bef9SDimitry Andric LifetimeBitcastUsers.push_back(IntrInst); 565e8d8bef9SDimitry Andric } 566e8d8bef9SDimitry Andric } 567e8d8bef9SDimitry Andric 568e8d8bef9SDimitry Andric for (Instruction *I : LifetimeBitcastUsers) { 569e8d8bef9SDimitry Andric Module *M = AIFunc->getParent(); 570e8d8bef9SDimitry Andric LLVMContext &Ctx = M->getContext(); 5715f757f3fSDimitry Andric auto *Int8PtrTy = PointerType::getUnqual(Ctx); 572e8d8bef9SDimitry Andric CastInst *CastI = 573*0fca6ea1SDimitry Andric CastInst::CreatePointerCast(AI, Int8PtrTy, "lt.cast", I->getIterator()); 574e8d8bef9SDimitry Andric I->replaceUsesOfWith(I->getOperand(1), CastI); 575e8d8bef9SDimitry Andric } 576e8d8bef9SDimitry Andric 5770b57cec5SDimitry Andric // Follow any bitcasts. 5780b57cec5SDimitry Andric SmallVector<Instruction *, 2> Bitcasts; 5790b57cec5SDimitry Andric SmallVector<LifetimeMarkerInfo, 2> BitcastLifetimeInfo; 5800b57cec5SDimitry Andric for (User *U : AI->users()) { 5810b57cec5SDimitry Andric if (U->stripInBoundsConstantOffsets() == AI) { 5820b57cec5SDimitry Andric Instruction *Bitcast = cast<Instruction>(U); 5838bcb0991SDimitry Andric LifetimeMarkerInfo LMI = getLifetimeMarkers(CEAC, Bitcast, ExitBlock); 5840b57cec5SDimitry Andric if (LMI.LifeStart) { 5850b57cec5SDimitry Andric Bitcasts.push_back(Bitcast); 5860b57cec5SDimitry Andric BitcastLifetimeInfo.push_back(LMI); 5870b57cec5SDimitry Andric continue; 5880b57cec5SDimitry Andric } 5890b57cec5SDimitry Andric } 5900b57cec5SDimitry Andric 5910b57cec5SDimitry Andric // Found unknown use of AI. 5920b57cec5SDimitry Andric if (!definedInRegion(Blocks, U)) { 5930b57cec5SDimitry Andric Bitcasts.clear(); 5940b57cec5SDimitry Andric break; 5950b57cec5SDimitry Andric } 5960b57cec5SDimitry Andric } 5970b57cec5SDimitry Andric 5980b57cec5SDimitry Andric // Either no bitcasts reference the alloca or there are unknown uses. 5990b57cec5SDimitry Andric if (Bitcasts.empty()) 6000b57cec5SDimitry Andric continue; 6010b57cec5SDimitry Andric 6020b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "Sinking alloca (via bitcast): " << *AI << "\n"); 6030b57cec5SDimitry Andric SinkCands.insert(AI); 6040b57cec5SDimitry Andric for (unsigned I = 0, E = Bitcasts.size(); I != E; ++I) { 6050b57cec5SDimitry Andric Instruction *BitcastAddr = Bitcasts[I]; 6060b57cec5SDimitry Andric const LifetimeMarkerInfo &LMI = BitcastLifetimeInfo[I]; 6070b57cec5SDimitry Andric assert(LMI.LifeStart && 6080b57cec5SDimitry Andric "Unsafe to sink bitcast without lifetime markers"); 6090b57cec5SDimitry Andric moveOrIgnoreLifetimeMarkers(LMI); 6100b57cec5SDimitry Andric if (!definedInRegion(Blocks, BitcastAddr)) { 6110b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "Sinking bitcast-of-alloca: " << *BitcastAddr 6120b57cec5SDimitry Andric << "\n"); 6130b57cec5SDimitry Andric SinkCands.insert(BitcastAddr); 6140b57cec5SDimitry Andric } 6150b57cec5SDimitry Andric } 6160b57cec5SDimitry Andric } 6170b57cec5SDimitry Andric } 6188bcb0991SDimitry Andric 6198bcb0991SDimitry Andric bool CodeExtractor::isEligible() const { 6208bcb0991SDimitry Andric if (Blocks.empty()) 6218bcb0991SDimitry Andric return false; 6228bcb0991SDimitry Andric BasicBlock *Header = *Blocks.begin(); 6238bcb0991SDimitry Andric Function *F = Header->getParent(); 6248bcb0991SDimitry Andric 6258bcb0991SDimitry Andric // For functions with varargs, check that varargs handling is only done in the 6268bcb0991SDimitry Andric // outlined function, i.e vastart and vaend are only used in outlined blocks. 6278bcb0991SDimitry Andric if (AllowVarArgs && F->getFunctionType()->isVarArg()) { 6288bcb0991SDimitry Andric auto containsVarArgIntrinsic = [](const Instruction &I) { 6298bcb0991SDimitry Andric if (const CallInst *CI = dyn_cast<CallInst>(&I)) 6308bcb0991SDimitry Andric if (const Function *Callee = CI->getCalledFunction()) 6318bcb0991SDimitry Andric return Callee->getIntrinsicID() == Intrinsic::vastart || 6328bcb0991SDimitry Andric Callee->getIntrinsicID() == Intrinsic::vaend; 6338bcb0991SDimitry Andric return false; 6348bcb0991SDimitry Andric }; 6358bcb0991SDimitry Andric 6368bcb0991SDimitry Andric for (auto &BB : *F) { 6378bcb0991SDimitry Andric if (Blocks.count(&BB)) 6388bcb0991SDimitry Andric continue; 6398bcb0991SDimitry Andric if (llvm::any_of(BB, containsVarArgIntrinsic)) 6408bcb0991SDimitry Andric return false; 6418bcb0991SDimitry Andric } 6428bcb0991SDimitry Andric } 6438bcb0991SDimitry Andric return true; 6440b57cec5SDimitry Andric } 6450b57cec5SDimitry Andric 6460b57cec5SDimitry Andric void CodeExtractor::findInputsOutputs(ValueSet &Inputs, ValueSet &Outputs, 6470b57cec5SDimitry Andric const ValueSet &SinkCands) const { 6480b57cec5SDimitry Andric for (BasicBlock *BB : Blocks) { 6490b57cec5SDimitry Andric // If a used value is defined outside the region, it's an input. If an 6500b57cec5SDimitry Andric // instruction is used outside the region, it's an output. 6510b57cec5SDimitry Andric for (Instruction &II : *BB) { 6528bcb0991SDimitry Andric for (auto &OI : II.operands()) { 6538bcb0991SDimitry Andric Value *V = OI; 6540b57cec5SDimitry Andric if (!SinkCands.count(V) && definedInCaller(Blocks, V)) 6550b57cec5SDimitry Andric Inputs.insert(V); 6560b57cec5SDimitry Andric } 6570b57cec5SDimitry Andric 6580b57cec5SDimitry Andric for (User *U : II.users()) 6590b57cec5SDimitry Andric if (!definedInRegion(Blocks, U)) { 6600b57cec5SDimitry Andric Outputs.insert(&II); 6610b57cec5SDimitry Andric break; 6620b57cec5SDimitry Andric } 6630b57cec5SDimitry Andric } 6640b57cec5SDimitry Andric } 6650b57cec5SDimitry Andric } 6660b57cec5SDimitry Andric 6670b57cec5SDimitry Andric /// severSplitPHINodesOfEntry - If a PHI node has multiple inputs from outside 6680b57cec5SDimitry Andric /// of the region, we need to split the entry block of the region so that the 6690b57cec5SDimitry Andric /// PHI node is easier to deal with. 6700b57cec5SDimitry Andric void CodeExtractor::severSplitPHINodesOfEntry(BasicBlock *&Header) { 6710b57cec5SDimitry Andric unsigned NumPredsFromRegion = 0; 6720b57cec5SDimitry Andric unsigned NumPredsOutsideRegion = 0; 6730b57cec5SDimitry Andric 6740b57cec5SDimitry Andric if (Header != &Header->getParent()->getEntryBlock()) { 6750b57cec5SDimitry Andric PHINode *PN = dyn_cast<PHINode>(Header->begin()); 6760b57cec5SDimitry Andric if (!PN) return; // No PHI nodes. 6770b57cec5SDimitry Andric 6780b57cec5SDimitry Andric // If the header node contains any PHI nodes, check to see if there is more 6790b57cec5SDimitry Andric // than one entry from outside the region. If so, we need to sever the 6800b57cec5SDimitry Andric // header block into two. 6810b57cec5SDimitry Andric for (unsigned i = 0, e = PN->getNumIncomingValues(); i != e; ++i) 6820b57cec5SDimitry Andric if (Blocks.count(PN->getIncomingBlock(i))) 6830b57cec5SDimitry Andric ++NumPredsFromRegion; 6840b57cec5SDimitry Andric else 6850b57cec5SDimitry Andric ++NumPredsOutsideRegion; 6860b57cec5SDimitry Andric 6870b57cec5SDimitry Andric // If there is one (or fewer) predecessor from outside the region, we don't 6880b57cec5SDimitry Andric // need to do anything special. 6890b57cec5SDimitry Andric if (NumPredsOutsideRegion <= 1) return; 6900b57cec5SDimitry Andric } 6910b57cec5SDimitry Andric 6920b57cec5SDimitry Andric // Otherwise, we need to split the header block into two pieces: one 6930b57cec5SDimitry Andric // containing PHI nodes merging values from outside of the region, and a 6940b57cec5SDimitry Andric // second that contains all of the code for the block and merges back any 6950b57cec5SDimitry Andric // incoming values from inside of the region. 6960b57cec5SDimitry Andric BasicBlock *NewBB = SplitBlock(Header, Header->getFirstNonPHI(), DT); 6970b57cec5SDimitry Andric 6980b57cec5SDimitry Andric // We only want to code extract the second block now, and it becomes the new 6990b57cec5SDimitry Andric // header of the region. 7000b57cec5SDimitry Andric BasicBlock *OldPred = Header; 7010b57cec5SDimitry Andric Blocks.remove(OldPred); 7020b57cec5SDimitry Andric Blocks.insert(NewBB); 7030b57cec5SDimitry Andric Header = NewBB; 7040b57cec5SDimitry Andric 7050b57cec5SDimitry Andric // Okay, now we need to adjust the PHI nodes and any branches from within the 7060b57cec5SDimitry Andric // region to go to the new header block instead of the old header block. 7070b57cec5SDimitry Andric if (NumPredsFromRegion) { 7080b57cec5SDimitry Andric PHINode *PN = cast<PHINode>(OldPred->begin()); 7090b57cec5SDimitry Andric // Loop over all of the predecessors of OldPred that are in the region, 7100b57cec5SDimitry Andric // changing them to branch to NewBB instead. 7110b57cec5SDimitry Andric for (unsigned i = 0, e = PN->getNumIncomingValues(); i != e; ++i) 7120b57cec5SDimitry Andric if (Blocks.count(PN->getIncomingBlock(i))) { 7130b57cec5SDimitry Andric Instruction *TI = PN->getIncomingBlock(i)->getTerminator(); 7140b57cec5SDimitry Andric TI->replaceUsesOfWith(OldPred, NewBB); 7150b57cec5SDimitry Andric } 7160b57cec5SDimitry Andric 7170b57cec5SDimitry Andric // Okay, everything within the region is now branching to the right block, we 7180b57cec5SDimitry Andric // just have to update the PHI nodes now, inserting PHI nodes into NewBB. 7190b57cec5SDimitry Andric BasicBlock::iterator AfterPHIs; 7200b57cec5SDimitry Andric for (AfterPHIs = OldPred->begin(); isa<PHINode>(AfterPHIs); ++AfterPHIs) { 7210b57cec5SDimitry Andric PHINode *PN = cast<PHINode>(AfterPHIs); 7220b57cec5SDimitry Andric // Create a new PHI node in the new region, which has an incoming value 7230b57cec5SDimitry Andric // from OldPred of PN. 7240b57cec5SDimitry Andric PHINode *NewPN = PHINode::Create(PN->getType(), 1 + NumPredsFromRegion, 7255f757f3fSDimitry Andric PN->getName() + ".ce"); 7265f757f3fSDimitry Andric NewPN->insertBefore(NewBB->begin()); 7270b57cec5SDimitry Andric PN->replaceAllUsesWith(NewPN); 7280b57cec5SDimitry Andric NewPN->addIncoming(PN, OldPred); 7290b57cec5SDimitry Andric 7300b57cec5SDimitry Andric // Loop over all of the incoming value in PN, moving them to NewPN if they 7310b57cec5SDimitry Andric // are from the extracted region. 7320b57cec5SDimitry Andric for (unsigned i = 0; i != PN->getNumIncomingValues(); ++i) { 7330b57cec5SDimitry Andric if (Blocks.count(PN->getIncomingBlock(i))) { 7340b57cec5SDimitry Andric NewPN->addIncoming(PN->getIncomingValue(i), PN->getIncomingBlock(i)); 7350b57cec5SDimitry Andric PN->removeIncomingValue(i); 7360b57cec5SDimitry Andric --i; 7370b57cec5SDimitry Andric } 7380b57cec5SDimitry Andric } 7390b57cec5SDimitry Andric } 7400b57cec5SDimitry Andric } 7410b57cec5SDimitry Andric } 7420b57cec5SDimitry Andric 7430b57cec5SDimitry Andric /// severSplitPHINodesOfExits - if PHI nodes in exit blocks have inputs from 7440b57cec5SDimitry Andric /// outlined region, we split these PHIs on two: one with inputs from region 7450b57cec5SDimitry Andric /// and other with remaining incoming blocks; then first PHIs are placed in 7460b57cec5SDimitry Andric /// outlined region. 7470b57cec5SDimitry Andric void CodeExtractor::severSplitPHINodesOfExits( 748*0fca6ea1SDimitry Andric const SetVector<BasicBlock *> &Exits) { 7490b57cec5SDimitry Andric for (BasicBlock *ExitBB : Exits) { 7500b57cec5SDimitry Andric BasicBlock *NewBB = nullptr; 7510b57cec5SDimitry Andric 7520b57cec5SDimitry Andric for (PHINode &PN : ExitBB->phis()) { 7530b57cec5SDimitry Andric // Find all incoming values from the outlining region. 7540b57cec5SDimitry Andric SmallVector<unsigned, 2> IncomingVals; 7550b57cec5SDimitry Andric for (unsigned i = 0; i < PN.getNumIncomingValues(); ++i) 7560b57cec5SDimitry Andric if (Blocks.count(PN.getIncomingBlock(i))) 7570b57cec5SDimitry Andric IncomingVals.push_back(i); 7580b57cec5SDimitry Andric 7590b57cec5SDimitry Andric // Do not process PHI if there is one (or fewer) predecessor from region. 7600b57cec5SDimitry Andric // If PHI has exactly one predecessor from region, only this one incoming 7610b57cec5SDimitry Andric // will be replaced on codeRepl block, so it should be safe to skip PHI. 7620b57cec5SDimitry Andric if (IncomingVals.size() <= 1) 7630b57cec5SDimitry Andric continue; 7640b57cec5SDimitry Andric 7650b57cec5SDimitry Andric // Create block for new PHIs and add it to the list of outlined if it 7660b57cec5SDimitry Andric // wasn't done before. 7670b57cec5SDimitry Andric if (!NewBB) { 7680b57cec5SDimitry Andric NewBB = BasicBlock::Create(ExitBB->getContext(), 7690b57cec5SDimitry Andric ExitBB->getName() + ".split", 7700b57cec5SDimitry Andric ExitBB->getParent(), ExitBB); 7715f757f3fSDimitry Andric NewBB->IsNewDbgInfoFormat = ExitBB->IsNewDbgInfoFormat; 772e8d8bef9SDimitry Andric SmallVector<BasicBlock *, 4> Preds(predecessors(ExitBB)); 7730b57cec5SDimitry Andric for (BasicBlock *PredBB : Preds) 7740b57cec5SDimitry Andric if (Blocks.count(PredBB)) 7750b57cec5SDimitry Andric PredBB->getTerminator()->replaceUsesOfWith(ExitBB, NewBB); 7760b57cec5SDimitry Andric BranchInst::Create(ExitBB, NewBB); 7770b57cec5SDimitry Andric Blocks.insert(NewBB); 7780b57cec5SDimitry Andric } 7790b57cec5SDimitry Andric 7800b57cec5SDimitry Andric // Split this PHI. 7815f757f3fSDimitry Andric PHINode *NewPN = PHINode::Create(PN.getType(), IncomingVals.size(), 7825f757f3fSDimitry Andric PN.getName() + ".ce"); 7835f757f3fSDimitry Andric NewPN->insertBefore(NewBB->getFirstNonPHIIt()); 7840b57cec5SDimitry Andric for (unsigned i : IncomingVals) 7850b57cec5SDimitry Andric NewPN->addIncoming(PN.getIncomingValue(i), PN.getIncomingBlock(i)); 7860b57cec5SDimitry Andric for (unsigned i : reverse(IncomingVals)) 7870b57cec5SDimitry Andric PN.removeIncomingValue(i, false); 7880b57cec5SDimitry Andric PN.addIncoming(NewPN, NewBB); 7890b57cec5SDimitry Andric } 7900b57cec5SDimitry Andric } 7910b57cec5SDimitry Andric } 7920b57cec5SDimitry Andric 7930b57cec5SDimitry Andric void CodeExtractor::splitReturnBlocks() { 7940b57cec5SDimitry Andric for (BasicBlock *Block : Blocks) 7950b57cec5SDimitry Andric if (ReturnInst *RI = dyn_cast<ReturnInst>(Block->getTerminator())) { 7960b57cec5SDimitry Andric BasicBlock *New = 7970b57cec5SDimitry Andric Block->splitBasicBlock(RI->getIterator(), Block->getName() + ".ret"); 7980b57cec5SDimitry Andric if (DT) { 7990b57cec5SDimitry Andric // Old dominates New. New node dominates all other nodes dominated 8000b57cec5SDimitry Andric // by Old. 8010b57cec5SDimitry Andric DomTreeNode *OldNode = DT->getNode(Block); 8020b57cec5SDimitry Andric SmallVector<DomTreeNode *, 8> Children(OldNode->begin(), 8030b57cec5SDimitry Andric OldNode->end()); 8040b57cec5SDimitry Andric 8050b57cec5SDimitry Andric DomTreeNode *NewNode = DT->addNewBlock(New, Block); 8060b57cec5SDimitry Andric 8070b57cec5SDimitry Andric for (DomTreeNode *I : Children) 8080b57cec5SDimitry Andric DT->changeImmediateDominator(I, NewNode); 8090b57cec5SDimitry Andric } 8100b57cec5SDimitry Andric } 8110b57cec5SDimitry Andric } 8120b57cec5SDimitry Andric 8130b57cec5SDimitry Andric /// constructFunction - make a function based on inputs and outputs, as follows: 8140b57cec5SDimitry Andric /// f(in0, ..., inN, out0, ..., outN) 8150b57cec5SDimitry Andric Function *CodeExtractor::constructFunction(const ValueSet &inputs, 8160b57cec5SDimitry Andric const ValueSet &outputs, 8170b57cec5SDimitry Andric BasicBlock *header, 8180b57cec5SDimitry Andric BasicBlock *newRootNode, 8190b57cec5SDimitry Andric BasicBlock *newHeader, 8200b57cec5SDimitry Andric Function *oldFunction, 8210b57cec5SDimitry Andric Module *M) { 8220b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "inputs: " << inputs.size() << "\n"); 8230b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "outputs: " << outputs.size() << "\n"); 8240b57cec5SDimitry Andric 8250b57cec5SDimitry Andric // This function returns unsigned, outputs will go back by reference. 8260b57cec5SDimitry Andric switch (NumExitBlocks) { 8270b57cec5SDimitry Andric case 0: 8280b57cec5SDimitry Andric case 1: RetTy = Type::getVoidTy(header->getContext()); break; 8290b57cec5SDimitry Andric case 2: RetTy = Type::getInt1Ty(header->getContext()); break; 8300b57cec5SDimitry Andric default: RetTy = Type::getInt16Ty(header->getContext()); break; 8310b57cec5SDimitry Andric } 8320b57cec5SDimitry Andric 83304eeddc0SDimitry Andric std::vector<Type *> ParamTy; 83404eeddc0SDimitry Andric std::vector<Type *> AggParamTy; 83504eeddc0SDimitry Andric ValueSet StructValues; 836bdd1243dSDimitry Andric const DataLayout &DL = M->getDataLayout(); 8370b57cec5SDimitry Andric 8380b57cec5SDimitry Andric // Add the types of the input values to the function's argument list 8390b57cec5SDimitry Andric for (Value *value : inputs) { 8400b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "value used in func: " << *value << "\n"); 84104eeddc0SDimitry Andric if (AggregateArgs && !ExcludeArgsFromAggregate.contains(value)) { 84204eeddc0SDimitry Andric AggParamTy.push_back(value->getType()); 84304eeddc0SDimitry Andric StructValues.insert(value); 84404eeddc0SDimitry Andric } else 84504eeddc0SDimitry Andric ParamTy.push_back(value->getType()); 8460b57cec5SDimitry Andric } 8470b57cec5SDimitry Andric 8480b57cec5SDimitry Andric // Add the types of the output values to the function's argument list. 8490b57cec5SDimitry Andric for (Value *output : outputs) { 8500b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "instr used in func: " << *output << "\n"); 85104eeddc0SDimitry Andric if (AggregateArgs && !ExcludeArgsFromAggregate.contains(output)) { 85204eeddc0SDimitry Andric AggParamTy.push_back(output->getType()); 85304eeddc0SDimitry Andric StructValues.insert(output); 85404eeddc0SDimitry Andric } else 855bdd1243dSDimitry Andric ParamTy.push_back( 856bdd1243dSDimitry Andric PointerType::get(output->getType(), DL.getAllocaAddrSpace())); 85704eeddc0SDimitry Andric } 85804eeddc0SDimitry Andric 85904eeddc0SDimitry Andric assert( 86004eeddc0SDimitry Andric (ParamTy.size() + AggParamTy.size()) == 86104eeddc0SDimitry Andric (inputs.size() + outputs.size()) && 86204eeddc0SDimitry Andric "Number of scalar and aggregate params does not match inputs, outputs"); 8631fd87a68SDimitry Andric assert((StructValues.empty() || AggregateArgs) && 8641fd87a68SDimitry Andric "Expeced StructValues only with AggregateArgs set"); 86504eeddc0SDimitry Andric 86604eeddc0SDimitry Andric // Concatenate scalar and aggregate params in ParamTy. 86704eeddc0SDimitry Andric size_t NumScalarParams = ParamTy.size(); 86804eeddc0SDimitry Andric StructType *StructTy = nullptr; 86904eeddc0SDimitry Andric if (AggregateArgs && !AggParamTy.empty()) { 87004eeddc0SDimitry Andric StructTy = StructType::get(M->getContext(), AggParamTy); 8715f757f3fSDimitry Andric ParamTy.push_back(PointerType::get( 8725f757f3fSDimitry Andric StructTy, ArgsInZeroAddressSpace ? 0 : DL.getAllocaAddrSpace())); 8730b57cec5SDimitry Andric } 8740b57cec5SDimitry Andric 8750b57cec5SDimitry Andric LLVM_DEBUG({ 8760b57cec5SDimitry Andric dbgs() << "Function type: " << *RetTy << " f("; 87704eeddc0SDimitry Andric for (Type *i : ParamTy) 8780b57cec5SDimitry Andric dbgs() << *i << ", "; 8790b57cec5SDimitry Andric dbgs() << ")\n"; 8800b57cec5SDimitry Andric }); 8810b57cec5SDimitry Andric 88204eeddc0SDimitry Andric FunctionType *funcType = FunctionType::get( 88304eeddc0SDimitry Andric RetTy, ParamTy, AllowVarArgs && oldFunction->isVarArg()); 8840b57cec5SDimitry Andric 8850b57cec5SDimitry Andric std::string SuffixToUse = 8860b57cec5SDimitry Andric Suffix.empty() 8870b57cec5SDimitry Andric ? (header->getName().empty() ? "extracted" : header->getName().str()) 8880b57cec5SDimitry Andric : Suffix; 8890b57cec5SDimitry Andric // Create the new function 8900b57cec5SDimitry Andric Function *newFunction = Function::Create( 8910b57cec5SDimitry Andric funcType, GlobalValue::InternalLinkage, oldFunction->getAddressSpace(), 8920b57cec5SDimitry Andric oldFunction->getName() + "." + SuffixToUse, M); 8935f757f3fSDimitry Andric newFunction->IsNewDbgInfoFormat = oldFunction->IsNewDbgInfoFormat; 8940b57cec5SDimitry Andric 8950b57cec5SDimitry Andric // Inherit all of the target dependent attributes and white-listed 8960b57cec5SDimitry Andric // target independent attributes. 8970b57cec5SDimitry Andric // (e.g. If the extracted region contains a call to an x86.sse 8980b57cec5SDimitry Andric // instruction we need to make sure that the extracted region has the 8990b57cec5SDimitry Andric // "target-features" attribute allowing it to be lowered. 9000b57cec5SDimitry Andric // FIXME: This should be changed to check to see if a specific 9010b57cec5SDimitry Andric // attribute can not be inherited. 902349cc55cSDimitry Andric for (const auto &Attr : oldFunction->getAttributes().getFnAttrs()) { 9030b57cec5SDimitry Andric if (Attr.isStringAttribute()) { 9040b57cec5SDimitry Andric if (Attr.getKindAsString() == "thunk") 9050b57cec5SDimitry Andric continue; 9060b57cec5SDimitry Andric } else 9070b57cec5SDimitry Andric switch (Attr.getKindAsEnum()) { 9080b57cec5SDimitry Andric // Those attributes cannot be propagated safely. Explicitly list them 90904eeddc0SDimitry Andric // here so we get a warning if new attributes are added. 9100b57cec5SDimitry Andric case Attribute::AllocSize: 9110b57cec5SDimitry Andric case Attribute::Builtin: 9120b57cec5SDimitry Andric case Attribute::Convergent: 9130b57cec5SDimitry Andric case Attribute::JumpTable: 9140b57cec5SDimitry Andric case Attribute::Naked: 9150b57cec5SDimitry Andric case Attribute::NoBuiltin: 9165ffd83dbSDimitry Andric case Attribute::NoMerge: 9170b57cec5SDimitry Andric case Attribute::NoReturn: 9180b57cec5SDimitry Andric case Attribute::NoSync: 9190b57cec5SDimitry Andric case Attribute::ReturnsTwice: 9200b57cec5SDimitry Andric case Attribute::Speculatable: 9210b57cec5SDimitry Andric case Attribute::StackAlignment: 9220b57cec5SDimitry Andric case Attribute::WillReturn: 92381ad6265SDimitry Andric case Attribute::AllocKind: 92481ad6265SDimitry Andric case Attribute::PresplitCoroutine: 925bdd1243dSDimitry Andric case Attribute::Memory: 92606c3fb27SDimitry Andric case Attribute::NoFPClass: 9275f757f3fSDimitry Andric case Attribute::CoroDestroyOnlyWhenComplete: 9280b57cec5SDimitry Andric continue; 9290b57cec5SDimitry Andric // Those attributes should be safe to propagate to the extracted function. 9300b57cec5SDimitry Andric case Attribute::AlwaysInline: 9310b57cec5SDimitry Andric case Attribute::Cold: 932349cc55cSDimitry Andric case Attribute::DisableSanitizerInstrumentation: 933753f127fSDimitry Andric case Attribute::FnRetThunkExtern: 934e8d8bef9SDimitry Andric case Attribute::Hot: 935*0fca6ea1SDimitry Andric case Attribute::HybridPatchable: 9360b57cec5SDimitry Andric case Attribute::NoRecurse: 9370b57cec5SDimitry Andric case Attribute::InlineHint: 9380b57cec5SDimitry Andric case Attribute::MinSize: 939e8d8bef9SDimitry Andric case Attribute::NoCallback: 9400b57cec5SDimitry Andric case Attribute::NoDuplicate: 9410b57cec5SDimitry Andric case Attribute::NoFree: 9420b57cec5SDimitry Andric case Attribute::NoImplicitFloat: 9430b57cec5SDimitry Andric case Attribute::NoInline: 9440b57cec5SDimitry Andric case Attribute::NonLazyBind: 9450b57cec5SDimitry Andric case Attribute::NoRedZone: 9460b57cec5SDimitry Andric case Attribute::NoUnwind: 94781ad6265SDimitry Andric case Attribute::NoSanitizeBounds: 948fe6060f1SDimitry Andric case Attribute::NoSanitizeCoverage: 9495ffd83dbSDimitry Andric case Attribute::NullPointerIsValid: 9505f757f3fSDimitry Andric case Attribute::OptimizeForDebugging: 9510b57cec5SDimitry Andric case Attribute::OptForFuzzing: 9520b57cec5SDimitry Andric case Attribute::OptimizeNone: 9530b57cec5SDimitry Andric case Attribute::OptimizeForSize: 9540b57cec5SDimitry Andric case Attribute::SafeStack: 9550b57cec5SDimitry Andric case Attribute::ShadowCallStack: 9560b57cec5SDimitry Andric case Attribute::SanitizeAddress: 9570b57cec5SDimitry Andric case Attribute::SanitizeMemory: 958*0fca6ea1SDimitry Andric case Attribute::SanitizeNumericalStability: 9590b57cec5SDimitry Andric case Attribute::SanitizeThread: 9600b57cec5SDimitry Andric case Attribute::SanitizeHWAddress: 9610b57cec5SDimitry Andric case Attribute::SanitizeMemTag: 9620b57cec5SDimitry Andric case Attribute::SpeculativeLoadHardening: 9630b57cec5SDimitry Andric case Attribute::StackProtect: 9640b57cec5SDimitry Andric case Attribute::StackProtectReq: 9650b57cec5SDimitry Andric case Attribute::StackProtectStrong: 9660b57cec5SDimitry Andric case Attribute::StrictFP: 9670b57cec5SDimitry Andric case Attribute::UWTable: 968fe6060f1SDimitry Andric case Attribute::VScaleRange: 9690b57cec5SDimitry Andric case Attribute::NoCfCheck: 970e8d8bef9SDimitry Andric case Attribute::MustProgress: 971e8d8bef9SDimitry Andric case Attribute::NoProfile: 972bdd1243dSDimitry Andric case Attribute::SkipProfile: 9730b57cec5SDimitry Andric break; 97404eeddc0SDimitry Andric // These attributes cannot be applied to functions. 97504eeddc0SDimitry Andric case Attribute::Alignment: 97681ad6265SDimitry Andric case Attribute::AllocatedPointer: 97781ad6265SDimitry Andric case Attribute::AllocAlign: 97804eeddc0SDimitry Andric case Attribute::ByVal: 97904eeddc0SDimitry Andric case Attribute::Dereferenceable: 98004eeddc0SDimitry Andric case Attribute::DereferenceableOrNull: 98104eeddc0SDimitry Andric case Attribute::ElementType: 98204eeddc0SDimitry Andric case Attribute::InAlloca: 98304eeddc0SDimitry Andric case Attribute::InReg: 98404eeddc0SDimitry Andric case Attribute::Nest: 98504eeddc0SDimitry Andric case Attribute::NoAlias: 98604eeddc0SDimitry Andric case Attribute::NoCapture: 98704eeddc0SDimitry Andric case Attribute::NoUndef: 98804eeddc0SDimitry Andric case Attribute::NonNull: 98904eeddc0SDimitry Andric case Attribute::Preallocated: 990bdd1243dSDimitry Andric case Attribute::ReadNone: 991bdd1243dSDimitry Andric case Attribute::ReadOnly: 99204eeddc0SDimitry Andric case Attribute::Returned: 99304eeddc0SDimitry Andric case Attribute::SExt: 99404eeddc0SDimitry Andric case Attribute::StructRet: 99504eeddc0SDimitry Andric case Attribute::SwiftError: 99604eeddc0SDimitry Andric case Attribute::SwiftSelf: 99704eeddc0SDimitry Andric case Attribute::SwiftAsync: 99804eeddc0SDimitry Andric case Attribute::ZExt: 99904eeddc0SDimitry Andric case Attribute::ImmArg: 100004eeddc0SDimitry Andric case Attribute::ByRef: 1001bdd1243dSDimitry Andric case Attribute::WriteOnly: 10025f757f3fSDimitry Andric case Attribute::Writable: 10035f757f3fSDimitry Andric case Attribute::DeadOnUnwind: 1004*0fca6ea1SDimitry Andric case Attribute::Range: 1005*0fca6ea1SDimitry Andric case Attribute::Initializes: 100604eeddc0SDimitry Andric // These are not really attributes. 100704eeddc0SDimitry Andric case Attribute::None: 100804eeddc0SDimitry Andric case Attribute::EndAttrKinds: 100904eeddc0SDimitry Andric case Attribute::EmptyKey: 101004eeddc0SDimitry Andric case Attribute::TombstoneKey: 101104eeddc0SDimitry Andric llvm_unreachable("Not a function attribute"); 10120b57cec5SDimitry Andric } 10130b57cec5SDimitry Andric 10140b57cec5SDimitry Andric newFunction->addFnAttr(Attr); 10150b57cec5SDimitry Andric } 1016*0fca6ea1SDimitry Andric 1017*0fca6ea1SDimitry Andric if (NumExitBlocks == 0) { 1018*0fca6ea1SDimitry Andric // Mark the new function `noreturn` if applicable. Terminators which resume 1019*0fca6ea1SDimitry Andric // exception propagation are treated as returning instructions. This is to 1020*0fca6ea1SDimitry Andric // avoid inserting traps after calls to outlined functions which unwind. 1021*0fca6ea1SDimitry Andric if (none_of(Blocks, [](const BasicBlock *BB) { 1022*0fca6ea1SDimitry Andric const Instruction *Term = BB->getTerminator(); 1023*0fca6ea1SDimitry Andric return isa<ReturnInst>(Term) || isa<ResumeInst>(Term); 1024*0fca6ea1SDimitry Andric })) 1025*0fca6ea1SDimitry Andric newFunction->setDoesNotReturn(); 1026*0fca6ea1SDimitry Andric } 1027*0fca6ea1SDimitry Andric 1028bdd1243dSDimitry Andric newFunction->insert(newFunction->end(), newRootNode); 10290b57cec5SDimitry Andric 103004eeddc0SDimitry Andric // Create scalar and aggregate iterators to name all of the arguments we 103104eeddc0SDimitry Andric // inserted. 103204eeddc0SDimitry Andric Function::arg_iterator ScalarAI = newFunction->arg_begin(); 103304eeddc0SDimitry Andric Function::arg_iterator AggAI = std::next(ScalarAI, NumScalarParams); 10340b57cec5SDimitry Andric 10350b57cec5SDimitry Andric // Rewrite all users of the inputs in the extracted region to use the 10360b57cec5SDimitry Andric // arguments (or appropriate addressing into struct) instead. 103704eeddc0SDimitry Andric for (unsigned i = 0, e = inputs.size(), aggIdx = 0; i != e; ++i) { 10380b57cec5SDimitry Andric Value *RewriteVal; 103904eeddc0SDimitry Andric if (AggregateArgs && StructValues.contains(inputs[i])) { 10400b57cec5SDimitry Andric Value *Idx[2]; 10410b57cec5SDimitry Andric Idx[0] = Constant::getNullValue(Type::getInt32Ty(header->getContext())); 104204eeddc0SDimitry Andric Idx[1] = ConstantInt::get(Type::getInt32Ty(header->getContext()), aggIdx); 1043*0fca6ea1SDimitry Andric BasicBlock::iterator TI = newFunction->begin()->getTerminator()->getIterator(); 10440b57cec5SDimitry Andric GetElementPtrInst *GEP = GetElementPtrInst::Create( 104504eeddc0SDimitry Andric StructTy, &*AggAI, Idx, "gep_" + inputs[i]->getName(), TI); 104604eeddc0SDimitry Andric RewriteVal = new LoadInst(StructTy->getElementType(aggIdx), GEP, 10470b57cec5SDimitry Andric "loadgep_" + inputs[i]->getName(), TI); 104804eeddc0SDimitry Andric ++aggIdx; 10490b57cec5SDimitry Andric } else 105004eeddc0SDimitry Andric RewriteVal = &*ScalarAI++; 10510b57cec5SDimitry Andric 10520b57cec5SDimitry Andric std::vector<User *> Users(inputs[i]->user_begin(), inputs[i]->user_end()); 10530b57cec5SDimitry Andric for (User *use : Users) 10540b57cec5SDimitry Andric if (Instruction *inst = dyn_cast<Instruction>(use)) 10550b57cec5SDimitry Andric if (Blocks.count(inst->getParent())) 10560b57cec5SDimitry Andric inst->replaceUsesOfWith(inputs[i], RewriteVal); 10570b57cec5SDimitry Andric } 10580b57cec5SDimitry Andric 10590b57cec5SDimitry Andric // Set names for input and output arguments. 106004eeddc0SDimitry Andric if (NumScalarParams) { 106104eeddc0SDimitry Andric ScalarAI = newFunction->arg_begin(); 106204eeddc0SDimitry Andric for (unsigned i = 0, e = inputs.size(); i != e; ++i, ++ScalarAI) 106304eeddc0SDimitry Andric if (!StructValues.contains(inputs[i])) 106404eeddc0SDimitry Andric ScalarAI->setName(inputs[i]->getName()); 106504eeddc0SDimitry Andric for (unsigned i = 0, e = outputs.size(); i != e; ++i, ++ScalarAI) 106604eeddc0SDimitry Andric if (!StructValues.contains(outputs[i])) 106704eeddc0SDimitry Andric ScalarAI->setName(outputs[i]->getName() + ".out"); 10680b57cec5SDimitry Andric } 10690b57cec5SDimitry Andric 10700b57cec5SDimitry Andric // Rewrite branches to basic blocks outside of the loop to new dummy blocks 10710b57cec5SDimitry Andric // within the new function. This must be done before we lose track of which 10720b57cec5SDimitry Andric // blocks were originally in the code region. 10730b57cec5SDimitry Andric std::vector<User *> Users(header->user_begin(), header->user_end()); 10748bcb0991SDimitry Andric for (auto &U : Users) 10750b57cec5SDimitry Andric // The BasicBlock which contains the branch is not in the region 10760b57cec5SDimitry Andric // modify the branch target to a new block 10778bcb0991SDimitry Andric if (Instruction *I = dyn_cast<Instruction>(U)) 10788bcb0991SDimitry Andric if (I->isTerminator() && I->getFunction() == oldFunction && 10798bcb0991SDimitry Andric !Blocks.count(I->getParent())) 10800b57cec5SDimitry Andric I->replaceUsesOfWith(header, newHeader); 10810b57cec5SDimitry Andric 10820b57cec5SDimitry Andric return newFunction; 10830b57cec5SDimitry Andric } 10840b57cec5SDimitry Andric 10850b57cec5SDimitry Andric /// Erase lifetime.start markers which reference inputs to the extraction 10860b57cec5SDimitry Andric /// region, and insert the referenced memory into \p LifetimesStart. 10870b57cec5SDimitry Andric /// 10880b57cec5SDimitry Andric /// The extraction region is defined by a set of blocks (\p Blocks), and a set 10890b57cec5SDimitry Andric /// of allocas which will be moved from the caller function into the extracted 10900b57cec5SDimitry Andric /// function (\p SunkAllocas). 10910b57cec5SDimitry Andric static void eraseLifetimeMarkersOnInputs(const SetVector<BasicBlock *> &Blocks, 10920b57cec5SDimitry Andric const SetVector<Value *> &SunkAllocas, 10930b57cec5SDimitry Andric SetVector<Value *> &LifetimesStart) { 10940b57cec5SDimitry Andric for (BasicBlock *BB : Blocks) { 1095349cc55cSDimitry Andric for (Instruction &I : llvm::make_early_inc_range(*BB)) { 1096349cc55cSDimitry Andric auto *II = dyn_cast<IntrinsicInst>(&I); 10970b57cec5SDimitry Andric if (!II || !II->isLifetimeStartOrEnd()) 10980b57cec5SDimitry Andric continue; 10990b57cec5SDimitry Andric 11000b57cec5SDimitry Andric // Get the memory operand of the lifetime marker. If the underlying 11010b57cec5SDimitry Andric // object is a sunk alloca, or is otherwise defined in the extraction 11020b57cec5SDimitry Andric // region, the lifetime marker must not be erased. 11030b57cec5SDimitry Andric Value *Mem = II->getOperand(1)->stripInBoundsOffsets(); 11040b57cec5SDimitry Andric if (SunkAllocas.count(Mem) || definedInRegion(Blocks, Mem)) 11050b57cec5SDimitry Andric continue; 11060b57cec5SDimitry Andric 11070b57cec5SDimitry Andric if (II->getIntrinsicID() == Intrinsic::lifetime_start) 11080b57cec5SDimitry Andric LifetimesStart.insert(Mem); 11090b57cec5SDimitry Andric II->eraseFromParent(); 11100b57cec5SDimitry Andric } 11110b57cec5SDimitry Andric } 11120b57cec5SDimitry Andric } 11130b57cec5SDimitry Andric 11140b57cec5SDimitry Andric /// Insert lifetime start/end markers surrounding the call to the new function 11150b57cec5SDimitry Andric /// for objects defined in the caller. 11160b57cec5SDimitry Andric static void insertLifetimeMarkersSurroundingCall( 11170b57cec5SDimitry Andric Module *M, ArrayRef<Value *> LifetimesStart, ArrayRef<Value *> LifetimesEnd, 11180b57cec5SDimitry Andric CallInst *TheCall) { 11190b57cec5SDimitry Andric LLVMContext &Ctx = M->getContext(); 11200b57cec5SDimitry Andric auto NegativeOne = ConstantInt::getSigned(Type::getInt64Ty(Ctx), -1); 11210b57cec5SDimitry Andric Instruction *Term = TheCall->getParent()->getTerminator(); 11220b57cec5SDimitry Andric 11230b57cec5SDimitry Andric // Emit lifetime markers for the pointers given in \p Objects. Insert the 11240b57cec5SDimitry Andric // markers before the call if \p InsertBefore, and after the call otherwise. 112506c3fb27SDimitry Andric auto insertMarkers = [&](Intrinsic::ID MarkerFunc, ArrayRef<Value *> Objects, 11260b57cec5SDimitry Andric bool InsertBefore) { 11270b57cec5SDimitry Andric for (Value *Mem : Objects) { 11280b57cec5SDimitry Andric assert((!isa<Instruction>(Mem) || cast<Instruction>(Mem)->getFunction() == 11290b57cec5SDimitry Andric TheCall->getFunction()) && 11300b57cec5SDimitry Andric "Input memory not defined in original function"); 11310b57cec5SDimitry Andric 113206c3fb27SDimitry Andric Function *Func = Intrinsic::getDeclaration(M, MarkerFunc, Mem->getType()); 113306c3fb27SDimitry Andric auto Marker = CallInst::Create(Func, {NegativeOne, Mem}); 11340b57cec5SDimitry Andric if (InsertBefore) 11350b57cec5SDimitry Andric Marker->insertBefore(TheCall); 11360b57cec5SDimitry Andric else 11370b57cec5SDimitry Andric Marker->insertBefore(Term); 11380b57cec5SDimitry Andric } 11390b57cec5SDimitry Andric }; 11400b57cec5SDimitry Andric 11410b57cec5SDimitry Andric if (!LifetimesStart.empty()) { 114206c3fb27SDimitry Andric insertMarkers(Intrinsic::lifetime_start, LifetimesStart, 114306c3fb27SDimitry Andric /*InsertBefore=*/true); 11440b57cec5SDimitry Andric } 11450b57cec5SDimitry Andric 11460b57cec5SDimitry Andric if (!LifetimesEnd.empty()) { 114706c3fb27SDimitry Andric insertMarkers(Intrinsic::lifetime_end, LifetimesEnd, 114806c3fb27SDimitry Andric /*InsertBefore=*/false); 11490b57cec5SDimitry Andric } 11500b57cec5SDimitry Andric } 11510b57cec5SDimitry Andric 11520b57cec5SDimitry Andric /// emitCallAndSwitchStatement - This method sets up the caller side by adding 11530b57cec5SDimitry Andric /// the call instruction, splitting any PHI nodes in the header block as 11540b57cec5SDimitry Andric /// necessary. 11550b57cec5SDimitry Andric CallInst *CodeExtractor::emitCallAndSwitchStatement(Function *newFunction, 11560b57cec5SDimitry Andric BasicBlock *codeReplacer, 11570b57cec5SDimitry Andric ValueSet &inputs, 11580b57cec5SDimitry Andric ValueSet &outputs) { 11590b57cec5SDimitry Andric // Emit a call to the new function, passing in: *pointer to struct (if 11600b57cec5SDimitry Andric // aggregating parameters), or plan inputs and allocated memory for outputs 116104eeddc0SDimitry Andric std::vector<Value *> params, ReloadOutputs, Reloads; 116204eeddc0SDimitry Andric ValueSet StructValues; 11630b57cec5SDimitry Andric 11640b57cec5SDimitry Andric Module *M = newFunction->getParent(); 11650b57cec5SDimitry Andric LLVMContext &Context = M->getContext(); 11660b57cec5SDimitry Andric const DataLayout &DL = M->getDataLayout(); 11670b57cec5SDimitry Andric CallInst *call = nullptr; 11680b57cec5SDimitry Andric 11690b57cec5SDimitry Andric // Add inputs as params, or to be filled into the struct 117004eeddc0SDimitry Andric unsigned ScalarInputArgNo = 0; 11710b57cec5SDimitry Andric SmallVector<unsigned, 1> SwiftErrorArgs; 11720b57cec5SDimitry Andric for (Value *input : inputs) { 117304eeddc0SDimitry Andric if (AggregateArgs && !ExcludeArgsFromAggregate.contains(input)) 117404eeddc0SDimitry Andric StructValues.insert(input); 11750b57cec5SDimitry Andric else { 11760b57cec5SDimitry Andric params.push_back(input); 11770b57cec5SDimitry Andric if (input->isSwiftError()) 117804eeddc0SDimitry Andric SwiftErrorArgs.push_back(ScalarInputArgNo); 11790b57cec5SDimitry Andric } 118004eeddc0SDimitry Andric ++ScalarInputArgNo; 11810b57cec5SDimitry Andric } 11820b57cec5SDimitry Andric 11830b57cec5SDimitry Andric // Create allocas for the outputs 118404eeddc0SDimitry Andric unsigned ScalarOutputArgNo = 0; 11850b57cec5SDimitry Andric for (Value *output : outputs) { 118604eeddc0SDimitry Andric if (AggregateArgs && !ExcludeArgsFromAggregate.contains(output)) { 118704eeddc0SDimitry Andric StructValues.insert(output); 11880b57cec5SDimitry Andric } else { 11890b57cec5SDimitry Andric AllocaInst *alloca = 11900b57cec5SDimitry Andric new AllocaInst(output->getType(), DL.getAllocaAddrSpace(), 11910b57cec5SDimitry Andric nullptr, output->getName() + ".loc", 1192*0fca6ea1SDimitry Andric codeReplacer->getParent()->front().begin()); 11930b57cec5SDimitry Andric ReloadOutputs.push_back(alloca); 11940b57cec5SDimitry Andric params.push_back(alloca); 119504eeddc0SDimitry Andric ++ScalarOutputArgNo; 11960b57cec5SDimitry Andric } 11970b57cec5SDimitry Andric } 11980b57cec5SDimitry Andric 11990b57cec5SDimitry Andric StructType *StructArgTy = nullptr; 12000b57cec5SDimitry Andric AllocaInst *Struct = nullptr; 120104eeddc0SDimitry Andric unsigned NumAggregatedInputs = 0; 120204eeddc0SDimitry Andric if (AggregateArgs && !StructValues.empty()) { 12030b57cec5SDimitry Andric std::vector<Type *> ArgTypes; 1204fe6060f1SDimitry Andric for (Value *V : StructValues) 1205fe6060f1SDimitry Andric ArgTypes.push_back(V->getType()); 12060b57cec5SDimitry Andric 12070b57cec5SDimitry Andric // Allocate a struct at the beginning of this function 12080b57cec5SDimitry Andric StructArgTy = StructType::get(newFunction->getContext(), ArgTypes); 120981ad6265SDimitry Andric Struct = new AllocaInst( 121081ad6265SDimitry Andric StructArgTy, DL.getAllocaAddrSpace(), nullptr, "structArg", 1211*0fca6ea1SDimitry Andric AllocationBlock ? AllocationBlock->getFirstInsertionPt() 1212*0fca6ea1SDimitry Andric : codeReplacer->getParent()->front().begin()); 12130b57cec5SDimitry Andric 12145f757f3fSDimitry Andric if (ArgsInZeroAddressSpace && DL.getAllocaAddrSpace() != 0) { 12155f757f3fSDimitry Andric auto *StructSpaceCast = new AddrSpaceCastInst( 12165f757f3fSDimitry Andric Struct, PointerType ::get(Context, 0), "structArg.ascast"); 12175f757f3fSDimitry Andric StructSpaceCast->insertAfter(Struct); 12185f757f3fSDimitry Andric params.push_back(StructSpaceCast); 12195f757f3fSDimitry Andric } else { 12205f757f3fSDimitry Andric params.push_back(Struct); 12215f757f3fSDimitry Andric } 122204eeddc0SDimitry Andric // Store aggregated inputs in the struct. 122304eeddc0SDimitry Andric for (unsigned i = 0, e = StructValues.size(); i != e; ++i) { 122404eeddc0SDimitry Andric if (inputs.contains(StructValues[i])) { 12250b57cec5SDimitry Andric Value *Idx[2]; 12260b57cec5SDimitry Andric Idx[0] = Constant::getNullValue(Type::getInt32Ty(Context)); 12270b57cec5SDimitry Andric Idx[1] = ConstantInt::get(Type::getInt32Ty(Context), i); 12280b57cec5SDimitry Andric GetElementPtrInst *GEP = GetElementPtrInst::Create( 12290b57cec5SDimitry Andric StructArgTy, Struct, Idx, "gep_" + StructValues[i]->getName()); 1230bdd1243dSDimitry Andric GEP->insertInto(codeReplacer, codeReplacer->end()); 12315ffd83dbSDimitry Andric new StoreInst(StructValues[i], GEP, codeReplacer); 123204eeddc0SDimitry Andric NumAggregatedInputs++; 123304eeddc0SDimitry Andric } 12340b57cec5SDimitry Andric } 12350b57cec5SDimitry Andric } 12360b57cec5SDimitry Andric 12370b57cec5SDimitry Andric // Emit the call to the function 12380b57cec5SDimitry Andric call = CallInst::Create(newFunction, params, 12390b57cec5SDimitry Andric NumExitBlocks > 1 ? "targetBlock" : ""); 12400b57cec5SDimitry Andric // Add debug location to the new call, if the original function has debug 12410b57cec5SDimitry Andric // info. In that case, the terminator of the entry block of the extracted 12420b57cec5SDimitry Andric // function contains the first debug location of the extracted function, 12430b57cec5SDimitry Andric // set in extractCodeRegion. 12440b57cec5SDimitry Andric if (codeReplacer->getParent()->getSubprogram()) { 12450b57cec5SDimitry Andric if (auto DL = newFunction->getEntryBlock().getTerminator()->getDebugLoc()) 12460b57cec5SDimitry Andric call->setDebugLoc(DL); 12470b57cec5SDimitry Andric } 1248bdd1243dSDimitry Andric call->insertInto(codeReplacer, codeReplacer->end()); 12490b57cec5SDimitry Andric 12500b57cec5SDimitry Andric // Set swifterror parameter attributes. 12510b57cec5SDimitry Andric for (unsigned SwiftErrArgNo : SwiftErrorArgs) { 12520b57cec5SDimitry Andric call->addParamAttr(SwiftErrArgNo, Attribute::SwiftError); 12530b57cec5SDimitry Andric newFunction->addParamAttr(SwiftErrArgNo, Attribute::SwiftError); 12540b57cec5SDimitry Andric } 12550b57cec5SDimitry Andric 125604eeddc0SDimitry Andric // Reload the outputs passed in by reference, use the struct if output is in 125704eeddc0SDimitry Andric // the aggregate or reload from the scalar argument. 125804eeddc0SDimitry Andric for (unsigned i = 0, e = outputs.size(), scalarIdx = 0, 125904eeddc0SDimitry Andric aggIdx = NumAggregatedInputs; 126004eeddc0SDimitry Andric i != e; ++i) { 12610b57cec5SDimitry Andric Value *Output = nullptr; 126204eeddc0SDimitry Andric if (AggregateArgs && StructValues.contains(outputs[i])) { 12630b57cec5SDimitry Andric Value *Idx[2]; 12640b57cec5SDimitry Andric Idx[0] = Constant::getNullValue(Type::getInt32Ty(Context)); 126504eeddc0SDimitry Andric Idx[1] = ConstantInt::get(Type::getInt32Ty(Context), aggIdx); 12660b57cec5SDimitry Andric GetElementPtrInst *GEP = GetElementPtrInst::Create( 12670b57cec5SDimitry Andric StructArgTy, Struct, Idx, "gep_reload_" + outputs[i]->getName()); 1268bdd1243dSDimitry Andric GEP->insertInto(codeReplacer, codeReplacer->end()); 12690b57cec5SDimitry Andric Output = GEP; 127004eeddc0SDimitry Andric ++aggIdx; 12710b57cec5SDimitry Andric } else { 127204eeddc0SDimitry Andric Output = ReloadOutputs[scalarIdx]; 127304eeddc0SDimitry Andric ++scalarIdx; 12740b57cec5SDimitry Andric } 12750b57cec5SDimitry Andric LoadInst *load = new LoadInst(outputs[i]->getType(), Output, 12765ffd83dbSDimitry Andric outputs[i]->getName() + ".reload", 12775ffd83dbSDimitry Andric codeReplacer); 12780b57cec5SDimitry Andric Reloads.push_back(load); 12790b57cec5SDimitry Andric std::vector<User *> Users(outputs[i]->user_begin(), outputs[i]->user_end()); 1280bdd1243dSDimitry Andric for (User *U : Users) { 1281bdd1243dSDimitry Andric Instruction *inst = cast<Instruction>(U); 12820b57cec5SDimitry Andric if (!Blocks.count(inst->getParent())) 12830b57cec5SDimitry Andric inst->replaceUsesOfWith(outputs[i], load); 12840b57cec5SDimitry Andric } 12850b57cec5SDimitry Andric } 12860b57cec5SDimitry Andric 12870b57cec5SDimitry Andric // Now we can emit a switch statement using the call as a value. 12880b57cec5SDimitry Andric SwitchInst *TheSwitch = 12890b57cec5SDimitry Andric SwitchInst::Create(Constant::getNullValue(Type::getInt16Ty(Context)), 12900b57cec5SDimitry Andric codeReplacer, 0, codeReplacer); 12910b57cec5SDimitry Andric 12920b57cec5SDimitry Andric // Since there may be multiple exits from the original region, make the new 12930b57cec5SDimitry Andric // function return an unsigned, switch on that number. This loop iterates 12940b57cec5SDimitry Andric // over all of the blocks in the extracted region, updating any terminator 12950b57cec5SDimitry Andric // instructions in the to-be-extracted region that branch to blocks that are 12960b57cec5SDimitry Andric // not in the region to be extracted. 12970b57cec5SDimitry Andric std::map<BasicBlock *, BasicBlock *> ExitBlockMap; 12980b57cec5SDimitry Andric 1299349cc55cSDimitry Andric // Iterate over the previously collected targets, and create new blocks inside 1300349cc55cSDimitry Andric // the function to branch to. 13010b57cec5SDimitry Andric unsigned switchVal = 0; 1302349cc55cSDimitry Andric for (BasicBlock *OldTarget : OldTargets) { 1303349cc55cSDimitry Andric if (Blocks.count(OldTarget)) 1304349cc55cSDimitry Andric continue; 13050b57cec5SDimitry Andric BasicBlock *&NewTarget = ExitBlockMap[OldTarget]; 1306349cc55cSDimitry Andric if (NewTarget) 1307349cc55cSDimitry Andric continue; 1308349cc55cSDimitry Andric 13090b57cec5SDimitry Andric // If we don't already have an exit stub for this non-extracted 13100b57cec5SDimitry Andric // destination, create one now! 13110b57cec5SDimitry Andric NewTarget = BasicBlock::Create(Context, 13120b57cec5SDimitry Andric OldTarget->getName() + ".exitStub", 13130b57cec5SDimitry Andric newFunction); 13140b57cec5SDimitry Andric unsigned SuccNum = switchVal++; 13150b57cec5SDimitry Andric 13160b57cec5SDimitry Andric Value *brVal = nullptr; 1317349cc55cSDimitry Andric assert(NumExitBlocks < 0xffff && "too many exit blocks for switch"); 13180b57cec5SDimitry Andric switch (NumExitBlocks) { 13190b57cec5SDimitry Andric case 0: 13200b57cec5SDimitry Andric case 1: break; // No value needed. 13210b57cec5SDimitry Andric case 2: // Conditional branch, return a bool 13220b57cec5SDimitry Andric brVal = ConstantInt::get(Type::getInt1Ty(Context), !SuccNum); 13230b57cec5SDimitry Andric break; 13240b57cec5SDimitry Andric default: 13250b57cec5SDimitry Andric brVal = ConstantInt::get(Type::getInt16Ty(Context), SuccNum); 13260b57cec5SDimitry Andric break; 13270b57cec5SDimitry Andric } 13280b57cec5SDimitry Andric 13290b57cec5SDimitry Andric ReturnInst::Create(Context, brVal, NewTarget); 13300b57cec5SDimitry Andric 13310b57cec5SDimitry Andric // Update the switch instruction. 13320b57cec5SDimitry Andric TheSwitch->addCase(ConstantInt::get(Type::getInt16Ty(Context), 13330b57cec5SDimitry Andric SuccNum), 13340b57cec5SDimitry Andric OldTarget); 13350b57cec5SDimitry Andric } 13360b57cec5SDimitry Andric 1337349cc55cSDimitry Andric for (BasicBlock *Block : Blocks) { 1338349cc55cSDimitry Andric Instruction *TI = Block->getTerminator(); 1339349cc55cSDimitry Andric for (unsigned i = 0, e = TI->getNumSuccessors(); i != e; ++i) { 1340349cc55cSDimitry Andric if (Blocks.count(TI->getSuccessor(i))) 1341349cc55cSDimitry Andric continue; 1342349cc55cSDimitry Andric BasicBlock *OldTarget = TI->getSuccessor(i); 1343349cc55cSDimitry Andric // add a new basic block which returns the appropriate value 1344349cc55cSDimitry Andric BasicBlock *NewTarget = ExitBlockMap[OldTarget]; 1345349cc55cSDimitry Andric assert(NewTarget && "Unknown target block!"); 1346349cc55cSDimitry Andric 13470b57cec5SDimitry Andric // rewrite the original branch instruction with this new target 13480b57cec5SDimitry Andric TI->setSuccessor(i, NewTarget); 13490b57cec5SDimitry Andric } 13500b57cec5SDimitry Andric } 13510b57cec5SDimitry Andric 13520b57cec5SDimitry Andric // Store the arguments right after the definition of output value. 13530b57cec5SDimitry Andric // This should be proceeded after creating exit stubs to be ensure that invoke 13540b57cec5SDimitry Andric // result restore will be placed in the outlined function. 135504eeddc0SDimitry Andric Function::arg_iterator ScalarOutputArgBegin = newFunction->arg_begin(); 135604eeddc0SDimitry Andric std::advance(ScalarOutputArgBegin, ScalarInputArgNo); 135704eeddc0SDimitry Andric Function::arg_iterator AggOutputArgBegin = newFunction->arg_begin(); 135804eeddc0SDimitry Andric std::advance(AggOutputArgBegin, ScalarInputArgNo + ScalarOutputArgNo); 135904eeddc0SDimitry Andric 136004eeddc0SDimitry Andric for (unsigned i = 0, e = outputs.size(), aggIdx = NumAggregatedInputs; i != e; 136104eeddc0SDimitry Andric ++i) { 13620b57cec5SDimitry Andric auto *OutI = dyn_cast<Instruction>(outputs[i]); 13630b57cec5SDimitry Andric if (!OutI) 13640b57cec5SDimitry Andric continue; 13650b57cec5SDimitry Andric 13660b57cec5SDimitry Andric // Find proper insertion point. 13670b57cec5SDimitry Andric BasicBlock::iterator InsertPt; 13680b57cec5SDimitry Andric // In case OutI is an invoke, we insert the store at the beginning in the 13690b57cec5SDimitry Andric // 'normal destination' BB. Otherwise we insert the store right after OutI. 13700b57cec5SDimitry Andric if (auto *InvokeI = dyn_cast<InvokeInst>(OutI)) 13710b57cec5SDimitry Andric InsertPt = InvokeI->getNormalDest()->getFirstInsertionPt(); 13720b57cec5SDimitry Andric else if (auto *Phi = dyn_cast<PHINode>(OutI)) 13730b57cec5SDimitry Andric InsertPt = Phi->getParent()->getFirstInsertionPt(); 13740b57cec5SDimitry Andric else 13750b57cec5SDimitry Andric InsertPt = std::next(OutI->getIterator()); 13760b57cec5SDimitry Andric 1377*0fca6ea1SDimitry Andric assert((InsertPt->getFunction() == newFunction || 1378*0fca6ea1SDimitry Andric Blocks.count(InsertPt->getParent())) && 13790b57cec5SDimitry Andric "InsertPt should be in new function"); 138004eeddc0SDimitry Andric if (AggregateArgs && StructValues.contains(outputs[i])) { 138104eeddc0SDimitry Andric assert(AggOutputArgBegin != newFunction->arg_end() && 138204eeddc0SDimitry Andric "Number of aggregate output arguments should match " 138304eeddc0SDimitry Andric "the number of defined values"); 13840b57cec5SDimitry Andric Value *Idx[2]; 13850b57cec5SDimitry Andric Idx[0] = Constant::getNullValue(Type::getInt32Ty(Context)); 138604eeddc0SDimitry Andric Idx[1] = ConstantInt::get(Type::getInt32Ty(Context), aggIdx); 13870b57cec5SDimitry Andric GetElementPtrInst *GEP = GetElementPtrInst::Create( 138804eeddc0SDimitry Andric StructArgTy, &*AggOutputArgBegin, Idx, "gep_" + outputs[i]->getName(), 1389*0fca6ea1SDimitry Andric InsertPt); 1390*0fca6ea1SDimitry Andric new StoreInst(outputs[i], GEP, InsertPt); 139104eeddc0SDimitry Andric ++aggIdx; 13920b57cec5SDimitry Andric // Since there should be only one struct argument aggregating 139304eeddc0SDimitry Andric // all the output values, we shouldn't increment AggOutputArgBegin, which 139404eeddc0SDimitry Andric // always points to the struct argument, in this case. 13950b57cec5SDimitry Andric } else { 139604eeddc0SDimitry Andric assert(ScalarOutputArgBegin != newFunction->arg_end() && 139704eeddc0SDimitry Andric "Number of scalar output arguments should match " 139804eeddc0SDimitry Andric "the number of defined values"); 1399*0fca6ea1SDimitry Andric new StoreInst(outputs[i], &*ScalarOutputArgBegin, InsertPt); 140004eeddc0SDimitry Andric ++ScalarOutputArgBegin; 14010b57cec5SDimitry Andric } 14020b57cec5SDimitry Andric } 14030b57cec5SDimitry Andric 14040b57cec5SDimitry Andric // Now that we've done the deed, simplify the switch instruction. 14050b57cec5SDimitry Andric Type *OldFnRetTy = TheSwitch->getParent()->getParent()->getReturnType(); 14060b57cec5SDimitry Andric switch (NumExitBlocks) { 14070b57cec5SDimitry Andric case 0: 14080b57cec5SDimitry Andric // There are no successors (the block containing the switch itself), which 14090b57cec5SDimitry Andric // means that previously this was the last part of the function, and hence 1410*0fca6ea1SDimitry Andric // this should be rewritten as a `ret` or `unreachable`. 1411*0fca6ea1SDimitry Andric if (newFunction->doesNotReturn()) { 1412*0fca6ea1SDimitry Andric // If fn is no return, end with an unreachable terminator. 1413*0fca6ea1SDimitry Andric (void)new UnreachableInst(Context, TheSwitch->getIterator()); 1414*0fca6ea1SDimitry Andric } else if (OldFnRetTy->isVoidTy()) { 1415*0fca6ea1SDimitry Andric // We have no return value. 1416*0fca6ea1SDimitry Andric ReturnInst::Create(Context, nullptr, 1417*0fca6ea1SDimitry Andric TheSwitch->getIterator()); // Return void 14180b57cec5SDimitry Andric } else if (OldFnRetTy == TheSwitch->getCondition()->getType()) { 14190b57cec5SDimitry Andric // return what we have 1420*0fca6ea1SDimitry Andric ReturnInst::Create(Context, TheSwitch->getCondition(), 1421*0fca6ea1SDimitry Andric TheSwitch->getIterator()); 14220b57cec5SDimitry Andric } else { 14230b57cec5SDimitry Andric // Otherwise we must have code extracted an unwind or something, just 14240b57cec5SDimitry Andric // return whatever we want. 1425*0fca6ea1SDimitry Andric ReturnInst::Create(Context, Constant::getNullValue(OldFnRetTy), 1426*0fca6ea1SDimitry Andric TheSwitch->getIterator()); 14270b57cec5SDimitry Andric } 14280b57cec5SDimitry Andric 14290b57cec5SDimitry Andric TheSwitch->eraseFromParent(); 14300b57cec5SDimitry Andric break; 14310b57cec5SDimitry Andric case 1: 14320b57cec5SDimitry Andric // Only a single destination, change the switch into an unconditional 14330b57cec5SDimitry Andric // branch. 1434*0fca6ea1SDimitry Andric BranchInst::Create(TheSwitch->getSuccessor(1), TheSwitch->getIterator()); 14350b57cec5SDimitry Andric TheSwitch->eraseFromParent(); 14360b57cec5SDimitry Andric break; 14370b57cec5SDimitry Andric case 2: 14380b57cec5SDimitry Andric BranchInst::Create(TheSwitch->getSuccessor(1), TheSwitch->getSuccessor(2), 1439*0fca6ea1SDimitry Andric call, TheSwitch->getIterator()); 14400b57cec5SDimitry Andric TheSwitch->eraseFromParent(); 14410b57cec5SDimitry Andric break; 14420b57cec5SDimitry Andric default: 14430b57cec5SDimitry Andric // Otherwise, make the default destination of the switch instruction be one 14440b57cec5SDimitry Andric // of the other successors. 14450b57cec5SDimitry Andric TheSwitch->setCondition(call); 14460b57cec5SDimitry Andric TheSwitch->setDefaultDest(TheSwitch->getSuccessor(NumExitBlocks)); 14470b57cec5SDimitry Andric // Remove redundant case 14480b57cec5SDimitry Andric TheSwitch->removeCase(SwitchInst::CaseIt(TheSwitch, NumExitBlocks-1)); 14490b57cec5SDimitry Andric break; 14500b57cec5SDimitry Andric } 14510b57cec5SDimitry Andric 14520b57cec5SDimitry Andric // Insert lifetime markers around the reloads of any output values. The 14530b57cec5SDimitry Andric // allocas output values are stored in are only in-use in the codeRepl block. 14540b57cec5SDimitry Andric insertLifetimeMarkersSurroundingCall(M, ReloadOutputs, ReloadOutputs, call); 14550b57cec5SDimitry Andric 14560b57cec5SDimitry Andric return call; 14570b57cec5SDimitry Andric } 14580b57cec5SDimitry Andric 14590b57cec5SDimitry Andric void CodeExtractor::moveCodeToFunction(Function *newFunction) { 1460349cc55cSDimitry Andric auto newFuncIt = newFunction->front().getIterator(); 14610b57cec5SDimitry Andric for (BasicBlock *Block : Blocks) { 14620b57cec5SDimitry Andric // Delete the basic block from the old function, and the list of blocks 1463bdd1243dSDimitry Andric Block->removeFromParent(); 14640b57cec5SDimitry Andric 14650b57cec5SDimitry Andric // Insert this basic block into the new function 1466349cc55cSDimitry Andric // Insert the original blocks after the entry block created 1467349cc55cSDimitry Andric // for the new function. The entry block may be followed 1468349cc55cSDimitry Andric // by a set of exit blocks at this point, but these exit 1469349cc55cSDimitry Andric // blocks better be placed at the end of the new function. 1470bdd1243dSDimitry Andric newFuncIt = newFunction->insert(std::next(newFuncIt), Block); 14710b57cec5SDimitry Andric } 14720b57cec5SDimitry Andric } 14730b57cec5SDimitry Andric 14740b57cec5SDimitry Andric void CodeExtractor::calculateNewCallTerminatorWeights( 14750b57cec5SDimitry Andric BasicBlock *CodeReplacer, 14760b57cec5SDimitry Andric DenseMap<BasicBlock *, BlockFrequency> &ExitWeights, 14770b57cec5SDimitry Andric BranchProbabilityInfo *BPI) { 14780b57cec5SDimitry Andric using Distribution = BlockFrequencyInfoImplBase::Distribution; 14790b57cec5SDimitry Andric using BlockNode = BlockFrequencyInfoImplBase::BlockNode; 14800b57cec5SDimitry Andric 14810b57cec5SDimitry Andric // Update the branch weights for the exit block. 14820b57cec5SDimitry Andric Instruction *TI = CodeReplacer->getTerminator(); 14830b57cec5SDimitry Andric SmallVector<unsigned, 8> BranchWeights(TI->getNumSuccessors(), 0); 14840b57cec5SDimitry Andric 14850b57cec5SDimitry Andric // Block Frequency distribution with dummy node. 14860b57cec5SDimitry Andric Distribution BranchDist; 14870b57cec5SDimitry Andric 14885ffd83dbSDimitry Andric SmallVector<BranchProbability, 4> EdgeProbabilities( 14895ffd83dbSDimitry Andric TI->getNumSuccessors(), BranchProbability::getUnknown()); 14905ffd83dbSDimitry Andric 14910b57cec5SDimitry Andric // Add each of the frequencies of the successors. 14920b57cec5SDimitry Andric for (unsigned i = 0, e = TI->getNumSuccessors(); i < e; ++i) { 14930b57cec5SDimitry Andric BlockNode ExitNode(i); 14940b57cec5SDimitry Andric uint64_t ExitFreq = ExitWeights[TI->getSuccessor(i)].getFrequency(); 14950b57cec5SDimitry Andric if (ExitFreq != 0) 14960b57cec5SDimitry Andric BranchDist.addExit(ExitNode, ExitFreq); 14970b57cec5SDimitry Andric else 14985ffd83dbSDimitry Andric EdgeProbabilities[i] = BranchProbability::getZero(); 14990b57cec5SDimitry Andric } 15000b57cec5SDimitry Andric 15010b57cec5SDimitry Andric // Check for no total weight. 15025ffd83dbSDimitry Andric if (BranchDist.Total == 0) { 15035ffd83dbSDimitry Andric BPI->setEdgeProbability(CodeReplacer, EdgeProbabilities); 15040b57cec5SDimitry Andric return; 15055ffd83dbSDimitry Andric } 15060b57cec5SDimitry Andric 15070b57cec5SDimitry Andric // Normalize the distribution so that they can fit in unsigned. 15080b57cec5SDimitry Andric BranchDist.normalize(); 15090b57cec5SDimitry Andric 15100b57cec5SDimitry Andric // Create normalized branch weights and set the metadata. 15110b57cec5SDimitry Andric for (unsigned I = 0, E = BranchDist.Weights.size(); I < E; ++I) { 15120b57cec5SDimitry Andric const auto &Weight = BranchDist.Weights[I]; 15130b57cec5SDimitry Andric 15140b57cec5SDimitry Andric // Get the weight and update the current BFI. 15150b57cec5SDimitry Andric BranchWeights[Weight.TargetNode.Index] = Weight.Amount; 15160b57cec5SDimitry Andric BranchProbability BP(Weight.Amount, BranchDist.Total); 15175ffd83dbSDimitry Andric EdgeProbabilities[Weight.TargetNode.Index] = BP; 15180b57cec5SDimitry Andric } 15195ffd83dbSDimitry Andric BPI->setEdgeProbability(CodeReplacer, EdgeProbabilities); 15200b57cec5SDimitry Andric TI->setMetadata( 15210b57cec5SDimitry Andric LLVMContext::MD_prof, 15220b57cec5SDimitry Andric MDBuilder(TI->getContext()).createBranchWeights(BranchWeights)); 15230b57cec5SDimitry Andric } 15240b57cec5SDimitry Andric 15255ffd83dbSDimitry Andric /// Erase debug info intrinsics which refer to values in \p F but aren't in 15265ffd83dbSDimitry Andric /// \p F. 15275ffd83dbSDimitry Andric static void eraseDebugIntrinsicsWithNonLocalRefs(Function &F) { 15285ffd83dbSDimitry Andric for (Instruction &I : instructions(F)) { 15295ffd83dbSDimitry Andric SmallVector<DbgVariableIntrinsic *, 4> DbgUsers; 1530*0fca6ea1SDimitry Andric SmallVector<DbgVariableRecord *, 4> DbgVariableRecords; 1531*0fca6ea1SDimitry Andric findDbgUsers(DbgUsers, &I, &DbgVariableRecords); 15325ffd83dbSDimitry Andric for (DbgVariableIntrinsic *DVI : DbgUsers) 15335ffd83dbSDimitry Andric if (DVI->getFunction() != &F) 15345ffd83dbSDimitry Andric DVI->eraseFromParent(); 1535*0fca6ea1SDimitry Andric for (DbgVariableRecord *DVR : DbgVariableRecords) 1536*0fca6ea1SDimitry Andric if (DVR->getFunction() != &F) 1537*0fca6ea1SDimitry Andric DVR->eraseFromParent(); 15385ffd83dbSDimitry Andric } 15395ffd83dbSDimitry Andric } 15405ffd83dbSDimitry Andric 15415ffd83dbSDimitry Andric /// Fix up the debug info in the old and new functions by pointing line 15425ffd83dbSDimitry Andric /// locations and debug intrinsics to the new subprogram scope, and by deleting 15435ffd83dbSDimitry Andric /// intrinsics which point to values outside of the new function. 15445ffd83dbSDimitry Andric static void fixupDebugInfoPostExtraction(Function &OldFunc, Function &NewFunc, 15455ffd83dbSDimitry Andric CallInst &TheCall) { 15465ffd83dbSDimitry Andric DISubprogram *OldSP = OldFunc.getSubprogram(); 15475ffd83dbSDimitry Andric LLVMContext &Ctx = OldFunc.getContext(); 15485ffd83dbSDimitry Andric 15495ffd83dbSDimitry Andric if (!OldSP) { 15505ffd83dbSDimitry Andric // Erase any debug info the new function contains. 15515ffd83dbSDimitry Andric stripDebugInfo(NewFunc); 15525ffd83dbSDimitry Andric // Make sure the old function doesn't contain any non-local metadata refs. 15535ffd83dbSDimitry Andric eraseDebugIntrinsicsWithNonLocalRefs(NewFunc); 15545ffd83dbSDimitry Andric return; 15555ffd83dbSDimitry Andric } 15565ffd83dbSDimitry Andric 15575ffd83dbSDimitry Andric // Create a subprogram for the new function. Leave out a description of the 15585ffd83dbSDimitry Andric // function arguments, as the parameters don't correspond to anything at the 15595ffd83dbSDimitry Andric // source level. 15605ffd83dbSDimitry Andric assert(OldSP->getUnit() && "Missing compile unit for subprogram"); 1561e8d8bef9SDimitry Andric DIBuilder DIB(*OldFunc.getParent(), /*AllowUnresolved=*/false, 15625ffd83dbSDimitry Andric OldSP->getUnit()); 1563bdd1243dSDimitry Andric auto SPType = 1564bdd1243dSDimitry Andric DIB.createSubroutineType(DIB.getOrCreateTypeArray(std::nullopt)); 15655ffd83dbSDimitry Andric DISubprogram::DISPFlags SPFlags = DISubprogram::SPFlagDefinition | 15665ffd83dbSDimitry Andric DISubprogram::SPFlagOptimized | 15675ffd83dbSDimitry Andric DISubprogram::SPFlagLocalToUnit; 15685ffd83dbSDimitry Andric auto NewSP = DIB.createFunction( 15695ffd83dbSDimitry Andric OldSP->getUnit(), NewFunc.getName(), NewFunc.getName(), OldSP->getFile(), 15705ffd83dbSDimitry Andric /*LineNo=*/0, SPType, /*ScopeLine=*/0, DINode::FlagZero, SPFlags); 15715ffd83dbSDimitry Andric NewFunc.setSubprogram(NewSP); 15725ffd83dbSDimitry Andric 15735f757f3fSDimitry Andric auto IsInvalidLocation = [&NewFunc](Value *Location) { 15745f757f3fSDimitry Andric // Location is invalid if it isn't a constant or an instruction, or is an 15755f757f3fSDimitry Andric // instruction but isn't in the new function. 15765f757f3fSDimitry Andric if (!Location || 15775f757f3fSDimitry Andric (!isa<Constant>(Location) && !isa<Instruction>(Location))) 15785f757f3fSDimitry Andric return true; 15795f757f3fSDimitry Andric Instruction *LocationInst = dyn_cast<Instruction>(Location); 15805f757f3fSDimitry Andric return LocationInst && LocationInst->getFunction() != &NewFunc; 15815f757f3fSDimitry Andric }; 15825f757f3fSDimitry Andric 15835ffd83dbSDimitry Andric // Debug intrinsics in the new function need to be updated in one of two 15845ffd83dbSDimitry Andric // ways: 15855ffd83dbSDimitry Andric // 1) They need to be deleted, because they describe a value in the old 15865ffd83dbSDimitry Andric // function. 15875ffd83dbSDimitry Andric // 2) They need to point to fresh metadata, e.g. because they currently 15885ffd83dbSDimitry Andric // point to a variable in the wrong scope. 15895ffd83dbSDimitry Andric SmallDenseMap<DINode *, DINode *> RemappedMetadata; 15905ffd83dbSDimitry Andric SmallVector<Instruction *, 4> DebugIntrinsicsToDelete; 1591*0fca6ea1SDimitry Andric SmallVector<DbgVariableRecord *, 4> DVRsToDelete; 1592bdd1243dSDimitry Andric DenseMap<const MDNode *, MDNode *> Cache; 15935f757f3fSDimitry Andric 15945f757f3fSDimitry Andric auto GetUpdatedDIVariable = [&](DILocalVariable *OldVar) { 15955f757f3fSDimitry Andric DINode *&NewVar = RemappedMetadata[OldVar]; 15965f757f3fSDimitry Andric if (!NewVar) { 15975f757f3fSDimitry Andric DILocalScope *NewScope = DILocalScope::cloneScopeForSubprogram( 15985f757f3fSDimitry Andric *OldVar->getScope(), *NewSP, Ctx, Cache); 15995f757f3fSDimitry Andric NewVar = DIB.createAutoVariable( 16005f757f3fSDimitry Andric NewScope, OldVar->getName(), OldVar->getFile(), OldVar->getLine(), 16015f757f3fSDimitry Andric OldVar->getType(), /*AlwaysPreserve=*/false, DINode::FlagZero, 16025f757f3fSDimitry Andric OldVar->getAlignInBits()); 16035f757f3fSDimitry Andric } 16045f757f3fSDimitry Andric return cast<DILocalVariable>(NewVar); 16055f757f3fSDimitry Andric }; 16065f757f3fSDimitry Andric 1607*0fca6ea1SDimitry Andric auto UpdateDbgLabel = [&](auto *LabelRecord) { 1608*0fca6ea1SDimitry Andric // Point the label record to a fresh label within the new function if 1609*0fca6ea1SDimitry Andric // the record was not inlined from some other function. 1610*0fca6ea1SDimitry Andric if (LabelRecord->getDebugLoc().getInlinedAt()) 1611*0fca6ea1SDimitry Andric return; 1612*0fca6ea1SDimitry Andric DILabel *OldLabel = LabelRecord->getLabel(); 1613*0fca6ea1SDimitry Andric DINode *&NewLabel = RemappedMetadata[OldLabel]; 1614*0fca6ea1SDimitry Andric if (!NewLabel) { 1615*0fca6ea1SDimitry Andric DILocalScope *NewScope = DILocalScope::cloneScopeForSubprogram( 1616*0fca6ea1SDimitry Andric *OldLabel->getScope(), *NewSP, Ctx, Cache); 1617*0fca6ea1SDimitry Andric NewLabel = DILabel::get(Ctx, NewScope, OldLabel->getName(), 1618*0fca6ea1SDimitry Andric OldLabel->getFile(), OldLabel->getLine()); 1619*0fca6ea1SDimitry Andric } 1620*0fca6ea1SDimitry Andric LabelRecord->setLabel(cast<DILabel>(NewLabel)); 1621*0fca6ea1SDimitry Andric }; 1622*0fca6ea1SDimitry Andric 1623*0fca6ea1SDimitry Andric auto UpdateDbgRecordsOnInst = [&](Instruction &I) -> void { 1624*0fca6ea1SDimitry Andric for (DbgRecord &DR : I.getDbgRecordRange()) { 1625*0fca6ea1SDimitry Andric if (DbgLabelRecord *DLR = dyn_cast<DbgLabelRecord>(&DR)) { 1626*0fca6ea1SDimitry Andric UpdateDbgLabel(DLR); 1627*0fca6ea1SDimitry Andric continue; 1628*0fca6ea1SDimitry Andric } 1629*0fca6ea1SDimitry Andric 1630*0fca6ea1SDimitry Andric DbgVariableRecord &DVR = cast<DbgVariableRecord>(DR); 16315f757f3fSDimitry Andric // Apply the two updates that dbg.values get: invalid operands, and 16325f757f3fSDimitry Andric // variable metadata fixup. 1633*0fca6ea1SDimitry Andric if (any_of(DVR.location_ops(), IsInvalidLocation)) { 1634*0fca6ea1SDimitry Andric DVRsToDelete.push_back(&DVR); 16355f757f3fSDimitry Andric continue; 16365f757f3fSDimitry Andric } 1637*0fca6ea1SDimitry Andric if (DVR.isDbgAssign() && IsInvalidLocation(DVR.getAddress())) { 1638*0fca6ea1SDimitry Andric DVRsToDelete.push_back(&DVR); 16397a6dacacSDimitry Andric continue; 16407a6dacacSDimitry Andric } 1641*0fca6ea1SDimitry Andric if (!DVR.getDebugLoc().getInlinedAt()) 1642*0fca6ea1SDimitry Andric DVR.setVariable(GetUpdatedDIVariable(DVR.getVariable())); 16435f757f3fSDimitry Andric } 16445f757f3fSDimitry Andric }; 16455f757f3fSDimitry Andric 16465ffd83dbSDimitry Andric for (Instruction &I : instructions(NewFunc)) { 1647*0fca6ea1SDimitry Andric UpdateDbgRecordsOnInst(I); 16485f757f3fSDimitry Andric 16495ffd83dbSDimitry Andric auto *DII = dyn_cast<DbgInfoIntrinsic>(&I); 16505ffd83dbSDimitry Andric if (!DII) 16515ffd83dbSDimitry Andric continue; 16525ffd83dbSDimitry Andric 1653bdd1243dSDimitry Andric // Point the intrinsic to a fresh label within the new function if the 1654bdd1243dSDimitry Andric // intrinsic was not inlined from some other function. 16555ffd83dbSDimitry Andric if (auto *DLI = dyn_cast<DbgLabelInst>(&I)) { 1656*0fca6ea1SDimitry Andric UpdateDbgLabel(DLI); 16575ffd83dbSDimitry Andric continue; 16585ffd83dbSDimitry Andric } 16595ffd83dbSDimitry Andric 1660fe6060f1SDimitry Andric auto *DVI = cast<DbgVariableIntrinsic>(DII); 1661fe6060f1SDimitry Andric // If any of the used locations are invalid, delete the intrinsic. 1662fe6060f1SDimitry Andric if (any_of(DVI->location_ops(), IsInvalidLocation)) { 16635ffd83dbSDimitry Andric DebugIntrinsicsToDelete.push_back(DVI); 16645ffd83dbSDimitry Andric continue; 16655ffd83dbSDimitry Andric } 16665f757f3fSDimitry Andric // DbgAssign intrinsics have an extra Value argument: 16675f757f3fSDimitry Andric if (auto *DAI = dyn_cast<DbgAssignIntrinsic>(DVI); 16685f757f3fSDimitry Andric DAI && IsInvalidLocation(DAI->getAddress())) { 16695f757f3fSDimitry Andric DebugIntrinsicsToDelete.push_back(DVI); 16705f757f3fSDimitry Andric continue; 16715f757f3fSDimitry Andric } 1672bdd1243dSDimitry Andric // If the variable was in the scope of the old function, i.e. it was not 1673bdd1243dSDimitry Andric // inlined, point the intrinsic to a fresh variable within the new function. 16745f757f3fSDimitry Andric if (!DVI->getDebugLoc().getInlinedAt()) 16755f757f3fSDimitry Andric DVI->setVariable(GetUpdatedDIVariable(DVI->getVariable())); 1676bdd1243dSDimitry Andric } 1677bdd1243dSDimitry Andric 16785ffd83dbSDimitry Andric for (auto *DII : DebugIntrinsicsToDelete) 16795ffd83dbSDimitry Andric DII->eraseFromParent(); 1680*0fca6ea1SDimitry Andric for (auto *DVR : DVRsToDelete) 1681*0fca6ea1SDimitry Andric DVR->getMarker()->MarkedInstr->dropOneDbgRecord(DVR); 16825ffd83dbSDimitry Andric DIB.finalizeSubprogram(NewSP); 16835ffd83dbSDimitry Andric 1684*0fca6ea1SDimitry Andric // Fix up the scope information attached to the line locations and the 1685*0fca6ea1SDimitry Andric // debug assignment metadata in the new function. 1686*0fca6ea1SDimitry Andric DenseMap<DIAssignID *, DIAssignID *> AssignmentIDMap; 16875ffd83dbSDimitry Andric for (Instruction &I : instructions(NewFunc)) { 16885ffd83dbSDimitry Andric if (const DebugLoc &DL = I.getDebugLoc()) 1689bdd1243dSDimitry Andric I.setDebugLoc( 1690bdd1243dSDimitry Andric DebugLoc::replaceInlinedAtSubprogram(DL, *NewSP, Ctx, Cache)); 1691*0fca6ea1SDimitry Andric for (DbgRecord &DR : I.getDbgRecordRange()) 1692*0fca6ea1SDimitry Andric DR.setDebugLoc(DebugLoc::replaceInlinedAtSubprogram(DR.getDebugLoc(), 1693*0fca6ea1SDimitry Andric *NewSP, Ctx, Cache)); 16945ffd83dbSDimitry Andric 16955ffd83dbSDimitry Andric // Loop info metadata may contain line locations. Fix them up. 1696bdd1243dSDimitry Andric auto updateLoopInfoLoc = [&Ctx, &Cache, NewSP](Metadata *MD) -> Metadata * { 1697fe6060f1SDimitry Andric if (auto *Loc = dyn_cast_or_null<DILocation>(MD)) 1698bdd1243dSDimitry Andric return DebugLoc::replaceInlinedAtSubprogram(Loc, *NewSP, Ctx, Cache); 1699fe6060f1SDimitry Andric return MD; 17005ffd83dbSDimitry Andric }; 17015ffd83dbSDimitry Andric updateLoopMetadataDebugLocations(I, updateLoopInfoLoc); 1702*0fca6ea1SDimitry Andric at::remapAssignID(AssignmentIDMap, I); 17035ffd83dbSDimitry Andric } 17045ffd83dbSDimitry Andric if (!TheCall.getDebugLoc()) 1705e8d8bef9SDimitry Andric TheCall.setDebugLoc(DILocation::get(Ctx, 0, 0, OldSP)); 17065ffd83dbSDimitry Andric 17075ffd83dbSDimitry Andric eraseDebugIntrinsicsWithNonLocalRefs(NewFunc); 17085ffd83dbSDimitry Andric } 17095ffd83dbSDimitry Andric 17108bcb0991SDimitry Andric Function * 17118bcb0991SDimitry Andric CodeExtractor::extractCodeRegion(const CodeExtractorAnalysisCache &CEAC) { 1712349cc55cSDimitry Andric ValueSet Inputs, Outputs; 1713349cc55cSDimitry Andric return extractCodeRegion(CEAC, Inputs, Outputs); 1714349cc55cSDimitry Andric } 1715349cc55cSDimitry Andric 1716349cc55cSDimitry Andric Function * 1717349cc55cSDimitry Andric CodeExtractor::extractCodeRegion(const CodeExtractorAnalysisCache &CEAC, 1718349cc55cSDimitry Andric ValueSet &inputs, ValueSet &outputs) { 17190b57cec5SDimitry Andric if (!isEligible()) 17200b57cec5SDimitry Andric return nullptr; 17210b57cec5SDimitry Andric 17220b57cec5SDimitry Andric // Assumption: this is a single-entry code region, and the header is the first 17230b57cec5SDimitry Andric // block in the region. 17240b57cec5SDimitry Andric BasicBlock *header = *Blocks.begin(); 17250b57cec5SDimitry Andric Function *oldFunction = header->getParent(); 17260b57cec5SDimitry Andric 17270b57cec5SDimitry Andric // Calculate the entry frequency of the new function before we change the root 17280b57cec5SDimitry Andric // block. 17290b57cec5SDimitry Andric BlockFrequency EntryFreq; 17300b57cec5SDimitry Andric if (BFI) { 17310b57cec5SDimitry Andric assert(BPI && "Both BPI and BFI are required to preserve profile info"); 17320b57cec5SDimitry Andric for (BasicBlock *Pred : predecessors(header)) { 17330b57cec5SDimitry Andric if (Blocks.count(Pred)) 17340b57cec5SDimitry Andric continue; 17350b57cec5SDimitry Andric EntryFreq += 17360b57cec5SDimitry Andric BFI->getBlockFreq(Pred) * BPI->getEdgeProbability(Pred, header); 17370b57cec5SDimitry Andric } 17380b57cec5SDimitry Andric } 17390b57cec5SDimitry Andric 174006c3fb27SDimitry Andric // Remove @llvm.assume calls that will be moved to the new function from the 174106c3fb27SDimitry Andric // old function's assumption cache. 17425ffd83dbSDimitry Andric for (BasicBlock *Block : Blocks) { 1743349cc55cSDimitry Andric for (Instruction &I : llvm::make_early_inc_range(*Block)) { 174406c3fb27SDimitry Andric if (auto *AI = dyn_cast<AssumeInst>(&I)) { 17455ffd83dbSDimitry Andric if (AC) 174606c3fb27SDimitry Andric AC->unregisterAssumption(AI); 174706c3fb27SDimitry Andric AI->eraseFromParent(); 17485ffd83dbSDimitry Andric } 17495ffd83dbSDimitry Andric } 17508bcb0991SDimitry Andric } 17518bcb0991SDimitry Andric 17520b57cec5SDimitry Andric // If we have any return instructions in the region, split those blocks so 17530b57cec5SDimitry Andric // that the return is not in the region. 17540b57cec5SDimitry Andric splitReturnBlocks(); 17550b57cec5SDimitry Andric 17560b57cec5SDimitry Andric // Calculate the exit blocks for the extracted region and the total exit 17570b57cec5SDimitry Andric // weights for each of those blocks. 17580b57cec5SDimitry Andric DenseMap<BasicBlock *, BlockFrequency> ExitWeights; 1759*0fca6ea1SDimitry Andric SetVector<BasicBlock *> ExitBlocks; 17600b57cec5SDimitry Andric for (BasicBlock *Block : Blocks) { 1761fe6060f1SDimitry Andric for (BasicBlock *Succ : successors(Block)) { 1762fe6060f1SDimitry Andric if (!Blocks.count(Succ)) { 17630b57cec5SDimitry Andric // Update the branch weight for this successor. 17640b57cec5SDimitry Andric if (BFI) { 1765fe6060f1SDimitry Andric BlockFrequency &BF = ExitWeights[Succ]; 1766fe6060f1SDimitry Andric BF += BFI->getBlockFreq(Block) * BPI->getEdgeProbability(Block, Succ); 17670b57cec5SDimitry Andric } 1768fe6060f1SDimitry Andric ExitBlocks.insert(Succ); 17690b57cec5SDimitry Andric } 17700b57cec5SDimitry Andric } 17710b57cec5SDimitry Andric } 17720b57cec5SDimitry Andric NumExitBlocks = ExitBlocks.size(); 17730b57cec5SDimitry Andric 1774349cc55cSDimitry Andric for (BasicBlock *Block : Blocks) { 17757a6dacacSDimitry Andric for (BasicBlock *OldTarget : successors(Block)) 17767a6dacacSDimitry Andric if (!Blocks.contains(OldTarget)) 1777349cc55cSDimitry Andric OldTargets.push_back(OldTarget); 1778349cc55cSDimitry Andric } 1779349cc55cSDimitry Andric 17800b57cec5SDimitry Andric // If we have to split PHI nodes of the entry or exit blocks, do so now. 17810b57cec5SDimitry Andric severSplitPHINodesOfEntry(header); 17820b57cec5SDimitry Andric severSplitPHINodesOfExits(ExitBlocks); 17830b57cec5SDimitry Andric 17840b57cec5SDimitry Andric // This takes place of the original loop 17850b57cec5SDimitry Andric BasicBlock *codeReplacer = BasicBlock::Create(header->getContext(), 17860b57cec5SDimitry Andric "codeRepl", oldFunction, 17870b57cec5SDimitry Andric header); 17885f757f3fSDimitry Andric codeReplacer->IsNewDbgInfoFormat = oldFunction->IsNewDbgInfoFormat; 17890b57cec5SDimitry Andric 17900b57cec5SDimitry Andric // The new function needs a root node because other nodes can branch to the 17910b57cec5SDimitry Andric // head of the region, but the entry node of a function cannot have preds. 17920b57cec5SDimitry Andric BasicBlock *newFuncRoot = BasicBlock::Create(header->getContext(), 17930b57cec5SDimitry Andric "newFuncRoot"); 17945f757f3fSDimitry Andric newFuncRoot->IsNewDbgInfoFormat = oldFunction->IsNewDbgInfoFormat; 17955f757f3fSDimitry Andric 17960b57cec5SDimitry Andric auto *BranchI = BranchInst::Create(header); 17970b57cec5SDimitry Andric // If the original function has debug info, we have to add a debug location 17980b57cec5SDimitry Andric // to the new branch instruction from the artificial entry block. 17990b57cec5SDimitry Andric // We use the debug location of the first instruction in the extracted 18000b57cec5SDimitry Andric // blocks, as there is no other equivalent line in the source code. 18010b57cec5SDimitry Andric if (oldFunction->getSubprogram()) { 18020b57cec5SDimitry Andric any_of(Blocks, [&BranchI](const BasicBlock *BB) { 18030b57cec5SDimitry Andric return any_of(*BB, [&BranchI](const Instruction &I) { 18040b57cec5SDimitry Andric if (!I.getDebugLoc()) 18050b57cec5SDimitry Andric return false; 1806*0fca6ea1SDimitry Andric // Don't use source locations attached to debug-intrinsics: they could 1807*0fca6ea1SDimitry Andric // be from completely unrelated scopes. 1808*0fca6ea1SDimitry Andric if (isa<DbgInfoIntrinsic>(I)) 1809*0fca6ea1SDimitry Andric return false; 18100b57cec5SDimitry Andric BranchI->setDebugLoc(I.getDebugLoc()); 18110b57cec5SDimitry Andric return true; 18120b57cec5SDimitry Andric }); 18130b57cec5SDimitry Andric }); 18140b57cec5SDimitry Andric } 1815bdd1243dSDimitry Andric BranchI->insertInto(newFuncRoot, newFuncRoot->end()); 18160b57cec5SDimitry Andric 1817349cc55cSDimitry Andric ValueSet SinkingCands, HoistingCands; 18188bcb0991SDimitry Andric BasicBlock *CommonExit = nullptr; 18198bcb0991SDimitry Andric findAllocas(CEAC, SinkingCands, HoistingCands, CommonExit); 18200b57cec5SDimitry Andric assert(HoistingCands.empty() || CommonExit); 18210b57cec5SDimitry Andric 18220b57cec5SDimitry Andric // Find inputs to, outputs from the code region. 18230b57cec5SDimitry Andric findInputsOutputs(inputs, outputs, SinkingCands); 18240b57cec5SDimitry Andric 18250b57cec5SDimitry Andric // Now sink all instructions which only have non-phi uses inside the region. 18260b57cec5SDimitry Andric // Group the allocas at the start of the block, so that any bitcast uses of 18270b57cec5SDimitry Andric // the allocas are well-defined. 18280b57cec5SDimitry Andric AllocaInst *FirstSunkAlloca = nullptr; 18290b57cec5SDimitry Andric for (auto *II : SinkingCands) { 18300b57cec5SDimitry Andric if (auto *AI = dyn_cast<AllocaInst>(II)) { 18310b57cec5SDimitry Andric AI->moveBefore(*newFuncRoot, newFuncRoot->getFirstInsertionPt()); 18320b57cec5SDimitry Andric if (!FirstSunkAlloca) 18330b57cec5SDimitry Andric FirstSunkAlloca = AI; 18340b57cec5SDimitry Andric } 18350b57cec5SDimitry Andric } 18360b57cec5SDimitry Andric assert((SinkingCands.empty() || FirstSunkAlloca) && 18370b57cec5SDimitry Andric "Did not expect a sink candidate without any allocas"); 18380b57cec5SDimitry Andric for (auto *II : SinkingCands) { 18390b57cec5SDimitry Andric if (!isa<AllocaInst>(II)) { 18400b57cec5SDimitry Andric cast<Instruction>(II)->moveAfter(FirstSunkAlloca); 18410b57cec5SDimitry Andric } 18420b57cec5SDimitry Andric } 18430b57cec5SDimitry Andric 18440b57cec5SDimitry Andric if (!HoistingCands.empty()) { 18450b57cec5SDimitry Andric auto *HoistToBlock = findOrCreateBlockForHoisting(CommonExit); 18460b57cec5SDimitry Andric Instruction *TI = HoistToBlock->getTerminator(); 18470b57cec5SDimitry Andric for (auto *II : HoistingCands) 18480b57cec5SDimitry Andric cast<Instruction>(II)->moveBefore(TI); 18490b57cec5SDimitry Andric } 18500b57cec5SDimitry Andric 18510b57cec5SDimitry Andric // Collect objects which are inputs to the extraction region and also 18520b57cec5SDimitry Andric // referenced by lifetime start markers within it. The effects of these 18530b57cec5SDimitry Andric // markers must be replicated in the calling function to prevent the stack 18540b57cec5SDimitry Andric // coloring pass from merging slots which store input objects. 18550b57cec5SDimitry Andric ValueSet LifetimesStart; 18560b57cec5SDimitry Andric eraseLifetimeMarkersOnInputs(Blocks, SinkingCands, LifetimesStart); 18570b57cec5SDimitry Andric 18580b57cec5SDimitry Andric // Construct new function based on inputs/outputs & add allocas for all defs. 18590b57cec5SDimitry Andric Function *newFunction = 18600b57cec5SDimitry Andric constructFunction(inputs, outputs, header, newFuncRoot, codeReplacer, 18610b57cec5SDimitry Andric oldFunction, oldFunction->getParent()); 18620b57cec5SDimitry Andric 18630b57cec5SDimitry Andric // Update the entry count of the function. 18640b57cec5SDimitry Andric if (BFI) { 18655f757f3fSDimitry Andric auto Count = BFI->getProfileCountFromFreq(EntryFreq); 186681ad6265SDimitry Andric if (Count) 18670b57cec5SDimitry Andric newFunction->setEntryCount( 1868bdd1243dSDimitry Andric ProfileCount(*Count, Function::PCT_Real)); // FIXME 18695f757f3fSDimitry Andric BFI->setBlockFreq(codeReplacer, EntryFreq); 18700b57cec5SDimitry Andric } 18710b57cec5SDimitry Andric 18720b57cec5SDimitry Andric CallInst *TheCall = 18730b57cec5SDimitry Andric emitCallAndSwitchStatement(newFunction, codeReplacer, inputs, outputs); 18740b57cec5SDimitry Andric 18750b57cec5SDimitry Andric moveCodeToFunction(newFunction); 18760b57cec5SDimitry Andric 18770b57cec5SDimitry Andric // Replicate the effects of any lifetime start/end markers which referenced 18780b57cec5SDimitry Andric // input objects in the extraction region by placing markers around the call. 18790b57cec5SDimitry Andric insertLifetimeMarkersSurroundingCall( 18800b57cec5SDimitry Andric oldFunction->getParent(), LifetimesStart.getArrayRef(), {}, TheCall); 18810b57cec5SDimitry Andric 18820b57cec5SDimitry Andric // Propagate personality info to the new function if there is one. 18830b57cec5SDimitry Andric if (oldFunction->hasPersonalityFn()) 18840b57cec5SDimitry Andric newFunction->setPersonalityFn(oldFunction->getPersonalityFn()); 18850b57cec5SDimitry Andric 18860b57cec5SDimitry Andric // Update the branch weights for the exit block. 18870b57cec5SDimitry Andric if (BFI && NumExitBlocks > 1) 18880b57cec5SDimitry Andric calculateNewCallTerminatorWeights(codeReplacer, ExitWeights, BPI); 18890b57cec5SDimitry Andric 18900b57cec5SDimitry Andric // Loop over all of the PHI nodes in the header and exit blocks, and change 18910b57cec5SDimitry Andric // any references to the old incoming edge to be the new incoming edge. 18920b57cec5SDimitry Andric for (BasicBlock::iterator I = header->begin(); isa<PHINode>(I); ++I) { 18930b57cec5SDimitry Andric PHINode *PN = cast<PHINode>(I); 18940b57cec5SDimitry Andric for (unsigned i = 0, e = PN->getNumIncomingValues(); i != e; ++i) 18950b57cec5SDimitry Andric if (!Blocks.count(PN->getIncomingBlock(i))) 18960b57cec5SDimitry Andric PN->setIncomingBlock(i, newFuncRoot); 18970b57cec5SDimitry Andric } 18980b57cec5SDimitry Andric 18990b57cec5SDimitry Andric for (BasicBlock *ExitBB : ExitBlocks) 19000b57cec5SDimitry Andric for (PHINode &PN : ExitBB->phis()) { 19010b57cec5SDimitry Andric Value *IncomingCodeReplacerVal = nullptr; 19020b57cec5SDimitry Andric for (unsigned i = 0, e = PN.getNumIncomingValues(); i != e; ++i) { 19030b57cec5SDimitry Andric // Ignore incoming values from outside of the extracted region. 19040b57cec5SDimitry Andric if (!Blocks.count(PN.getIncomingBlock(i))) 19050b57cec5SDimitry Andric continue; 19060b57cec5SDimitry Andric 19070b57cec5SDimitry Andric // Ensure that there is only one incoming value from codeReplacer. 19080b57cec5SDimitry Andric if (!IncomingCodeReplacerVal) { 19090b57cec5SDimitry Andric PN.setIncomingBlock(i, codeReplacer); 19100b57cec5SDimitry Andric IncomingCodeReplacerVal = PN.getIncomingValue(i); 19110b57cec5SDimitry Andric } else 19120b57cec5SDimitry Andric assert(IncomingCodeReplacerVal == PN.getIncomingValue(i) && 19130b57cec5SDimitry Andric "PHI has two incompatbile incoming values from codeRepl"); 19140b57cec5SDimitry Andric } 19150b57cec5SDimitry Andric } 19160b57cec5SDimitry Andric 19175ffd83dbSDimitry Andric fixupDebugInfoPostExtraction(*oldFunction, *newFunction, *TheCall); 19180b57cec5SDimitry Andric 19190b57cec5SDimitry Andric LLVM_DEBUG(if (verifyFunction(*newFunction, &errs())) { 19200b57cec5SDimitry Andric newFunction->dump(); 19210b57cec5SDimitry Andric report_fatal_error("verification of newFunction failed!"); 19220b57cec5SDimitry Andric }); 19230b57cec5SDimitry Andric LLVM_DEBUG(if (verifyFunction(*oldFunction)) 19240b57cec5SDimitry Andric report_fatal_error("verification of oldFunction failed!")); 19255ffd83dbSDimitry Andric LLVM_DEBUG(if (AC && verifyAssumptionCache(*oldFunction, *newFunction, AC)) 19268bcb0991SDimitry Andric report_fatal_error("Stale Asumption cache for old Function!")); 19270b57cec5SDimitry Andric return newFunction; 19280b57cec5SDimitry Andric } 19298bcb0991SDimitry Andric 19305ffd83dbSDimitry Andric bool CodeExtractor::verifyAssumptionCache(const Function &OldFunc, 19315ffd83dbSDimitry Andric const Function &NewFunc, 19328bcb0991SDimitry Andric AssumptionCache *AC) { 19338bcb0991SDimitry Andric for (auto AssumeVH : AC->assumptions()) { 193406c3fb27SDimitry Andric auto *I = dyn_cast_or_null<CallInst>(AssumeVH); 19355ffd83dbSDimitry Andric if (!I) 19365ffd83dbSDimitry Andric continue; 19375ffd83dbSDimitry Andric 19385ffd83dbSDimitry Andric // There shouldn't be any llvm.assume intrinsics in the new function. 19395ffd83dbSDimitry Andric if (I->getFunction() != &OldFunc) 19408bcb0991SDimitry Andric return true; 19415ffd83dbSDimitry Andric 19425ffd83dbSDimitry Andric // There shouldn't be any stale affected values in the assumption cache 19435ffd83dbSDimitry Andric // that were previously in the old function, but that have now been moved 19445ffd83dbSDimitry Andric // to the new function. 19455ffd83dbSDimitry Andric for (auto AffectedValVH : AC->assumptionsFor(I->getOperand(0))) { 194606c3fb27SDimitry Andric auto *AffectedCI = dyn_cast_or_null<CallInst>(AffectedValVH); 19475ffd83dbSDimitry Andric if (!AffectedCI) 19485ffd83dbSDimitry Andric continue; 19495ffd83dbSDimitry Andric if (AffectedCI->getFunction() != &OldFunc) 19505ffd83dbSDimitry Andric return true; 1951e8d8bef9SDimitry Andric auto *AssumedInst = cast<Instruction>(AffectedCI->getOperand(0)); 19525ffd83dbSDimitry Andric if (AssumedInst->getFunction() != &OldFunc) 19535ffd83dbSDimitry Andric return true; 19545ffd83dbSDimitry Andric } 19558bcb0991SDimitry Andric } 19568bcb0991SDimitry Andric return false; 19578bcb0991SDimitry Andric } 195804eeddc0SDimitry Andric 195904eeddc0SDimitry Andric void CodeExtractor::excludeArgFromAggregate(Value *Arg) { 196004eeddc0SDimitry Andric ExcludeArgsFromAggregate.insert(Arg); 196104eeddc0SDimitry Andric } 1962