111 lines · cpp
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-exception6//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 18using namespace clang;19using namespace clang::CodeGen;20 21//===----------------------------------------------------------------------===//22// Target codegen info implementation for DirectX.23//===----------------------------------------------------------------------===//24 25namespace {26 27class DirectXTargetCodeGenInfo : public TargetCodeGenInfo {28public:29 DirectXTargetCodeGenInfo(CodeGen::CodeGenTypes &CGT)30 : TargetCodeGenInfo(std::make_unique<DefaultABIInfo>(CGT)) {}31 32 llvm::Type *getHLSLType(CodeGenModule &CGM, const Type *T,33 const CGHLSLOffsetInfo &OffsetInfo) const override;34 35 llvm::Type *getHLSLPadding(CodeGenModule &CGM,36 CharUnits NumBytes) const override {37 unsigned Size = NumBytes.getQuantity();38 return llvm::TargetExtType::get(CGM.getLLVMContext(), "dx.Padding", {},39 {Size});40 }41 42 bool isHLSLPadding(llvm::Type *Ty) const override {43 if (auto *TET = dyn_cast<llvm::TargetExtType>(Ty))44 return TET->getName() == "dx.Padding";45 return false;46 }47};48 49llvm::Type *DirectXTargetCodeGenInfo::getHLSLType(50 CodeGenModule &CGM, const Type *Ty,51 const CGHLSLOffsetInfo &OffsetInfo) const {52 auto *ResType = dyn_cast<HLSLAttributedResourceType>(Ty);53 if (!ResType)54 return nullptr;55 56 llvm::LLVMContext &Ctx = CGM.getLLVMContext();57 const HLSLAttributedResourceType::Attributes &ResAttrs = ResType->getAttrs();58 switch (ResAttrs.ResourceClass) {59 case llvm::dxil::ResourceClass::UAV:60 case llvm::dxil::ResourceClass::SRV: {61 // TypedBuffer and RawBuffer both need element type62 QualType ContainedTy = ResType->getContainedType();63 if (ContainedTy.isNull())64 return nullptr;65 66 // convert element type67 llvm::Type *ElemType = CGM.getTypes().ConvertTypeForMem(ContainedTy);68 69 llvm::StringRef TypeName =70 ResAttrs.RawBuffer ? "dx.RawBuffer" : "dx.TypedBuffer";71 SmallVector<unsigned, 3> Ints = {/*IsWriteable*/ ResAttrs.ResourceClass ==72 llvm::dxil::ResourceClass::UAV,73 /*IsROV*/ ResAttrs.IsROV};74 if (!ResAttrs.RawBuffer) {75 const clang::Type *ElemType = ContainedTy->getUnqualifiedDesugaredType();76 if (ElemType->isVectorType())77 ElemType = cast<clang::VectorType>(ElemType)78 ->getElementType()79 ->getUnqualifiedDesugaredType();80 Ints.push_back(/*IsSigned*/ ElemType->isSignedIntegerType());81 }82 83 return llvm::TargetExtType::get(Ctx, TypeName, {ElemType}, Ints);84 }85 case llvm::dxil::ResourceClass::CBuffer: {86 QualType ContainedTy = ResType->getContainedType();87 if (ContainedTy.isNull() || !ContainedTy->isStructureType())88 return nullptr;89 90 llvm::StructType *BufferLayoutTy =91 HLSLBufferLayoutBuilder(CGM).layOutStruct(92 ContainedTy->getAsCanonical<RecordType>(), OffsetInfo);93 if (!BufferLayoutTy)94 return nullptr;95 96 return llvm::TargetExtType::get(Ctx, "dx.CBuffer", {BufferLayoutTy});97 }98 case llvm::dxil::ResourceClass::Sampler:99 llvm_unreachable("dx.Sampler handles are not implemented yet");100 break;101 }102 llvm_unreachable("Unknown llvm::dxil::ResourceClass enum");103}104 105} // namespace106 107std::unique_ptr<TargetCodeGenInfo>108CodeGen::createDirectXTargetCodeGenInfo(CodeGenModule &CGM) {109 return std::make_unique<DirectXTargetCodeGenInfo>(CGM.getTypes());110}111