================ @@ -54,78 +54,108 @@ void addDxilValVersion(StringRef ValVersionStr, llvm::Module &M) { auto *DXILValMD = M.getOrInsertNamedMetadata(DXILValKey); DXILValMD->addOperand(Val); } + void addDisableOptimizations(llvm::Module &M) { StringRef Key = "dx.disable_optimizations"; M.addModuleFlag(llvm::Module::ModFlagBehavior::Override, Key, 1); } -// cbuffer will be translated into global variable in special address space. -// If translate into C, -// cbuffer A { -// float a; -// float b; -// } -// float foo() { return a + b; } + +// Creates resource handle representing the constant buffer. +// For cbuffer declaration: // -// will be translated into +// cbuffer MyConstants { +// float a; +// } // -// struct A { -// float a; -// float b; -// } cbuffer_A __attribute__((address_space(4))); -// float foo() { return cbuffer_A.a + cbuffer_A.b; } +// creates a structure type MyConstants and then returns the resource handle +// that would be spelled as: // -// layoutBuffer will create the struct A type. -// replaceBuffer will replace use of global variable a and b with cbuffer_A.a -// and cbuffer_A.b. +// __hlsl_resource_t [[hlsl::resource_class(CBuffer)]] +// [[contained_type(MyConstants)]] // -void layoutBuffer(CGHLSLRuntime::Buffer &Buf, const DataLayout &DL) { - if (Buf.Constants.empty()) - return; - - std::vector<llvm::Type *> EltTys; - for (auto &Const : Buf.Constants) { - GlobalVariable *GV = Const.first; - Const.second = EltTys.size(); - llvm::Type *Ty = GV->getValueType(); - EltTys.emplace_back(Ty); +static const clang::Type *getBufferHandleType(CGHLSLRuntime::Buffer &Buf) { + HLSLBufferDecl *BD = Buf.Decl; + ASTContext &AST = BD->getASTContext(); + + // create struct type for the constant buffer; filter out any declarations + // that are not a VarDecls or that are static + CXXRecordDecl *StructDecl = CXXRecordDecl::Create( + BD->getASTContext(), TagDecl::TagKind::Class, BD->getDeclContext(), + BD->getLocation(), BD->getLocation(), BD->getIdentifier()); + StructDecl->startDefinition(); + for (Decl *it : Buf.Decl->decls()) { + const VarDecl *VD = dyn_cast<VarDecl>(it); + if (!VD || VD->getStorageClass() == SC_Static) + continue; + auto *Field = FieldDecl::Create( + AST, StructDecl, VD->getLocation(), VD->getLocation(), + VD->getIdentifier(), VD->getType(), VD->getTypeSourceInfo(), nullptr, + false, InClassInitStyle::ICIS_NoInit); + Field->setAccess(AccessSpecifier::AS_private); + StructDecl->addDecl(Field); } - Buf.LayoutStruct = llvm::StructType::get(EltTys[0]->getContext(), EltTys); + StructDecl->completeDefinition(); + assert(!StructDecl->fields().empty() && "empty cbuffer should not get here"); + + // create the resource handle type + HLSLAttributedResourceType::Attributes ResAttrs(dxil::ResourceClass::CBuffer, + false, false); + QualType ContainedTy = QualType(StructDecl->getTypeForDecl(), 0); + return AST + .getHLSLAttributedResourceType(AST.HLSLResourceTy, ContainedTy, ResAttrs) + .getTypePtr(); } -GlobalVariable *replaceBuffer(CGHLSLRuntime::Buffer &Buf) { - // Create global variable for CB. - GlobalVariable *CBGV = new GlobalVariable( - Buf.LayoutStruct, /*isConstant*/ true, - GlobalValue::LinkageTypes::ExternalLinkage, nullptr, - llvm::formatv("{0}{1}", Buf.Name, Buf.IsCBuffer ? ".cb." : ".tb."), - GlobalValue::NotThreadLocal); - - IRBuilder<> B(CBGV->getContext()); - Value *ZeroIdx = B.getInt32(0); - // Replace Const use with CB use. - for (auto &[GV, Offset] : Buf.Constants) { - Value *GEP = - B.CreateGEP(Buf.LayoutStruct, CBGV, {ZeroIdx, B.getInt32(Offset)}); - - assert(Buf.LayoutStruct->getElementType(Offset) == GV->getValueType() && - "constant type mismatch"); - - // Replace. - GV->replaceAllUsesWith(GEP); - // Erase GV. - GV->removeDeadConstantUsers(); - GV->eraseFromParent(); +// Replaces all uses of the temporary constant buffer global variables with +// buffer access intrinsic resource.getpointer and GEP. +static void replaceBufferGlobals(CodeGenModule &CGM, + CGHLSLRuntime::Buffer &Buf) { + assert(Buf.IsCBuffer && "tbuffer codegen is not yet supported"); + + GlobalVariable *BufGV = Buf.GlobalVar; + llvm::Type *TargetTy = BufGV->getValueType(); + llvm::Type *BufStructTy = cast<TargetExtType>(TargetTy)->getTypeParameter(0); + unsigned Index = 0; + for (auto ConstIt = Buf.Constants.begin(); ConstIt != Buf.Constants.end(); + ++ConstIt, ++Index) { + GlobalVariable *ConstGV = *ConstIt; + + // TODO: Map to an hlsl_device address space. ---------------- llvm-beanz wrote:
```suggestion // TODO: Map to an hlsl_device address space (#109877). ``` https://github.com/llvm/llvm-project/pull/119755 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits