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 "Don't specialize functions that have less than this number of "
66 "Maximum codesize growth allowed per function"));
70 "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 "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"));
93 "Enable specialization of functions that take a literal constant as an "
102 (Pred == BB || Pred == Succ || DeadBlocks.
contains(Pred));
112Cost InstCostVisitor::estimateBasicBlocks(
116 while (!WorkList.
empty()) {
122 if (!DeadBlocks.
insert(BB).second)
127 if (
auto *
II = dyn_cast<IntrinsicInst>(&
I))
128 if (
II->getIntrinsicID() == Intrinsic::ssa_copy)
137 <<
" for user " <<
I <<
"\n");
145 canEliminateSuccessor(BB, SuccBB, DeadBlocks))
152 if (
auto *
C = dyn_cast<Constant>(V))
154 return KnownConstants.
lookup(V);
159 while (!PendingPHIs.empty()) {
163 B += getUserBonus(Phi);
170 LLVM_DEBUG(
dbgs() <<
"FnSpecialization: Analysing bonus for constant: "
171 <<
C->getNameOrAsOperand() <<
"\n");
173 for (
auto *U :
A->users())
174 if (
auto *UI = dyn_cast<Instruction>(U))
176 B += getUserBonus(UI,
A,
C);
178 LLVM_DEBUG(
dbgs() <<
"FnSpecialization: Accumulated bonus {CodeSize = "
179 <<
B.CodeSize <<
", Latency = " <<
B.Latency
180 <<
"} for argument " << *
A <<
"\n");
191 : KnownConstants.
end();
194 if (
auto *
I = dyn_cast<SwitchInst>(
User)) {
195 CodeSize = estimateSwitchInst(*
I);
196 }
else if (
auto *
I = dyn_cast<BranchInst>(
User)) {
197 CodeSize = estimateBranchInst(*
I);
218 <<
", Latency = " <<
Latency <<
"} for user "
223 if (
auto *UI = dyn_cast<Instruction>(U))
225 B += getUserBonus(UI,
User,
C);
231 assert(LastVisited != KnownConstants.
end() &&
"Invalid iterator!");
233 if (
I.getCondition() != LastVisited->first)
236 auto *
C = dyn_cast<ConstantInt>(LastVisited->second);
240 BasicBlock *Succ =
I.findCaseValue(
C)->getCaseSuccessor();
245 for (
const auto &Case :
I.cases()) {
248 canEliminateSuccessor(
I.getParent(), BB, DeadBlocks))
252 return estimateBasicBlocks(WorkList);
256 assert(LastVisited != KnownConstants.
end() &&
"Invalid iterator!");
258 if (
I.getCondition() != LastVisited->first)
261 BasicBlock *Succ =
I.getSuccessor(LastVisited->second->isOneValue());
266 canEliminateSuccessor(
I.getParent(), Succ, DeadBlocks))
269 return estimateBasicBlocks(WorkList);
272bool InstCostVisitor::discoverTransitivelyIncomingValues(
279 while (!WorkList.
empty()) {
286 if (!TransitivePHIs.
insert(PN).second)
293 if (
auto *Inst = dyn_cast<Instruction>(V))
304 if (
auto *Phi = dyn_cast<PHINode>(V)) {
320 bool Inserted = VisitedPHIs.insert(&
I).second;
322 bool HaveSeenIncomingPHI =
false;
324 for (
unsigned Idx = 0, E =
I.getNumIncomingValues();
Idx != E; ++
Idx) {
328 if (
auto *Inst = dyn_cast<Instruction>(V))
329 if (Inst == &
I || DeadBlocks.
contains(
I.getIncomingBlock(
Idx)))
344 PendingPHIs.push_back(&
I);
348 if (isa<PHINode>(V)) {
350 HaveSeenIncomingPHI =
true;
361 if (!HaveSeenIncomingPHI)
365 if (!discoverTransitivelyIncomingValues(Const, &
I, TransitivePHIs))
372 assert(LastVisited != KnownConstants.
end() &&
"Invalid iterator!");
375 return LastVisited->second;
387 for (
unsigned Idx = 0, E =
I.getNumOperands() - 1;
Idx != E; ++
Idx) {
400 assert(LastVisited != KnownConstants.
end() &&
"Invalid iterator!");
402 if (isa<ConstantPointerNull>(LastVisited->second))
411 for (
unsigned Idx = 0, E =
I.getNumOperands();
Idx != E; ++
Idx) {
424 assert(LastVisited != KnownConstants.
end() &&
"Invalid iterator!");
426 if (
I.getCondition() != LastVisited->first)
429 Value *
V = LastVisited->second->isZeroValue() ?
I.getFalseValue()
441 assert(LastVisited != KnownConstants.
end() &&
"Invalid iterator!");
443 bool Swap =
I.getOperand(1) == LastVisited->first;
444 Value *
V = Swap ?
I.getOperand(0) :
I.getOperand(1);
456 assert(LastVisited != KnownConstants.
end() &&
"Invalid iterator!");
462 assert(LastVisited != KnownConstants.
end() &&
"Invalid iterator!");
464 bool Swap =
I.getOperand(1) == LastVisited->first;
465 Value *
V = Swap ?
I.getOperand(0) :
I.getOperand(1);
471 return dyn_cast_or_null<Constant>(Swap ?
478 Value *StoreValue =
nullptr;
484 if (
auto *Bitcast = dyn_cast<BitCastInst>(
User)) {
490 if (
auto *Store = dyn_cast<StoreInst>(
User)) {
492 if (StoreValue ||
Store->isVolatile())
494 StoreValue =
Store->getValueOperand();
504 return getCandidateConstant(StoreValue);
515 if (
auto *ConstVal = dyn_cast<ConstantInt>(Val))
517 auto *Alloca = dyn_cast<AllocaInst>(Val);
520 return getPromotableAlloca(Alloca, Call);
546void FunctionSpecializer::promoteConstantStackValues(
Function *
F) {
547 for (
User *U :
F->users()) {
549 auto *
Call = dyn_cast<CallInst>(U);
556 for (
const Use &U :
Call->args()) {
557 unsigned Idx =
Call->getArgOperandNo(&U);
564 auto *ConstVal = getConstantStackValue(Call, ArgOp);
570 "specialized.arg." +
Twine(++NGlobals));
581 auto *
II = dyn_cast<IntrinsicInst>(&Inst);
584 if (
II->getIntrinsicID() != Intrinsic::ssa_copy)
586 Inst.replaceAllUsesWith(
II->getOperand(0));
587 Inst.eraseFromParent();
593void FunctionSpecializer::cleanUpSSA() {
615 if (NumSpecsCreated > 0)
616 dbgs() <<
"FnSpecialization: Created " << NumSpecsCreated
617 <<
" specializations in module " << M.
getName() <<
"\n");
619 removeDeadFunctions();
631 unsigned NumCandidates = 0;
633 if (!isCandidateFunction(&
F))
636 auto [It, Inserted] = FunctionMetrics.try_emplace(&
F);
643 Metrics.analyzeBasicBlock(&BB, GetTTI(
F), EphValues);
660 int64_t Sz = *
Metrics.NumInsts.getValue();
661 assert(Sz > 0 &&
"CodeSize should be positive");
663 unsigned FuncSize =
static_cast<unsigned>(Sz);
666 <<
F.getName() <<
" is " << FuncSize <<
"\n");
668 if (Inserted &&
Metrics.isRecursive)
669 promoteConstantStackValues(&
F);
671 if (!findSpecializations(&
F, FuncSize, AllSpecs, SM)) {
673 dbgs() <<
"FnSpecialization: No possible specializations found for "
674 <<
F.getName() <<
"\n");
681 if (!NumCandidates) {
684 <<
"FnSpecialization: No possible specializations found in module\n");
691 auto CompareScore = [&AllSpecs](
unsigned I,
unsigned J) {
692 if (AllSpecs[
I].Score != AllSpecs[J].Score)
693 return AllSpecs[
I].Score > AllSpecs[J].Score;
696 const unsigned NSpecs =
697 std::min(NumCandidates *
MaxClones,
unsigned(AllSpecs.
size()));
699 std::iota(BestSpecs.
begin(), BestSpecs.
begin() + NSpecs, 0);
700 if (AllSpecs.
size() > NSpecs) {
701 LLVM_DEBUG(
dbgs() <<
"FnSpecialization: Number of candidates exceed "
702 <<
"the maximum number of clones threshold.\n"
703 <<
"FnSpecialization: Specializing the "
705 <<
" most profitable candidates.\n");
706 std::make_heap(BestSpecs.
begin(), BestSpecs.
begin() + NSpecs, CompareScore);
707 for (
unsigned I = NSpecs,
N = AllSpecs.
size();
I <
N; ++
I) {
708 BestSpecs[NSpecs] =
I;
709 std::push_heap(BestSpecs.
begin(), BestSpecs.
end(), CompareScore);
710 std::pop_heap(BestSpecs.
begin(), BestSpecs.
end(), CompareScore);
714 LLVM_DEBUG(
dbgs() <<
"FnSpecialization: List of specializations \n";
715 for (
unsigned I = 0;
I < NSpecs; ++
I) {
716 const Spec &S = AllSpecs[BestSpecs[
I]];
717 dbgs() <<
"FnSpecialization: Function " << S.
F->
getName()
718 <<
" , score " << S.
Score <<
"\n";
720 dbgs() <<
"FnSpecialization: FormalArg = "
729 for (
unsigned I = 0;
I < NSpecs; ++
I) {
730 Spec &S = AllSpecs[BestSpecs[
I]];
731 S.
Clone = createSpecialization(S.
F, S.
Sig);
737 Call->setCalledFunction(S.
Clone);
741 OriginalFuncs.insert(S.
F);
750 auto [Begin,
End] = SM[
F];
751 updateCallSites(
F, AllSpecs.
begin() + Begin, AllSpecs.
begin() +
End);
755 if (
F->getReturnType()->isVoidTy())
757 if (
F->getReturnType()->isStructTy()) {
758 auto *STy = cast<StructType>(
F->getReturnType());
764 "Return value ought to be tracked");
768 for (
User *U :
F->users()) {
769 if (
auto *CS = dyn_cast<CallBase>(U)) {
771 if (CS->getCalledFunction() !=
F)
782 if (FunctionMetrics[
F].isRecursive)
783 promoteConstantStackValues(
F);
788void FunctionSpecializer::removeDeadFunctions() {
791 <<
F->getName() <<
"\n");
794 F->eraseFromParent();
796 FullySpecialized.clear();
804 Clone->
setName(
F->getName() +
".specialized." +
Twine(NSpecs));
809bool FunctionSpecializer::findSpecializations(
Function *
F,
unsigned FuncSize,
820 if (isArgumentInteresting(&Arg))
821 Args.push_back(&Arg);
826 for (
User *U :
F->users()) {
827 if (!isa<CallInst>(U) && !isa<InvokeInst>(U))
829 auto &CS = *cast<CallBase>(U);
832 if (CS.getCalledFunction() !=
F)
837 if (CS.hasFnAttr(Attribute::MinSize))
849 Constant *
C = getCandidateConstant(CS.getArgOperand(
A->getArgNo()));
852 LLVM_DEBUG(
dbgs() <<
"FnSpecialization: Found interesting argument "
853 <<
A->getName() <<
" : " <<
C->getNameOrAsOperand()
862 if (
auto It = UniqueSpecs.
find(S); It != UniqueSpecs.
end()) {
869 if (CS.getFunction() ==
F)
871 const unsigned Index = It->second;
880 Score += getInliningBonus(
A.Formal,
A.Actual);
885 LLVM_DEBUG(
dbgs() <<
"FnSpecialization: Specialization bonus {CodeSize = "
886 <<
B.CodeSize <<
", Latency = " <<
B.Latency
887 <<
", Inlining = " << Score <<
"}\n");
889 FunctionGrowth[
F] += FuncSize -
B.CodeSize;
891 auto IsProfitable = [](
Bonus &
B,
unsigned Score,
unsigned FuncSize,
892 unsigned FuncGrowth) ->
bool {
912 if (!IsProfitable(
B, Score, FuncSize, FunctionGrowth[
F]))
916 Score += std::max(
B.CodeSize,
B.Latency);
918 if (CS.getFunction() !=
F)
920 const unsigned Index = AllSpecs.
size() - 1;
921 UniqueSpecs[S] =
Index;
923 It->second.second =
Index + 1;
927 return !UniqueSpecs.
empty();
930bool FunctionSpecializer::isCandidateFunction(
Function *
F) {
931 if (
F->isDeclaration() ||
F->arg_empty())
934 if (
F->hasFnAttribute(Attribute::NoDuplicate))
938 if (Specializations.contains(
F))
942 if (
F->hasOptSize() ||
952 if (
F->hasFnAttribute(Attribute::AlwaysInline))
955 LLVM_DEBUG(
dbgs() <<
"FnSpecialization: Try function: " <<
F->getName()
977 Specializations.insert(Clone);
988 Function *CalledFunction = dyn_cast<Function>(
C->stripPointerCasts());
993 auto &CalleeTTI = (GetTTI)(*CalledFunction);
1000 int InliningBonus = 0;
1001 for (
User *U :
A->users()) {
1002 if (!isa<CallInst>(U) && !isa<InvokeInst>(U))
1004 auto *CS = cast<CallBase>(U);
1005 if (CS->getCalledOperand() !=
A)
1022 getInlineCost(*CS, CalledFunction, Params, CalleeTTI, GetAC, GetTLI);
1027 InliningBonus += Params.DefaultThreshold;
1031 LLVM_DEBUG(
dbgs() <<
"FnSpecialization: Inlining bonus " << InliningBonus
1032 <<
" for user " << *U <<
"\n");
1035 return InliningBonus > 0 ?
static_cast<unsigned>(InliningBonus) : 0;
1040bool FunctionSpecializer::isArgumentInteresting(
Argument *
A) {
1042 if (
A->user_empty())
1045 Type *Ty =
A->getType();
1052 if (
A->hasByValAttr() && !
A->getParent()->onlyReadsMemory())
1064 :
SCCPSolver::isOverdefined(Solver.getLatticeValueFor(
A));
1068 dbgs() <<
"FnSpecialization: Found interesting parameter "
1069 <<
A->getNameOrAsOperand() <<
"\n";
1071 dbgs() <<
"FnSpecialization: Nothing to do, parameter "
1072 <<
A->getNameOrAsOperand() <<
" is already constant\n";
1074 return IsOverdefined;
1079Constant *FunctionSpecializer::getCandidateConstant(
Value *V) {
1080 if (isa<PoisonValue>(V))
1091 if (
C &&
C->getType()->isPointerTy() && !
C->isNullValue())
1099void FunctionSpecializer::updateCallSites(
Function *
F,
const Spec *Begin,
1103 for (
User *U :
F->users())
1104 if (
auto *CS = dyn_cast<CallBase>(U);
1105 CS && CS->getCalledFunction() ==
F &&
1109 unsigned NCallsLeft = ToUpdate.
size();
1111 bool ShouldDecrementCount = CS->getFunction() ==
F;
1114 const Spec *BestSpec =
nullptr;
1116 if (!S.Clone || (BestSpec && S.Score <= BestSpec->
Score))
1120 unsigned ArgNo = Arg.Formal->getArgNo();
1121 return getCandidateConstant(CS->getArgOperand(ArgNo)) != Arg.Actual;
1131 CS->setCalledFunction(BestSpec->
Clone);
1132 ShouldDecrementCount =
true;
1135 if (ShouldDecrementCount)
1143 FullySpecialized.insert(
F);
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
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 > 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 > MaxDiscoveryIterations("funcspec-max-discovery-iterations", cl::init(100), cl::Hidden, cl::desc("The maximum number of iterations allowed " "when searching for transitive " "phis"))
static Constant * findConstantFor(Value *V, ConstMap &KnownConstants)
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 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 > 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< unsigned > MinFunctionSize("funcspec-min-function-size", cl::init(300), cl::Hidden, cl::desc("Don't specialize functions that have less than this number of " "instructions"))
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 cl::opt< bool > SpecializeLiteralConstant("funcspec-for-literal-constant", cl::init(false), cl::Hidden, cl::desc("Enable specialization of functions that take a literal constant as an " "argument"))
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.
BlockFrequency getEntryFreq() const
BlockFrequency getBlockFreq(const BasicBlock *BB) const
getblockFreq - Return block frequency.
uint64_t getFrequency() const
Returns the frequency as a fixpoint number scaled by the entry frequency.
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.
bool isBlockExecutable(BasicBlock *BB)
Bonus getSpecializationBonus(Argument *A, Constant *C)
Compute a bonus for replacing argument A with constant C.
Bonus getBonusFromPendingPHIs()
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...
const MapVector< Function *, ValueLatticeElement > & getTrackedRetVals()
getTrackedRetVals - Get the inferred return value map.
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.
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.
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.
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)
bool contains(const_arg_type_t< ValueT > V) const
Check if the set contains the given element.
constexpr char Args[]
Key for Kernel::Metadata::mArgs.
@ C
The default llvm calling convention, compatible with C.
const int IndirectCallThreshold
@ Bitcast
Perform the operation on a different, but equivalently sized type.
Predicate getPredicate(unsigned Condition, unsigned Hint)
Return predicate consisting of specified condition and hint bits.
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.
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