27#define DEBUG_TYPE "function-specialization"
29STATISTIC(NumSpecsCreated,
"Number of specializations created");
31bool InstCostVisitor::canEliminateSuccessor(
BasicBlock *BB,
35 return I++ < Opts.funcspec_max_block_predecessors &&
46Cost InstCostVisitor::estimateBasicBlocks(
50 while (!WorkList.
empty()) {
56 assert(Solver.isBlockExecutable(BB) &&
"BB already found dead by IPSCCP!");
57 if (!DeadBlocks.insert(BB).second)
60 for (Instruction &
I : *BB) {
62 if (KnownConstants.contains(&
I))
68 <<
" for user " <<
I <<
"\n");
84 if (
auto *
C = Solver.getConstantOrNull(
V))
86 return KnownConstants.lookup(
V);
91 while (!PendingPHIs.empty()) {
95 CodeSize += getCodeSizeSavingsForUser(Phi);
102 LLVM_DEBUG(
dbgs() <<
"FnSpecialization: Analysing bonus for constant: "
103 <<
C->getNameOrAsOperand() <<
"\n");
105 for (
auto *U :
A->users())
108 CodeSize += getCodeSizeSavingsForUser(UI,
A,
C);
110 LLVM_DEBUG(
dbgs() <<
"FnSpecialization: Accumulated bonus {CodeSize = "
111 <<
CodeSize <<
"} for argument " << *
A <<
"\n");
128 auto &BFI = GetBFI(*F);
129 Cost TotalLatency = 0;
131 for (
auto Pair : KnownConstants) {
136 uint64_t Weight = BFI.getBlockFreq(
I->getParent()).getFrequency() /
137 BFI.getEntryFreq().getFrequency();
143 <<
"} for instruction " << *
I <<
"\n");
159 : KnownConstants.end();
175 KnownConstants.insert({
User,
C});
180 <<
"} for user " << *User <<
"\n");
182 for (
auto *U :
User->users())
185 CodeSize += getCodeSizeSavingsForUser(UI, User,
C);
191 assert(LastVisited != KnownConstants.end() &&
"Invalid iterator!");
193 if (
I.getCondition() != LastVisited->first)
200 BasicBlock *Succ =
I.findCaseValue(
C)->getCaseSuccessor();
205 for (
const auto &Case :
I.cases()) {
208 canEliminateSuccessor(
I.getParent(), BB))
212 return estimateBasicBlocks(WorkList);
216 assert(LastVisited != KnownConstants.end() &&
"Invalid iterator!");
218 if (
I.getCondition() != LastVisited->first)
221 BasicBlock *Succ =
I.getSuccessor(LastVisited->second->isOneValue());
228 return estimateBasicBlocks(WorkList);
231bool InstCostVisitor::discoverTransitivelyIncomingValues(
238 while (!WorkList.
empty()) {
241 if (++Iter > Opts.funcspec_max_discovery_iterations ||
245 if (!TransitivePHIs.
insert(PN).second)
256 if (Constant *
C = findConstantFor(
V)) {
276 if (
I.getNumIncomingValues() > Opts.funcspec_max_incoming_phi_values)
279 bool Inserted = VisitedPHIs.insert(&
I).second;
281 bool HaveSeenIncomingPHI =
false;
283 for (
unsigned Idx = 0,
E =
I.getNumIncomingValues(); Idx !=
E; ++Idx) {
284 Value *
V =
I.getIncomingValue(Idx);
291 if (Constant *
C = findConstantFor(
V)) {
303 PendingPHIs.push_back(&
I);
309 HaveSeenIncomingPHI =
true;
320 if (!HaveSeenIncomingPHI)
323 DenseSet<PHINode *> TransitivePHIs;
324 if (!discoverTransitivelyIncomingValues(Const, &
I, TransitivePHIs))
331 assert(LastVisited != KnownConstants.end() &&
"Invalid iterator!");
334 return LastVisited->second;
339 assert(LastVisited != KnownConstants.end() &&
"Invalid iterator!");
348 for (
unsigned Idx = 0,
E =
I.getNumOperands() - 1; Idx !=
E; ++Idx) {
363 assert(LastVisited != KnownConstants.end() &&
"Invalid iterator!");
374 for (
unsigned Idx = 0,
E =
I.getNumOperands(); Idx !=
E; ++Idx) {
387 assert(LastVisited != KnownConstants.end() &&
"Invalid iterator!");
389 if (
I.getCondition() == LastVisited->first) {
390 Value *
V = LastVisited->second->isNullValue() ?
I.getFalseValue()
392 return findConstantFor(
V);
394 if (Constant *Condition = findConstantFor(
I.getCondition()))
395 if ((
I.getTrueValue() == LastVisited->first && Condition->isOneValue()) ||
396 (
I.getFalseValue() == LastVisited->first && Condition->isNullValue()))
397 return LastVisited->second;
407 assert(LastVisited != KnownConstants.end() &&
"Invalid iterator!");
410 bool ConstOnRHS =
I.getOperand(1) == LastVisited->first;
411 Value *
V = ConstOnRHS ?
I.getOperand(0) :
I.getOperand(1);
423 const ValueLatticeElement &OtherLV = Solver.getLatticeValueFor(
V);
424 auto &V1State = ConstOnRHS ? OtherLV : ConstLV;
425 auto &V2State = ConstOnRHS ? ConstLV : OtherLV;
426 return V1State.
getCompare(
I.getPredicate(),
I.getType(), V2State, DL);
430 assert(LastVisited != KnownConstants.end() &&
"Invalid iterator!");
436 assert(LastVisited != KnownConstants.end() &&
"Invalid iterator!");
438 bool ConstOnRHS =
I.getOperand(1) == LastVisited->first;
439 Value *
V = ConstOnRHS ?
I.getOperand(0) :
I.getOperand(1);
442 Value *ConstVal = LastVisited->second;
448 simplifyBinOp(
I.getOpcode(), ConstVal, OtherVal, SimplifyQuery(DL)));
453 Value *StoreValue =
nullptr;
454 for (
auto *User : Alloca->
users()) {
462 if (StoreValue ||
Store->isVolatile())
464 StoreValue =
Store->getValueOperand();
474 return getCandidateConstant(StoreValue);
489 if (!
C || !
C->getType()->isIntegerTy())
517void FunctionSpecializer::promoteConstantStackValues(
Function *
F) {
518 for (User *U :
F->users()) {
535 auto *ConstVal = getConstantStackValue(
Call, ArgOp);
539 Value *GV =
new GlobalVariable(M, ConstVal->
getType(),
true,
541 "specialized.arg." + Twine(++NGlobals));
553 if (!BC || BC->getType() != BC->getOperand(0)->getType())
555 Inst.replaceAllUsesWith(BC->getOperand(0));
556 Inst.eraseFromParent();
562void FunctionSpecializer::cleanUpSSA() {
583 : Opts(
getIPOOptions(M)), Solver(Solver), M(M), FAM(FAM), GetBFI(GetBFI),
584 GetTLI(GetTLI), GetTTI(GetTTI), GetAC(GetAC) {}
588 if (NumSpecsCreated > 0)
589 dbgs() <<
"FnSpecialization: Created " << NumSpecsCreated
590 <<
" specializations in module " << M.getName() <<
"\n");
592 removeDeadFunctions();
600 int64_t
Value =
C.getValue();
602 assert(
Value >= 0 &&
"CodeSize and Latency cannot be negative");
605 return static_cast<unsigned>(
Value);
616 unsigned NumCandidates = 0;
618 if (!isCandidateFunction(&
F))
621 auto [It, Inserted] = FunctionMetrics.try_emplace(&
F);
628 Metrics.analyzeBasicBlock(&BB, GetTTI(
F), EphValues);
634 const bool RequireMinSize =
635 !Opts.funcspec_force && (Opts.funcspec_for_literal_constant ||
636 !
F.hasFnAttribute(Attribute::NoInline));
642 (RequireMinSize &&
Metrics.NumInsts < Opts.funcspec_min_function_size))
649 if (!Opts.funcspec_for_literal_constant && !Inserted &&
653 int64_t Sz =
Metrics.NumInsts.getValue();
654 assert(Sz > 0 &&
"CodeSize should be positive");
656 unsigned FuncSize =
static_cast<unsigned>(Sz);
659 <<
F.getName() <<
" is " << FuncSize <<
"\n");
661 if (Inserted &&
Metrics.isRecursive)
662 promoteConstantStackValues(&
F);
664 if (!findSpecializations(&
F, FuncSize, AllSpecs, SM)) {
666 dbgs() <<
"FnSpecialization: No possible specializations found for "
667 <<
F.getName() <<
"\n");
674 if (!NumCandidates) {
677 <<
"FnSpecialization: No possible specializations found in module\n");
684 auto CompareScore = [&AllSpecs](
unsigned I,
unsigned J) {
685 if (AllSpecs[
I].Score != AllSpecs[J].Score)
686 return AllSpecs[
I].Score > AllSpecs[J].Score;
689 const unsigned NSpecs = std::min(NumCandidates * Opts.funcspec_max_clones,
690 unsigned(AllSpecs.
size()));
692 std::iota(BestSpecs.
begin(), BestSpecs.
begin() + NSpecs, 0);
693 if (AllSpecs.
size() > NSpecs) {
694 LLVM_DEBUG(
dbgs() <<
"FnSpecialization: Number of candidates exceed "
695 <<
"the maximum number of clones threshold.\n"
696 <<
"FnSpecialization: Specializing the "
698 <<
" most profitable candidates.\n");
699 std::make_heap(BestSpecs.
begin(), BestSpecs.
begin() + NSpecs, CompareScore);
700 for (
unsigned I = NSpecs,
N = AllSpecs.
size();
I <
N; ++
I) {
701 BestSpecs[NSpecs] =
I;
702 std::push_heap(BestSpecs.
begin(), BestSpecs.
end(), CompareScore);
703 std::pop_heap(BestSpecs.
begin(), BestSpecs.
end(), CompareScore);
707 LLVM_DEBUG(
dbgs() <<
"FnSpecialization: List of specializations \n";
708 for (
unsigned I = 0;
I < NSpecs; ++
I) {
709 const Spec &S = AllSpecs[BestSpecs[
I]];
710 dbgs() <<
"FnSpecialization: Function " << S.
F->
getName()
711 <<
" , score " << S.
Score <<
"\n";
713 dbgs() <<
"FnSpecialization: FormalArg = "
722 for (
unsigned I = 0;
I < NSpecs; ++
I) {
723 Spec &S = AllSpecs[BestSpecs[
I]];
729 S.
Clone = createSpecialization(S.
F, S.
Sig);
735 <<
" to call " << Clone->
getName() <<
"\n");
737 auto &BFI = GetBFI(*
Call->getFunction());
738 std::optional<uint64_t>
Count =
739 BFI.getBlockProfileCount(
Call->getParent());
741 std::optional<uint64_t> MaybeCloneCount = Clone->
getEntryCount();
742 if (MaybeCloneCount) {
743 uint64_t CallCount = *
Count + *MaybeCloneCount;
745 if (std::optional<uint64_t> MaybeOriginalCount =
747 uint64_t OriginalCount = *MaybeOriginalCount;
748 if (OriginalCount >= *
Count) {
761 OriginalFuncs.insert(S.
F);
764 Solver.solveWhileResolvedUndefsIn(Clones);
770 auto [Begin,
End] = SM[
F];
771 updateCallSites(
F, AllSpecs.
begin() + Begin, AllSpecs.
begin() +
End);
775 if (
F->getReturnType()->isVoidTy())
777 if (
F->getReturnType()->isStructTy()) {
779 if (!Solver.isStructLatticeConstant(
F, STy))
782 auto It = Solver.getTrackedRetVals().find(
F);
783 assert(It != Solver.getTrackedRetVals().end() &&
784 "Return value ought to be tracked");
788 for (
User *U :
F->users()) {
791 if (CS->getCalledFunction() !=
F)
793 Solver.resetLatticeValueFor(CS);
799 Solver.solveWhileResolvedUndefs();
802 if (FunctionMetrics[
F].isRecursive)
803 promoteConstantStackValues(
F);
808void FunctionSpecializer::removeDeadFunctions() {
811 <<
F->getName() <<
"\n");
813 FAM->clear(*
F,
F->getName());
819 "User of dead function must be call or invoke");
824 F->eraseFromParent();
826 DeadFunctions.clear();
834 Clone->
setName(
F->getName() +
".specialized." +
Twine(NSpecs));
839bool FunctionSpecializer::findSpecializations(
Function *
F,
unsigned FuncSize,
845 DenseMap<SpecSig, unsigned> UniqueSpecs;
849 for (Argument &Arg :
F->args())
850 if (isArgumentInteresting(&Arg))
851 Args.push_back(&Arg);
856 for (User *U :
F->users()) {
862 if (CS.getCalledFunction() !=
F)
867 if (CS.hasFnAttr(Attribute::MinSize))
872 if (!Solver.isBlockExecutable(CS.
getParent()))
878 for (Argument *
A : Args) {
879 Constant *
C = getCandidateConstant(CS.getArgOperand(
A->getArgNo()));
882 LLVM_DEBUG(
dbgs() <<
"FnSpecialization: Found interesting argument "
883 <<
A->getName() <<
" : " <<
C->getNameOrAsOperand()
892 if (
auto It = UniqueSpecs.
find(S); It != UniqueSpecs.
end()) {
901 const unsigned Index = It->second;
908 for (ArgInfo &
A : S.
Args) {
910 Score += getInliningBonus(
A.Formal,
A.Actual);
915 unsigned SpecSize = FuncSize - CodeSizeSavings;
917 auto IsProfitable = [&]() ->
bool {
919 if (Opts.funcspec_force)
923 dbgs() <<
"FnSpecialization: Specialization bonus {Inlining = "
924 << Score <<
" (" << (Score * 100 / FuncSize) <<
"%)}\n");
927 if (Score > Opts.funcspec_min_inlining_bonus * FuncSize / 100)
931 dbgs() <<
"FnSpecialization: Specialization bonus {CodeSize = "
932 << CodeSizeSavings <<
" ("
933 << (CodeSizeSavings * 100 / FuncSize) <<
"%)}\n");
936 if (CodeSizeSavings <
937 Opts.funcspec_min_codesize_savings * FuncSize / 100)
941 unsigned LatencySavings =
945 dbgs() <<
"FnSpecialization: Specialization bonus {Latency = "
946 << LatencySavings <<
" ("
947 << (LatencySavings * 100 / FuncSize) <<
"%)}\n");
950 if (LatencySavings < Opts.funcspec_min_latency_savings * FuncSize / 100)
953 if ((FunctionGrowth[
F] + SpecSize) / FuncSize >
954 Opts.funcspec_max_codesize_growth)
957 Score += std::max(CodeSizeSavings, LatencySavings);
968 Spec.CallSites.push_back(&CS);
969 const unsigned Index = AllSpecs.
size() - 1;
970 UniqueSpecs[S] =
Index;
971 if (
auto [It, Inserted] = SM.try_emplace(
F, Index, Index + 1); !Inserted)
972 It->second.second =
Index + 1;
976 return !UniqueSpecs.
empty();
979bool FunctionSpecializer::isCandidateFunction(
Function *
F) {
980 if (
F->isDeclaration() ||
F->arg_empty())
983 if (
F->isInterposable())
986 if (
F->hasFnAttribute(Attribute::NoDuplicate))
993 if (Specializations.contains(
F))
1002 if (!Solver.isBlockExecutable(&
F->getEntryBlock()))
1006 if (
F->hasFnAttribute(Attribute::AlwaysInline))
1009 LLVM_DEBUG(
dbgs() <<
"FnSpecialization: Try function: " <<
F->getName()
1022 if (
F->getEntryCount())
1028 Solver.setLatticeValueForSpecializationArguments(Clone, S.
Args);
1029 Solver.markBlockExecutable(&Clone->
front());
1030 Solver.addArgumentTrackedFunction(Clone);
1031 Solver.addTrackedFunction(Clone);
1034 Specializations.insert(Clone);
1046 if (!CalledFunction)
1050 auto &CallerTTI = (GetTTI)(*
A->getParent());
1057 int InliningBonus = 0;
1062 for (User *U :
A->users()) {
1066 if (CS->getCalledOperand() !=
A)
1078 getInlineCost(*CS, CalledFunction, Params, CallerTTI, GetAC, GetTLI);
1083 InliningBonus += Params.DefaultThreshold;
1087 LLVM_DEBUG(
dbgs() <<
"FnSpecialization: Inlining bonus " << InliningBonus
1088 <<
" for user " << *U <<
"\n");
1091 return InliningBonus > 0 ?
static_cast<unsigned>(InliningBonus) : 0;
1096bool FunctionSpecializer::isArgumentInteresting(
Argument *
A) {
1098 if (
A->user_empty())
1101 Type *Ty =
A->getType();
1103 (!Opts.funcspec_for_literal_constant ||
1109 if (
A->hasByValAttr() && !
A->getParent()->onlyReadsMemory())
1113 if (!Solver.isArgumentTrackedFunction(
A->getParent()))
1121 : SCCPSolver::isOverdefined(Solver.getLatticeValueFor(
A));
1125 dbgs() <<
"FnSpecialization: Found interesting parameter "
1126 <<
A->getNameOrAsOperand() <<
"\n";
1128 dbgs() <<
"FnSpecialization: Nothing to do, parameter "
1129 <<
A->getNameOrAsOperand() <<
" is already constant\n";
1131 return IsOverdefined;
1144 C = Solver.getConstantOrNull(
V);
1148 if (
C &&
C->getType()->isPointerTy() && !
C->isNullValue())
1150 GV && !(GV->isConstant() || Opts.funcspec_on_address))
1156void FunctionSpecializer::updateCallSites(
Function *
F,
const Spec *Begin,
1160 for (User *U :
F->users())
1162 CS && CS->getCalledFunction() ==
F &&
1163 Solver.isBlockExecutable(CS->
getParent()))
1166 unsigned NCallsLeft = ToUpdate.
size();
1167 for (CallBase *CS : ToUpdate) {
1171 const Spec *BestSpec =
nullptr;
1173 if (!S.Clone || (BestSpec && S.Score <= BestSpec->
Score))
1176 if (
any_of(S.Sig.
Args, [CS,
this](
const ArgInfo &Arg) {
1177 unsigned ArgNo = Arg.Formal->getArgNo();
1178 return getCandidateConstant(CS->getArgOperand(ArgNo)) != Arg.Actual;
1188 CS->setCalledFunction(BestSpec->
Clone);
1189 ShouldDecrementCount =
true;
1192 if (ShouldDecrementCount)
1200 if (NCallsLeft == 0 && Solver.isArgumentTrackedFunction(
F) &&
1201 !
F->hasAddressTaken()) {
1202 Solver.markFunctionUnreachable(
F);
1203 DeadFunctions.insert(
F);
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static GCRegistry::Add< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static Function * cloneCandidateFunction(Function *F, unsigned NSpecs)
Clone the function F and remove the ssa_copy intrinsics added by the SCCPSolver in the cloned version...
static void removeSSACopy(Function &F)
static unsigned getCostValue(const Cost &C)
Get the unsigned Value of given Cost object.
const AbstractManglingParser< Derived, Alloc >::OperatorInfo AbstractManglingParser< Derived, Alloc >::Ops[]
FunctionAnalysisManager FAM
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
an instruction to allocate memory on the stack
This class represents an incoming formal argument to a Function.
A cache of @llvm.assume calls within a function.
LLVM Basic Block Representation.
BlockFrequencyInfo pass uses BlockFrequencyInfoImpl implementation to estimate IR basic block frequen...
Base class for all callable instructions (InvokeInst and CallInst) Holds everything related to callin...
bool onlyReadsMemory(unsigned OpNo) const
Value * getArgOperand(unsigned i) const
void setArgOperand(unsigned i, Value *v)
iterator_range< User::op_iterator > args()
Iteration adapter for range-for loops.
unsigned getArgOperandNo(const Use *U) const
Given a use for a arg operand, get the arg operand number that corresponds to it.
This class represents a function call, abstracting a target machine's calling convention.
This is the base class for all instructions that perform data casts.
This class is the base class for the comparison instructions.
Conditional Branch instruction.
This is an important base class in LLVM.
bool contains(const_arg_type_t< KeyT > Val) const
Return true if the specified key is in the map, false otherwise.
iterator find(const_arg_type_t< KeyT > Val)
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
Implements a dense probed hash-table based set.
This class represents a freeze function that returns random concrete value if an operand is either a ...
LLVM_ABI ~FunctionSpecializer()
LLVM_ABI bool run()
Attempt to specialize functions in the module to enable constant propagation across function boundari...
LLVM_ABI FunctionSpecializer(SCCPSolver &Solver, Module &M, FunctionAnalysisManager *FAM, std::function< BlockFrequencyInfo &(Function &)> GetBFI, std::function< const TargetLibraryInfo &(Function &)> GetTLI, std::function< TargetTransformInfo &(Function &)> GetTTI, std::function< AssumptionCache &(Function &)> GetAC)
InstCostVisitor getInstCostVisitorFor(Function *F)
FunctionType * getFunctionType() const
Returns the FunctionType for me.
const BasicBlock & front() const
std::optional< uint64_t > getEntryCount() const
Get the entry count for this function.
void setEntryCount(uint64_t Count, const DenseSet< GlobalValue::GUID > *Imports=nullptr)
Set the entry count for this function.
an instruction for type-safe pointer arithmetic to access elements of arrays and structs
void setLinkage(LinkageTypes LT)
@ InternalLinkage
Rename collisions when linking (static functions).
int getCostDelta() const
Get the cost delta from the threshold for inlining.
LLVM_ABI Cost getLatencySavingsForKnownConstants()
Compute the latency savings from replacing all arguments with constants for a specialization candidat...
LLVM_ABI Cost getCodeSizeSavingsForArg(Argument *A, Constant *C)
Compute the codesize savings for replacing argument A with constant C.
LLVM_ABI Cost getCodeSizeSavingsFromPendingPHIs()
bool isBlockExecutable(BasicBlock *BB) const
void visit(Iterator Start, Iterator End)
LLVM_ABI InstListType::iterator eraseFromParent()
This method unlinks 'this' from the containing basic block and deletes it.
LLVM_ABI const Function * getFunction() const
Return the function this instruction belongs to.
iterator_range< user_iterator > users()
An instruction for reading from memory.
A Module instance is used to store all the information related to an LLVM module.
BasicBlock * getIncomingBlock(unsigned i) const
Return incoming basic block number i.
Value * getIncomingValue(unsigned i) const
Return incoming value number x.
unsigned getNumIncomingValues() const
Return the number of incoming edges.
static LLVM_ABI PoisonValue * get(Type *T)
Static factory methods - Return an 'poison' object of the specified type.
SCCPSolver - This interface class is a general purpose solver for Sparse Conditional Constant Propaga...
static LLVM_ABI bool isOverdefined(const ValueLatticeElement &LV)
This class represents the LLVM 'select' instruction.
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
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.
Provides information about what library functions are available for the current target.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
bool isPointerTy() const
True if this is an instance of PointerType.
bool isStructTy() const
True if this is an instance of StructType.
bool isFloatingPointTy() const
Return true if this is one of the floating-point types.
bool isIntegerTy() const
True if this is an instance of IntegerType.
A Use represents the edge between a Value definition and its users.
LLVM_ABI Constant * getCompare(CmpInst::Predicate Pred, Type *Ty, const ValueLatticeElement &Other, const DataLayout &DL) const
true, false or undef constants, or nullptr if the comparison cannot be evaluated.
static ValueLatticeElement get(Constant *C)
LLVM Value Representation.
Type * getType() const
All values are typed, get the type of this value.
LLVM_ABI void setName(const Twine &Name)
Change the name of the value.
LLVM_ABI std::string getNameOrAsOperand() const
LLVM_ABI void replaceAllUsesWith(Value *V)
Change all uses of this to point to a new Value.
LLVM_ABI const Value * stripPointerCasts() const
Strip off pointer casts, all-zero GEPs and address space casts.
LLVM_ABI StringRef getName() const
Return a constant reference to the value's name.
std::pair< iterator, bool > insert(const ValueT &V)
const ParentTy * getParent() const
constexpr char Args[]
Key for Kernel::Metadata::mArgs.
@ BasicBlock
Various leaf nodes.
const int IndirectCallThreshold
@ User
could "use" a pointer
This is an optimization pass for GlobalISel generic memory operations.
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
hash_code hash_value(const FixedPointSemantics &Val)
LLVM_ABI InlineCost getInlineCost(CallBase &Call, const InlineParams &Params, TargetTransformInfo &CallerTTI, function_ref< AssumptionCache &(Function &)> GetAssumptionCache, function_ref< const TargetLibraryInfo &(Function &)> GetTLI, function_ref< BlockFrequencyInfo &(Function &)> GetBFI=nullptr, ProfileSummaryInfo *PSI=nullptr, OptimizationRemarkEmitter *ORE=nullptr, function_ref< EphemeralValuesCache &(Function &)> GetEphValuesCache=nullptr)
Get an InlineCost object representing the cost of inlining this callsite.
LLVM_ABI InlineParams getInlineParams(const LLVMContext &C)
Generate the parameters to tune the inline cost analysis based only on the commandline options.
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
auto successors(const MachineBasicBlock *BB)
@ Store
The extracted value is stored (ExtractElement only).
DenseMap< Function *, std::pair< unsigned, unsigned > > SpecMap
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
LLVM_ABI bool shouldOptimizeForSize(const MachineFunction *MF, ProfileSummaryInfo *PSI, const MachineBlockFrequencyInfo *BFI, PGSOQueryType QueryType=PGSOQueryType::Other)
Returns true if machine function MF is suggested to be size-optimized based on the profile.
iterator_range< early_inc_iterator_impl< detail::IterOfRange< RangeT > > > make_early_inc_range(RangeT &&Range)
Make a range that does early increment to allow mutation of the underlying range without disrupting i...
LLVM_ABI Constant * ConstantFoldCall(const CallBase *Call, Function *F, ArrayRef< Constant * > Operands, const TargetLibraryInfo *TLI=nullptr, bool AllowNonDeterministic=true)
ConstantFoldCall - Attempt to constant fold a call to the specified function with the specified argum...
LLVM_ABI bool canConstantFoldCallTo(const CallBase *Call, const Function *F, const TargetLibraryInfo *TLI=nullptr)
canConstantFoldCallTo - Return true if its even possible to fold a call to the specified function.
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Value
LLVM_ABI Constant * ConstantFoldCompareInstOperands(unsigned Predicate, Constant *LHS, Constant *RHS, const DataLayout &DL, const TargetLibraryInfo *TLI=nullptr, const Function *CtxF=nullptr)
Attempt to constant fold a compare instruction (icmp/fcmp) with the specified operands.
auto dyn_cast_or_null(const Y &Val)
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
const IPOOptions & getIPOOptions(const LLVMContext &C)
LLVM_ABI Constant * ConstantFoldUnaryOpOperand(unsigned Opcode, Constant *Op, const DataLayout &DL)
Attempt to constant fold a unary operation with the specified operand.
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
LLVM_ABI Constant * ConstantFoldCastOperand(unsigned Opcode, Constant *C, Type *DestTy, const DataLayout &DL)
Attempt to constant fold a cast with the specified operand.
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
LLVM_ABI const Value * getUnderlyingObject(const Value *V, unsigned MaxLookup=MaxLookupSearchDepth, bool MustPreserveProvenance=false)
This method strips off any GEP address adjustments, pointer casts or llvm.threadlocal....
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
LLVM_ABI Value * simplifyBinOp(unsigned Opcode, Value *LHS, Value *RHS, const SimplifyQuery &Q)
Given operands for a BinaryOperator, fold the result or return null.
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Count
LLVM_ABI bool isGuaranteedNotToBeUndefOrPoison(const Value *V, AssumptionCache *AC=nullptr, const Instruction *CtxI=nullptr, const DominatorTree *DT=nullptr, unsigned Depth=0)
Return true if this function can prove that V does not have undef bits and is never poison.
ArrayRef(const T &OneElt) -> ArrayRef< T >
ValueMap< const Value *, WeakTrackingVH > ValueToValueMapTy
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
auto predecessors(const MachineBasicBlock *BB)
LLVM_ABI Constant * ConstantFoldLoadFromConstPtr(Constant *C, Type *Ty, APInt Offset, const DataLayout &DL)
Return the value that a load from C with offset Offset would produce if it is constant and determinab...
AnalysisManager< Function > FunctionAnalysisManager
Convenience typedef for the Function analysis manager.
LLVM_ABI Constant * ConstantFoldInstOperands(const Instruction *I, ArrayRef< Constant * > Ops, const DataLayout &DL, const TargetLibraryInfo *TLI=nullptr, bool AllowNonDeterministic=true)
ConstantFoldInstOperands - Attempt to constant fold an instruction with the specified operands.
@ End
Run the machine verifier once, at the end of the pipeline.
LLVM_ABI Function * CloneFunction(Function *F, ValueToValueMapTy &VMap, ClonedCodeInfo *CodeInfo=nullptr)
Return a copy of the specified function and add it to that function's module.
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
Helper struct shared between Function Specialization and SCCP Solver.
Utility to calculate the size and a few similar metrics for a set of basic blocks.
static LLVM_ABI void collectEphemeralValues(const Loop *L, AssumptionCache *AC, SmallPtrSetImpl< const Value * > &EphValues)
Collect a loop's ephemeral values (those used only by an assume or similar intrinsics in the loop).
static unsigned getHashValue(const SpecSig &S)
static bool isEqual(const SpecSig &LHS, const SpecSig &RHS)
An information struct used to provide DenseMap with the various necessary components for a given valu...
SmallVector< ArgInfo, 4 > Args
SmallVector< CallBase * > CallSites