24#define DEBUG_TYPE "call-promotion-utils"
54 int Idx = Phi.getBasicBlockIndex(OrigBlock);
57 Phi.setIncomingBlock(
Idx, MergeBlock);
86 int Idx = Phi.getBasicBlockIndex(OrigBlock);
89 auto *V = Phi.getIncomingValue(
Idx);
90 Phi.setIncomingBlock(
Idx, ThenBlock);
91 Phi.addIncoming(V, ElseBlock);
114 Builder.SetInsertPoint(MergeBlock, MergeBlock->
begin());
117 for (
User *U : UsersToUpdate)
118 U->replaceUsesOfWith(OrigInst, Phi);
119 Phi->addIncoming(OrigInst, OrigInst->
getParent());
120 Phi->addIncoming(NewInst, NewInst->
getParent());
172 if (
auto *Invoke = dyn_cast<InvokeInst>(&CB))
174 &
SplitEdge(Invoke->getParent(), Invoke->getNormalDest())->
front();
184 for (
User *U : UsersToUpdate)
185 U->replaceUsesOfWith(&CB, Cast);
302 ThenBlock->
setName(
"if.true.direct_targ");
307 Value *NewRetVal = NewInst;
309 if (
auto *BitCast = dyn_cast_or_null<BitCastInst>(Next)) {
310 assert(BitCast->getOperand(0) == OrigInst &&
311 "bitcast following musttail call must use the call");
312 auto NewBitCast = BitCast->clone();
313 NewBitCast->replaceUsesOfWith(OrigInst, NewInst);
314 NewBitCast->insertBefore(ThenTerm);
315 NewRetVal = NewBitCast;
316 Next = BitCast->getNextNode();
320 ReturnInst *Ret = dyn_cast_or_null<ReturnInst>(Next);
321 assert(Ret &&
"musttail call must precede a ret with an optional bitcast");
322 auto NewRet = Ret->clone();
323 if (Ret->getReturnValue())
324 NewRet->replaceUsesOfWith(Ret->getReturnValue(), NewRetVal);
325 NewRet->insertBefore(ThenTerm);
344 ThenBlock->
setName(
"if.true.direct_targ");
345 ElseBlock->
setName(
"if.false.orig_indirect");
346 MergeBlock->
setName(
"if.end.icp");
355 if (
auto *OrigInvoke = dyn_cast<InvokeInst>(OrigInst)) {
356 auto *NewInvoke = cast<InvokeInst>(NewInst);
364 Builder.SetInsertPoint(MergeBlock);
365 Builder.CreateBr(OrigInvoke->getNormalDest());
373 OrigInvoke->setNormalDest(MergeBlock);
374 NewInvoke->setNormalDest(MergeBlock);
384 const char **FailureReason) {
387 auto &
DL = Callee->getParent()->getDataLayout();
392 Type *FuncRetTy = Callee->getReturnType();
393 if (CallRetTy != FuncRetTy)
396 *FailureReason =
"Return type mismatch";
401 unsigned NumParams = Callee->getFunctionType()->getNumParams();
408 if (NumArgs != NumParams && !Callee->isVarArg()) {
410 *FailureReason =
"The number of arguments mismatch";
418 for (;
I < NumParams; ++
I) {
421 if (Callee->hasParamAttribute(
I, Attribute::ByVal) !=
424 *FailureReason =
"byval mismatch";
427 if (Callee->hasParamAttribute(
I, Attribute::InAlloca) !=
430 *FailureReason =
"inalloca mismatch";
434 Type *FormalTy = Callee->getFunctionType()->getFunctionParamType(
I);
436 if (FormalTy == ActualTy)
440 *FailureReason =
"Argument type mismatch";
451 *FailureReason =
"Musttail call Argument type mismatch";
456 for (;
I < NumArgs;
I++) {
458 assert(Callee->isVarArg());
461 *FailureReason =
"SRet arg to vararg function";
490 Type *CalleeRetTy = Callee->getReturnType();
498 auto CalleeType = Callee->getFunctionType();
499 auto CalleeParamNum = CalleeType->getNumParams();
505 bool AttributeChanged =
false;
507 for (
unsigned ArgNo = 0; ArgNo < CalleeParamNum; ++ArgNo) {
509 Type *FormalTy = CalleeType->getParamType(ArgNo);
510 Type *ActualTy = Arg->getType();
511 if (FormalTy != ActualTy) {
521 ArgAttrs.
addByValAttr(Callee->getParamByValType(ArgNo));
526 AttributeChanged =
true;
535 if (!CallSiteRetTy->
isVoidTy() && CallSiteRetTy != CalleeRetTy) {
538 AttributeChanged =
true;
542 if (AttributeChanged)
568 LoadInst *VTableEntryLoad = dyn_cast<LoadInst>(Callee);
569 if (!VTableEntryLoad)
572 APInt VTableOffset(
DL.getTypeSizeInBits(VTableEntryPtr->
getType()), 0);
574 DL, VTableOffset,
true);
575 LoadInst *VTablePtrLoad = dyn_cast<LoadInst>(VTableBasePtr);
579 APInt ObjectOffset(
DL.getTypeSizeInBits(Object->getType()), 0);
580 Value *ObjectBase = Object->stripAndAccumulateConstantOffsets(
581 DL, ObjectOffset,
true);
582 if (!(isa<AllocaInst>(ObjectBase) && ObjectOffset == 0))
589 VTablePtrLoad, VTablePtrLoad->
getParent(), BBI, 0,
nullptr,
nullptr);
592 APInt VTableOffsetGVBase(
DL.getTypeSizeInBits(VTablePtr->
getType()), 0);
594 DL, VTableOffsetGVBase,
true);
601 APInt VTableGVOffset = VTableOffsetGVBase + VTableOffset;
609 Function *DirectCallee = dyn_cast<Function>(
Ptr->stripPointerCasts());
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
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
const SmallVectorImpl< MachineOperand > & Cond
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
Class for arbitrary precision integers.
uint64_t getZExtValue() const
Get zero extended value.
unsigned getActiveBits() const
Compute the number of active bits in the value.
Type * getByValType() const
Retrieve the byval type.
AttrBuilder & addByValAttr(Type *Ty)
This turns a byval type into the form used internally in Attribute.
Type * getInAllocaType() const
Retrieve the inalloca type.
AttrBuilder & addInAllocaAttr(Type *Ty)
This turns an inalloca type into the form used internally in Attribute.
AttrBuilder & remove(const AttributeMask &AM)
Remove the attributes from the builder.
AttributeSet getFnAttrs() const
The function attributes are returned.
static AttributeList get(LLVMContext &C, ArrayRef< std::pair< unsigned, Attribute > > Attrs)
Create an AttributeList with the specified parameters in it.
AttributeSet getRetAttrs() const
The attributes for the ret value are returned.
bool hasParamAttr(unsigned ArgNo, Attribute::AttrKind Kind) const
Return true if the attribute exists for the given argument.
AttributeSet getParamAttrs(unsigned ArgNo) const
The attributes for the argument or parameter at the given index are returned.
static AttributeSet get(LLVMContext &C, const AttrBuilder &B)
LLVM Basic Block Representation.
iterator begin()
Instruction iterator methods.
iterator_range< const_phi_iterator > phis() const
Returns a range that iterates over the phis in the basic block.
const Instruction & front() const
InstListType::iterator iterator
Instruction iterators...
Base class for all callable instructions (InvokeInst and CallInst) Holds everything related to callin...
Function * getCalledFunction() const
Returns the function called, or null if this is an indirect function invocation or the function signa...
bool paramHasAttr(unsigned ArgNo, Attribute::AttrKind Kind) const
Determine whether the argument or parameter has the given attribute.
bool isMustTailCall() const
Tests if this call site must be tail call optimized.
Value * getCalledOperand() const
void setAttributes(AttributeList A)
Set the parameter attributes for this call.
Value * getArgOperand(unsigned i) const
void mutateFunctionType(FunctionType *FTy)
void setArgOperand(unsigned i, Value *v)
FunctionType * getFunctionType() const
void setCalledOperand(Value *V)
unsigned arg_size() const
AttributeList getAttributes() const
Return the parameter attributes for this call.
Function * getCaller()
Helper to get the caller (the parent function).
This is the base class for all instructions that perform data casts.
static CastInst * CreateBitOrPointerCast(Value *S, Type *Ty, const Twine &Name="", Instruction *InsertBefore=nullptr)
Create a BitCast, a PtrToInt, or an IntToPTr cast instruction.
static bool isBitOrNoopPointerCastable(Type *SrcTy, Type *DestTy, const DataLayout &DL)
Check whether a bitcast, inttoptr, or ptrtoint cast between these types is valid and a no-op.
This is an important base class in LLVM.
A parsed version of the target data layout string in and methods for querying it.
Module * getParent()
Get the module that this global value is contained inside of...
const Constant * getInitializer() const
getInitializer - Return the initializer for this global variable.
bool isConstant() const
If the value is a global constant, its value is immutable throughout the runtime execution of the pro...
bool hasDefinitiveInitializer() const
hasDefinitiveInitializer - Whether the global variable has an initializer, and any other instances of...
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
Instruction * clone() const
Create a copy of 'this' instruction that is identical in all ways except the following:
void insertBefore(Instruction *InsertPos)
Insert an unlinked instruction into a basic block immediately before the specified instruction.
const BasicBlock * getParent() const
void setMetadata(unsigned KindID, MDNode *Node)
Set the metadata of the specified kind to the specified node.
SymbolTableList< Instruction >::iterator eraseFromParent()
This method unlinks 'this' from the containing basic block and deletes it.
void moveBefore(Instruction *MovePos)
Unlink this instruction from its current basic block and insert it into the basic block that MovePos ...
BasicBlock * getUnwindDest() const
BasicBlock * getNormalDest() const
This is an important class for using LLVM in a threaded context.
An instruction for reading from memory.
Value * getPointerOperand()
A Module instance is used to store all the information related to an LLVM module.
Class to represent pointers.
unsigned getAddressSpace() const
Return the address space of the Pointer type.
Return a value (possibly void), from a function.
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
The instances of the Type class are immutable: once they are created, they are never changed.
bool isVoidTy() const
Return true if this is 'void'.
LLVM Value Representation.
Type * getType() const
All values are typed, get the type of this value.
const Value * stripAndAccumulateConstantOffsets(const DataLayout &DL, APInt &Offset, bool AllowNonInbounds, bool AllowInvariantGroup=false, function_ref< bool(Value &Value, APInt &Offset)> ExternalAnalysis=nullptr) const
Accumulate the constant offset this value has compared to a base pointer.
void setName(const Twine &Name)
Change the name of the value.
iterator_range< user_iterator > users()
self_iterator getIterator()
NodeTy * getNextNode()
Get the next node, or nullptr for the list tail.
AttributeMask typeIncompatible(Type *Ty, AttributeSafetyKind ASK=ASK_ALL)
Which attributes cannot be applied to a type.
This is an optimization pass for GlobalISel generic memory operations.
bool isLegalToPromote(const CallBase &CB, Function *Callee, const char **FailureReason=nullptr)
Return true if the given indirect call site can be made to call Callee.
CallBase & promoteCallWithIfThenElse(CallBase &CB, Function *Callee, MDNode *BranchWeights=nullptr)
Promote the given indirect call site to conditionally call Callee.
Value * FindAvailableLoadedValue(LoadInst *Load, BasicBlock *ScanBB, BasicBlock::iterator &ScanFrom, unsigned MaxInstsToScan=DefMaxInstsToScan, AAResults *AA=nullptr, bool *IsLoadCSE=nullptr, unsigned *NumScanedInst=nullptr)
Scan backwards to see if we have the value of the given load available locally within a small number ...
void SplitBlockAndInsertIfThenElse(Value *Cond, BasicBlock::iterator SplitBefore, Instruction **ThenTerm, Instruction **ElseTerm, MDNode *BranchWeights=nullptr, DomTreeUpdater *DTU=nullptr, LoopInfo *LI=nullptr)
SplitBlockAndInsertIfThenElse is similar to SplitBlockAndInsertIfThen, but also creates the ElseBlock...
CallBase & versionCallSite(CallBase &CB, Value *Callee, MDNode *BranchWeights)
Predicate and clone the given call site.
CallBase & promoteCall(CallBase &CB, Function *Callee, CastInst **RetBitCast=nullptr)
Promote the given indirect call site to unconditionally call Callee.
bool tryPromoteCall(CallBase &CB)
Try to promote (devirtualize) a virtual call on an Alloca.
Instruction * SplitBlockAndInsertIfThen(Value *Cond, BasicBlock::iterator SplitBefore, bool Unreachable, MDNode *BranchWeights=nullptr, DomTreeUpdater *DTU=nullptr, LoopInfo *LI=nullptr, BasicBlock *ThenBlock=nullptr)
Split the containing block at the specified instruction - everything before SplitBefore stays in the ...
BasicBlock * SplitEdge(BasicBlock *From, BasicBlock *To, DominatorTree *DT=nullptr, LoopInfo *LI=nullptr, MemorySSAUpdater *MSSAU=nullptr, const Twine &BBName="")
Split the edge connecting the specified blocks, and return the newly created basic block between From...
Constant * getPointerAtOffset(Constant *I, uint64_t Offset, Module &M, Constant *TopLevelGlobal=nullptr)
Processes a Constant recursively looking into elements of arrays, structs and expressions to find a t...