diff options
| author | Dimitry Andric <dim@FreeBSD.org> | 2019-12-20 19:53:05 +0000 | 
|---|---|---|
| committer | Dimitry Andric <dim@FreeBSD.org> | 2019-12-20 19:53:05 +0000 | 
| commit | 0b57cec536236d46e3dba9bd041533462f33dbb7 (patch) | |
| tree | 56229dbdbbf76d18580f72f789003db17246c8d9 /contrib/llvm/lib/CodeGen/IntrinsicLowering.cpp | |
| parent | 718ef55ec7785aae63f98f8ca05dc07ed399c16d (diff) | |
Notes
Diffstat (limited to 'contrib/llvm/lib/CodeGen/IntrinsicLowering.cpp')
| -rw-r--r-- | contrib/llvm/lib/CodeGen/IntrinsicLowering.cpp | 509 | 
1 files changed, 0 insertions, 509 deletions
diff --git a/contrib/llvm/lib/CodeGen/IntrinsicLowering.cpp b/contrib/llvm/lib/CodeGen/IntrinsicLowering.cpp deleted file mode 100644 index 8cbd8bcaeabb..000000000000 --- a/contrib/llvm/lib/CodeGen/IntrinsicLowering.cpp +++ /dev/null @@ -1,509 +0,0 @@ -//===-- IntrinsicLowering.cpp - Intrinsic Lowering default implementation -===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// -// -// This file implements the IntrinsicLowering class. -// -//===----------------------------------------------------------------------===// - -#include "llvm/CodeGen/IntrinsicLowering.h" -#include "llvm/ADT/SmallVector.h" -#include "llvm/IR/CallSite.h" -#include "llvm/IR/Constants.h" -#include "llvm/IR/DataLayout.h" -#include "llvm/IR/DerivedTypes.h" -#include "llvm/IR/IRBuilder.h" -#include "llvm/IR/Module.h" -#include "llvm/IR/Type.h" -#include "llvm/Support/ErrorHandling.h" -#include "llvm/Support/raw_ostream.h" -using namespace llvm; - -/// This function is used when we want to lower an intrinsic call to a call of -/// an external function. This handles hard cases such as when there was already -/// a prototype for the external function, but that prototype doesn't match the -/// arguments we expect to pass in. -template <class ArgIt> -static CallInst *ReplaceCallWith(const char *NewFn, CallInst *CI, -                                 ArgIt ArgBegin, ArgIt ArgEnd, -                                 Type *RetTy) { -  // If we haven't already looked up this function, check to see if the -  // program already contains a function with this name. -  Module *M = CI->getModule(); -  // Get or insert the definition now. -  std::vector<Type *> ParamTys; -  for (ArgIt I = ArgBegin; I != ArgEnd; ++I) -    ParamTys.push_back((*I)->getType()); -  FunctionCallee FCache = -      M->getOrInsertFunction(NewFn, FunctionType::get(RetTy, ParamTys, false)); - -  IRBuilder<> Builder(CI->getParent(), CI->getIterator()); -  SmallVector<Value *, 8> Args(ArgBegin, ArgEnd); -  CallInst *NewCI = Builder.CreateCall(FCache, Args); -  NewCI->setName(CI->getName()); -  if (!CI->use_empty()) -    CI->replaceAllUsesWith(NewCI); -  return NewCI; -} - -// VisualStudio defines setjmp as _setjmp -#if defined(_MSC_VER) && defined(setjmp) && \ -                         !defined(setjmp_undefined_for_msvc) -#  pragma push_macro("setjmp") -#  undef setjmp -#  define setjmp_undefined_for_msvc -#endif - -/// Emit the code to lower bswap of V before the specified instruction IP. -static Value *LowerBSWAP(LLVMContext &Context, Value *V, Instruction *IP) { -  assert(V->getType()->isIntOrIntVectorTy() && "Can't bswap a non-integer type!"); - -  unsigned BitSize = V->getType()->getScalarSizeInBits(); - -  IRBuilder<> Builder(IP); - -  switch(BitSize) { -  default: llvm_unreachable("Unhandled type size of value to byteswap!"); -  case 16: { -    Value *Tmp1 = Builder.CreateShl(V, ConstantInt::get(V->getType(), 8), -                                    "bswap.2"); -    Value *Tmp2 = Builder.CreateLShr(V, ConstantInt::get(V->getType(), 8), -                                     "bswap.1"); -    V = Builder.CreateOr(Tmp1, Tmp2, "bswap.i16"); -    break; -  } -  case 32: { -    Value *Tmp4 = Builder.CreateShl(V, ConstantInt::get(V->getType(), 24), -                                    "bswap.4"); -    Value *Tmp3 = Builder.CreateShl(V, ConstantInt::get(V->getType(), 8), -                                    "bswap.3"); -    Value *Tmp2 = Builder.CreateLShr(V, ConstantInt::get(V->getType(), 8), -                                     "bswap.2"); -    Value *Tmp1 = Builder.CreateLShr(V,ConstantInt::get(V->getType(), 24), -                                     "bswap.1"); -    Tmp3 = Builder.CreateAnd(Tmp3, -                         ConstantInt::get(V->getType(), 0xFF0000), -                             "bswap.and3"); -    Tmp2 = Builder.CreateAnd(Tmp2, -                           ConstantInt::get(V->getType(), 0xFF00), -                             "bswap.and2"); -    Tmp4 = Builder.CreateOr(Tmp4, Tmp3, "bswap.or1"); -    Tmp2 = Builder.CreateOr(Tmp2, Tmp1, "bswap.or2"); -    V = Builder.CreateOr(Tmp4, Tmp2, "bswap.i32"); -    break; -  } -  case 64: { -    Value *Tmp8 = Builder.CreateShl(V, ConstantInt::get(V->getType(), 56), -                                    "bswap.8"); -    Value *Tmp7 = Builder.CreateShl(V, ConstantInt::get(V->getType(), 40), -                                    "bswap.7"); -    Value *Tmp6 = Builder.CreateShl(V, ConstantInt::get(V->getType(), 24), -                                    "bswap.6"); -    Value *Tmp5 = Builder.CreateShl(V, ConstantInt::get(V->getType(), 8), -                                    "bswap.5"); -    Value* Tmp4 = Builder.CreateLShr(V, ConstantInt::get(V->getType(), 8), -                                     "bswap.4"); -    Value* Tmp3 = Builder.CreateLShr(V, -                                     ConstantInt::get(V->getType(), 24), -                                     "bswap.3"); -    Value* Tmp2 = Builder.CreateLShr(V, -                                     ConstantInt::get(V->getType(), 40), -                                     "bswap.2"); -    Value* Tmp1 = Builder.CreateLShr(V, -                                     ConstantInt::get(V->getType(), 56), -                                     "bswap.1"); -    Tmp7 = Builder.CreateAnd(Tmp7, -                             ConstantInt::get(V->getType(), -                                              0xFF000000000000ULL), -                             "bswap.and7"); -    Tmp6 = Builder.CreateAnd(Tmp6, -                             ConstantInt::get(V->getType(), -                                              0xFF0000000000ULL), -                             "bswap.and6"); -    Tmp5 = Builder.CreateAnd(Tmp5, -                        ConstantInt::get(V->getType(), -                             0xFF00000000ULL), -                             "bswap.and5"); -    Tmp4 = Builder.CreateAnd(Tmp4, -                        ConstantInt::get(V->getType(), -                             0xFF000000ULL), -                             "bswap.and4"); -    Tmp3 = Builder.CreateAnd(Tmp3, -                             ConstantInt::get(V->getType(), -                             0xFF0000ULL), -                             "bswap.and3"); -    Tmp2 = Builder.CreateAnd(Tmp2, -                             ConstantInt::get(V->getType(), -                             0xFF00ULL), -                             "bswap.and2"); -    Tmp8 = Builder.CreateOr(Tmp8, Tmp7, "bswap.or1"); -    Tmp6 = Builder.CreateOr(Tmp6, Tmp5, "bswap.or2"); -    Tmp4 = Builder.CreateOr(Tmp4, Tmp3, "bswap.or3"); -    Tmp2 = Builder.CreateOr(Tmp2, Tmp1, "bswap.or4"); -    Tmp8 = Builder.CreateOr(Tmp8, Tmp6, "bswap.or5"); -    Tmp4 = Builder.CreateOr(Tmp4, Tmp2, "bswap.or6"); -    V = Builder.CreateOr(Tmp8, Tmp4, "bswap.i64"); -    break; -  } -  } -  return V; -} - -/// Emit the code to lower ctpop of V before the specified instruction IP. -static Value *LowerCTPOP(LLVMContext &Context, Value *V, Instruction *IP) { -  assert(V->getType()->isIntegerTy() && "Can't ctpop a non-integer type!"); - -  static const uint64_t MaskValues[6] = { -    0x5555555555555555ULL, 0x3333333333333333ULL, -    0x0F0F0F0F0F0F0F0FULL, 0x00FF00FF00FF00FFULL, -    0x0000FFFF0000FFFFULL, 0x00000000FFFFFFFFULL -  }; - -  IRBuilder<> Builder(IP); - -  unsigned BitSize = V->getType()->getPrimitiveSizeInBits(); -  unsigned WordSize = (BitSize + 63) / 64; -  Value *Count = ConstantInt::get(V->getType(), 0); - -  for (unsigned n = 0; n < WordSize; ++n) { -    Value *PartValue = V; -    for (unsigned i = 1, ct = 0; i < (BitSize>64 ? 64 : BitSize); -         i <<= 1, ++ct) { -      Value *MaskCst = ConstantInt::get(V->getType(), MaskValues[ct]); -      Value *LHS = Builder.CreateAnd(PartValue, MaskCst, "cppop.and1"); -      Value *VShift = Builder.CreateLShr(PartValue, -                                        ConstantInt::get(V->getType(), i), -                                         "ctpop.sh"); -      Value *RHS = Builder.CreateAnd(VShift, MaskCst, "cppop.and2"); -      PartValue = Builder.CreateAdd(LHS, RHS, "ctpop.step"); -    } -    Count = Builder.CreateAdd(PartValue, Count, "ctpop.part"); -    if (BitSize > 64) { -      V = Builder.CreateLShr(V, ConstantInt::get(V->getType(), 64), -                             "ctpop.part.sh"); -      BitSize -= 64; -    } -  } - -  return Count; -} - -/// Emit the code to lower ctlz of V before the specified instruction IP. -static Value *LowerCTLZ(LLVMContext &Context, Value *V, Instruction *IP) { - -  IRBuilder<> Builder(IP); - -  unsigned BitSize = V->getType()->getPrimitiveSizeInBits(); -  for (unsigned i = 1; i < BitSize; i <<= 1) { -    Value *ShVal = ConstantInt::get(V->getType(), i); -    ShVal = Builder.CreateLShr(V, ShVal, "ctlz.sh"); -    V = Builder.CreateOr(V, ShVal, "ctlz.step"); -  } - -  V = Builder.CreateNot(V); -  return LowerCTPOP(Context, V, IP); -} - -static void ReplaceFPIntrinsicWithCall(CallInst *CI, const char *Fname, -                                       const char *Dname, -                                       const char *LDname) { -  CallSite CS(CI); -  switch (CI->getArgOperand(0)->getType()->getTypeID()) { -  default: llvm_unreachable("Invalid type in intrinsic"); -  case Type::FloatTyID: -    ReplaceCallWith(Fname, CI, CS.arg_begin(), CS.arg_end(), -                  Type::getFloatTy(CI->getContext())); -    break; -  case Type::DoubleTyID: -    ReplaceCallWith(Dname, CI, CS.arg_begin(), CS.arg_end(), -                  Type::getDoubleTy(CI->getContext())); -    break; -  case Type::X86_FP80TyID: -  case Type::FP128TyID: -  case Type::PPC_FP128TyID: -    ReplaceCallWith(LDname, CI, CS.arg_begin(), CS.arg_end(), -                  CI->getArgOperand(0)->getType()); -    break; -  } -} - -void IntrinsicLowering::LowerIntrinsicCall(CallInst *CI) { -  IRBuilder<> Builder(CI); -  LLVMContext &Context = CI->getContext(); - -  const Function *Callee = CI->getCalledFunction(); -  assert(Callee && "Cannot lower an indirect call!"); - -  CallSite CS(CI); -  switch (Callee->getIntrinsicID()) { -  case Intrinsic::not_intrinsic: -    report_fatal_error("Cannot lower a call to a non-intrinsic function '"+ -                      Callee->getName() + "'!"); -  default: -    report_fatal_error("Code generator does not support intrinsic function '"+ -                      Callee->getName()+"'!"); - -  case Intrinsic::expect: { -    // Just replace __builtin_expect(exp, c) with EXP. -    Value *V = CI->getArgOperand(0); -    CI->replaceAllUsesWith(V); -    break; -  } - -    // The setjmp/longjmp intrinsics should only exist in the code if it was -    // never optimized (ie, right out of the CFE), or if it has been hacked on -    // by the lowerinvoke pass.  In both cases, the right thing to do is to -    // convert the call to an explicit setjmp or longjmp call. -  case Intrinsic::setjmp: { -    Value *V = ReplaceCallWith("setjmp", CI, CS.arg_begin(), CS.arg_end(), -                               Type::getInt32Ty(Context)); -    if (!CI->getType()->isVoidTy()) -      CI->replaceAllUsesWith(V); -    break; -  } -  case Intrinsic::sigsetjmp: -     if (!CI->getType()->isVoidTy()) -       CI->replaceAllUsesWith(Constant::getNullValue(CI->getType())); -     break; - -  case Intrinsic::longjmp: { -    ReplaceCallWith("longjmp", CI, CS.arg_begin(), CS.arg_end(), -                    Type::getVoidTy(Context)); -    break; -  } - -  case Intrinsic::siglongjmp: { -    // Insert the call to abort -    ReplaceCallWith("abort", CI, CS.arg_end(), CS.arg_end(), -                    Type::getVoidTy(Context)); -    break; -  } -  case Intrinsic::ctpop: -    CI->replaceAllUsesWith(LowerCTPOP(Context, CI->getArgOperand(0), CI)); -    break; - -  case Intrinsic::bswap: -    CI->replaceAllUsesWith(LowerBSWAP(Context, CI->getArgOperand(0), CI)); -    break; - -  case Intrinsic::ctlz: -    CI->replaceAllUsesWith(LowerCTLZ(Context, CI->getArgOperand(0), CI)); -    break; - -  case Intrinsic::cttz: { -    // cttz(x) -> ctpop(~X & (X-1)) -    Value *Src = CI->getArgOperand(0); -    Value *NotSrc = Builder.CreateNot(Src); -    NotSrc->setName(Src->getName() + ".not"); -    Value *SrcM1 = ConstantInt::get(Src->getType(), 1); -    SrcM1 = Builder.CreateSub(Src, SrcM1); -    Src = LowerCTPOP(Context, Builder.CreateAnd(NotSrc, SrcM1), CI); -    CI->replaceAllUsesWith(Src); -    break; -  } - -  case Intrinsic::stacksave: -  case Intrinsic::stackrestore: { -    if (!Warned) -      errs() << "WARNING: this target does not support the llvm.stack" -             << (Callee->getIntrinsicID() == Intrinsic::stacksave ? -               "save" : "restore") << " intrinsic.\n"; -    Warned = true; -    if (Callee->getIntrinsicID() == Intrinsic::stacksave) -      CI->replaceAllUsesWith(Constant::getNullValue(CI->getType())); -    break; -  } - -  case Intrinsic::get_dynamic_area_offset: -    errs() << "WARNING: this target does not support the custom llvm.get." -              "dynamic.area.offset.  It is being lowered to a constant 0\n"; -    // Just lower it to a constant 0 because for most targets -    // @llvm.get.dynamic.area.offset is lowered to zero. -    CI->replaceAllUsesWith(ConstantInt::get(CI->getType(), 0)); -    break; -  case Intrinsic::returnaddress: -  case Intrinsic::frameaddress: -    errs() << "WARNING: this target does not support the llvm." -           << (Callee->getIntrinsicID() == Intrinsic::returnaddress ? -             "return" : "frame") << "address intrinsic.\n"; -    CI->replaceAllUsesWith( -        ConstantPointerNull::get(cast<PointerType>(CI->getType()))); -    break; -  case Intrinsic::addressofreturnaddress: -    errs() << "WARNING: this target does not support the " -              "llvm.addressofreturnaddress intrinsic.\n"; -    CI->replaceAllUsesWith( -        ConstantPointerNull::get(cast<PointerType>(CI->getType()))); -    break; - -  case Intrinsic::prefetch: -    break;    // Simply strip out prefetches on unsupported architectures - -  case Intrinsic::pcmarker: -    break;    // Simply strip out pcmarker on unsupported architectures -  case Intrinsic::readcyclecounter: { -    errs() << "WARNING: this target does not support the llvm.readcyclecoun" -           << "ter intrinsic.  It is being lowered to a constant 0\n"; -    CI->replaceAllUsesWith(ConstantInt::get(Type::getInt64Ty(Context), 0)); -    break; -  } - -  case Intrinsic::dbg_declare: -  case Intrinsic::dbg_label: -    break;    // Simply strip out debugging intrinsics - -  case Intrinsic::eh_typeid_for: -    // Return something different to eh_selector. -    CI->replaceAllUsesWith(ConstantInt::get(CI->getType(), 1)); -    break; - -  case Intrinsic::annotation: -  case Intrinsic::ptr_annotation: -    // Just drop the annotation, but forward the value -    CI->replaceAllUsesWith(CI->getOperand(0)); -    break; - -  case Intrinsic::assume: -  case Intrinsic::var_annotation: -    break;   // Strip out these intrinsics - -  case Intrinsic::memcpy: { -    Type *IntPtr = DL.getIntPtrType(Context); -    Value *Size = Builder.CreateIntCast(CI->getArgOperand(2), IntPtr, -                                        /* isSigned */ false); -    Value *Ops[3]; -    Ops[0] = CI->getArgOperand(0); -    Ops[1] = CI->getArgOperand(1); -    Ops[2] = Size; -    ReplaceCallWith("memcpy", CI, Ops, Ops+3, CI->getArgOperand(0)->getType()); -    break; -  } -  case Intrinsic::memmove: { -    Type *IntPtr = DL.getIntPtrType(Context); -    Value *Size = Builder.CreateIntCast(CI->getArgOperand(2), IntPtr, -                                        /* isSigned */ false); -    Value *Ops[3]; -    Ops[0] = CI->getArgOperand(0); -    Ops[1] = CI->getArgOperand(1); -    Ops[2] = Size; -    ReplaceCallWith("memmove", CI, Ops, Ops+3, CI->getArgOperand(0)->getType()); -    break; -  } -  case Intrinsic::memset: { -    Value *Op0 = CI->getArgOperand(0); -    Type *IntPtr = DL.getIntPtrType(Op0->getType()); -    Value *Size = Builder.CreateIntCast(CI->getArgOperand(2), IntPtr, -                                        /* isSigned */ false); -    Value *Ops[3]; -    Ops[0] = Op0; -    // Extend the amount to i32. -    Ops[1] = Builder.CreateIntCast(CI->getArgOperand(1), -                                   Type::getInt32Ty(Context), -                                   /* isSigned */ false); -    Ops[2] = Size; -    ReplaceCallWith("memset", CI, Ops, Ops+3, CI->getArgOperand(0)->getType()); -    break; -  } -  case Intrinsic::sqrt: { -    ReplaceFPIntrinsicWithCall(CI, "sqrtf", "sqrt", "sqrtl"); -    break; -  } -  case Intrinsic::log: { -    ReplaceFPIntrinsicWithCall(CI, "logf", "log", "logl"); -    break; -  } -  case Intrinsic::log2: { -    ReplaceFPIntrinsicWithCall(CI, "log2f", "log2", "log2l"); -    break; -  } -  case Intrinsic::log10: { -    ReplaceFPIntrinsicWithCall(CI, "log10f", "log10", "log10l"); -    break; -  } -  case Intrinsic::exp: { -    ReplaceFPIntrinsicWithCall(CI, "expf", "exp", "expl"); -    break; -  } -  case Intrinsic::exp2: { -    ReplaceFPIntrinsicWithCall(CI, "exp2f", "exp2", "exp2l"); -    break; -  } -  case Intrinsic::pow: { -    ReplaceFPIntrinsicWithCall(CI, "powf", "pow", "powl"); -    break; -  } -  case Intrinsic::sin: { -    ReplaceFPIntrinsicWithCall(CI, "sinf", "sin", "sinl"); -    break; -  } -  case Intrinsic::cos: { -    ReplaceFPIntrinsicWithCall(CI, "cosf", "cos", "cosl"); -    break; -  } -  case Intrinsic::floor: { -    ReplaceFPIntrinsicWithCall(CI, "floorf", "floor", "floorl"); -    break; -  } -  case Intrinsic::ceil: { -    ReplaceFPIntrinsicWithCall(CI, "ceilf", "ceil", "ceill"); -    break; -  } -  case Intrinsic::trunc: { -    ReplaceFPIntrinsicWithCall(CI, "truncf", "trunc", "truncl"); -    break; -  } -  case Intrinsic::round: { -    ReplaceFPIntrinsicWithCall(CI, "roundf", "round", "roundl"); -    break; -  } -  case Intrinsic::copysign: { -    ReplaceFPIntrinsicWithCall(CI, "copysignf", "copysign", "copysignl"); -    break; -  } -  case Intrinsic::flt_rounds: -     // Lower to "round to the nearest" -     if (!CI->getType()->isVoidTy()) -       CI->replaceAllUsesWith(ConstantInt::get(CI->getType(), 1)); -     break; -  case Intrinsic::invariant_start: -  case Intrinsic::lifetime_start: -    // Discard region information. -    CI->replaceAllUsesWith(UndefValue::get(CI->getType())); -    break; -  case Intrinsic::invariant_end: -  case Intrinsic::lifetime_end: -    // Discard region information. -    break; -  } - -  assert(CI->use_empty() && -         "Lowering should have eliminated any uses of the intrinsic call!"); -  CI->eraseFromParent(); -} - -bool IntrinsicLowering::LowerToByteSwap(CallInst *CI) { -  // Verify this is a simple bswap. -  if (CI->getNumArgOperands() != 1 || -      CI->getType() != CI->getArgOperand(0)->getType() || -      !CI->getType()->isIntegerTy()) -    return false; - -  IntegerType *Ty = dyn_cast<IntegerType>(CI->getType()); -  if (!Ty) -    return false; - -  // Okay, we can do this xform, do so now. -  Module *M = CI->getModule(); -  Function *Int = Intrinsic::getDeclaration(M, Intrinsic::bswap, Ty); - -  Value *Op = CI->getArgOperand(0); -  Op = CallInst::Create(Int, Op, CI->getName(), CI); - -  CI->replaceAllUsesWith(Op); -  CI->eraseFromParent(); -  return true; -}  | 
