1 //===- DirectX.cpp---------------------------------------------------------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #include "ABIInfoImpl.h" 10 #include "CodeGenModule.h" 11 #include "HLSLBufferLayoutBuilder.h" 12 #include "TargetInfo.h" 13 #include "clang/AST/Type.h" 14 #include "llvm/ADT/SmallVector.h" 15 #include "llvm/IR/DerivedTypes.h" 16 #include "llvm/IR/Type.h" 17 18 using namespace clang; 19 using namespace clang::CodeGen; 20 21 //===----------------------------------------------------------------------===// 22 // Target codegen info implementation for DirectX. 23 //===----------------------------------------------------------------------===// 24 25 namespace { 26 27 class DirectXTargetCodeGenInfo : public TargetCodeGenInfo { 28 public: 29 DirectXTargetCodeGenInfo(CodeGen::CodeGenTypes &CGT) 30 : TargetCodeGenInfo(std::make_unique<DefaultABIInfo>(CGT)) {} 31 32 llvm::Type * 33 getHLSLType(CodeGenModule &CGM, const Type *T, 34 const SmallVector<int32_t> *Packoffsets = nullptr) const override; 35 }; 36 37 llvm::Type *DirectXTargetCodeGenInfo::getHLSLType( 38 CodeGenModule &CGM, const Type *Ty, 39 const SmallVector<int32_t> *Packoffsets) const { 40 auto *ResType = dyn_cast<HLSLAttributedResourceType>(Ty); 41 if (!ResType) 42 return nullptr; 43 44 llvm::LLVMContext &Ctx = CGM.getLLVMContext(); 45 const HLSLAttributedResourceType::Attributes &ResAttrs = ResType->getAttrs(); 46 switch (ResAttrs.ResourceClass) { 47 case llvm::dxil::ResourceClass::UAV: 48 case llvm::dxil::ResourceClass::SRV: { 49 // TypedBuffer and RawBuffer both need element type 50 QualType ContainedTy = ResType->getContainedType(); 51 if (ContainedTy.isNull()) 52 return nullptr; 53 54 // convert element type 55 llvm::Type *ElemType = CGM.getTypes().ConvertTypeForMem(ContainedTy); 56 57 llvm::StringRef TypeName = 58 ResAttrs.RawBuffer ? "dx.RawBuffer" : "dx.TypedBuffer"; 59 SmallVector<unsigned, 3> Ints = {/*IsWriteable*/ ResAttrs.ResourceClass == 60 llvm::dxil::ResourceClass::UAV, 61 /*IsROV*/ ResAttrs.IsROV}; 62 if (!ResAttrs.RawBuffer) { 63 const clang::Type *ElemType = ContainedTy->getUnqualifiedDesugaredType(); 64 if (ElemType->isVectorType()) 65 ElemType = cast<clang::VectorType>(ElemType) 66 ->getElementType() 67 ->getUnqualifiedDesugaredType(); 68 Ints.push_back(/*IsSigned*/ ElemType->isSignedIntegerType()); 69 } 70 71 return llvm::TargetExtType::get(Ctx, TypeName, {ElemType}, Ints); 72 } 73 case llvm::dxil::ResourceClass::CBuffer: { 74 QualType ContainedTy = ResType->getContainedType(); 75 if (ContainedTy.isNull() || !ContainedTy->isStructureType()) 76 return nullptr; 77 78 llvm::Type *BufferLayoutTy = 79 HLSLBufferLayoutBuilder(CGM, "dx.Layout") 80 .createLayoutType(ContainedTy->getAsStructureType(), Packoffsets); 81 if (!BufferLayoutTy) 82 return nullptr; 83 84 return llvm::TargetExtType::get(Ctx, "dx.CBuffer", {BufferLayoutTy}); 85 } 86 case llvm::dxil::ResourceClass::Sampler: 87 llvm_unreachable("dx.Sampler handles are not implemented yet"); 88 break; 89 } 90 llvm_unreachable("Unknown llvm::dxil::ResourceClass enum"); 91 } 92 93 } // namespace 94 95 std::unique_ptr<TargetCodeGenInfo> 96 CodeGen::createDirectXTargetCodeGenInfo(CodeGenModule &CGM) { 97 return std::make_unique<DirectXTargetCodeGenInfo>(CGM.getTypes()); 98 } 99