27#define DEBUG_TYPE "function-specialization"
29STATISTIC(NumSpecsCreated,
"Number of specializations created");
33 "Force function specialization for every call site with a constant "
38 "The maximum number of clones allowed for a single function "
44 cl::desc(
"The maximum number of iterations allowed "
45 "when searching for transitive "
50 cl::desc(
"The maximum number of incoming values a PHI node can have to be "
51 "considered during the specialization bonus estimation"));
55 "The maximum number of predecessors a basic block can have to be "
56 "considered during the estimation of dead code"));
60 cl::desc(
"Don't specialize functions that have less than this number of "
65 "Maximum codesize growth allowed per function"));
69 cl::desc(
"Reject specializations whose codesize savings are less than this "
70 "much percent of the original function size"));
74 cl::desc(
"Reject specializations whose latency savings are less than this "
75 "much percent of the original function size"));
79 cl::desc(
"Reject specializations whose inlining bonus is less than this "
80 "much percent of the original function size"));
84 "Enable function specialization on the address of global values"));
89 "Enable specialization of functions that take a literal constant as an "
94bool InstCostVisitor::canEliminateSuccessor(
BasicBlock *BB,
109Cost InstCostVisitor::estimateBasicBlocks(
113 while (!WorkList.
empty()) {
119 assert(Solver.isBlockExecutable(BB) &&
"BB already found dead by IPSCCP!");
120 if (!DeadBlocks.insert(BB).second)
123 for (Instruction &
I : *BB) {
125 if (KnownConstants.contains(&
I))
131 <<
" for user " <<
I <<
"\n");
147 if (
auto *
C = Solver.getConstantOrNull(V))
149 return KnownConstants.lookup(V);
154 while (!PendingPHIs.empty()) {
158 CodeSize += getCodeSizeSavingsForUser(Phi);
165 LLVM_DEBUG(
dbgs() <<
"FnSpecialization: Analysing bonus for constant: "
166 <<
C->getNameOrAsOperand() <<
"\n");
168 for (
auto *U :
A->users())
171 CodeSize += getCodeSizeSavingsForUser(UI,
A,
C);
173 LLVM_DEBUG(
dbgs() <<
"FnSpecialization: Accumulated bonus {CodeSize = "
174 <<
CodeSize <<
"} for argument " << *
A <<
"\n");
191 auto &BFI = GetBFI(*F);
192 Cost TotalLatency = 0;
194 for (
auto Pair : KnownConstants) {
199 uint64_t Weight = BFI.getBlockFreq(
I->getParent()).getFrequency() /
200 BFI.getEntryFreq().getFrequency();
206 <<
"} for instruction " << *
I <<
"\n");
222 : KnownConstants.end();
238 KnownConstants.insert({
User,
C});
243 <<
"} for user " << *User <<
"\n");
245 for (
auto *U :
User->users())
248 CodeSize += getCodeSizeSavingsForUser(UI, User,
C);
254 assert(LastVisited != KnownConstants.end() &&
"Invalid iterator!");
256 if (
I.getCondition() != LastVisited->first)
263 BasicBlock *Succ =
I.findCaseValue(
C)->getCaseSuccessor();
268 for (
const auto &Case :
I.cases()) {
271 canEliminateSuccessor(
I.getParent(), BB))
275 return estimateBasicBlocks(WorkList);
279 assert(LastVisited != KnownConstants.end() &&
"Invalid iterator!");
281 if (
I.getCondition() != LastVisited->first)
284 BasicBlock *Succ =
I.getSuccessor(LastVisited->second->isOneValue());
291 return estimateBasicBlocks(WorkList);
294bool InstCostVisitor::discoverTransitivelyIncomingValues(
301 while (!WorkList.
empty()) {
308 if (!TransitivePHIs.
insert(PN).second)
319 if (Constant *
C = findConstantFor(V)) {
342 bool Inserted = VisitedPHIs.insert(&
I).second;
344 bool HaveSeenIncomingPHI =
false;
346 for (
unsigned Idx = 0,
E =
I.getNumIncomingValues(); Idx !=
E; ++Idx) {
347 Value *
V =
I.getIncomingValue(Idx);
354 if (Constant *
C = findConstantFor(V)) {
366 PendingPHIs.push_back(&
I);
372 HaveSeenIncomingPHI =
true;
383 if (!HaveSeenIncomingPHI)
386 DenseSet<PHINode *> TransitivePHIs;
387 if (!discoverTransitivelyIncomingValues(Const, &
I, TransitivePHIs))
394 assert(LastVisited != KnownConstants.end() &&
"Invalid iterator!");
397 return LastVisited->second;
402 assert(LastVisited != KnownConstants.end() &&
"Invalid iterator!");
411 for (
unsigned Idx = 0,
E =
I.getNumOperands() - 1; Idx !=
E; ++Idx) {
426 assert(LastVisited != KnownConstants.end() &&
"Invalid iterator!");
437 for (
unsigned Idx = 0,
E =
I.getNumOperands(); Idx !=
E; ++Idx) {
450 assert(LastVisited != KnownConstants.end() &&
"Invalid iterator!");
452 if (
I.getCondition() == LastVisited->first) {
453 Value *
V = LastVisited->second->isZeroValue() ?
I.getFalseValue()
455 return findConstantFor(V);
457 if (Constant *Condition = findConstantFor(
I.getCondition()))
458 if ((
I.getTrueValue() == LastVisited->first && Condition->isOneValue()) ||
459 (
I.getFalseValue() == LastVisited->first && Condition->isZeroValue()))
460 return LastVisited->second;
470 assert(LastVisited != KnownConstants.end() &&
"Invalid iterator!");
473 bool ConstOnRHS =
I.getOperand(1) == LastVisited->first;
474 Value *
V = ConstOnRHS ?
I.getOperand(0) :
I.getOperand(1);
486 const ValueLatticeElement &OtherLV = Solver.getLatticeValueFor(V);
487 auto &V1State = ConstOnRHS ? OtherLV : ConstLV;
488 auto &V2State = ConstOnRHS ? ConstLV : OtherLV;
489 return V1State.
getCompare(
I.getPredicate(),
I.getType(), V2State, DL);
493 assert(LastVisited != KnownConstants.end() &&
"Invalid iterator!");
499 assert(LastVisited != KnownConstants.end() &&
"Invalid iterator!");
501 bool ConstOnRHS =
I.getOperand(1) == LastVisited->first;
502 Value *
V = ConstOnRHS ?
I.getOperand(0) :
I.getOperand(1);
505 Value *ConstVal = LastVisited->second;
511 simplifyBinOp(
I.getOpcode(), ConstVal, OtherVal, SimplifyQuery(DL)));
516 Value *StoreValue =
nullptr;
517 for (
auto *User : Alloca->
users()) {
525 if (StoreValue ||
Store->isVolatile())
527 StoreValue =
Store->getValueOperand();
537 return getCandidateConstant(StoreValue);
553 return getPromotableAlloca(Alloca,
Call);
579void FunctionSpecializer::promoteConstantStackValues(
Function *
F) {
580 for (User *U :
F->users()) {
597 auto *ConstVal = getConstantStackValue(
Call, ArgOp);
601 Value *GV =
new GlobalVariable(M, ConstVal->
getType(),
true,
603 "specialized.arg." + Twine(++NGlobals));
615 if (!BC || BC->getType() != BC->getOperand(0)->getType())
617 Inst.replaceAllUsesWith(BC->getOperand(0));
618 Inst.eraseFromParent();
624void FunctionSpecializer::cleanUpSSA() {
625 for (Function *
F : Specializations)
646 if (NumSpecsCreated > 0)
647 dbgs() <<
"FnSpecialization: Created " << NumSpecsCreated
648 <<
" specializations in module " << M.getName() <<
"\n");
650 removeDeadFunctions();
658 int64_t
Value =
C.getValue();
660 assert(
Value >= 0 &&
"CodeSize and Latency cannot be negative");
663 return static_cast<unsigned>(
Value);
674 unsigned NumCandidates = 0;
676 if (!isCandidateFunction(&
F))
679 auto [It, Inserted] = FunctionMetrics.try_emplace(&
F);
686 Metrics.analyzeBasicBlock(&BB, GetTTI(
F), EphValues);
691 const bool RequireMinSize =
709 int64_t Sz =
Metrics.NumInsts.getValue();
710 assert(Sz > 0 &&
"CodeSize should be positive");
712 unsigned FuncSize =
static_cast<unsigned>(Sz);
715 <<
F.getName() <<
" is " << FuncSize <<
"\n");
717 if (Inserted &&
Metrics.isRecursive)
718 promoteConstantStackValues(&
F);
720 if (!findSpecializations(&
F, FuncSize, AllSpecs, SM)) {
722 dbgs() <<
"FnSpecialization: No possible specializations found for "
723 <<
F.getName() <<
"\n");
730 if (!NumCandidates) {
733 <<
"FnSpecialization: No possible specializations found in module\n");
740 auto CompareScore = [&AllSpecs](
unsigned I,
unsigned J) {
741 if (AllSpecs[
I].Score != AllSpecs[J].Score)
742 return AllSpecs[
I].Score > AllSpecs[J].Score;
745 const unsigned NSpecs =
746 std::min(NumCandidates *
MaxClones,
unsigned(AllSpecs.
size()));
748 std::iota(BestSpecs.
begin(), BestSpecs.
begin() + NSpecs, 0);
749 if (AllSpecs.
size() > NSpecs) {
750 LLVM_DEBUG(
dbgs() <<
"FnSpecialization: Number of candidates exceed "
751 <<
"the maximum number of clones threshold.\n"
752 <<
"FnSpecialization: Specializing the "
754 <<
" most profitable candidates.\n");
755 std::make_heap(BestSpecs.
begin(), BestSpecs.
begin() + NSpecs, CompareScore);
756 for (
unsigned I = NSpecs,
N = AllSpecs.
size();
I <
N; ++
I) {
757 BestSpecs[NSpecs] =
I;
758 std::push_heap(BestSpecs.
begin(), BestSpecs.
end(), CompareScore);
759 std::pop_heap(BestSpecs.
begin(), BestSpecs.
end(), CompareScore);
763 LLVM_DEBUG(
dbgs() <<
"FnSpecialization: List of specializations \n";
764 for (
unsigned I = 0;
I < NSpecs; ++
I) {
765 const Spec &S = AllSpecs[BestSpecs[
I]];
766 dbgs() <<
"FnSpecialization: Function " << S.
F->
getName()
767 <<
" , score " << S.
Score <<
"\n";
769 dbgs() <<
"FnSpecialization: FormalArg = "
778 for (
unsigned I = 0;
I < NSpecs; ++
I) {
779 Spec &S = AllSpecs[BestSpecs[
I]];
785 S.
Clone = createSpecialization(S.
F, S.
Sig);
791 <<
" to call " << Clone->
getName() <<
"\n");
793 auto &BFI = GetBFI(*
Call->getFunction());
794 std::optional<uint64_t>
Count =
795 BFI.getBlockProfileCount(
Call->getParent());
797 std::optional<llvm::Function::ProfileCount> MaybeCloneCount =
799 assert(MaybeCloneCount &&
"Clone entry count was not set!");
802 if (std::optional<llvm::Function::ProfileCount> MaybeOriginalCount =
804 uint64_t OriginalCount = MaybeOriginalCount->getCount();
805 if (OriginalCount >= *
Count) {
817 OriginalFuncs.insert(S.
F);
820 Solver.solveWhileResolvedUndefsIn(Clones);
826 auto [Begin, End] = SM[
F];
827 updateCallSites(
F, AllSpecs.
begin() + Begin, AllSpecs.
begin() + End);
831 if (
F->getReturnType()->isVoidTy())
833 if (
F->getReturnType()->isStructTy()) {
835 if (!Solver.isStructLatticeConstant(
F, STy))
838 auto It = Solver.getTrackedRetVals().find(
F);
839 assert(It != Solver.getTrackedRetVals().end() &&
840 "Return value ought to be tracked");
844 for (
User *U :
F->users()) {
847 if (CS->getCalledFunction() !=
F)
849 Solver.resetLatticeValueFor(CS);
855 Solver.solveWhileResolvedUndefs();
858 if (FunctionMetrics[
F].isRecursive)
859 promoteConstantStackValues(
F);
864void FunctionSpecializer::removeDeadFunctions() {
867 <<
F->getName() <<
"\n");
869 FAM->clear(*
F,
F->getName());
875 "User of dead function must be call or invoke");
880 F->eraseFromParent();
882 DeadFunctions.clear();
890 Clone->
setName(
F->getName() +
".specialized." +
Twine(NSpecs));
895bool FunctionSpecializer::findSpecializations(
Function *
F,
unsigned FuncSize,
901 DenseMap<SpecSig, unsigned> UniqueSpecs;
905 for (Argument &Arg :
F->args())
906 if (isArgumentInteresting(&Arg))
907 Args.push_back(&Arg);
912 for (User *U :
F->users()) {
918 if (CS.getCalledFunction() !=
F)
923 if (CS.hasFnAttr(Attribute::MinSize))
928 if (!Solver.isBlockExecutable(CS.
getParent()))
934 for (Argument *
A : Args) {
935 Constant *
C = getCandidateConstant(CS.getArgOperand(
A->getArgNo()));
938 LLVM_DEBUG(
dbgs() <<
"FnSpecialization: Found interesting argument "
939 <<
A->getName() <<
" : " <<
C->getNameOrAsOperand()
948 if (
auto It = UniqueSpecs.
find(S); It != UniqueSpecs.
end()) {
957 const unsigned Index = It->second;
964 for (ArgInfo &
A : S.
Args) {
966 Score += getInliningBonus(
A.Formal,
A.Actual);
971 unsigned SpecSize = FuncSize - CodeSizeSavings;
973 auto IsProfitable = [&]() ->
bool {
979 dbgs() <<
"FnSpecialization: Specialization bonus {Inlining = "
980 << Score <<
" (" << (Score * 100 / FuncSize) <<
"%)}\n");
987 dbgs() <<
"FnSpecialization: Specialization bonus {CodeSize = "
988 << CodeSizeSavings <<
" ("
989 << (CodeSizeSavings * 100 / FuncSize) <<
"%)}\n");
996 unsigned LatencySavings =
1000 dbgs() <<
"FnSpecialization: Specialization bonus {Latency = "
1001 << LatencySavings <<
" ("
1002 << (LatencySavings * 100 / FuncSize) <<
"%)}\n");
1011 Score += std::max(CodeSizeSavings, LatencySavings);
1016 if (!IsProfitable())
1022 Spec.CallSites.push_back(&CS);
1023 const unsigned Index = AllSpecs.
size() - 1;
1024 UniqueSpecs[S] =
Index;
1025 if (
auto [It, Inserted] = SM.try_emplace(
F, Index, Index + 1); !Inserted)
1026 It->second.second =
Index + 1;
1030 return !UniqueSpecs.
empty();
1033bool FunctionSpecializer::isCandidateFunction(
Function *
F) {
1034 if (
F->isDeclaration() ||
F->arg_empty())
1037 if (
F->hasFnAttribute(Attribute::NoDuplicate))
1041 if (Specializations.contains(
F))
1050 if (!Solver.isBlockExecutable(&
F->getEntryBlock()))
1054 if (
F->hasFnAttribute(Attribute::AlwaysInline))
1057 LLVM_DEBUG(
dbgs() <<
"FnSpecialization: Try function: " <<
F->getName()
1076 Solver.setLatticeValueForSpecializationArguments(Clone, S.
Args);
1077 Solver.markBlockExecutable(&Clone->
front());
1078 Solver.addArgumentTrackedFunction(Clone);
1079 Solver.addTrackedFunction(Clone);
1082 Specializations.insert(Clone);
1094 if (!CalledFunction)
1098 auto &CalleeTTI = (GetTTI)(*CalledFunction);
1105 int InliningBonus = 0;
1106 for (User *U :
A->users()) {
1110 if (CS->getCalledOperand() !=
A)
1127 getInlineCost(*CS, CalledFunction, Params, CalleeTTI, GetAC, GetTLI);
1132 InliningBonus += Params.DefaultThreshold;
1136 LLVM_DEBUG(
dbgs() <<
"FnSpecialization: Inlining bonus " << InliningBonus
1137 <<
" for user " << *U <<
"\n");
1140 return InliningBonus > 0 ?
static_cast<unsigned>(InliningBonus) : 0;
1145bool FunctionSpecializer::isArgumentInteresting(
Argument *
A) {
1147 if (
A->user_empty())
1150 Type *Ty =
A->getType();
1157 if (
A->hasByValAttr() && !
A->getParent()->onlyReadsMemory())
1161 if (!Solver.isArgumentTrackedFunction(
A->getParent()))
1169 : SCCPSolver::isOverdefined(Solver.getLatticeValueFor(
A));
1173 dbgs() <<
"FnSpecialization: Found interesting parameter "
1174 <<
A->getNameOrAsOperand() <<
"\n";
1176 dbgs() <<
"FnSpecialization: Nothing to do, parameter "
1177 <<
A->getNameOrAsOperand() <<
" is already constant\n";
1179 return IsOverdefined;
1184Constant *FunctionSpecializer::getCandidateConstant(
Value *V) {
1192 C = Solver.getConstantOrNull(V);
1196 if (
C &&
C->getType()->isPointerTy() && !
C->isNullValue())
1204void FunctionSpecializer::updateCallSites(
Function *
F,
const Spec *Begin,
1208 for (User *U :
F->users())
1210 CS && CS->getCalledFunction() ==
F &&
1211 Solver.isBlockExecutable(CS->
getParent()))
1214 unsigned NCallsLeft = ToUpdate.
size();
1215 for (CallBase *CS : ToUpdate) {
1219 const Spec *BestSpec =
nullptr;
1220 for (
const Spec &S :
make_range(Begin, End)) {
1221 if (!S.Clone || (BestSpec && S.Score <= BestSpec->
Score))
1224 if (
any_of(S.Sig.
Args, [CS,
this](
const ArgInfo &Arg) {
1225 unsigned ArgNo = Arg.Formal->getArgNo();
1226 return getCandidateConstant(CS->getArgOperand(ArgNo)) != Arg.Actual;
1236 CS->setCalledFunction(BestSpec->
Clone);
1237 ShouldDecrementCount =
true;
1240 if (ShouldDecrementCount)
1248 if (NCallsLeft == 0 && Solver.isArgumentTrackedFunction(
F) &&
1249 !
F->hasAddressTaken()) {
1250 Solver.markFunctionUnreachable(
F);
1251 DeadFunctions.insert(
F);
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static cl::opt< bool > ForceSpecialization("force-specialization", cl::init(false), cl::Hidden, cl::desc("Force function specialization for every call site with a constant " "argument"))
static cl::opt< unsigned > MaxDiscoveryIterations("funcspec-max-discovery-iterations", cl::init(100), cl::Hidden, cl::desc("The maximum number of iterations allowed " "when searching for transitive " "phis"))
static cl::opt< unsigned > MinFunctionSize("funcspec-min-function-size", cl::init(500), cl::Hidden, cl::desc("Don't specialize functions that have less than this number of " "instructions"))
static cl::opt< bool > SpecializeLiteralConstant("funcspec-for-literal-constant", cl::init(true), cl::Hidden, cl::desc("Enable specialization of functions that take a literal constant as an " "argument"))
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 cl::opt< unsigned > MaxCodeSizeGrowth("funcspec-max-codesize-growth", cl::init(3), cl::Hidden, cl::desc("Maximum codesize growth allowed per function"))
static cl::opt< unsigned > MaxClones("funcspec-max-clones", cl::init(3), cl::Hidden, cl::desc("The maximum number of clones allowed for a single function " "specialization"))
static cl::opt< unsigned > MinCodeSizeSavings("funcspec-min-codesize-savings", cl::init(20), cl::Hidden, cl::desc("Reject specializations whose codesize savings are less than this " "much percent of the original function size"))
static cl::opt< unsigned > MinInliningBonus("funcspec-min-inlining-bonus", cl::init(300), cl::Hidden, cl::desc("Reject specializations whose inlining bonus is less than this " "much percent of the original function size"))
static cl::opt< unsigned > MaxIncomingPhiValues("funcspec-max-incoming-phi-values", cl::init(8), cl::Hidden, cl::desc("The maximum number of incoming values a PHI node can have to be " "considered during the specialization bonus estimation"))
static cl::opt< unsigned > MaxBlockPredecessors("funcspec-max-block-predecessors", cl::init(2), cl::Hidden, cl::desc("The maximum number of predecessors a basic block can have to be " "considered during the estimation of dead code"))
static cl::opt< bool > SpecializeOnAddress("funcspec-on-address", cl::init(false), cl::Hidden, cl::desc("Enable function specialization on the address of global values"))
static unsigned getCostValue(const Cost &C)
Get the unsigned Value of given Cost object.
static cl::opt< unsigned > MinLatencySavings("funcspec-min-latency-savings", cl::init(20), cl::Hidden, cl::desc("Reject specializations whose latency savings are less than this " "much percent of the original function size"))
const AbstractManglingParser< Derived, Alloc >::OperatorInfo AbstractManglingParser< Derived, Alloc >::Ops[]
mir Rename Register Operands
FunctionAnalysisManager FAM
cl::opt< bool > ProfcheckDisableMetadataFixes("profcheck-disable-metadata-fixes", cl::Hidden, cl::init(false), cl::desc("Disable metadata propagation fixes discovered through Issue #147390"))
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
Type * getAllocatedType() const
Return the type that is being allocated by the instruction.
This class represents an incoming formal argument to a Function.
LLVM Basic Block Representation.
Conditional or Unconditional Branch instruction.
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.
This is an important base class in LLVM.
iterator find(const_arg_type_t< KeyT > Val)
bool contains(const_arg_type_t< KeyT > Val) const
Return true if the specified key is in the map, false otherwise.
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...
InstCostVisitor getInstCostVisitorFor(Function *F)
FunctionType * getFunctionType() const
Returns the FunctionType for me.
const BasicBlock & front() const
std::optional< ProfileCount > getEntryCount(bool AllowSynthetic=false) const
Get the entry count for this function.
void setEntryCount(ProfileCount 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.
An instruction for reading from memory.
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.
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.
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.
iterator_range< user_iterator > users()
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.
@ C
The default llvm calling convention, compatible with C.
@ BasicBlock
Various leaf nodes.
const int IndirectCallThreshold
initializer< Ty > init(const Ty &Val)
@ User
could "use" a pointer
This is an optimization pass for GlobalISel generic memory operations.
FunctionAddr VTableAddr Value
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 bool canConstantFoldCallTo(const CallBase *Call, const Function *F)
canConstantFoldCallTo - Return true if its even possible to fold a call to the specified function.
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
auto successors(const MachineBasicBlock *BB)
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.
LLVM_ABI Constant * ConstantFoldCompareInstOperands(unsigned Predicate, Constant *LHS, Constant *RHS, const DataLayout &DL, const TargetLibraryInfo *TLI=nullptr, const Instruction *I=nullptr)
Attempt to constant fold a compare instruction (icmp/fcmp) with the specified operands.
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...
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.
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.
FunctionAddr VTableAddr Count
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...
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 InlineCost getInlineCost(CallBase &Call, const InlineParams &Params, TargetTransformInfo &CalleeTTI, 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 Value * simplifyBinOp(unsigned Opcode, Value *LHS, Value *RHS, const SimplifyQuery &Q)
Given operands for a BinaryOperator, fold the result or return null.
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 >
LLVM_ABI InlineParams getInlineParams()
Generate the parameters to tune the inline cost analysis based only on the commandline options.
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...
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.
LLVM_ABI const Value * getUnderlyingObject(const Value *V, unsigned MaxLookup=MaxLookupSearchDepth)
This method strips off any GEP address adjustments, pointer casts or llvm.threadlocal....
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)
static SpecSig getEmptyKey()
static SpecSig getTombstoneKey()
An information struct used to provide DenseMap with the various necessary components for a given valu...
SmallVector< ArgInfo, 4 > Args
SmallVector< CallBase * > CallSites