40 #define DEBUG_TYPE "arm-codegenprepare" 46 cl::desc(
"Disable ARM specific CodeGenPrepare pass"));
50 cl::desc(
"Use DSP instructions for scalar operations"));
54 cl::desc(
"Use DSP instructions for scalar operations\ 55 with immediate operands"));
125 void PrepareConstants(
void);
126 void ExtendSources(
void);
127 void ConvertTruncs(
void);
128 void PromoteTree(
void);
129 void TruncateSinks(
void);
133 IRPromoter(
Module *M) : M(M), Ctx(M->getContext()),
134 ExtTy(
Type::getInt32Ty(Ctx)) { }
137 void Mutate(
Type *OrigTy,
146 IRPromoter *Promoter =
nullptr;
147 std::set<Value*> AllVisited;
151 bool isSupportedValue(
Value *V);
153 bool TryToPromote(
Value *V);
157 static unsigned TypeSize;
158 Type *OrigTy =
nullptr;
166 StringRef getPassName()
const override {
return "ARM IR optimizations"; }
168 bool doInitialization(
Module &M)
override;
170 bool doFinalization(
Module &M)
override;
176 if (!isa<Instruction>(V))
179 unsigned Opc = cast<Instruction>(V)->
getOpcode();
180 return Opc == Instruction::AShr || Opc == Instruction::SDiv ||
181 Opc == Instruction::SRem;
211 if (
auto *Ld = dyn_cast<LoadInst>(V))
212 Ty = cast<PointerType>(Ld->getPointerOperandType())->getElementType();
214 if (!isa<IntegerType>(Ty) ||
229 if (!isa<IntegerType>(V->
getType()))
233 if (isa<Argument>(V))
235 else if (isa<LoadInst>(V))
237 else if (isa<BitCastInst>(V))
239 else if (
auto *Call = dyn_cast<CallInst>(V))
240 return Call->hasRetAttr(Attribute::AttrKind::ZExt);
241 else if (
auto *Trunc = dyn_cast<TruncInst>(V))
260 if (
auto *
Store = dyn_cast<StoreInst>(V))
262 if (
auto *
Return = dyn_cast<ReturnInst>(V))
264 if (
auto *ZExt = dyn_cast<ZExtInst>(V))
266 if (
auto *Switch = dyn_cast<SwitchInst>(V))
268 if (
auto *ICmp = dyn_cast<ICmpInst>(V))
271 return isa<CallInst>(V);
276 bool ARMCodeGenPrepare::isSafeOverflow(
Instruction *
I) {
351 bool IsDecreasing = ((Opc == Instruction::Sub) && !NegImm) ||
358 if (CI->isSigned() || CI->isEquality())
362 if (
auto *Const = dyn_cast<ConstantInt>(CI->getOperand(0)))
364 else if (
auto *Const = dyn_cast<ConstantInt>(CI->getOperand(1)))
384 }
else if (Total.
ugt(Max))
387 LLVM_DEBUG(
dbgs() <<
"ARM CGP: Allowing safe overflow for " << *I <<
"\n");
402 if (isa<ICmpInst>(I))
411 if (!isa<Instruction>(V))
417 return !isa<OverflowingBinaryOperator>(V);
433 case Instruction::Sub:
443 bool ReplacedAll =
true;
445 LLVM_DEBUG(
dbgs() <<
"ARM CGP: Replacing " << *From <<
" with " << *To
449 auto *
User = cast<Instruction>(U.getUser());
450 if (InstTo &&
User->isIdenticalTo(InstTo)) {
457 for (
auto *U : Users)
458 U->replaceUsesOfWith(From, To);
461 if (
auto *I = dyn_cast<Instruction>(From))
462 InstsToRemove.insert(I);
465 void IRPromoter::PrepareConstants() {
486 for (
auto *V : *Visited) {
487 if (!isa<Instruction>(V))
490 auto *I = cast<Instruction>(V);
491 if (SafeToPromote->count(I)) {
493 if (!isa<OverflowingBinaryOperator>(I))
496 if (
auto *Const = dyn_cast<ConstantInt>(I->
getOperand(1))) {
497 if (!Const->isNegative())
506 Builder.SetInsertPoint(I);
507 Value *NewVal = Opc == Instruction::Sub ?
508 Builder.CreateAdd(I->
getOperand(0), NewConst) :
509 Builder.CreateSub(I->
getOperand(0), NewConst);
510 LLVM_DEBUG(
dbgs() <<
"ARM CGP: New equivalent: " << *NewVal <<
"\n");
512 if (
auto *NewInst = dyn_cast<Instruction>(NewVal)) {
513 NewInst->copyIRFlags(I);
514 NewInsts.insert(NewInst);
516 InstsToRemove.insert(I);
521 for (
auto *I : NewInsts)
525 void IRPromoter::ExtendSources() {
529 assert(V->
getType() != ExtTy &&
"zext already extends to i32");
530 LLVM_DEBUG(
dbgs() <<
"ARM CGP: Inserting ZExt for " << *V <<
"\n");
531 Builder.SetInsertPoint(InsertPt);
532 if (
auto *I = dyn_cast<Instruction>(V))
535 Value *ZExt = Builder.CreateZExt(V, ExtTy);
536 if (
auto *I = dyn_cast<Instruction>(ZExt)) {
537 if (isa<Argument>(V))
544 ReplaceAllUsersOfWith(V, ZExt);
549 for (
auto V : *Sources) {
551 if (
auto *I = dyn_cast<Instruction>(V))
553 else if (
auto *
Arg = dyn_cast<Argument>(V)) {
563 void IRPromoter::PromoteTree() {
570 for (
auto *V : *Visited) {
571 if (Sources->count(V))
574 auto *I = cast<Instruction>(V);
583 if (
auto *Const = dyn_cast<ConstantInt>(Op)) {
586 }
else if (isa<UndefValue>(Op))
598 for (
auto *V : *Visited) {
603 if (Sources->count(I) || Sinks->count(I))
606 if (!
shouldPromote(I) || SafeToPromote->count(I) || NewInsts.count(I))
616 Builder.SetInsertPoint(I);
619 CallInst *Call = Builder.CreateCall(DSPInst, Args);
620 NewInsts.insert(Call);
621 ReplaceAllUsersOfWith(I, Call);
625 void IRPromoter::TruncateSinks() {
631 if (!isa<Instruction>(V) || !isa<IntegerType>(V->
getType()))
634 if ((!Promoted.count(V) && !NewInsts.count(V)) || Sources->count(V))
637 LLVM_DEBUG(
dbgs() <<
"ARM CGP: Creating " << *TruncTy <<
" Trunc for " 639 Builder.SetInsertPoint(cast<Instruction>(V));
642 NewInsts.insert(Trunc);
648 for (
auto I : *Sinks) {
652 if (
auto *Call = dyn_cast<CallInst>(I)) {
653 for (
unsigned i = 0; i < Call->getNumArgOperands(); ++i) {
654 Value *
Arg = Call->getArgOperand(i);
655 Type *Ty = TruncTysMap[Call][i];
657 Trunc->moveBefore(Call);
658 Call->setArgOperand(i, Trunc);
665 if (
auto *Switch = dyn_cast<SwitchInst>(I)) {
666 Type *Ty = TruncTysMap[Switch][0];
667 if (
Instruction *Trunc = InsertTrunc(Switch->getCondition(), Ty)) {
668 Trunc->moveBefore(Switch);
669 Switch->setCondition(Trunc);
676 Type *Ty = TruncTysMap[
I][i];
678 Trunc->moveBefore(I);
685 void IRPromoter::Cleanup() {
688 for (
auto V : *Visited) {
689 if (!isa<CastInst>(V))
692 auto ZExt = cast<CastInst>(V);
693 if (ZExt->getDestTy() != ExtTy)
696 Value *Src = ZExt->getOperand(0);
697 if (ZExt->getSrcTy() == ZExt->getDestTy()) {
698 LLVM_DEBUG(
dbgs() <<
"ARM CGP: Removing unnecessary cast: " << *ZExt
700 ReplaceAllUsersOfWith(ZExt, Src);
706 if (NewInsts.count(Src) && isa<ZExtInst>(V) && isa<TruncInst>(Src)) {
707 auto *Trunc = cast<TruncInst>(Src);
708 assert(Trunc->getOperand(0)->getType() == ExtTy &&
709 "expected inserted trunc to be operating on i32");
710 ReplaceAllUsersOfWith(ZExt, Trunc->getOperand(0));
714 for (
auto *I : InstsToRemove) {
720 InstsToRemove.
clear();
726 void IRPromoter::ConvertTruncs() {
729 for (
auto *V : *Visited) {
730 if (!isa<TruncInst>(V) || Sources->count(V))
733 auto *Trunc = cast<TruncInst>(V);
736 Builder.SetInsertPoint(Trunc);
740 Value *Masked = Builder.CreateAnd(Trunc->getOperand(0),
Mask);
742 if (
auto *I = dyn_cast<Instruction>(Masked))
745 ReplaceAllUsersOfWith(Trunc, Masked);
749 void IRPromoter::Mutate(
Type *OrigTy,
755 << ARMCodeGenPrepare::TypeSize <<
" to 32-bits\n");
757 assert(isa<IntegerType>(OrigTy) &&
"expected integer type");
758 this->OrigTy = cast<IntegerType>(OrigTy);
760 "original type not smaller than extended type");
762 this->Visited = &Visited;
763 this->Sources = &Sources;
764 this->Sinks = &Sinks;
765 this->SafeToPromote = &SafeToPromote;
768 for (
auto *I : Sinks) {
769 if (
auto *Call = dyn_cast<CallInst>(I)) {
770 for (
unsigned i = 0; i < Call->getNumArgOperands(); ++i) {
771 Value *
Arg = Call->getArgOperand(i);
772 TruncTysMap[Call].push_back(Arg->
getType());
774 }
else if (
auto *Switch = dyn_cast<SwitchInst>(I))
775 TruncTysMap[I].push_back(Switch->getCondition()->getType());
811 bool ARMCodeGenPrepare::isSupportedValue(
Value *V) {
812 if (
auto *I = dyn_cast<ICmpInst>(V)) {
823 if (isa<StoreInst>(V) || isa<GetElementPtrInst>(V))
827 if( isa<BranchInst>(V) || isa<SwitchInst>(V) || isa<BasicBlock>(V))
831 if ((isa<Constant>(V) && !isa<ConstantExpr>(V)) || isa<Argument>(V))
834 if (isa<PHINode>(V) || isa<SelectInst>(V) || isa<ReturnInst>(V) ||
838 if (isa<SExtInst>(V))
841 if (
auto *Cast = dyn_cast<CastInst>(V))
847 if (
auto *Call = dyn_cast<CallInst>(V))
849 Call->hasRetAttr(Attribute::AttrKind::ZExt);
851 if (!isa<BinaryOperator>(V))
858 LLVM_DEBUG(
dbgs() <<
"ARM CGP: No, instruction can generate sign bits.\n");
873 if (SafeToPromote.
count(I))
889 if (
ST->isThumb() && !
ST->hasThumb2())
898 if (isa<Constant>(
Op)) {
903 LLVM_DEBUG(
dbgs() <<
"ARM CGP: Will use an intrinsic for: " << *I <<
"\n");
907 bool ARMCodeGenPrepare::TryToPromote(
Value *V) {
910 if (TypeSize > 16 || TypeSize < 8)
913 SafeToPromote.
clear();
918 LLVM_DEBUG(
dbgs() <<
"ARM CGP: TryToPromote: " << *V <<
", TypeSize = " 919 << TypeSize <<
"\n");
930 auto AddLegalInst = [&](
Value *V) {
931 if (CurrentVisited.
count(V))
936 if (isa<GetElementPtrInst>(V))
949 while (!WorkList.
empty()) {
952 if (CurrentVisited.
count(V))
956 if (!isa<Instruction>(V) && !
isSource(V))
963 if (AllVisited.count(V))
967 AllVisited.insert(V);
971 Sinks.
insert(cast<Instruction>(V));
977 if (
auto *I = dyn_cast<Instruction>(V)) {
980 if (!AddLegalInst(U))
990 if (!AddLegalInst(U.getUser()))
997 for (
auto *I : CurrentVisited)
1000 unsigned ToPromote = 0;
1001 for (
auto *V : CurrentVisited) {
1002 if (Sources.
count(V))
1004 if (Sinks.
count(cast<Instruction>(V)))
1012 Promoter->Mutate(OrigTy, CurrentVisited, Sources, Sinks, SafeToPromote);
1016 bool ARMCodeGenPrepare::doInitialization(
Module &M) {
1017 Promoter =
new IRPromoter(&M);
1025 auto *TPC = &getAnalysis<TargetPassConfig>();
1031 bool MadeChange =
false;
1036 auto &Insts = BB.getInstList();
1037 for (
auto &I : Insts) {
1038 if (AllVisited.count(&I))
1041 if (isa<ICmpInst>(I)) {
1042 auto &CI = cast<ICmpInst>(
I);
1045 if (CI.isSigned() || !isa<IntegerType>(CI.getOperand(0)->getType()))
1050 for (
auto &
Op : CI.operands()) {
1051 if (
auto *I = dyn_cast<Instruction>(
Op))
1052 MadeChange |= TryToPromote(I);
1067 bool ARMCodeGenPrepare::doFinalization(
Module &M) {
1073 "ARM IR optimizations",
false,
false)
1077 char ARMCodeGenPrepare::
ID = 0;
1078 unsigned ARMCodeGenPrepare::TypeSize = 0;
1081 return new ARMCodeGenPrepare();
APInt abs() const
Get the absolute value;.
static unsigned getBitWidth(Type *Ty, const DataLayout &DL)
Returns the bitwidth of the given scalar or pointer type.
SymbolTableList< Instruction >::iterator eraseFromParent()
This method unlinks 'this' from the containing basic block and deletes it.
static bool generateSignBits(Value *V)
iterator_range< use_iterator > uses()
static bool isSupportedType(Value *V)
Some instructions can use 8- and 16-bit operands, and we don't need to promote anything larger...
static APInt getAllOnesValue(unsigned numBits)
Get the all-ones value.
static Intrinsic::ID getNarrowIntrinsic(Instruction *I)
Return the intrinsic for the instruction that can perform the same operation but on a narrow type...
void dropAllReferences()
Drop all references to operands.
LLVM_ATTRIBUTE_NORETURN void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
This class represents lattice values for constants.
A Module instance is used to store all the information related to an LLVM module. ...
void push_back(const T &Elt)
APInt zext(unsigned width) const
Zero extend to a new width.
This class represents a function call, abstracting a target machine's calling convention.
bool isLegalToPromote(CallSite CS, Function *Callee, const char **FailureReason=nullptr)
Return true if the given indirect call site can be made to call Callee.
setjmp/longjmp based exceptions
iv Induction Variable Users
const T & back() const
Return the last element of the SetVector.
unsigned getBitWidth() const
Return the number of bits in the APInt.
void dump() const
Support for debugging, callable in GDB: V->dump()
AnalysisUsage & addRequired()
INITIALIZE_PASS_BEGIN(ARMCodeGenPrepare, DEBUG_TYPE, "ARM IR optimizations", false, false) INITIALIZE_PASS_END(ARMCodeGenPrepare
A Use represents the edge between a Value definition and its users.
static bool isPromotedResultSafe(Value *V)
Return whether we can safely mutate V's type to ExtTy without having to be concerned with zero extend...
static Optional< unsigned > getOpcode(ArrayRef< VPValue *> Values)
Returns the opcode of Values or ~0 if they do not all agree.
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
This file contains the simple types necessary to represent the attributes associated with functions a...
void pop_back()
Remove the last element of the SetVector.
Target-Independent Code Generator Pass Configuration Options.
static bool shouldPromote(Value *V)
static Constant * getZExt(Constant *C, Type *Ty, bool OnlyIfReduced=false)
static bool isSource(Value *V)
Return true if the given value is a source in the use-def chain, producing a narrow 'TypeSize' value...
Type * getType() const
All values are typed, get the type of this value.
static bool LessOrEqualTypeSize(Value *V)
bool insert(const value_type &X)
Insert a new element into the SetVector.
const APInt & getValue() const
Return the constant as an APInt value reference.
static bool GreaterThanTypeSize(Value *V)
unsigned getOpcode() const
Returns a member of one of the enums like Instruction::Add.
void replaceAllUsesWith(Value *V)
Change all uses of this to point to a new Value.
Function * getDeclaration(Module *M, ID id, ArrayRef< Type *> Tys=None)
Create or insert an LLVM Function declaration for an intrinsic, and return it.
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)
const_iterator getFirstInsertionPt() const
Returns an iterator to the first instruction in this block that is suitable for inserting a non-PHI i...
LLVM Basic Block Representation.
The instances of the Type class are immutable: once they are created, they are never changed...
This is an important class for using LLVM in a threaded context.
This is an important base class in LLVM.
This file contains the declarations for the subclasses of Constant, which represent the different fla...
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.
Represent the analysis usage information of a pass.
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.
static bool EqualTypeSize(Value *V)
Class to represent integer types.
static cl::opt< bool > EnableDSPWithImms("arm-enable-scalar-dsp-imms", cl::Hidden, cl::init(false), cl::desc("Use DSP instructions for scalar operations\ with immediate operands"))
static UndefValue * get(Type *T)
Static factory methods - Return an 'undef' object of the specified type.
INITIALIZE_PASS_END(RegBankSelect, DEBUG_TYPE, "Assign register bank of generic virtual registers", false, false) RegBankSelect
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
unsigned getNumOperands() const
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements...
This is the shared class of boolean and integer constants.
BlockVerifier::State From
unsigned getScalarSizeInBits() const LLVM_READONLY
If this is a vector type, return the getPrimitiveSizeInBits value for the element type...
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small...
static cl::opt< bool > DisableCGP("arm-disable-cgp", cl::Hidden, cl::init(true), cl::desc("Disable ARM specific CodeGenPrepare pass"))
static Constant * get(Type *Ty, uint64_t V, bool isSigned=false)
If Ty is a vector type, return a Constant with a splat of the given value.
void setOperand(unsigned i, Value *Val)
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Class for arbitrary precision integers.
static APInt getMaxValue(unsigned numBits)
Gets maximum unsigned value of APInt for specific bit width.
amdgpu Simplify well known AMD library false Value Value * Arg
bool ugt(const APInt &RHS) const
Unsigned greather than comparison.
const DebugLoc & getDebugLoc() const
Return the debug location for this node as a DebugLoc.
static bool LessThanTypeSize(Value *V)
StringRef getName() const
Return a constant reference to the value's name.
static cl::opt< bool > EnableDSP("arm-enable-scalar-dsp", cl::Hidden, cl::init(false), cl::desc("Use DSP instructions for scalar operations"))
bool empty() const
Determine if the SetVector is empty or not.
bool verifyFunction(const Function &F, raw_ostream *OS=nullptr)
Check a function for errors, useful for use when debugging a pass.
LLVM_NODISCARD std::enable_if<!is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type >::type dyn_cast(const Y &Val)
bool hasNoUnsignedWrap() const
Determine whether the no unsigned wrap flag is set.
void mutateType(Type *Ty)
Mutate the type of this Value to be of the specified type.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
void moveAfter(Instruction *MovePos)
Unlink this instruction from its current basic block and insert it into the basic block that MovePos ...
user_iterator user_begin()
unsigned getPrimitiveSizeInBits() const LLVM_READONLY
Return the basic size of this type if it is a primitive type.
LLVM Value Representation.
FunctionPass * createARMCodeGenPreparePass()
std::underlying_type< E >::type Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
void moveBefore(Instruction *MovePos)
Unlink this instruction from its current basic block and insert it into the basic block that MovePos ...
Primary interface to the complete machine description for the target machine.
bool hasOneUse() const
Return true if there is exactly one user of this value.
StringRef - Represent a constant reference to a string, i.e.
const STC & getSubtarget(const Function &F) const
This method returns a pointer to the specified type of TargetSubtargetInfo.
Statically lint checks LLVM IR
constexpr char Args[]
Key for Kernel::Metadata::mArgs.
static bool isSink(Value *V)
Return true if V will require any promoted values to be truncated for the the IR to remain valid...