diff options
Diffstat (limited to 'contrib/llvm-project/llvm/lib/Target/DirectX/DXILOpLowering.cpp')
-rw-r--r-- | contrib/llvm-project/llvm/lib/Target/DirectX/DXILOpLowering.cpp | 167 |
1 files changed, 6 insertions, 161 deletions
diff --git a/contrib/llvm-project/llvm/lib/Target/DirectX/DXILOpLowering.cpp b/contrib/llvm-project/llvm/lib/Target/DirectX/DXILOpLowering.cpp index 11b89e4ec890..20c08f47745d 100644 --- a/contrib/llvm-project/llvm/lib/Target/DirectX/DXILOpLowering.cpp +++ b/contrib/llvm-project/llvm/lib/Target/DirectX/DXILOpLowering.cpp @@ -11,6 +11,7 @@ //===----------------------------------------------------------------------===// #include "DXILConstants.h" +#include "DXILOpBuilder.h" #include "DirectX.h" #include "llvm/ADT/SmallVector.h" #include "llvm/CodeGen/Passes.h" @@ -28,168 +29,12 @@ using namespace llvm; using namespace llvm::DXIL; -constexpr StringLiteral DXILOpNamePrefix = "dx.op."; - -enum OverloadKind : uint16_t { - VOID = 1, - HALF = 1 << 1, - FLOAT = 1 << 2, - DOUBLE = 1 << 3, - I1 = 1 << 4, - I8 = 1 << 5, - I16 = 1 << 6, - I32 = 1 << 7, - I64 = 1 << 8, - UserDefineType = 1 << 9, - ObjectType = 1 << 10, -}; - -static const char *getOverloadTypeName(OverloadKind Kind) { - switch (Kind) { - case OverloadKind::HALF: - return "f16"; - case OverloadKind::FLOAT: - return "f32"; - case OverloadKind::DOUBLE: - return "f64"; - case OverloadKind::I1: - return "i1"; - case OverloadKind::I8: - return "i8"; - case OverloadKind::I16: - return "i16"; - case OverloadKind::I32: - return "i32"; - case OverloadKind::I64: - return "i64"; - case OverloadKind::VOID: - case OverloadKind::ObjectType: - case OverloadKind::UserDefineType: - break; - } - llvm_unreachable("invalid overload type for name"); - return "void"; -} - -static OverloadKind getOverloadKind(Type *Ty) { - Type::TypeID T = Ty->getTypeID(); - switch (T) { - case Type::VoidTyID: - return OverloadKind::VOID; - case Type::HalfTyID: - return OverloadKind::HALF; - case Type::FloatTyID: - return OverloadKind::FLOAT; - case Type::DoubleTyID: - return OverloadKind::DOUBLE; - case Type::IntegerTyID: { - IntegerType *ITy = cast<IntegerType>(Ty); - unsigned Bits = ITy->getBitWidth(); - switch (Bits) { - case 1: - return OverloadKind::I1; - case 8: - return OverloadKind::I8; - case 16: - return OverloadKind::I16; - case 32: - return OverloadKind::I32; - case 64: - return OverloadKind::I64; - default: - llvm_unreachable("invalid overload type"); - return OverloadKind::VOID; - } - } - case Type::PointerTyID: - return OverloadKind::UserDefineType; - case Type::StructTyID: - return OverloadKind::ObjectType; - default: - llvm_unreachable("invalid overload type"); - return OverloadKind::VOID; - } -} - -static std::string getTypeName(OverloadKind Kind, Type *Ty) { - if (Kind < OverloadKind::UserDefineType) { - return getOverloadTypeName(Kind); - } else if (Kind == OverloadKind::UserDefineType) { - StructType *ST = cast<StructType>(Ty); - return ST->getStructName().str(); - } else if (Kind == OverloadKind::ObjectType) { - StructType *ST = cast<StructType>(Ty); - return ST->getStructName().str(); - } else { - std::string Str; - raw_string_ostream OS(Str); - Ty->print(OS); - return OS.str(); - } -} - -// Static properties. -struct OpCodeProperty { - DXIL::OpCode OpCode; - // Offset in DXILOpCodeNameTable. - unsigned OpCodeNameOffset; - DXIL::OpCodeClass OpCodeClass; - // Offset in DXILOpCodeClassNameTable. - unsigned OpCodeClassNameOffset; - uint16_t OverloadTys; - llvm::Attribute::AttrKind FuncAttr; -}; - -// Include getOpCodeClassName getOpCodeProperty and getOpCodeName which -// generated by tableGen. -#define DXIL_OP_OPERATION_TABLE -#include "DXILOperation.inc" -#undef DXIL_OP_OPERATION_TABLE - -static std::string constructOverloadName(OverloadKind Kind, Type *Ty, - const OpCodeProperty &Prop) { - if (Kind == OverloadKind::VOID) { - return (Twine(DXILOpNamePrefix) + getOpCodeClassName(Prop)).str(); - } - return (Twine(DXILOpNamePrefix) + getOpCodeClassName(Prop) + "." + - getTypeName(Kind, Ty)) - .str(); -} - -static FunctionCallee createDXILOpFunction(DXIL::OpCode DXILOp, Function &F, - Module &M) { - const OpCodeProperty *Prop = getOpCodeProperty(DXILOp); - - // Get return type as overload type for DXILOp. - // Only simple mapping case here, so return type is good enough. - Type *OverloadTy = F.getReturnType(); - - OverloadKind Kind = getOverloadKind(OverloadTy); - // FIXME: find the issue and report error in clang instead of check it in - // backend. - if ((Prop->OverloadTys & (uint16_t)Kind) == 0) { - llvm_unreachable("invalid overload"); - } - - std::string FnName = constructOverloadName(Kind, OverloadTy, *Prop); - assert(!M.getFunction(FnName) && "Function already exists"); - - auto &Ctx = M.getContext(); - Type *OpCodeTy = Type::getInt32Ty(Ctx); - - SmallVector<Type *> ArgTypes; - // DXIL has i32 opcode as first arg. - ArgTypes.emplace_back(OpCodeTy); - FunctionType *FT = F.getFunctionType(); - ArgTypes.append(FT->param_begin(), FT->param_end()); - FunctionType *DXILOpFT = FunctionType::get(OverloadTy, ArgTypes, false); - return M.getOrInsertFunction(FnName, DXILOpFT); -} - static void lowerIntrinsic(DXIL::OpCode DXILOp, Function &F, Module &M) { - auto DXILOpFn = createDXILOpFunction(DXILOp, F, M); IRBuilder<> B(M.getContext()); Value *DXILOpArg = B.getInt32(static_cast<unsigned>(DXILOp)); + DXILOpBuilder DXILB(M, B); + Type *OverloadTy = + DXILB.getOverloadTy(DXILOp, F.getFunctionType(), /*NoOpCodeParam*/ true); for (User *U : make_early_inc_range(F.users())) { CallInst *CI = dyn_cast<CallInst>(U); if (!CI) @@ -199,8 +44,8 @@ static void lowerIntrinsic(DXIL::OpCode DXILOp, Function &F, Module &M) { Args.emplace_back(DXILOpArg); Args.append(CI->arg_begin(), CI->arg_end()); B.SetInsertPoint(CI); - CallInst *DXILCI = B.CreateCall(DXILOpFn, Args); - LLVM_DEBUG(DXILCI->setName(getOpCodeName(DXILOp))); + CallInst *DXILCI = DXILB.createDXILOpCall(DXILOp, OverloadTy, CI->args()); + CI->replaceAllUsesWith(DXILCI); CI->eraseFromParent(); } |