28#define DEBUG_TYPE "function-specialization"
30STATISTIC(NumSpecsCreated,
"Number of specializations created");
34 "Force function specialization for every call site with a constant "
39 "The maximum number of clones allowed for a single function "
45 cl::desc(
"The maximum number of iterations allowed "
46 "when searching for transitive "
51 cl::desc(
"The maximum number of incoming values a PHI node can have to be "
52 "considered during the specialization bonus estimation"));
56 "The maximum number of predecessors a basic block can have to be "
57 "considered during the estimation of dead code"));
61 cl::desc(
"Don't specialize functions that have less than this number of "
66 "Maximum codesize growth allowed per function"));
70 cl::desc(
"Reject specializations whose codesize savings are less than this "
71 "much percent of the original function size"));
75 cl::desc(
"Reject specializations whose latency savings are less than this "
76 "much percent of the original function size"));
80 cl::desc(
"Reject specializations whose inlining bonus is less than this "
81 "much percent of the original function size"));
85 "Enable function specialization on the address of global values"));
90 "Enable specialization of functions that take a literal constant as an "
93bool InstCostVisitor::canEliminateSuccessor(
BasicBlock *BB,
108Cost InstCostVisitor::estimateBasicBlocks(
112 while (!WorkList.
empty()) {
119 if (!DeadBlocks.insert(BB).second)
130 <<
" for user " <<
I <<
"\n");
144 if (
auto *
C = dyn_cast<Constant>(V))
148 return KnownConstants.
lookup(V);
153 while (!PendingPHIs.empty()) {
157 CodeSize += getCodeSizeSavingsForUser(Phi);
164 LLVM_DEBUG(
dbgs() <<
"FnSpecialization: Analysing bonus for constant: "
165 <<
C->getNameOrAsOperand() <<
"\n");
167 for (
auto *U :
A->users())
168 if (
auto *UI = dyn_cast<Instruction>(U))
170 CodeSize += getCodeSizeSavingsForUser(UI,
A,
C);
172 LLVM_DEBUG(
dbgs() <<
"FnSpecialization: Accumulated bonus {CodeSize = "
173 << CodeSize <<
"} for argument " << *
A <<
"\n");
190 auto &BFI = GetBFI(*F);
191 Cost TotalLatency = 0;
193 for (
auto Pair : KnownConstants) {
198 uint64_t Weight = BFI.getBlockFreq(
I->getParent()).getFrequency() /
199 BFI.getEntryFreq().getFrequency();
205 <<
"} for instruction " << *
I <<
"\n");
221 : KnownConstants.
end();
224 if (
auto *
I = dyn_cast<SwitchInst>(
User)) {
225 CodeSize = estimateSwitchInst(*
I);
226 }
else if (
auto *
I = dyn_cast<BranchInst>(
User)) {
227 CodeSize = estimateBranchInst(*
I);
242 <<
"} for user " << *
User <<
"\n");
245 if (
auto *UI = dyn_cast<Instruction>(U))
247 CodeSize += getCodeSizeSavingsForUser(UI,
User,
C);
253 assert(LastVisited != KnownConstants.
end() &&
"Invalid iterator!");
255 if (
I.getCondition() != LastVisited->first)
258 auto *
C = dyn_cast<ConstantInt>(LastVisited->second);
262 BasicBlock *Succ =
I.findCaseValue(
C)->getCaseSuccessor();
267 for (
const auto &Case :
I.cases()) {
270 canEliminateSuccessor(
I.getParent(), BB))
274 return estimateBasicBlocks(WorkList);
278 assert(LastVisited != KnownConstants.
end() &&
"Invalid iterator!");
280 if (
I.getCondition() != LastVisited->first)
283 BasicBlock *Succ =
I.getSuccessor(LastVisited->second->isOneValue());
290 return estimateBasicBlocks(WorkList);
293bool InstCostVisitor::discoverTransitivelyIncomingValues(
300 while (!WorkList.
empty()) {
307 if (!TransitivePHIs.
insert(PN).second)
314 if (
auto *Inst = dyn_cast<Instruction>(V))
325 if (
auto *Phi = dyn_cast<PHINode>(V)) {
341 bool Inserted = VisitedPHIs.insert(&
I).second;
343 bool HaveSeenIncomingPHI =
false;
345 for (
unsigned Idx = 0, E =
I.getNumIncomingValues();
Idx != E; ++
Idx) {
349 if (
auto *Inst = dyn_cast<Instruction>(V))
365 PendingPHIs.push_back(&
I);
369 if (isa<PHINode>(V)) {
371 HaveSeenIncomingPHI =
true;
382 if (!HaveSeenIncomingPHI)
386 if (!discoverTransitivelyIncomingValues(Const, &
I, TransitivePHIs))
393 assert(LastVisited != KnownConstants.
end() &&
"Invalid iterator!");
396 return LastVisited->second;
401 assert(LastVisited != KnownConstants.
end() &&
"Invalid iterator!");
404 if (
auto *
II = dyn_cast<IntrinsicInst>(&
I);
405 II &&
II->getIntrinsicID() == Intrinsic::ssa_copy) {
406 return LastVisited->second;
416 for (
unsigned Idx = 0, E =
I.getNumOperands() - 1;
Idx != E; ++
Idx) {
418 if (isa<MetadataAsValue>(V))
431 assert(LastVisited != KnownConstants.
end() &&
"Invalid iterator!");
433 if (isa<ConstantPointerNull>(LastVisited->second))
442 for (
unsigned Idx = 0, E =
I.getNumOperands();
Idx != E; ++
Idx) {
455 assert(LastVisited != KnownConstants.
end() &&
"Invalid iterator!");
457 if (
I.getCondition() == LastVisited->first) {
458 Value *
V = LastVisited->second->isZeroValue() ?
I.getFalseValue()
460 return findConstantFor(V);
462 if (
Constant *Condition = findConstantFor(
I.getCondition()))
463 if ((
I.getTrueValue() == LastVisited->first && Condition->isOneValue()) ||
464 (
I.getFalseValue() == LastVisited->first && Condition->isZeroValue()))
465 return LastVisited->second;
475 assert(LastVisited != KnownConstants.
end() &&
"Invalid iterator!");
478 bool ConstOnRHS =
I.getOperand(1) == LastVisited->first;
479 Value *
V = ConstOnRHS ?
I.getOperand(0) :
I.getOperand(1);
492 auto &V1State = ConstOnRHS ? OtherLV : ConstLV;
493 auto &V2State = ConstOnRHS ? ConstLV : OtherLV;
494 return V1State.
getCompare(
I.getPredicate(),
I.getType(), V2State, DL);
498 assert(LastVisited != KnownConstants.
end() &&
"Invalid iterator!");
504 assert(LastVisited != KnownConstants.
end() &&
"Invalid iterator!");
506 bool ConstOnRHS =
I.getOperand(1) == LastVisited->first;
507 Value *
V = ConstOnRHS ?
I.getOperand(0) :
I.getOperand(1);
510 Value *ConstVal = LastVisited->second;
515 return dyn_cast_or_null<Constant>(
521 Value *StoreValue =
nullptr;
528 if (
auto *Store = dyn_cast<StoreInst>(
User)) {
530 if (StoreValue ||
Store->isVolatile())
532 StoreValue =
Store->getValueOperand();
542 return getCandidateConstant(StoreValue);
553 if (
auto *ConstVal = dyn_cast<ConstantInt>(Val))
555 auto *Alloca = dyn_cast<AllocaInst>(Val);
558 return getPromotableAlloca(Alloca, Call);
584void FunctionSpecializer::promoteConstantStackValues(
Function *
F) {
585 for (
User *U :
F->users()) {
587 auto *
Call = dyn_cast<CallInst>(U);
594 for (
const Use &U :
Call->args()) {
595 unsigned Idx =
Call->getArgOperandNo(&U);
602 auto *ConstVal = getConstantStackValue(Call, ArgOp);
608 "specialized.arg." +
Twine(++NGlobals));
619 auto *
II = dyn_cast<IntrinsicInst>(&Inst);
622 if (
II->getIntrinsicID() != Intrinsic::ssa_copy)
624 Inst.replaceAllUsesWith(
II->getOperand(0));
625 Inst.eraseFromParent();
631void FunctionSpecializer::cleanUpSSA() {
653 if (NumSpecsCreated > 0)
654 dbgs() <<
"FnSpecialization: Created " << NumSpecsCreated
655 <<
" specializations in module " << M.
getName() <<
"\n");
657 removeDeadFunctions();
665 int64_t
Value = *
C.getValue();
667 assert(
Value >= 0 &&
"CodeSize and Latency cannot be negative");
670 return static_cast<unsigned>(
Value);
681 unsigned NumCandidates = 0;
683 if (!isCandidateFunction(&
F))
686 auto [It, Inserted] = FunctionMetrics.try_emplace(&
F);
693 Metrics.analyzeBasicBlock(&BB, GetTTI(
F), EphValues);
698 const bool RequireMinSize =
716 int64_t Sz = *
Metrics.NumInsts.getValue();
717 assert(Sz > 0 &&
"CodeSize should be positive");
719 unsigned FuncSize =
static_cast<unsigned>(Sz);
722 <<
F.getName() <<
" is " << FuncSize <<
"\n");
724 if (Inserted &&
Metrics.isRecursive)
725 promoteConstantStackValues(&
F);
727 if (!findSpecializations(&
F, FuncSize, AllSpecs, SM)) {
729 dbgs() <<
"FnSpecialization: No possible specializations found for "
730 <<
F.getName() <<
"\n");
737 if (!NumCandidates) {
740 <<
"FnSpecialization: No possible specializations found in module\n");
747 auto CompareScore = [&AllSpecs](
unsigned I,
unsigned J) {
748 if (AllSpecs[
I].Score != AllSpecs[J].Score)
749 return AllSpecs[
I].Score > AllSpecs[J].Score;
752 const unsigned NSpecs =
753 std::min(NumCandidates *
MaxClones,
unsigned(AllSpecs.
size()));
755 std::iota(BestSpecs.
begin(), BestSpecs.
begin() + NSpecs, 0);
756 if (AllSpecs.
size() > NSpecs) {
757 LLVM_DEBUG(
dbgs() <<
"FnSpecialization: Number of candidates exceed "
758 <<
"the maximum number of clones threshold.\n"
759 <<
"FnSpecialization: Specializing the "
761 <<
" most profitable candidates.\n");
762 std::make_heap(BestSpecs.
begin(), BestSpecs.
begin() + NSpecs, CompareScore);
763 for (
unsigned I = NSpecs,
N = AllSpecs.
size();
I <
N; ++
I) {
764 BestSpecs[NSpecs] =
I;
765 std::push_heap(BestSpecs.
begin(), BestSpecs.
end(), CompareScore);
766 std::pop_heap(BestSpecs.
begin(), BestSpecs.
end(), CompareScore);
770 LLVM_DEBUG(
dbgs() <<
"FnSpecialization: List of specializations \n";
771 for (
unsigned I = 0;
I < NSpecs; ++
I) {
772 const Spec &S = AllSpecs[BestSpecs[
I]];
773 dbgs() <<
"FnSpecialization: Function " << S.
F->
getName()
774 <<
" , score " << S.
Score <<
"\n";
776 dbgs() <<
"FnSpecialization: FormalArg = "
785 for (
unsigned I = 0;
I < NSpecs; ++
I) {
786 Spec &S = AllSpecs[BestSpecs[
I]];
792 S.
Clone = createSpecialization(S.
F, S.
Sig);
798 Call->setCalledFunction(S.
Clone);
802 OriginalFuncs.insert(S.
F);
811 auto [Begin,
End] = SM[
F];
812 updateCallSites(
F, AllSpecs.
begin() + Begin, AllSpecs.
begin() +
End);
816 if (
F->getReturnType()->isVoidTy())
818 if (
F->getReturnType()->isStructTy()) {
819 auto *STy = cast<StructType>(
F->getReturnType());
825 "Return value ought to be tracked");
829 for (
User *U :
F->users()) {
830 if (
auto *CS = dyn_cast<CallBase>(U)) {
832 if (CS->getCalledFunction() !=
F)
843 if (FunctionMetrics[
F].isRecursive)
844 promoteConstantStackValues(
F);
849void FunctionSpecializer::removeDeadFunctions() {
852 <<
F->getName() <<
"\n");
855 F->eraseFromParent();
857 FullySpecialized.clear();
865 Clone->
setName(
F->getName() +
".specialized." +
Twine(NSpecs));
870bool FunctionSpecializer::findSpecializations(
Function *
F,
unsigned FuncSize,
881 if (isArgumentInteresting(&Arg))
882 Args.push_back(&Arg);
887 for (
User *U :
F->users()) {
888 if (!isa<CallInst>(U) && !isa<InvokeInst>(U))
890 auto &CS = *cast<CallBase>(U);
893 if (CS.getCalledFunction() !=
F)
898 if (CS.hasFnAttr(Attribute::MinSize))
910 Constant *
C = getCandidateConstant(CS.getArgOperand(
A->getArgNo()));
913 LLVM_DEBUG(
dbgs() <<
"FnSpecialization: Found interesting argument "
914 <<
A->getName() <<
" : " <<
C->getNameOrAsOperand()
923 if (
auto It = UniqueSpecs.
find(S); It != UniqueSpecs.
end()) {
930 if (CS.getFunction() ==
F)
932 const unsigned Index = It->second;
941 Score += getInliningBonus(
A.Formal,
A.Actual);
946 unsigned SpecSize = FuncSize - CodeSizeSavings;
948 auto IsProfitable = [&]() ->
bool {
954 dbgs() <<
"FnSpecialization: Specialization bonus {Inlining = "
955 << Score <<
" (" << (Score * 100 / FuncSize) <<
"%)}\n");
962 dbgs() <<
"FnSpecialization: Specialization bonus {CodeSize = "
963 << CodeSizeSavings <<
" ("
964 << (CodeSizeSavings * 100 / FuncSize) <<
"%)}\n");
971 unsigned LatencySavings =
975 dbgs() <<
"FnSpecialization: Specialization bonus {Latency = "
976 << LatencySavings <<
" ("
977 << (LatencySavings * 100 / FuncSize) <<
"%)}\n");
986 Score += std::max(CodeSizeSavings, LatencySavings);
996 if (CS.getFunction() !=
F)
998 const unsigned Index = AllSpecs.
size() - 1;
999 UniqueSpecs[S] =
Index;
1000 if (
auto [It, Inserted] = SM.
try_emplace(
F, Index, Index + 1); !Inserted)
1001 It->second.second =
Index + 1;
1005 return !UniqueSpecs.
empty();
1008bool FunctionSpecializer::isCandidateFunction(
Function *
F) {
1009 if (
F->isDeclaration() ||
F->arg_empty())
1012 if (
F->hasFnAttribute(Attribute::NoDuplicate))
1016 if (Specializations.contains(
F))
1029 if (
F->hasFnAttribute(Attribute::AlwaysInline))
1032 LLVM_DEBUG(
dbgs() <<
"FnSpecialization: Try function: " <<
F->getName()
1054 Specializations.insert(Clone);
1065 Function *CalledFunction = dyn_cast<Function>(
C->stripPointerCasts());
1066 if (!CalledFunction)
1070 auto &CalleeTTI = (GetTTI)(*CalledFunction);
1077 int InliningBonus = 0;
1078 for (
User *U :
A->users()) {
1079 if (!isa<CallInst>(U) && !isa<InvokeInst>(U))
1081 auto *CS = cast<CallBase>(U);
1082 if (CS->getCalledOperand() !=
A)
1099 getInlineCost(*CS, CalledFunction, Params, CalleeTTI, GetAC, GetTLI);
1104 InliningBonus += Params.DefaultThreshold;
1108 LLVM_DEBUG(
dbgs() <<
"FnSpecialization: Inlining bonus " << InliningBonus
1109 <<
" for user " << *U <<
"\n");
1112 return InliningBonus > 0 ?
static_cast<unsigned>(InliningBonus) : 0;
1117bool FunctionSpecializer::isArgumentInteresting(
Argument *
A) {
1119 if (
A->user_empty())
1122 Type *Ty =
A->getType();
1129 if (
A->hasByValAttr() && !
A->getParent()->onlyReadsMemory())
1141 :
SCCPSolver::isOverdefined(Solver.getLatticeValueFor(
A));
1145 dbgs() <<
"FnSpecialization: Found interesting parameter "
1146 <<
A->getNameOrAsOperand() <<
"\n";
1148 dbgs() <<
"FnSpecialization: Nothing to do, parameter "
1149 <<
A->getNameOrAsOperand() <<
" is already constant\n";
1151 return IsOverdefined;
1156Constant *FunctionSpecializer::getCandidateConstant(
Value *V) {
1157 if (isa<PoisonValue>(V))
1168 if (
C &&
C->getType()->isPointerTy() && !
C->isNullValue())
1176void FunctionSpecializer::updateCallSites(
Function *
F,
const Spec *Begin,
1180 for (
User *U :
F->users())
1181 if (
auto *CS = dyn_cast<CallBase>(U);
1182 CS && CS->getCalledFunction() ==
F &&
1186 unsigned NCallsLeft = ToUpdate.
size();
1188 bool ShouldDecrementCount = CS->getFunction() ==
F;
1191 const Spec *BestSpec =
nullptr;
1193 if (!S.Clone || (BestSpec && S.Score <= BestSpec->
Score))
1197 unsigned ArgNo = Arg.Formal->getArgNo();
1198 return getCandidateConstant(CS->getArgOperand(ArgNo)) != Arg.Actual;
1208 CS->setCalledFunction(BestSpec->
Clone);
1209 ShouldDecrementCount =
true;
1212 if (ShouldDecrementCount)
1220 FullySpecialized.insert(
F);
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 > MinLatencySavings("funcspec-min-latency-savings", cl::init(40), cl::Hidden, cl::desc("Reject specializations whose latency savings are less than this " "much percent of the original function size"))
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.
mir Rename Register Operands
uint64_t IntrinsicInst * II
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
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 ...
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.
Cost getLatencySavingsForKnownConstants()
Compute the latency savings from replacing all arguments with constants for a specialization candidat...
Cost getCodeSizeSavingsForArg(Argument *A, Constant *C)
Compute the codesize savings for replacing argument A with constant C.
Cost getCodeSizeSavingsFromPendingPHIs()
bool isBlockExecutable(BasicBlock *BB) const
void visit(Iterator Start, Iterator End)
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.
SCCPSolver - This interface class is a general purpose solver for Sparse Conditional Constant Propaga...
void resetLatticeValueFor(CallBase *Call)
Invalidate the Lattice Value of Call and its users after specializing the call.
bool isStructLatticeConstant(Function *F, StructType *STy)
void addTrackedFunction(Function *F)
addTrackedFunction - If the SCCP solver is supposed to track calls into and out of the specified func...
void solveWhileResolvedUndefsIn(Module &M)
void addArgumentTrackedFunction(Function *F)
void solveWhileResolvedUndefs()
std::vector< ValueLatticeElement > getStructLatticeValueFor(Value *V) const
Constant * getConstantOrNull(Value *V) const
Return either a Constant or nullptr for a given Value.
const ValueLatticeElement & getLatticeValueFor(Value *V) const
bool isBlockExecutable(BasicBlock *BB) const
bool markBlockExecutable(BasicBlock *BB)
markBlockExecutable - This method can be used by clients to mark all of the blocks that are known to ...
void setLatticeValueForSpecializationArguments(Function *F, const SmallVectorImpl< ArgInfo > &Args)
Set the Lattice Value for the arguments of a specialization F.
const MapVector< Function *, ValueLatticeElement > & getTrackedRetVals() const
getTrackedRetVals - Get the inferred return value map.
static bool isOverdefined(const ValueLatticeElement &LV)
void markFunctionUnreachable(Function *F)
Mark all of the blocks in function F non-executable.
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.
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.
void setName(const Twine &Name)
Change the name of the value.
std::string getNameOrAsOperand() const
iterator_range< user_iterator > users()
const Value * stripPointerCasts() const
Strip off pointer casts, all-zero GEPs and address space casts.
StringRef getName() const
Return a constant reference to the value's name.
std::pair< iterator, bool > insert(const ValueT &V)
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)
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.
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.
const Value * getUnderlyingObject(const Value *V, unsigned MaxLookup=6)
This method strips off any GEP address adjustments, pointer casts or llvm.threadlocal....
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...
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...
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)
Get an InlineCost object representing the cost of inlining this callsite.
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
Constant * ConstantFoldUnaryOpOperand(unsigned Opcode, Constant *Op, const DataLayout &DL)
Attempt to constant fold a unary operation with the specified operand.
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Constant * ConstantFoldInstOperands(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.
Constant * ConstantFoldCastOperand(unsigned Opcode, Constant *C, Type *DestTy, const DataLayout &DL)
Attempt to constant fold a cast with the specified operand.
Value * simplifyBinOp(unsigned Opcode, Value *LHS, Value *RHS, const SimplifyQuery &Q)
Given operands for a BinaryOperator, fold the result or return null.
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.
InlineParams getInlineParams()
Generate the parameters to tune the inline cost analysis based only on the commandline options.
auto predecessors(const MachineBasicBlock *BB)
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...
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 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