31 ArgIt ArgBegin, ArgIt ArgEnd,
37 std::vector<Type *> ParamTys;
38 for (ArgIt
I = ArgBegin;
I != ArgEnd; ++
I)
39 ParamTys.push_back((*I)->getType());
41 M->getOrInsertFunction(NewFn, FunctionType::get(
RetTy, ParamTys,
false));
54 assert(V->getType()->isIntOrIntVectorTy() &&
"Can't bswap a non-integer type!");
56 unsigned BitSize = V->getType()->getScalarSizeInBits();
63 Value *Tmp1 = Builder.
CreateShl(V, ConstantInt::get(V->getType(), 8),
67 V = Builder.
CreateOr(Tmp1, Tmp2,
"bswap.i16");
71 Value *Tmp4 = Builder.
CreateShl(V, ConstantInt::get(V->getType(), 24),
73 Value *Tmp3 = Builder.
CreateShl(V, ConstantInt::get(V->getType(), 8),
80 ConstantInt::get(V->getType(), 0xFF0000),
83 ConstantInt::get(V->getType(), 0xFF00),
85 Tmp4 = Builder.
CreateOr(Tmp4, Tmp3,
"bswap.or1");
86 Tmp2 = Builder.
CreateOr(Tmp2, Tmp1,
"bswap.or2");
87 V = Builder.
CreateOr(Tmp4, Tmp2,
"bswap.i32");
91 Value *Tmp8 = Builder.
CreateShl(V, ConstantInt::get(V->getType(), 56),
93 Value *Tmp7 = Builder.
CreateShl(V, ConstantInt::get(V->getType(), 40),
95 Value *Tmp6 = Builder.
CreateShl(V, ConstantInt::get(V->getType(), 24),
97 Value *Tmp5 = Builder.
CreateShl(V, ConstantInt::get(V->getType(), 8),
102 ConstantInt::get(V->getType(), 24),
105 ConstantInt::get(V->getType(), 40),
108 ConstantInt::get(V->getType(), 56),
111 ConstantInt::get(V->getType(),
112 0xFF000000000000ULL),
115 ConstantInt::get(V->getType(),
119 ConstantInt::get(V->getType(),
123 ConstantInt::get(V->getType(),
127 ConstantInt::get(V->getType(),
131 ConstantInt::get(V->getType(),
134 Tmp8 = Builder.
CreateOr(Tmp8, Tmp7,
"bswap.or1");
135 Tmp6 = Builder.
CreateOr(Tmp6, Tmp5,
"bswap.or2");
136 Tmp4 = Builder.
CreateOr(Tmp4, Tmp3,
"bswap.or3");
137 Tmp2 = Builder.
CreateOr(Tmp2, Tmp1,
"bswap.or4");
138 Tmp8 = Builder.
CreateOr(Tmp8, Tmp6,
"bswap.or5");
139 Tmp4 = Builder.
CreateOr(Tmp4, Tmp2,
"bswap.or6");
140 V = Builder.
CreateOr(Tmp8, Tmp4,
"bswap.i64");
149 assert(V->getType()->isIntegerTy() &&
"Can't ctpop a non-integer type!");
151 static const uint64_t MaskValues[6] = {
152 0x5555555555555555ULL, 0x3333333333333333ULL,
153 0x0F0F0F0F0F0F0F0FULL, 0x00FF00FF00FF00FFULL,
154 0x0000FFFF0000FFFFULL, 0x00000000FFFFFFFFULL
159 unsigned BitSize = V->getType()->getPrimitiveSizeInBits();
160 unsigned WordSize = (BitSize + 63) / 64;
161 Value *Count = ConstantInt::get(V->getType(), 0);
163 for (
unsigned n = 0; n < WordSize; ++n) {
164 Value *PartValue = V;
165 for (
unsigned i = 1, ct = 0; i < (BitSize>64 ? 64 : BitSize);
167 Value *MaskCst = ConstantInt::get(V->getType(), MaskValues[ct]);
170 ConstantInt::get(V->getType(), i),
175 Count = Builder.
CreateAdd(PartValue, Count,
"ctpop.part");
177 V = Builder.
CreateLShr(V, ConstantInt::get(V->getType(), 64),
191 unsigned BitSize = V->getType()->getPrimitiveSizeInBits();
192 for (
unsigned i = 1; i < BitSize; i <<= 1) {
193 Value *ShVal = ConstantInt::get(V->getType(), i);
194 ShVal = Builder.
CreateLShr(V, ShVal,
"ctlz.sh");
195 V = Builder.
CreateOr(V, ShVal,
"ctlz.step");
204 const char *LDname) {
229 assert(Callee &&
"Cannot lower an indirect call!");
231 switch (Callee->getIntrinsicID()) {
234 Callee->getName() +
"'!");
237 Callee->getName()+
"'!");
239 case Intrinsic::expect: {
246 case Intrinsic::ctpop:
250 case Intrinsic::bswap:
254 case Intrinsic::ctlz:
258 case Intrinsic::cttz: {
262 NotSrc->
setName(Src->getName() +
".not");
263 Value *SrcM1 = ConstantInt::get(Src->getType(), 1);
270 case Intrinsic::stacksave:
271 case Intrinsic::stackrestore: {
273 errs() <<
"WARNING: this target does not support the llvm.stack"
274 << (Callee->getIntrinsicID() == Intrinsic::stacksave ?
275 "save" :
"restore") <<
" intrinsic.\n";
277 if (Callee->getIntrinsicID() == Intrinsic::stacksave)
282 case Intrinsic::get_dynamic_area_offset:
283 errs() <<
"WARNING: this target does not support the custom llvm.get."
284 "dynamic.area.offset. It is being lowered to a constant 0\n";
289 case Intrinsic::returnaddress:
290 case Intrinsic::frameaddress:
291 errs() <<
"WARNING: this target does not support the llvm."
292 << (Callee->getIntrinsicID() == Intrinsic::returnaddress ?
293 "return" :
"frame") <<
"address intrinsic.\n";
297 case Intrinsic::addressofreturnaddress:
298 errs() <<
"WARNING: this target does not support the "
299 "llvm.addressofreturnaddress intrinsic.\n";
304 case Intrinsic::prefetch:
307 case Intrinsic::pcmarker:
309 case Intrinsic::readcyclecounter: {
310 errs() <<
"WARNING: this target does not support the llvm.readcyclecoun"
311 <<
"ter intrinsic. It is being lowered to a constant 0\n";
315 case Intrinsic::readsteadycounter: {
316 errs() <<
"WARNING: this target does not support the llvm.readsteadycounter"
317 <<
" intrinsic. It is being lowered to a constant 0\n";
322 case Intrinsic::dbg_declare:
323 case Intrinsic::dbg_label:
326 case Intrinsic::eh_typeid_for:
331 case Intrinsic::annotation:
332 case Intrinsic::ptr_annotation:
337 case Intrinsic::assume:
338 case Intrinsic::experimental_noalias_scope_decl:
339 case Intrinsic::var_annotation:
342 case Intrinsic::memcpy: {
353 case Intrinsic::memmove: {
364 case Intrinsic::memset: {
379 case Intrinsic::sqrt: {
383 case Intrinsic::log: {
387 case Intrinsic::log2: {
391 case Intrinsic::log10: {
395 case Intrinsic::exp: {
399 case Intrinsic::exp2: {
403 case Intrinsic::pow: {
407 case Intrinsic::sin: {
411 case Intrinsic::cos: {
415 case Intrinsic::floor: {
419 case Intrinsic::ceil: {
423 case Intrinsic::trunc: {
427 case Intrinsic::round: {
431 case Intrinsic::roundeven: {
435 case Intrinsic::copysign: {
439 case Intrinsic::get_rounding:
444 case Intrinsic::invariant_start:
445 case Intrinsic::lifetime_start:
449 case Intrinsic::invariant_end:
450 case Intrinsic::lifetime_end:
456 "Lowering should have eliminated any uses of the intrinsic call!");
This file contains the declarations for the subclasses of Constant, which represent the different fla...
static Value * LowerCTLZ(LLVMContext &Context, Value *V, Instruction *IP)
Emit the code to lower ctlz of V before the specified instruction IP.
static void ReplaceFPIntrinsicWithCall(CallInst *CI, const char *Fname, const char *Dname, const char *LDname)
static CallInst * ReplaceCallWith(const char *NewFn, CallInst *CI, ArgIt ArgBegin, ArgIt ArgEnd, Type *RetTy)
This function is used when we want to lower an intrinsic call to a call of an external function.
static Value * LowerCTPOP(LLVMContext &Context, Value *V, Instruction *IP)
Emit the code to lower ctpop of V before the specified instruction IP.
static Value * LowerBSWAP(LLVMContext &Context, Value *V, Instruction *IP)
Emit the code to lower bswap of V before the specified instruction IP.
Module.h This file contains the declarations for the Module class.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file defines the SmallVector class.
Function * getCalledFunction() const
Returns the function called, or null if this is an indirect function invocation or the function signa...
User::op_iterator arg_begin()
Return the iterator pointing to the beginning of the argument list.
Value * getArgOperand(unsigned i) const
User::op_iterator arg_end()
Return the iterator pointing to the end of the argument list.
unsigned arg_size() const
This class represents a function call, abstracting a target machine's calling convention.
static CallInst * Create(FunctionType *Ty, Value *F, const Twine &NameStr, BasicBlock::iterator InsertBefore)
static ConstantPointerNull * get(PointerType *T)
Static factory methods - Return objects of the specified value.
static Constant * getNullValue(Type *Ty)
Constructor to create a '0' constant of arbitrary type.
This class represents an Operation in the Expression.
IntegerType * getIntPtrType(LLVMContext &C, unsigned AddressSpace=0) const
Returns an integer type with size at least as big as that of a pointer in the given address space.
A handy container for a FunctionType+Callee-pointer pair, which can be passed around as a single enti...
Value * CreateLShr(Value *LHS, Value *RHS, const Twine &Name="", bool isExact=false)
Value * CreateNot(Value *V, const Twine &Name="")
Value * CreateSub(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
Value * CreateShl(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
Value * CreateAnd(Value *LHS, Value *RHS, const Twine &Name="")
Value * CreateAdd(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
Value * CreateOr(Value *LHS, Value *RHS, const Twine &Name="")
Value * CreateIntCast(Value *V, Type *DestTy, bool isSigned, const Twine &Name="")
CallInst * CreateCall(FunctionType *FTy, Value *Callee, ArrayRef< Value * > Args=std::nullopt, const Twine &Name="", MDNode *FPMathTag=nullptr)
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
const Module * getModule() const
Return the module owning the function this instruction belongs to or nullptr it the function does not...
const BasicBlock * getParent() const
InstListType::iterator eraseFromParent()
This method unlinks 'this' from the containing basic block and deletes it.
Class to represent integer types.
void LowerIntrinsicCall(CallInst *CI)
Replace a call to the specified intrinsic function.
static bool LowerToByteSwap(CallInst *CI)
Try to replace a call instruction with a call to a bswap intrinsic.
This is an important class for using LLVM in a threaded context.
A Module instance is used to store all the information related to an LLVM module.
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.
static Type * getDoubleTy(LLVMContext &C)
@ FloatTyID
32-bit floating point type
@ DoubleTyID
64-bit floating point type
@ X86_FP80TyID
80-bit floating point type (X87)
@ PPC_FP128TyID
128-bit floating point type (two 64-bits, PowerPC)
@ FP128TyID
128-bit floating point type (112-bit significand)
static IntegerType * getInt32Ty(LLVMContext &C)
static IntegerType * getInt64Ty(LLVMContext &C)
static Type * getFloatTy(LLVMContext &C)
bool isIntegerTy() const
True if this is an instance of IntegerType.
TypeID getTypeID() const
Return the type id for the type.
bool isVoidTy() const
Return true if this is 'void'.
static UndefValue * get(Type *T)
Static factory methods - Return an 'undef' object of the specified type.
Value * getOperand(unsigned i) const
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.
void replaceAllUsesWith(Value *V)
Change all uses of this to point to a new Value.
LLVMContext & getContext() const
All values hold a context through their type.
StringRef getName() const
Return a constant reference to the value's name.
self_iterator getIterator()
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Function * getDeclaration(Module *M, ID id, ArrayRef< Type * > Tys=std::nullopt)
Create or insert an LLVM Function declaration for an intrinsic, and return it.
This is an optimization pass for GlobalISel generic memory operations.
void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.