beanz updated this revision to Diff 451660. beanz added a comment. This is a fairly significant reworking of this patch to handle entry functions being called (which I hadn't anticipated). There may be some additional tweaks required, but the general flow here is:
(1) Don't prevent mangling of entry functions, this allows us to generate calls based on the mangled function name which makes things happy. (2) Do codegen the function with parameters following the C++ codegen paths with no alterations (3) Also generate a c-exported, unmanged, void(void) function for each entry which populates semantic arguments and calls into the mangled entry function This solution results in code generation that covers the required cases, and the optimizer can (and will) eliminate the wrapper function in all cases that it can, and in any case that it can't the compiler will explode because recurison is not allowed in HLSL unless it can be translated to a loop by the compiler. Fun right? This now depends on D131625 <https://reviews.llvm.org/D131625>, which is a small change to enforce that all entry parameters have semantic annotations. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D131203/new/ https://reviews.llvm.org/D131203 Files: clang/lib/AST/Mangle.cpp clang/lib/CodeGen/CGHLSLRuntime.cpp clang/lib/CodeGen/CGHLSLRuntime.h clang/lib/CodeGen/CodeGenFunction.cpp clang/test/CodeGenHLSL/semantics/GroupIndex-codegen.hlsl
Index: clang/test/CodeGenHLSL/semantics/GroupIndex-codegen.hlsl =================================================================== --- /dev/null +++ clang/test/CodeGenHLSL/semantics/GroupIndex-codegen.hlsl @@ -0,0 +1,18 @@ +// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.0-compute -x hlsl -emit-llvm -disable-llvm-passes -o - -hlsl-entry main %s + +[numthreads(1,1,1)] +void main(unsigned GI : SV_GroupIndex) { + main(GI - 1); +} + +// For HLSL entry functions, we are generating a C-export function that wraps +// the C++-mangled entry function. The wrapper function can be used to populate +// semantic parameters and provides the expected void(void) signature that +// drivers expect for entry points. + +//CHECK: define void @main() { +//CHECK-NEXT: entry: +//CHECK-NEXT: %0 = call i32 @llvm.dx.flattened.thread.id.in.group() +//CHECK-NEXT: call void @"?main@@YAXI@Z"(i32 %0) +//CHECK-NEXT: ret void +//CHECK-NEXT: } Index: clang/lib/CodeGen/CodeGenFunction.cpp =================================================================== --- clang/lib/CodeGen/CodeGenFunction.cpp +++ clang/lib/CodeGen/CodeGenFunction.cpp @@ -16,6 +16,7 @@ #include "CGCXXABI.h" #include "CGCleanup.h" #include "CGDebugInfo.h" +#include "CGHLSLRuntime.h" #include "CGOpenMPRuntime.h" #include "CodeGenModule.h" #include "CodeGenPGO.h" @@ -907,6 +908,9 @@ if (D && D->hasAttr<NoProfileFunctionAttr>()) Fn->addFnAttr(llvm::Attribute::NoProfile); + if (D && D->hasAttr<HLSLShaderAttr>()) + CGM.getHLSLRuntime().emitEntryFunction(FD, Fn); + if (D) { // Function attributes take precedence over command line flags. if (auto *A = D->getAttr<FunctionReturnThunksAttr>()) { Index: clang/lib/CodeGen/CGHLSLRuntime.h =================================================================== --- clang/lib/CodeGen/CGHLSLRuntime.h +++ clang/lib/CodeGen/CGHLSLRuntime.h @@ -15,6 +15,8 @@ #ifndef LLVM_CLANG_LIB_CODEGEN_CGHLSLRUNTIME_H #define LLVM_CLANG_LIB_CODEGEN_CGHLSLRUNTIME_H +#include "llvm/IR/IRBuilder.h" + #include "clang/Basic/HLSLRuntime.h" namespace llvm { @@ -26,6 +28,7 @@ class CallExpr; class Type; class VarDecl; +class ParmVarDecl; class FunctionDecl; @@ -39,6 +42,8 @@ uint32_t ResourceCounters[static_cast<uint32_t>( hlsl::ResourceClass::NumClasses)] = {0}; + llvm::Value *emitInputSemantic(llvm::IRBuilder<> &B, const ParmVarDecl &D); + public: CGHLSLRuntime(CodeGenModule &CGM) : CGM(CGM) {} virtual ~CGHLSLRuntime() {} @@ -48,6 +53,8 @@ void finishCodeGen(); void setHLSLFunctionAttributes(llvm::Function *, const FunctionDecl *); + + void emitEntryFunction(const FunctionDecl *FD, llvm::Function *Fn); }; } // namespace CodeGen Index: clang/lib/CodeGen/CGHLSLRuntime.cpp =================================================================== --- clang/lib/CodeGen/CGHLSLRuntime.cpp +++ clang/lib/CodeGen/CGHLSLRuntime.cpp @@ -14,7 +14,9 @@ #include "CGHLSLRuntime.h" #include "CodeGenModule.h" +#include "clang/AST/Decl.h" #include "clang/Basic/TargetOptions.h" +#include "llvm/IR/IntrinsicsDirectX.h" #include "llvm/IR/Metadata.h" #include "llvm/IR/Module.h" @@ -95,3 +97,36 @@ ShaderAttr->ConvertShaderTypeToStr(ShaderAttr->getType())); } } + +llvm::Value *CGHLSLRuntime::emitInputSemantic(IRBuilder<> &B, + const ParmVarDecl &D) { + assert(D.hasAttrs() && "Entry parameter missing annotation attribute!"); + if (D.hasAttr<HLSLSV_GroupIndexAttr>()) { + llvm::Function *DxGroupIndex = + CGM.getIntrinsic(Intrinsic::dx_flattened_thread_id_in_group); + CallInst *CI = B.CreateCall(FunctionCallee(DxGroupIndex)); + return CI; + } + assert(false && "Unhandled parameter attribute"); + return nullptr; +} + +void CGHLSLRuntime::emitEntryFunction(const FunctionDecl *FD, + llvm::Function *Fn) { + llvm::Module &M = CGM.getModule(); + llvm::LLVMContext &Ctx = M.getContext(); + auto *EntryTy = llvm::FunctionType::get(llvm::Type::getVoidTy(Ctx), false); + Function *EntryFn = + Function::Create(EntryTy, Function::ExternalLinkage, FD->getName(), &M); + BasicBlock *BB = BasicBlock::Create(Ctx, "entry", EntryFn); + IRBuilder<> B(BB); + llvm::SmallVector<Value *> Args; + for (const auto Param : FD->parameters()) { + Args.push_back(emitInputSemantic(B, *Param)); + } + + CallInst *CI = B.CreateCall(FunctionCallee(Fn), Args); + (void)CI; + // FIXME: Handle codegen for return type semantics + B.CreateRetVoid(); +} Index: clang/lib/AST/Mangle.cpp =================================================================== --- clang/lib/AST/Mangle.cpp +++ clang/lib/AST/Mangle.cpp @@ -133,10 +133,6 @@ if (isa<MSGuidDecl>(D)) return true; - // HLSL shader entry function never need to be mangled. - if (getASTContext().getLangOpts().HLSL && D->hasAttr<HLSLShaderAttr>()) - return false; - return shouldMangleCXXName(D); }
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits