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 "
92bool InstCostVisitor::canEliminateSuccessor(
BasicBlock *BB,
107Cost InstCostVisitor::estimateBasicBlocks(
111 while (!WorkList.
empty()) {
118 if (!DeadBlocks.insert(BB).second)
129 <<
" for user " <<
I <<
"\n");
143 if (
auto *
C = dyn_cast<Constant>(V))
147 return KnownConstants.
lookup(V);
152 while (!PendingPHIs.empty()) {
156 CodeSize += getCodeSizeSavingsForUser(Phi);
163 LLVM_DEBUG(
dbgs() <<
"FnSpecialization: Analysing bonus for constant: "
164 <<
C->getNameOrAsOperand() <<
"\n");
166 for (
auto *U :
A->users())
167 if (
auto *UI = dyn_cast<Instruction>(U))
169 CodeSize += getCodeSizeSavingsForUser(UI,
A,
C);
171 LLVM_DEBUG(
dbgs() <<
"FnSpecialization: Accumulated bonus {CodeSize = "
172 <<
CodeSize <<
"} for argument " << *
A <<
"\n");
189 auto &BFI = GetBFI(*F);
190 Cost TotalLatency = 0;
192 for (
auto Pair : KnownConstants) {
197 uint64_t Weight = BFI.getBlockFreq(
I->getParent()).getFrequency() /
198 BFI.getEntryFreq().getFrequency();
204 <<
"} for instruction " << *
I <<
"\n");
220 : KnownConstants.
end();
223 if (
auto *
I = dyn_cast<SwitchInst>(
User)) {
225 }
else if (
auto *
I = dyn_cast<BranchInst>(
User)) {
241 <<
"} for user " << *
User <<
"\n");
244 if (
auto *UI = dyn_cast<Instruction>(U))
252 assert(LastVisited != KnownConstants.
end() &&
"Invalid iterator!");
254 if (
I.getCondition() != LastVisited->first)
257 auto *
C = dyn_cast<ConstantInt>(LastVisited->second);
261 BasicBlock *Succ =
I.findCaseValue(
C)->getCaseSuccessor();
266 for (
const auto &Case :
I.cases()) {
269 canEliminateSuccessor(
I.getParent(), BB))
273 return estimateBasicBlocks(WorkList);
277 assert(LastVisited != KnownConstants.
end() &&
"Invalid iterator!");
279 if (
I.getCondition() != LastVisited->first)
282 BasicBlock *Succ =
I.getSuccessor(LastVisited->second->isOneValue());
289 return estimateBasicBlocks(WorkList);
292bool InstCostVisitor::discoverTransitivelyIncomingValues(
299 while (!WorkList.
empty()) {
306 if (!TransitivePHIs.
insert(PN).second)
313 if (
auto *Inst = dyn_cast<Instruction>(V))
324 if (
auto *Phi = dyn_cast<PHINode>(V)) {
340 bool Inserted = VisitedPHIs.insert(&
I).second;
342 bool HaveSeenIncomingPHI =
false;
344 for (
unsigned Idx = 0, E =
I.getNumIncomingValues();
Idx != E; ++
Idx) {
348 if (
auto *Inst = dyn_cast<Instruction>(V))
364 PendingPHIs.push_back(&
I);
368 if (isa<PHINode>(V)) {
370 HaveSeenIncomingPHI =
true;
381 if (!HaveSeenIncomingPHI)
385 if (!discoverTransitivelyIncomingValues(Const, &
I, TransitivePHIs))
392 assert(LastVisited != KnownConstants.
end() &&
"Invalid iterator!");
395 return LastVisited->second;
400 assert(LastVisited != KnownConstants.
end() &&
"Invalid iterator!");
409 for (
unsigned Idx = 0, E =
I.getNumOperands() - 1;
Idx != E; ++
Idx) {
411 if (isa<MetadataAsValue>(V))
424 assert(LastVisited != KnownConstants.
end() &&
"Invalid iterator!");
426 if (isa<ConstantPointerNull>(LastVisited->second))
435 for (
unsigned Idx = 0, E =
I.getNumOperands();
Idx != E; ++
Idx) {
448 assert(LastVisited != KnownConstants.
end() &&
"Invalid iterator!");
450 if (
I.getCondition() == LastVisited->first) {
451 Value *
V = LastVisited->second->isZeroValue() ?
I.getFalseValue()
453 return findConstantFor(V);
455 if (
Constant *Condition = findConstantFor(
I.getCondition()))
456 if ((
I.getTrueValue() == LastVisited->first && Condition->isOneValue()) ||
457 (
I.getFalseValue() == LastVisited->first && Condition->isZeroValue()))
458 return LastVisited->second;
468 assert(LastVisited != KnownConstants.
end() &&
"Invalid iterator!");
471 bool ConstOnRHS =
I.getOperand(1) == LastVisited->first;
472 Value *
V = ConstOnRHS ?
I.getOperand(0) :
I.getOperand(1);
485 auto &V1State = ConstOnRHS ? OtherLV : ConstLV;
486 auto &V2State = ConstOnRHS ? ConstLV : OtherLV;
487 return V1State.
getCompare(
I.getPredicate(),
I.getType(), V2State, DL);
491 assert(LastVisited != KnownConstants.
end() &&
"Invalid iterator!");
497 assert(LastVisited != KnownConstants.
end() &&
"Invalid iterator!");
499 bool ConstOnRHS =
I.getOperand(1) == LastVisited->first;
500 Value *
V = ConstOnRHS ?
I.getOperand(0) :
I.getOperand(1);
503 Value *ConstVal = LastVisited->second;
508 return dyn_cast_or_null<Constant>(
514 Value *StoreValue =
nullptr;
521 if (
auto *Store = dyn_cast<StoreInst>(
User)) {
523 if (StoreValue ||
Store->isVolatile())
525 StoreValue =
Store->getValueOperand();
535 return getCandidateConstant(StoreValue);
546 if (
auto *ConstVal = dyn_cast<ConstantInt>(Val))
548 auto *Alloca = dyn_cast<AllocaInst>(Val);
551 return getPromotableAlloca(Alloca, Call);
577void FunctionSpecializer::promoteConstantStackValues(
Function *
F) {
578 for (
User *U :
F->users()) {
580 auto *
Call = dyn_cast<CallInst>(U);
587 for (
const Use &U :
Call->args()) {
588 unsigned Idx =
Call->getArgOperandNo(&U);
595 auto *ConstVal = getConstantStackValue(Call, ArgOp);
601 "specialized.arg." +
Twine(++NGlobals));
612 auto *BC = dyn_cast<BitCastInst>(&Inst);
613 if (!BC || BC->getType() != BC->getOperand(0)->getType())
615 Inst.replaceAllUsesWith(BC->getOperand(0));
616 Inst.eraseFromParent();
622void FunctionSpecializer::cleanUpSSA() {
644 if (NumSpecsCreated > 0)
645 dbgs() <<
"FnSpecialization: Created " << NumSpecsCreated
646 <<
" specializations in module " << M.
getName() <<
"\n");
648 removeDeadFunctions();
656 int64_t
Value =
C.getValue();
658 assert(
Value >= 0 &&
"CodeSize and Latency cannot be negative");
661 return static_cast<unsigned>(
Value);
672 unsigned NumCandidates = 0;
674 if (!isCandidateFunction(&
F))
677 auto [It, Inserted] = FunctionMetrics.try_emplace(&
F);
684 Metrics.analyzeBasicBlock(&BB, GetTTI(
F), EphValues);
689 const bool RequireMinSize =
707 int64_t Sz =
Metrics.NumInsts.getValue();
708 assert(Sz > 0 &&
"CodeSize should be positive");
710 unsigned FuncSize =
static_cast<unsigned>(Sz);
713 <<
F.getName() <<
" is " << FuncSize <<
"\n");
715 if (Inserted &&
Metrics.isRecursive)
716 promoteConstantStackValues(&
F);
718 if (!findSpecializations(&
F, FuncSize, AllSpecs, SM)) {
720 dbgs() <<
"FnSpecialization: No possible specializations found for "
721 <<
F.getName() <<
"\n");
728 if (!NumCandidates) {
731 <<
"FnSpecialization: No possible specializations found in module\n");
738 auto CompareScore = [&AllSpecs](
unsigned I,
unsigned J) {
739 if (AllSpecs[
I].Score != AllSpecs[J].Score)
740 return AllSpecs[
I].Score > AllSpecs[J].Score;
743 const unsigned NSpecs =
744 std::min(NumCandidates *
MaxClones,
unsigned(AllSpecs.
size()));
746 std::iota(BestSpecs.
begin(), BestSpecs.
begin() + NSpecs, 0);
747 if (AllSpecs.
size() > NSpecs) {
748 LLVM_DEBUG(
dbgs() <<
"FnSpecialization: Number of candidates exceed "
749 <<
"the maximum number of clones threshold.\n"
750 <<
"FnSpecialization: Specializing the "
752 <<
" most profitable candidates.\n");
753 std::make_heap(BestSpecs.
begin(), BestSpecs.
begin() + NSpecs, CompareScore);
754 for (
unsigned I = NSpecs,
N = AllSpecs.
size();
I <
N; ++
I) {
755 BestSpecs[NSpecs] =
I;
756 std::push_heap(BestSpecs.
begin(), BestSpecs.
end(), CompareScore);
757 std::pop_heap(BestSpecs.
begin(), BestSpecs.
end(), CompareScore);
761 LLVM_DEBUG(
dbgs() <<
"FnSpecialization: List of specializations \n";
762 for (
unsigned I = 0;
I < NSpecs; ++
I) {
763 const Spec &S = AllSpecs[BestSpecs[
I]];
764 dbgs() <<
"FnSpecialization: Function " << S.
F->
getName()
765 <<
" , score " << S.
Score <<
"\n";
767 dbgs() <<
"FnSpecialization: FormalArg = "
776 for (
unsigned I = 0;
I < NSpecs; ++
I) {
777 Spec &S = AllSpecs[BestSpecs[
I]];
783 S.
Clone = createSpecialization(S.
F, S.
Sig);
789 Call->setCalledFunction(S.
Clone);
793 OriginalFuncs.insert(S.
F);
802 auto [Begin,
End] = SM[
F];
803 updateCallSites(
F, AllSpecs.
begin() + Begin, AllSpecs.
begin() +
End);
807 if (
F->getReturnType()->isVoidTy())
809 if (
F->getReturnType()->isStructTy()) {
810 auto *STy = cast<StructType>(
F->getReturnType());
816 "Return value ought to be tracked");
820 for (
User *U :
F->users()) {
821 if (
auto *CS = dyn_cast<CallBase>(U)) {
823 if (CS->getCalledFunction() !=
F)
834 if (FunctionMetrics[
F].isRecursive)
835 promoteConstantStackValues(
F);
840void FunctionSpecializer::removeDeadFunctions() {
843 <<
F->getName() <<
"\n");
850 assert((isa<CallInst>(U) || isa<InvokeInst>(U)) &&
851 "User of dead function must be call or invoke");
856 F->eraseFromParent();
858 DeadFunctions.clear();
866 Clone->
setName(
F->getName() +
".specialized." +
Twine(NSpecs));
871bool FunctionSpecializer::findSpecializations(
Function *
F,
unsigned FuncSize,
882 if (isArgumentInteresting(&Arg))
883 Args.push_back(&Arg);
888 for (
User *U :
F->users()) {
889 if (!isa<CallInst>(U) && !isa<InvokeInst>(U))
891 auto &CS = *cast<CallBase>(U);
894 if (CS.getCalledFunction() !=
F)
899 if (CS.hasFnAttr(Attribute::MinSize))
911 Constant *
C = getCandidateConstant(CS.getArgOperand(
A->getArgNo()));
914 LLVM_DEBUG(
dbgs() <<
"FnSpecialization: Found interesting argument "
915 <<
A->getName() <<
" : " <<
C->getNameOrAsOperand()
924 if (
auto It = UniqueSpecs.
find(S); It != UniqueSpecs.
end()) {
933 const unsigned Index = It->second;
942 Score += getInliningBonus(
A.Formal,
A.Actual);
947 unsigned SpecSize = FuncSize - CodeSizeSavings;
949 auto IsProfitable = [&]() ->
bool {
955 dbgs() <<
"FnSpecialization: Specialization bonus {Inlining = "
956 << Score <<
" (" << (Score * 100 / FuncSize) <<
"%)}\n");
963 dbgs() <<
"FnSpecialization: Specialization bonus {CodeSize = "
964 << CodeSizeSavings <<
" ("
965 << (CodeSizeSavings * 100 / FuncSize) <<
"%)}\n");
972 unsigned LatencySavings =
976 dbgs() <<
"FnSpecialization: Specialization bonus {Latency = "
977 << LatencySavings <<
" ("
978 << (LatencySavings * 100 / FuncSize) <<
"%)}\n");
987 Score += std::max(CodeSizeSavings, LatencySavings);
999 const unsigned Index = AllSpecs.
size() - 1;
1000 UniqueSpecs[S] =
Index;
1001 if (
auto [It, Inserted] = SM.
try_emplace(
F, Index, Index + 1); !Inserted)
1002 It->second.second =
Index + 1;
1006 return !UniqueSpecs.
empty();
1009bool FunctionSpecializer::isCandidateFunction(
Function *
F) {
1010 if (
F->isDeclaration() ||
F->arg_empty())
1013 if (
F->hasFnAttribute(Attribute::NoDuplicate))
1017 if (Specializations.contains(
F))
1030 if (
F->hasFnAttribute(Attribute::AlwaysInline))
1033 LLVM_DEBUG(
dbgs() <<
"FnSpecialization: Try function: " <<
F->getName()
1055 Specializations.insert(Clone);
1066 Function *CalledFunction = dyn_cast<Function>(
C->stripPointerCasts());
1067 if (!CalledFunction)
1071 auto &CalleeTTI = (GetTTI)(*CalledFunction);
1078 int InliningBonus = 0;
1079 for (
User *U :
A->users()) {
1080 if (!isa<CallInst>(U) && !isa<InvokeInst>(U))
1082 auto *CS = cast<CallBase>(U);
1083 if (CS->getCalledOperand() !=
A)
1100 getInlineCost(*CS, CalledFunction, Params, CalleeTTI, GetAC, GetTLI);
1105 InliningBonus += Params.DefaultThreshold;
1109 LLVM_DEBUG(
dbgs() <<
"FnSpecialization: Inlining bonus " << InliningBonus
1110 <<
" for user " << *U <<
"\n");
1113 return InliningBonus > 0 ?
static_cast<unsigned>(InliningBonus) : 0;
1118bool FunctionSpecializer::isArgumentInteresting(
Argument *
A) {
1120 if (
A->user_empty())
1123 Type *Ty =
A->getType();
1130 if (
A->hasByValAttr() && !
A->getParent()->onlyReadsMemory())
1142 :
SCCPSolver::isOverdefined(Solver.getLatticeValueFor(
A));
1146 dbgs() <<
"FnSpecialization: Found interesting parameter "
1147 <<
A->getNameOrAsOperand() <<
"\n";
1149 dbgs() <<
"FnSpecialization: Nothing to do, parameter "
1150 <<
A->getNameOrAsOperand() <<
" is already constant\n";
1152 return IsOverdefined;
1157Constant *FunctionSpecializer::getCandidateConstant(
Value *V) {
1158 if (isa<PoisonValue>(V))
1169 if (
C &&
C->getType()->isPointerTy() && !
C->isNullValue())
1177void FunctionSpecializer::updateCallSites(
Function *
F,
const Spec *Begin,
1181 for (
User *U :
F->users())
1182 if (
auto *CS = dyn_cast<CallBase>(U);
1183 CS && CS->getCalledFunction() ==
F &&
1187 unsigned NCallsLeft = ToUpdate.
size();
1192 const Spec *BestSpec =
nullptr;
1194 if (!S.Clone || (BestSpec && S.Score <= BestSpec->
Score))
1198 unsigned ArgNo = Arg.Formal->getArgNo();
1199 return getCandidateConstant(CS->getArgOperand(ArgNo)) != Arg.Actual;
1209 CS->setCalledFunction(BestSpec->
Clone);
1210 ShouldDecrementCount =
true;
1213 if (ShouldDecrementCount)
1222 !
F->hasAddressTaken()) {
1224 DeadFunctions.insert(
F);
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
Returns the sub type a function will return at a given Idx Should correspond to the result type of an ExtractValue instruction executed with just that one unsigned Idx
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"))
mir Rename Register Operands
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.
void clear(IRUnitT &IR, llvm::StringRef Name)
Clear any cached analysis results for a single unit of IR.
This class represents an incoming formal argument to a Function.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
LLVM Basic Block Representation.
Conditional or Unconditional Branch instruction.
Base class for all callable instructions (InvokeInst and CallInst) Holds everything related to callin...
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.
ValueT lookup(const_arg_type_t< KeyT > Val) const
lookup - Return the entry for the specified key, or a default constructed value if no such entry exis...
iterator find(const_arg_type_t< KeyT > Val)
std::pair< iterator, bool > try_emplace(KeyT &&Key, Ts &&...Args)
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
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).
Represents the cost of inlining a function.
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.
StringRef getName() const
Get a short "name" for the 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...
LLVM_ABI void resetLatticeValueFor(CallBase *Call)
Invalidate the Lattice Value of Call and its users after specializing the call.
LLVM_ABI bool isStructLatticeConstant(Function *F, StructType *STy)
LLVM_ABI void addTrackedFunction(Function *F)
addTrackedFunction - If the SCCP solver is supposed to track calls into and out of the specified func...
LLVM_ABI void solveWhileResolvedUndefsIn(Module &M)
LLVM_ABI void addArgumentTrackedFunction(Function *F)
LLVM_ABI void solveWhileResolvedUndefs()
LLVM_ABI std::vector< ValueLatticeElement > getStructLatticeValueFor(Value *V) const
LLVM_ABI Constant * getConstantOrNull(Value *V) const
Return either a Constant or nullptr for a given Value.
LLVM_ABI const ValueLatticeElement & getLatticeValueFor(Value *V) const
LLVM_ABI bool isBlockExecutable(BasicBlock *BB) const
LLVM_ABI bool markBlockExecutable(BasicBlock *BB)
markBlockExecutable - This method can be used by clients to mark all of the blocks that are known to ...
LLVM_ABI void setLatticeValueForSpecializationArguments(Function *F, const SmallVectorImpl< ArgInfo > &Args)
Set the Lattice Value for the arguments of a specialization F.
LLVM_ABI const MapVector< Function *, ValueLatticeElement > & getTrackedRetVals() const
getTrackedRetVals - Get the inferred return value map.
static LLVM_ABI bool isOverdefined(const ValueLatticeElement &LV)
LLVM_ABI void markFunctionUnreachable(Function *F)
Mark all of the blocks in function F non-executable.
LLVM_ABI bool isArgumentTrackedFunction(Function *F)
Returns true if the given function is in the solver's set of argument-tracked functions.
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...
The instances of the Type class are immutable: once they are created, they are never changed.
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.
This class represents lattice values for constants.
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.
const int IndirectCallThreshold
initializer< Ty > init(const Ty &Val)
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 bool canConstantFoldCallTo(const CallBase *Call, const Function *F)
canConstantFoldCallTo - Return true if its even possible to fold a call to the specified function.
auto successors(const MachineBasicBlock *BB)
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...
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.
LLVM_ABI Constant * ConstantFoldCastOperand(unsigned Opcode, Constant *C, Type *DestTy, const DataLayout &DL)
Attempt to constant fold a cast with the specified operand.
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.
LLVM_ABI InlineParams getInlineParams()
Generate the parameters to tune the inline cost analysis based only on the commandline options.
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