173417c51Spython3kgae //===----- CGHLSLRuntime.h - Interface to HLSL Runtimes -----*- C++ -*-===// 273417c51Spython3kgae // 373417c51Spython3kgae // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 473417c51Spython3kgae // See https://llvm.org/LICENSE.txt for license information. 573417c51Spython3kgae // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 673417c51Spython3kgae // 773417c51Spython3kgae //===----------------------------------------------------------------------===// 873417c51Spython3kgae // 973417c51Spython3kgae // This provides an abstract class for HLSL code generation. Concrete 1073417c51Spython3kgae // subclasses of this implement code generation for specific HLSL 1173417c51Spython3kgae // runtime libraries. 1273417c51Spython3kgae // 1373417c51Spython3kgae //===----------------------------------------------------------------------===// 1473417c51Spython3kgae 1573417c51Spython3kgae #ifndef LLVM_CLANG_LIB_CODEGEN_CGHLSLRUNTIME_H 1673417c51Spython3kgae #define LLVM_CLANG_LIB_CODEGEN_CGHLSLRUNTIME_H 1773417c51Spython3kgae 1822c477f9SChris Bieneman #include "llvm/IR/IRBuilder.h" 191cb64d75SFarzon Lotfi #include "llvm/IR/Intrinsics.h" 201cb64d75SFarzon Lotfi #include "llvm/IR/IntrinsicsDirectX.h" 211cb64d75SFarzon Lotfi #include "llvm/IR/IntrinsicsSPIRV.h" 2222c477f9SChris Bieneman 231cb64d75SFarzon Lotfi #include "clang/Basic/Builtins.h" 245dbb92d8SChris Bieneman #include "clang/Basic/HLSLRuntime.h" 255dbb92d8SChris Bieneman 26ebe9c7f3SXiang Li #include "llvm/ADT/SmallVector.h" 27ebe9c7f3SXiang Li #include "llvm/ADT/StringRef.h" 2813163dd8SXiang Li #include "llvm/Frontend/HLSL/HLSLResource.h" 29ebe9c7f3SXiang Li 30a1580d7bSKazu Hirata #include <optional> 31ebe9c7f3SXiang Li #include <vector> 32ebe9c7f3SXiang Li 331cb64d75SFarzon Lotfi // A function generator macro for picking the right intrinsic 341cb64d75SFarzon Lotfi // for the target backend 351cb64d75SFarzon Lotfi #define GENERATE_HLSL_INTRINSIC_FUNCTION(FunctionName, IntrinsicPostfix) \ 361cb64d75SFarzon Lotfi llvm::Intrinsic::ID get##FunctionName##Intrinsic() { \ 371cb64d75SFarzon Lotfi llvm::Triple::ArchType Arch = getArch(); \ 381cb64d75SFarzon Lotfi switch (Arch) { \ 391cb64d75SFarzon Lotfi case llvm::Triple::dxil: \ 401cb64d75SFarzon Lotfi return llvm::Intrinsic::dx_##IntrinsicPostfix; \ 411cb64d75SFarzon Lotfi case llvm::Triple::spirv: \ 421cb64d75SFarzon Lotfi return llvm::Intrinsic::spv_##IntrinsicPostfix; \ 431cb64d75SFarzon Lotfi default: \ 441cb64d75SFarzon Lotfi llvm_unreachable("Intrinsic " #IntrinsicPostfix \ 451cb64d75SFarzon Lotfi " not supported by target architecture"); \ 461cb64d75SFarzon Lotfi } \ 471cb64d75SFarzon Lotfi } 481cb64d75SFarzon Lotfi 495dbb92d8SChris Bieneman namespace llvm { 505dbb92d8SChris Bieneman class GlobalVariable; 51906e41f4SXiang Li class Function; 52ebe9c7f3SXiang Li class StructType; 535dbb92d8SChris Bieneman } // namespace llvm 54ebe9c7f3SXiang Li 5573417c51Spython3kgae namespace clang { 565dbb92d8SChris Bieneman class VarDecl; 5722c477f9SChris Bieneman class ParmVarDecl; 58ebe9c7f3SXiang Li class HLSLBufferDecl; 5913163dd8SXiang Li class HLSLResourceBindingAttr; 60ebe9c7f3SXiang Li class Type; 61ebe9c7f3SXiang Li class DeclContext; 6273417c51Spython3kgae 63906e41f4SXiang Li class FunctionDecl; 64906e41f4SXiang Li 6573417c51Spython3kgae namespace CodeGen { 6673417c51Spython3kgae 6773417c51Spython3kgae class CodeGenModule; 6873417c51Spython3kgae 6973417c51Spython3kgae class CGHLSLRuntime { 70ebe9c7f3SXiang Li public: 711cb64d75SFarzon Lotfi //===----------------------------------------------------------------------===// 721cb64d75SFarzon Lotfi // Start of reserved area for HLSL intrinsic getters. 731cb64d75SFarzon Lotfi //===----------------------------------------------------------------------===// 741cb64d75SFarzon Lotfi 751cb64d75SFarzon Lotfi GENERATE_HLSL_INTRINSIC_FUNCTION(All, all) 76105dcc88SFarzon Lotfi GENERATE_HLSL_INTRINSIC_FUNCTION(Any, any) 77c098435eSJoshua Batista GENERATE_HLSL_INTRINSIC_FUNCTION(Cross, cross) 7826475050SFinn Plummer GENERATE_HLSL_INTRINSIC_FUNCTION(Degrees, degrees) 79c92d9b06SAndrii Levytskyi GENERATE_HLSL_INTRINSIC_FUNCTION(Frac, frac) 80c4c54af5SFarzon Lotfi GENERATE_HLSL_INTRINSIC_FUNCTION(Lerp, lerp) 811b2d11deSJoshua Batista GENERATE_HLSL_INTRINSIC_FUNCTION(Normalize, normalize) 8235a2b609SHelena Kotas GENERATE_HLSL_INTRINSIC_FUNCTION(Rsqrt, rsqrt) 836a38e19cSS. Bharadwaj Yadavalli GENERATE_HLSL_INTRINSIC_FUNCTION(Saturate, saturate) 84dce50397STim Gymnich GENERATE_HLSL_INTRINSIC_FUNCTION(Sign, sign) 852d47a0baSJoshua Batista GENERATE_HLSL_INTRINSIC_FUNCTION(Step, step) 869df94e27SAdam Yang GENERATE_HLSL_INTRINSIC_FUNCTION(Radians, radians) 871cb64d75SFarzon Lotfi GENERATE_HLSL_INTRINSIC_FUNCTION(ThreadId, thread_id) 88951a284fSZhengxing li GENERATE_HLSL_INTRINSIC_FUNCTION(GroupThreadId, thread_id_in_group) 897a761100SZhengxing li GENERATE_HLSL_INTRINSIC_FUNCTION(GroupId, group_id) 90319c7a42SGreg Roth GENERATE_HLSL_INTRINSIC_FUNCTION(FDot, fdot) 91319c7a42SGreg Roth GENERATE_HLSL_INTRINSIC_FUNCTION(SDot, sdot) 92319c7a42SGreg Roth GENERATE_HLSL_INTRINSIC_FUNCTION(UDot, udot) 933cdac067SFinn Plummer GENERATE_HLSL_INTRINSIC_FUNCTION(Dot4AddI8Packed, dot4add_i8packed) 94bf30b6c3SFinn Plummer GENERATE_HLSL_INTRINSIC_FUNCTION(Dot4AddU8Packed, dot4add_u8packed) 9541a6e9cfSAshley Coleman GENERATE_HLSL_INTRINSIC_FUNCTION(WaveActiveAllTrue, wave_all) 966735c5ebSAshley Coleman GENERATE_HLSL_INTRINSIC_FUNCTION(WaveActiveAnyTrue, wave_any) 97e520b283SFinn Plummer GENERATE_HLSL_INTRINSIC_FUNCTION(WaveActiveCountBits, wave_active_countbits) 98afb6dafcSNathan Gauër GENERATE_HLSL_INTRINSIC_FUNCTION(WaveIsFirstLane, wave_is_first_lane) 996d13cc94SFinn Plummer GENERATE_HLSL_INTRINSIC_FUNCTION(WaveReadLaneAt, wave_readlane) 100fb90733eSSarah Spall GENERATE_HLSL_INTRINSIC_FUNCTION(FirstBitUHigh, firstbituhigh) 101fb90733eSSarah Spall GENERATE_HLSL_INTRINSIC_FUNCTION(FirstBitSHigh, firstbitshigh) 102*4f48abffSAshley Coleman GENERATE_HLSL_INTRINSIC_FUNCTION(FirstBitLow, firstbitlow) 10336d757f8SAdam Yang GENERATE_HLSL_INTRINSIC_FUNCTION(NClamp, nclamp) 10436d757f8SAdam Yang GENERATE_HLSL_INTRINSIC_FUNCTION(SClamp, sclamp) 10536d757f8SAdam Yang GENERATE_HLSL_INTRINSIC_FUNCTION(UClamp, uclamp) 1061cb64d75SFarzon Lotfi 10792e575d7SSteven Perron GENERATE_HLSL_INTRINSIC_FUNCTION(CreateResourceGetPointer, 10892e575d7SSteven Perron resource_getpointer) 109aa07f922SJustin Bogner GENERATE_HLSL_INTRINSIC_FUNCTION(CreateHandleFromBinding, 110aa07f922SJustin Bogner resource_handlefrombinding) 111aa07f922SJustin Bogner GENERATE_HLSL_INTRINSIC_FUNCTION(BufferUpdateCounter, resource_updatecounter) 112dd2b2b8bSAdam Yang GENERATE_HLSL_INTRINSIC_FUNCTION(GroupMemoryBarrierWithGroupSync, 113dd2b2b8bSAdam Yang group_memory_barrier_with_group_sync) 1147dbfa7b9SHelena Kotas 1151cb64d75SFarzon Lotfi //===----------------------------------------------------------------------===// 1161cb64d75SFarzon Lotfi // End of reserved area for HLSL intrinsic getters. 1171cb64d75SFarzon Lotfi //===----------------------------------------------------------------------===// 1181cb64d75SFarzon Lotfi 11913163dd8SXiang Li struct BufferResBinding { 12013163dd8SXiang Li // The ID like 2 in register(b2, space1). 1216ad0788cSKazu Hirata std::optional<unsigned> Reg; 12213163dd8SXiang Li // The Space like 1 is register(b2, space1). 12313163dd8SXiang Li // Default value is 0. 12413163dd8SXiang Li unsigned Space; 12513163dd8SXiang Li BufferResBinding(HLSLResourceBindingAttr *Attr); 12613163dd8SXiang Li }; 127ebe9c7f3SXiang Li struct Buffer { 128ebe9c7f3SXiang Li Buffer(const HLSLBufferDecl *D); 129ebe9c7f3SXiang Li llvm::StringRef Name; 130ebe9c7f3SXiang Li // IsCBuffer - Whether the buffer is a cbuffer (and not a tbuffer). 131ebe9c7f3SXiang Li bool IsCBuffer; 13213163dd8SXiang Li BufferResBinding Binding; 133ebe9c7f3SXiang Li // Global variable and offset for each constant. 134ebe9c7f3SXiang Li std::vector<std::pair<llvm::GlobalVariable *, unsigned>> Constants; 135ebe9c7f3SXiang Li llvm::StructType *LayoutStruct = nullptr; 136ebe9c7f3SXiang Li }; 137ebe9c7f3SXiang Li 13873417c51Spython3kgae protected: 13973417c51Spython3kgae CodeGenModule &CGM; 14073417c51Spython3kgae 14114ae5d2bSXiang Li llvm::Value *emitInputSemantic(llvm::IRBuilder<> &B, const ParmVarDecl &D, 14214ae5d2bSXiang Li llvm::Type *Ty); 14322c477f9SChris Bieneman 14473417c51Spython3kgae public: 14573417c51Spython3kgae CGHLSLRuntime(CodeGenModule &CGM) : CGM(CGM) {} 14673417c51Spython3kgae virtual ~CGHLSLRuntime() {} 14773417c51Spython3kgae 14852956b0fSHelena Kotas llvm::Type *convertHLSLSpecificType(const Type *T); 14952956b0fSHelena Kotas 1505dbb92d8SChris Bieneman void annotateHLSLResource(const VarDecl *D, llvm::GlobalVariable *GV); 151a8a49923SChris Bieneman void generateGlobalCtorDtorCalls(); 1525dbb92d8SChris Bieneman 153ebe9c7f3SXiang Li void addBuffer(const HLSLBufferDecl *D); 15473417c51Spython3kgae void finishCodeGen(); 155906e41f4SXiang Li 15622c477f9SChris Bieneman void setHLSLEntryAttributes(const FunctionDecl *FD, llvm::Function *Fn); 15722c477f9SChris Bieneman 15822c477f9SChris Bieneman void emitEntryFunction(const FunctionDecl *FD, llvm::Function *Fn); 1592c8bd4a7SHelena Kotas void setHLSLFunctionAttributes(const FunctionDecl *FD, llvm::Function *Fn); 1607dbfa7b9SHelena Kotas void handleGlobalVarDefinition(const VarDecl *VD, llvm::GlobalVariable *Var); 1617dbfa7b9SHelena Kotas 16298e3075dSSteven Perron llvm::Instruction *getConvergenceToken(llvm::BasicBlock &BB); 163ebe9c7f3SXiang Li 164ebe9c7f3SXiang Li private: 16513163dd8SXiang Li void addBufferResourceAnnotation(llvm::GlobalVariable *GV, 166a7183a15SXiang Li llvm::hlsl::ResourceClass RC, 1677a13e410SJustin Bogner llvm::hlsl::ResourceKind RK, bool IsROV, 1684f54d715SJustin Bogner llvm::hlsl::ElementType ET, 16913163dd8SXiang Li BufferResBinding &Binding); 170ebe9c7f3SXiang Li void addConstant(VarDecl *D, Buffer &CB); 171ebe9c7f3SXiang Li void addBufferDecls(const DeclContext *DC, Buffer &CB); 1721cb64d75SFarzon Lotfi llvm::Triple::ArchType getArch(); 173ebe9c7f3SXiang Li llvm::SmallVector<Buffer> Buffers; 17473417c51Spython3kgae }; 17573417c51Spython3kgae 17673417c51Spython3kgae } // namespace CodeGen 17773417c51Spython3kgae } // namespace clang 17873417c51Spython3kgae 17973417c51Spython3kgae #endif 180