32 cl::desc(
"Whether or not to compute detailed function properties."));
36 cl::desc(
"The minimum number of instructions a basic block should contain "
37 "before being considered big."));
41 cl::desc(
"The minimum number of instructions a basic block should contain "
42 "before being considered medium-sized."));
47 cl::desc(
"The minimum number of arguments a function call must have before "
48 "it is considered having many arguments."));
51int64_t getNumBlocksFromCond(
const BasicBlock &BB) {
53 if (
const auto *BI = dyn_cast<BranchInst>(BB.
getTerminator())) {
54 if (BI->isConditional())
55 Ret += BI->getNumSuccessors();
56 }
else if (
const auto *SI = dyn_cast<SwitchInst>(BB.
getTerminator())) {
57 Ret += (
SI->getNumCases() + (
nullptr !=
SI->getDefaultDest()));
63 return ((!
F.hasLocalLinkage()) ? 1 : 0) +
F.getNumUses();
67void FunctionPropertiesInfo::reIncludeBB(
const BasicBlock &BB) {
71void FunctionPropertiesInfo::updateForBB(
const BasicBlock &BB,
77 for (
const auto &
I : BB) {
78 if (
auto *CS = dyn_cast<CallBase>(&
I)) {
79 const auto *
Callee = CS->getCalledFunction();
80 if (Callee && !
Callee->isIntrinsic() && !
Callee->isDeclaration())
83 if (
I.getOpcode() == Instruction::Load) {
85 }
else if (
I.getOpcode() == Instruction::Store) {
93 if (SuccessorCount == 1)
95 else if (SuccessorCount == 2)
97 else if (SuccessorCount > 2)
100 unsigned PredecessorCount =
pred_size(&BB);
101 if (PredecessorCount == 1)
103 else if (PredecessorCount == 2)
105 else if (PredecessorCount > 2)
118 if (SuccessorCount > 1) {
127 if (
const auto *BI = dyn_cast<BranchInst>(BB.getTerminator())) {
128 if (!BI->isConditional())
132 for (
const Instruction &
I : BB.instructionsWithoutDebug()) {
136 if (
I.getType()->isFloatTy())
138 else if (
I.getType()->isIntegerTy())
141 if (isa<IntrinsicInst>(
I))
144 if (
const auto *Call = dyn_cast<CallInst>(&
I)) {
145 if (
Call->isIndirectCall())
150 if (
Call->getType()->isIntegerTy())
152 else if (
Call->getType()->isFloatingPointTy())
154 else if (
Call->getType()->isPointerTy())
156 else if (
Call->getType()->isVectorTy()) {
157 if (
Call->getType()->getScalarType()->isIntegerTy())
159 else if (
Call->getType()->getScalarType()->isFloatingPointTy())
161 else if (
Call->getType()->getScalarType()->isPointerTy())
168 for (
const auto &Arg :
Call->args()) {
169 if (Arg->getType()->isPointerTy()) {
176#define COUNT_OPERAND(OPTYPE) \
177 if (isa<OPTYPE>(Operand)) { \
178 OPTYPE##OperandCount += Direction; \
182 for (
unsigned int OperandIndex = 0; OperandIndex <
I.getNumOperands();
184 Value *Operand =
I.getOperand(OperandIndex);
208 *BB.getParent(), *IR2VecVocab);
210 BB.getContext().emitError(
"Error creating IR2Vec embeddings");
213 const auto &BBEmbedding = Embedder->getBBVector(BB);
217 FunctionEmbedding -= BBEmbedding;
219 FunctionEmbedding += BBEmbedding;
223void FunctionPropertiesInfo::updateAggregateStats(
const Function &
F,
229 std::deque<const Loop *> Worklist;
231 while (!Worklist.empty()) {
232 const auto *
L = Worklist.front();
234 std::max(
MaxLoopDepth,
static_cast<int64_t
>(
L->getLoopDepth()));
235 Worklist.pop_front();
246 .getCachedResult<IR2VecVocabAnalysis>(*
F.getParent());
256 if (Vocabulary && Vocabulary->
isValid()) {
257 FPI.IR2VecVocab = Vocabulary;
260 for (
const auto &BB :
F)
263 FPI.updateAggregateStats(
F, LI);
328#define PRINT_PROPERTY(PROP_NAME) OS << #PROP_NAME ": " << PROP_NAME << "\n";
392 OS <<
"Printing analysis results of CFA for function "
393 <<
"'" <<
F.getName() <<
"':"
402 assert(isa<CallInst>(CB) || isa<InvokeInst>(CB));
409 LikelyToChangeBBs.
insert(&CallSiteBB);
421 CallUsers.erase(&CallSiteBB);
427 Successors.insert_range(
successors(&CallSiteBB));
436 if (Inserted.insert(Succ).second)
437 DomTreeUpdates.
emplace_back(DominatorTree::UpdateKind::Delete,
450 if (
const auto *
II = dyn_cast<InvokeInst>(&CB)) {
451 const auto *UnwindDest =
II->getUnwindDest();
452 Successors.insert_range(
successors(UnwindDest));
455 if (Inserted.insert(Succ).second)
456 DomTreeUpdates.
emplace_back(DominatorTree::UpdateKind::Delete,
466 Successors.erase(&CallSiteBB);
474 for (
const auto *BB : LikelyToChangeBBs)
475 FPI.updateForBB(*BB, -1);
478DominatorTree &FunctionPropertiesUpdater::getUpdatedDominatorTree(
487 if (Inserted.insert(Succ).second)
488 FinalDomTreeUpdates.
push_back({DominatorTree::UpdateKind::Insert,
494 for (
auto &Upd : DomTreeUpdates)
499#ifdef EXPENSIVE_CHECKS
500 assert(DT.
verify(DominatorTree::VerificationLevel::Full));
532 auto &DT = getUpdatedDominatorTree(
FAM);
534 if (&CallSiteBB != &*Caller.
begin())
541 for (
const auto *Succ : Successors)
551 const auto IncludeSuccessorsMark = Reinclude.
size();
552 bool CSInsertion = Reinclude.
insert(&CallSiteBB);
555 for (
size_t I = 0;
I < Reinclude.
size(); ++
I) {
556 const auto *BB = Reinclude[
I];
557 FPI.reIncludeBB(*BB);
558 if (
I >= IncludeSuccessorsMark)
566 const auto AlreadyExcludedMark = Unreachable.
size();
567 for (
size_t I = 0;
I < Unreachable.
size(); ++
I) {
568 const auto *U = Unreachable[
I];
569 if (
I >= AlreadyExcludedMark)
570 FPI.updateForBB(*U, -1);
577 FPI.updateAggregateStats(Caller, LI);
578#ifdef EXPENSIVE_CHECKS
583bool FunctionPropertiesUpdater::isUpdateValid(
Function &
F,
587 DominatorTree::VerificationLevel::Full))
592 .getCachedResult<IR2VecVocabAnalysis>(*
F.getParent());
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static const Function * getParent(const Value *V)
This file contains the declarations for the subclasses of Constant, which represent the different fla...
#define PRINT_PROPERTY(PROP_NAME)
static cl::opt< unsigned > CallWithManyArgumentsThreshold("call-with-many-arguments-threshold", cl::Hidden, cl::init(4), cl::desc("The minimum number of arguments a function call must have before " "it is considered having many arguments."))
#define COUNT_OPERAND(OPTYPE)
This file provides various utilities for inspecting and working with the control flow graph in LLVM I...
uint64_t IntrinsicInst * II
FunctionAnalysisManager FAM
This file implements a set that has insertion order iteration characteristics.
A container for analyses that lazily runs them and caches their results.
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
This class represents an incoming formal argument to a Function.
LLVM Basic Block Representation.
const Instruction * getTerminator() const LLVM_READONLY
Returns the terminator instruction if the block is well formed or null if the block is not well forme...
Base class for all callable instructions (InvokeInst and CallInst) Holds everything related to callin...
ConstantFP - Floating Point Values [float, double].
This is the shared class of boolean and integer constants.
This is an important base class in LLVM.
Implements a dense probed hash-table based set.
Analysis pass which computes a DominatorTree.
bool verify(VerificationLevel VL=VerificationLevel::Full) const
verify - checks if the tree is correct.
void applyUpdates(ArrayRef< UpdateType > Updates)
Inform the dominator tree about a sequence of CFG edge insertions and deletions and perform a batch u...
Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree.
LLVM_ABI bool isReachableFromEntry(const Use &U) const
Provide an overload for a Use.
static LLVM_ABI AnalysisKey Key
LLVM_ABI FunctionPropertiesInfo run(Function &F, FunctionAnalysisManager &FAM)
int64_t BasicBlocksWithMoreThanTwoSuccessors
int64_t BasicBlocksWithSinglePredecessor
int64_t CallReturnsVectorPointerCount
int64_t CallReturnsPointerCount
int64_t CallWithManyArgumentsCount
int64_t CallReturnsVectorIntCount
int64_t CallReturnsVectorFloatCount
int64_t CastInstructionCount
int64_t BasicBlockCount
Number of basic blocks.
int64_t CriticalEdgeCount
int64_t Uses
Number of uses of this function, plus 1 if the function is callable outside the module.
int64_t InlineAsmOperandCount
int64_t ConstantFPOperandCount
int64_t BasicBlocksWithTwoSuccessors
int64_t InstructionOperandCount
int64_t CallWithPointerArgumentCount
int64_t FloatingPointInstructionCount
int64_t TopLevelLoopCount
int64_t CallReturnsIntegerCount
int64_t BlocksReachedFromConditionalInstruction
Number of blocks reached from a conditional instruction, or that are 'cases' of a SwitchInstr.
int64_t GlobalValueOperandCount
int64_t UnconditionalBranchCount
int64_t ArgumentOperandCount
int64_t BasicBlocksWithSingleSuccessor
LLVM_ABI bool operator==(const FunctionPropertiesInfo &FPI) const
int64_t BasicBlockOperandCount
int64_t ControlFlowEdgeCount
int64_t BasicBlocksWithTwoPredecessors
int64_t MediumBasicBlocks
int64_t IntegerInstructionCount
static LLVM_ABI FunctionPropertiesInfo getFunctionPropertiesInfo(const Function &F, const DominatorTree &DT, const LoopInfo &LI, const ir2vec::Vocabulary *Vocabulary)
int64_t CallReturnsFloatCount
LLVM_ABI void print(raw_ostream &OS) const
int64_t TotalInstructionCount
int64_t BasicBlocksWithMoreThanTwoPredecessors
int64_t ConstantOperandCount
int64_t ConstantIntOperandCount
int64_t UnknownOperandCount
int64_t DirectCallsToDefinedFunctions
Number of direct calls made from this function to other functions defined in this module.
int64_t IndirectCallCount
LLVM_ABI PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM)
LLVM_ABI FunctionPropertiesUpdater(FunctionPropertiesInfo &FPI, CallBase &CB)
LLVM_ABI void finish(FunctionAnalysisManager &FAM) const
Analysis pass that exposes the LoopInfo for a function.
An analysis over an "inner" IR unit that provides access to an analysis manager over a "outer" IR uni...
A set of analyses that are preserved following a run of a transformation pass.
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
A vector that has set insertion semantics.
size_type size() const
Determine the number of elements in the SetVector.
void insert_range(Range &&R)
bool insert(const value_type &X)
Insert a new element into the SetVector.
void insert_range(Range &&R)
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
reference emplace_back(ArgTypes &&... Args)
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
LLVM Value Representation.
iterator_range< user_iterator > users()
static LLVM_ABI std::unique_ptr< Embedder > create(IR2VecKind Mode, const Function &F, const Vocabulary &Vocab)
Factory method to create an Embedder object.
Class for storing and accessing the IR2Vec vocabulary.
LLVM_ABI bool isValid() const
LLVM_ABI unsigned getDimension() const
This class implements an extremely fast bulk output stream that can only output to a stream.
initializer< Ty > init(const Ty &Val)
This is an optimization pass for GlobalISel generic memory operations.
Printable print(const GCNRegPressure &RP, const GCNSubtarget *ST=nullptr, unsigned DynamicVGPRBlockSize=0)
auto size(R &&Range, std::enable_if_t< std::is_base_of< std::random_access_iterator_tag, typename std::iterator_traits< decltype(Range.begin())>::iterator_category >::value, void > *=nullptr)
Get the size of a range.
auto successors(const MachineBasicBlock *BB)
LLVM_ABI cl::opt< bool > EnableDetailedFunctionProperties("enable-detailed-function-properties", cl::Hidden, cl::init(false), cl::desc("Whether or not to compute detailed function properties."))
void append_range(Container &C, Range &&R)
Wrapper function to append range R to container C.
auto pred_size(const MachineBasicBlock *BB)
auto succ_size(const MachineBasicBlock *BB)
static cl::opt< unsigned > BigBasicBlockInstructionThreshold("big-basic-block-instruction-threshold", cl::Hidden, cl::init(500), cl::desc("The minimum number of instructions a basic block should contain " "before being considered big."))
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.
static cl::opt< unsigned > MediumBasicBlockInstructionThreshold("medium-basic-block-instruction-threshold", cl::Hidden, cl::init(15), cl::desc("The minimum number of instructions a basic block should contain " "before being considered medium-sized."))
A special type used by analysis passes to provide an address that identifies that particular analysis...
Direction
An enum for the direction of the loop.
Embedding is a datatype that wraps std::vector<double>.
LLVM_ABI bool approximatelyEquals(const Embedding &RHS, double Tolerance=1e-4) const
Returns true if the embedding is approximately equal to the RHS embedding within the specified tolera...