#include "llvm/Transforms/Utils/CodeExtractor.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SetVector.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/Analysis/AssumptionCache.h"
#include "llvm/Analysis/BlockFrequencyInfo.h"
#include "llvm/Analysis/BlockFrequencyInfoImpl.h"
#include "llvm/Analysis/BranchProbabilityInfo.h"
#include "llvm/IR/Argument.h"
#include "llvm/IR/Attributes.h"
#include "llvm/IR/BasicBlock.h"
#include "llvm/IR/CFG.h"
#include "llvm/IR/Constant.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/DIBuilder.h"
#include "llvm/IR/DataLayout.h"
#include "llvm/IR/DebugInfo.h"
#include "llvm/IR/DebugInfoMetadata.h"
#include "llvm/IR/DerivedTypes.h"
#include "llvm/IR/Dominators.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/GlobalValue.h"
#include "llvm/IR/InstIterator.h"
#include "llvm/IR/InstrTypes.h"
#include "llvm/IR/Instruction.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/IntrinsicInst.h"
#include "llvm/IR/Intrinsics.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/MDBuilder.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/PatternMatch.h"
#include "llvm/IR/Type.h"
#include "llvm/IR/User.h"
#include "llvm/IR/Value.h"
#include "llvm/IR/Verifier.h"
#include "llvm/Support/BlockFrequency.h"
#include "llvm/Support/BranchProbability.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Transforms/Utils/BasicBlockUtils.h"
#include <cassert>
#include <cstdint>
#include <iterator>
#include <map>
#include <utility>
#include <vector>
usingnamespacellvm;
usingnamespacellvm::PatternMatch;
ProfileCount;
#define DEBUG_TYPE …
static cl::opt<bool>
AggregateArgsOpt("aggregate-extracted-args", cl::Hidden,
cl::desc("Aggregate arguments to code-extracted functions"));
static bool isBlockValidForExtraction(const BasicBlock &BB,
const SetVector<BasicBlock *> &Result,
bool AllowVarArgs, bool AllowAlloca) { … }
static SetVector<BasicBlock *>
buildExtractionBlockSet(ArrayRef<BasicBlock *> BBs, DominatorTree *DT,
bool AllowVarArgs, bool AllowAlloca) { … }
CodeExtractor::CodeExtractor(ArrayRef<BasicBlock *> BBs, DominatorTree *DT,
bool AggregateArgs, BlockFrequencyInfo *BFI,
BranchProbabilityInfo *BPI, AssumptionCache *AC,
bool AllowVarArgs, bool AllowAlloca,
BasicBlock *AllocationBlock, std::string Suffix,
bool ArgsInZeroAddressSpace)
: … { … }
static bool definedInRegion(const SetVector<BasicBlock *> &Blocks, Value *V) { … }
static bool definedInCaller(const SetVector<BasicBlock *> &Blocks, Value *V) { … }
static BasicBlock *getCommonExitBlock(const SetVector<BasicBlock *> &Blocks) { … }
CodeExtractorAnalysisCache::CodeExtractorAnalysisCache(Function &F) { … }
void CodeExtractorAnalysisCache::findSideEffectInfoForBlock(BasicBlock &BB) { … }
bool CodeExtractorAnalysisCache::doesBlockContainClobberOfAddr(
BasicBlock &BB, AllocaInst *Addr) const { … }
bool CodeExtractor::isLegalToShrinkwrapLifetimeMarkers(
const CodeExtractorAnalysisCache &CEAC, Instruction *Addr) const { … }
BasicBlock *
CodeExtractor::findOrCreateBlockForHoisting(BasicBlock *CommonExitBlock) { … }
CodeExtractor::LifetimeMarkerInfo
CodeExtractor::getLifetimeMarkers(const CodeExtractorAnalysisCache &CEAC,
Instruction *Addr,
BasicBlock *ExitBlock) const { … }
void CodeExtractor::findAllocas(const CodeExtractorAnalysisCache &CEAC,
ValueSet &SinkCands, ValueSet &HoistCands,
BasicBlock *&ExitBlock) const { … }
bool CodeExtractor::isEligible() const { … }
void CodeExtractor::findInputsOutputs(ValueSet &Inputs, ValueSet &Outputs,
const ValueSet &SinkCands,
bool CollectGlobalInputs) const { … }
void CodeExtractor::severSplitPHINodesOfEntry(BasicBlock *&Header) { … }
void CodeExtractor::severSplitPHINodesOfExits(
const SetVector<BasicBlock *> &Exits) { … }
void CodeExtractor::splitReturnBlocks() { … }
Function *CodeExtractor::constructFunction(const ValueSet &inputs,
const ValueSet &outputs,
BasicBlock *header,
BasicBlock *newRootNode,
BasicBlock *newHeader,
Function *oldFunction,
Module *M) { … }
static void eraseLifetimeMarkersOnInputs(const SetVector<BasicBlock *> &Blocks,
const SetVector<Value *> &SunkAllocas,
SetVector<Value *> &LifetimesStart) { … }
static void insertLifetimeMarkersSurroundingCall(
Module *M, ArrayRef<Value *> LifetimesStart, ArrayRef<Value *> LifetimesEnd,
CallInst *TheCall) { … }
CallInst *CodeExtractor::emitCallAndSwitchStatement(Function *newFunction,
BasicBlock *codeReplacer,
ValueSet &inputs,
ValueSet &outputs) { … }
void CodeExtractor::moveCodeToFunction(Function *newFunction) { … }
void CodeExtractor::calculateNewCallTerminatorWeights(
BasicBlock *CodeReplacer,
DenseMap<BasicBlock *, BlockFrequency> &ExitWeights,
BranchProbabilityInfo *BPI) { … }
static void eraseDebugIntrinsicsWithNonLocalRefs(Function &F) { … }
static void fixupDebugInfoPostExtraction(Function &OldFunc, Function &NewFunc,
CallInst &TheCall) { … }
Function *
CodeExtractor::extractCodeRegion(const CodeExtractorAnalysisCache &CEAC) { … }
Function *
CodeExtractor::extractCodeRegion(const CodeExtractorAnalysisCache &CEAC,
ValueSet &inputs, ValueSet &outputs) { … }
bool CodeExtractor::verifyAssumptionCache(const Function &OldFunc,
const Function &NewFunc,
AssumptionCache *AC) { … }
void CodeExtractor::excludeArgFromAggregate(Value *Arg) { … }