74 #define DEBUG_TYPE "callsite-splitting" 76 STATISTIC(NumCallSiteSplit,
"Number of call-site split");
83 cl::desc(
"Only allow instructions before a call, if " 84 "their cost is below DuplicationThreshold"),
89 for (
auto &
I : CS.
args()) {
99 for (
auto &
I : CS.
args()) {
111 assert(isa<Constant>(Cmp->
getOperand(1)) &&
"Expected a constant operand.");
132 ConditionsTy &Conditions) {
134 if (!BI || !BI->isConditional())
138 Value *Cond = BI->getCondition();
142 ICmpInst *Cmp = cast<ICmpInst>(Cond);
145 Conditions.
push_back({Cmp, From->getTerminator()->getSuccessor(0) == To
147 : Cmp->getInversePredicate()});
155 ConditionsTy &Conditions,
BasicBlock *StopAt) {
168 for (
auto &Cond : Conditions) {
169 Value *
Arg = Cond.first->getOperand(0);
170 Constant *ConstVal = cast<Constant>(Cond.first->getOperand(1));
182 assert(Preds.
size() == 2 &&
"Expected exactly 2 predecessors!");
190 if (!isa<CallInst>(Instr))
196 if (Preds.
size() != 2 || isa<IndirectBrInst>(Preds[0]->getTerminator()) ||
197 isa<IndirectBrInst>(Preds[1]->getTerminator()))
210 for (
auto &InstBeforeCall :
249 assert(RI &&
"`musttail` call must be followed by `ret` instruction");
315 if (!IsMustTailCall && !Instr->
use_empty()) {
320 LLVM_DEBUG(
dbgs() <<
"split call-site : " << *Instr <<
" into \n");
322 assert(Preds.size() == 2 &&
"The ValueToValueMaps array has size 2.");
326 for (
unsigned i = 0; i < Preds.size(); i++) {
329 TailBB, PredBB, &*std::next(Instr->
getIterator()), ValueToValueMaps[i],
331 assert(SplitBlock &&
"Unexpected new basic block split.");
341 for (
auto &CI : CS.
args()) {
343 NewCS.setArgument(ArgNo, PN.getIncomingValueForBlock(SplitBlock));
361 if (IsMustTailCall) {
367 assert(Splits.
size() == 2 &&
"Expected exactly 2 splits!");
368 for (
unsigned i = 0; i < Splits.
size(); i++) {
369 Splits[i]->getTerminator()->eraseFromParent();
378 auto *OriginalBegin = &*TailBB->
begin();
393 while (
I != TailBB->
rend()) {
398 if (isa<PHINode>(CurrentI))
402 for (
auto &Mapping : ValueToValueMaps)
404 cast<Instruction>(Mapping[CurrentI])->
getParent());
406 CurrentI->replaceAllUsesWith(NewPN);
410 if (CurrentI == OriginalBegin)
423 for (
auto &BI : *Parent) {
424 if (
PHINode *PN = dyn_cast<PHINode>(&BI)) {
425 for (
auto &
I : CS.
args())
427 assert(PN->getNumIncomingValues() == 2 &&
428 "Unexpected number of incoming values");
429 if (PN->getIncomingBlock(0) == PN->getIncomingBlock(1))
431 if (PN->getIncomingValue(0) == PN->getIncomingValue(1))
433 if (isa<Constant>(PN->getIncomingValue(0)) &&
434 isa<Constant>(PN->getIncomingValue(1)))
452 return {{Preds[0], {}}, {Preds[1], {}}};
461 if (Preds[0] == Preds[1])
470 BasicBlock *StopAt = CSDTNode ? CSDTNode->getIDom()->getBlock() :
nullptr;
473 for (
auto *Pred :
make_range(Preds.rbegin(), Preds.rend())) {
474 ConditionsTy Conditions;
482 if (
all_of(PredsCS, [](
const std::pair<BasicBlock *, ConditionsTy> &
P) {
483 return P.second.
empty();
497 if (PredsWithConds.empty())
499 if (PredsWithConds.empty())
510 bool Changed =
false;
545 struct CallSiteSplittingLegacyPass :
public FunctionPass {
563 auto &TLI = getAnalysis<TargetLibraryInfoWrapperPass>().getTLI();
564 auto &TTI = getAnalysis<TargetTransformInfoWrapperPass>().getTTI(F);
565 auto &DT = getAnalysis<DominatorTreeWrapperPass>().getDomTree();
573 "Call-site splitting",
false,
false)
578 "Call-site splitting",
false, false)
580 return new CallSiteSplittingLegacyPass();
Return a value (possibly void), from a function.
User::op_iterator arg_iterator
The type of iterator to use when looping over actual arguments at this call site. ...
SymbolTableList< Instruction >::iterator eraseFromParent()
This method unlinks 'this' from the containing basic block and deletes it.
bool canSplitPredecessors() const
class_match< Value > m_Value()
Match an arbitrary value and ignore it.
static bool canSplitCallSite(CallSite CS, TargetTransformInfo &TTI)
AnalysisUsage & addPreserved()
Add the specified Pass class to the set of analyses preserved by this pass.
void addIncoming(Value *V, BasicBlock *BB)
Add an incoming value to the end of the PHI list.
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
unsigned arg_size() const
BasicBlock * DuplicateInstructionsInSplitBetween(BasicBlock *BB, BasicBlock *PredBB, Instruction *StopAt, ValueToValueMapTy &ValueMapping, DomTreeUpdater &DTU)
Split edge between BB and PredBB and duplicate all non-Phi instructions from BB between its beginning...
static PredsWithCondsTy shouldSplitOnPHIPredicatedArgument(CallSite CS)
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
This class represents lattice values for constants.
static bool tryToSplitCallSite(CallSite CS, TargetTransformInfo &TTI, DomTreeUpdater &DTU)
SmallVector< ConditionTy, 2 > ConditionsTy
void push_back(const T &Elt)
DominatorTree & getDomTree()
Flush DomTree updates and return DomTree.
class_match< Constant > m_Constant()
Match an arbitrary Constant and ignore it.
iterator_range< IterTy > args() const
Analysis pass providing the TargetTransformInfo.
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly...
STATISTIC(NumFunctions, "Total number of functions")
Analysis pass which computes a DominatorTree.
const Instruction * getTerminator() const LLVM_READONLY
Returns the terminator instruction if the block is well formed or null if the block is not well forme...
static void recordConditions(CallSite CS, BasicBlock *Pred, ConditionsTy &Conditions, BasicBlock *StopAt)
Record ICmp conditions relevant to any argument in CS following Pred's single predecessors.
static void copyMustTailReturn(BasicBlock *SplitBB, Instruction *CI, Instruction *NewCI)
Copy mandatory musttail return sequence that follows original CI, and link it up to NewCI value inste...
iterator begin()
Instruction iterator methods.
INITIALIZE_PASS_BEGIN(CallSiteSplittingLegacyPass, "callsite-splitting", "Call-site splitting", false, false) INITIALIZE_PASS_END(CallSiteSplittingLegacyPass
bool match(Val *V, const Pattern &P)
AnalysisUsage & addRequired()
#define INITIALIZE_PASS_DEPENDENCY(depName)
static void splitCallSite(CallSite CS, const SmallVectorImpl< std::pair< BasicBlock *, ConditionsTy >> &Preds, DomTreeUpdater &DTU)
For each (predecessor, conditions from predecessors) pair, it will split the basic block containing t...
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void initializeCallSiteSplittingLegacyPassPass(PassRegistry &)
InstrTy * getInstruction() const
void setName(const Twine &Name)
Change the name of the value.
static cl::opt< unsigned > DuplicationThreshold("callsite-splitting-duplication-threshold", cl::Hidden, cl::desc("Only allow instructions before a call, if " "their cost is below DuplicationThreshold"), cl::init(5))
Only allow instructions before a call, if their CodeSize cost is below DuplicationThreshold.
void setArgument(unsigned ArgNo, Value *newVal)
Instruction * clone() const
Create a copy of 'this' instruction that is identical in all ways except the following: ...
bool isNullValue() const
Return true if this is the value that would be returned by getNullValue.
virtual void getAnalysisUsage(AnalysisUsage &) const
getAnalysisUsage - This function should be overriden by passes that need analysis information to do t...
Type * getType() const
All values are typed, get the type of this value.
This class represents a no-op cast from one type to another.
bool paramHasAttr(unsigned ArgNo, Attribute::AttrKind Kind) const
Return true if the call or the callee has the given attribute.
void replaceAllUsesWith(Value *V)
Change all uses of this to point to a new Value.
Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree...
amdgpu Simplify well known AMD library false Value * Callee
Value * getOperand(unsigned i) const
bool isVoidTy() const
Return true if this is 'void'.
static bool runOnFunction(Function &F, bool PostInlining)
initializer< Ty > init(const Ty &Val)
Type * getReturnType() const
Returns the type of the ret val.
A set of analyses that are preserved following a run of a transformation pass.
void setDebugLoc(DebugLoc Loc)
Set the debug location information for this instruction.
const BasicBlock * getSinglePredecessor() const
Return the predecessor of this block if it has a single predecessor block.
static void addNonNullAttribute(CallSite CS, Value *Op)
void insertBefore(Instruction *InsertPos)
Insert an unlinked instruction into a basic block immediately before the specified instruction...
LLVM Basic Block Representation.
void deleteBB(BasicBlock *DelBB)
Delete DelBB.
Conditional or Unconditional Branch instruction.
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
This is an important base class in LLVM.
bool isPointerTy() const
True if this is an instance of PointerType.
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
void removeParamAttr(unsigned ArgNo, Attribute::AttrKind Kind)
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM)
Run the pass over the function.
Represent the analysis usage information of a pass.
This instruction compares its operands according to the predicate given to the constructor.
Predicate
This enumeration lists the possible predicates for CmpInst subclasses.
FunctionPass class - This class is used to implement most global optimizations.
size_type count(ConstPtrType Ptr) const
count - Return 1 if the specified pointer is in the set, 0 otherwise.
self_iterator getIterator()
static void setConstantInArgument(CallSite CS, Value *Op, Constant *ConstValue)
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
DomTreeNodeBase< NodeT > * getNode(const NodeT *BB) const
getNode - return the (Post)DominatorTree node for the specified basic block.
static bool doCallSiteSplitting(Function &F, TargetLibraryInfo &TLI, TargetTransformInfo &TTI, DominatorTree &DT)
void deleteEdge(BasicBlock *From, BasicBlock *To)
Notify all available trees on an edge deletion.
INITIALIZE_PASS_END(RegBankSelect, DEBUG_TYPE, "Assign register bank of generic virtual registers", false, false) RegBankSelect
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
std::pair< ICmpInst *, unsigned > ConditionTy
Iterator for intrusive lists based on ilist_node.
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements...
BlockVerifier::State From
static void recordCondition(CallSite CS, BasicBlock *From, BasicBlock *To, ConditionsTy &Conditions)
If From has a conditional jump to To, add the condition to Conditions, if it is relevant to any argum...
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small...
Provides information about what library functions are available for the current target.
static PHINode * Create(Type *Ty, unsigned NumReservedValues, const Twine &NameStr="", Instruction *InsertBefore=nullptr)
Constructors - NumReservedValues is a hint for the number of incoming edges that this phi node will h...
pred_range predecessors(BasicBlock *BB)
void setOperand(unsigned i, Value *Val)
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
static bool isCondRelevantToAnyCallArgument(ICmpInst *Cmp, CallSite CS)
amdgpu Simplify well known AMD library false Value Value * Arg
const DebugLoc & getDebugLoc() const
Return the debug location for this node as a DebugLoc.
reverse_self_iterator getReverseIterator()
LLVM_NODISCARD bool empty() const
StringRef getName() const
Return a constant reference to the value's name.
const Function * getParent() const
Return the enclosing method, or null if none.
static Instruction * cloneInstForMustTail(Instruction *I, Instruction *Before, Value *V)
static bool isPredicatedOnPHI(CallSite CS)
LLVM_NODISCARD std::enable_if<!is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type >::type dyn_cast(const Y &Val)
static SmallVector< BasicBlock *, 2 > getTwoPredecessors(BasicBlock *BB)
void preserve()
Mark an analysis as preserved.
iterator_range< const_phi_iterator > phis() const
Returns a range that iterates over the phis in the basic block.
bool isDeclaration() const
Return true if the primary definition of this global value is outside of the current translation unit...
FunTy * getCalledFunction() const
Return the function being called if this is a direct call, otherwise return null (if it's an indirect...
Analysis pass providing the TargetLibraryInfo.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
bool isEHPad() const
Return true if this basic block is an exception handling block.
bool isInstructionTriviallyDead(Instruction *I, const TargetLibraryInfo *TLI=nullptr)
Return true if the result produced by the instruction is not used, and the instruction has no side ef...
LLVM Value Representation.
static void addConditions(CallSite CS, const ConditionsTy &Conditions)
static const Function * getParent(const Value *V)
BasicBlock * SplitBlock(BasicBlock *Old, Instruction *SplitPt, DominatorTree *DT=nullptr, LoopInfo *LI=nullptr, MemorySSAUpdater *MSSAU=nullptr)
Split the specified block at the specified instruction - everything before SplitPt stays in Old and e...
A container for analyses that lazily runs them and caches their results.
const Instruction * getFirstNonPHIOrDbg() const
Returns a pointer to the first instruction in this block that is not a PHINode or a debug intrinsic...
Legacy analysis pass which computes a DominatorTree.
bool hasDomTree() const
Returns true if it holds a DominatorTree.
bool isMustTailCall() const
Tests if this call site must be tail call optimized.
void addParamAttr(unsigned ArgNo, Attribute::AttrKind Kind)
const BasicBlock * getParent() const
CmpClass_match< LHS, RHS, ICmpInst, ICmpInst::Predicate > m_ICmp(ICmpInst::Predicate &Pred, const LHS &L, const RHS &R)
static PredsWithCondsTy shouldSplitOnPredicatedArgument(CallSite CS, DomTreeUpdater &DTU)
FunctionPass * createCallSiteSplittingPass()