diff options
Diffstat (limited to 'clang/lib/CodeGen')
| -rw-r--r-- | clang/lib/CodeGen/CGCall.cpp | 1 | ||||
| -rw-r--r-- | clang/lib/CodeGen/CGHLSLRuntime.cpp | 46 | ||||
| -rw-r--r-- | clang/lib/CodeGen/CGHLSLRuntime.h | 35 | ||||
| -rw-r--r-- | clang/lib/CodeGen/CodeGenModule.cpp | 3 | ||||
| -rw-r--r-- | clang/lib/CodeGen/HLSLBufferLayoutBuilder.cpp | 37 | ||||
| -rw-r--r-- | clang/lib/CodeGen/HLSLBufferLayoutBuilder.h | 10 | ||||
| -rw-r--r-- | clang/lib/CodeGen/TargetInfo.h | 6 | ||||
| -rw-r--r-- | clang/lib/CodeGen/Targets/DirectX.cpp | 9 | ||||
| -rw-r--r-- | clang/lib/CodeGen/Targets/SPIR.cpp | 19 |
9 files changed, 101 insertions, 65 deletions
diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp index d4d5ea8..efacb3c 100644 --- a/clang/lib/CodeGen/CGCall.cpp +++ b/clang/lib/CodeGen/CGCall.cpp @@ -1991,6 +1991,7 @@ static void getTrivialDefaultFunctionAttributes( // This is the default behavior. break; case CodeGenOptions::FramePointerKind::Reserved: + case CodeGenOptions::FramePointerKind::NonLeafNoReserve: case CodeGenOptions::FramePointerKind::NonLeaf: case CodeGenOptions::FramePointerKind::All: FuncAttrs.addAttribute("frame-pointer", diff --git a/clang/lib/CodeGen/CGHLSLRuntime.cpp b/clang/lib/CodeGen/CGHLSLRuntime.cpp index e392a12..4bdba9b 100644 --- a/clang/lib/CodeGen/CGHLSLRuntime.cpp +++ b/clang/lib/CodeGen/CGHLSLRuntime.cpp @@ -261,12 +261,12 @@ static std::optional<llvm::Value *> initializeLocalResourceArray( llvm::Type * CGHLSLRuntime::convertHLSLSpecificType(const Type *T, - SmallVector<int32_t> *Packoffsets) { + const CGHLSLOffsetInfo &OffsetInfo) { assert(T->isHLSLSpecificType() && "Not an HLSL specific type!"); // Check if the target has a specific translation for this type first. if (llvm::Type *TargetTy = - CGM.getTargetCodeGenInfo().getHLSLType(CGM, T, Packoffsets)) + CGM.getTargetCodeGenInfo().getHLSLType(CGM, T, OffsetInfo)) return TargetTy; llvm_unreachable("Generic handling of HLSL types is not supported."); @@ -357,25 +357,14 @@ createBufferHandleType(const HLSLBufferDecl *BufDecl) { return cast<HLSLAttributedResourceType>(QT.getTypePtr()); } -// Iterates over all declarations in the HLSL buffer and based on the -// packoffset or register(c#) annotations it fills outs the Layout -// vector with the user-specified layout offsets. -// The buffer offsets can be specified 2 ways: -// 1. declarations in cbuffer {} block can have a packoffset annotation -// (translates to HLSLPackOffsetAttr) -// 2. default constant buffer declarations at global scope can have -// register(c#) annotations (translates to HLSLResourceBindingAttr with -// RegisterType::C) -// It is not guaranteed that all declarations in a buffer have an annotation. -// For those where it is not specified a -1 value is added to the Layout -// vector. In the final layout these declarations will be placed at the end -// of the HLSL buffer after all of the elements with specified offset. -static void fillPackoffsetLayout(const HLSLBufferDecl *BufDecl, - SmallVector<int32_t> &Layout) { - assert(Layout.empty() && "expected empty vector for layout"); - assert(BufDecl->hasValidPackoffset()); +CGHLSLOffsetInfo CGHLSLOffsetInfo::fromDecl(const HLSLBufferDecl &BufDecl) { + CGHLSLOffsetInfo Result; - for (Decl *D : BufDecl->buffer_decls()) { + // If we don't have packoffset info, just return an empty result. + if (!BufDecl.hasValidPackoffset()) + return Result; + + for (Decl *D : BufDecl.buffer_decls()) { if (isa<CXXRecordDecl, EmptyDecl>(D) || isa<FunctionDecl>(D)) { continue; } @@ -384,11 +373,11 @@ static void fillPackoffsetLayout(const HLSLBufferDecl *BufDecl, continue; if (!VD->hasAttrs()) { - Layout.push_back(-1); + Result.Offsets.push_back(Unspecified); continue; } - int32_t Offset = -1; + uint32_t Offset = Unspecified; for (auto *Attr : VD->getAttrs()) { if (auto *POA = dyn_cast<HLSLPackOffsetAttr>(Attr)) { Offset = POA->getOffsetInBytes(); @@ -401,8 +390,9 @@ static void fillPackoffsetLayout(const HLSLBufferDecl *BufDecl, break; } } - Layout.push_back(Offset); + Result.Offsets.push_back(Offset); } + return Result; } // Codegen for HLSLBufferDecl @@ -419,13 +409,9 @@ void CGHLSLRuntime::addBuffer(const HLSLBufferDecl *BufDecl) { return; // create global variable for the constant buffer - SmallVector<int32_t> Layout; - if (BufDecl->hasValidPackoffset()) - fillPackoffsetLayout(BufDecl, Layout); - - llvm::TargetExtType *TargetTy = - cast<llvm::TargetExtType>(convertHLSLSpecificType( - ResHandleTy, BufDecl->hasValidPackoffset() ? &Layout : nullptr)); + CGHLSLOffsetInfo OffsetInfo = CGHLSLOffsetInfo::fromDecl(*BufDecl); + llvm::TargetExtType *TargetTy = cast<llvm::TargetExtType>( + convertHLSLSpecificType(ResHandleTy, OffsetInfo)); llvm::GlobalVariable *BufGV = new GlobalVariable( TargetTy, /*isConstant*/ false, GlobalValue::LinkageTypes::ExternalLinkage, PoisonValue::get(TargetTy), diff --git a/clang/lib/CodeGen/CGHLSLRuntime.h b/clang/lib/CodeGen/CGHLSLRuntime.h index 9d31714..488a322 100644 --- a/clang/lib/CodeGen/CGHLSLRuntime.h +++ b/clang/lib/CodeGen/CGHLSLRuntime.h @@ -81,6 +81,33 @@ class CodeGenModule; class CodeGenFunction; class LValue; +class CGHLSLOffsetInfo { + SmallVector<uint32_t> Offsets; + +public: + static const uint32_t Unspecified = ~0U; + + /// Iterates over all declarations in the HLSL buffer and based on the + /// packoffset or register(c#) annotations it fills outs the Offsets vector + /// with the user-specified layout offsets. The buffer offsets can be + /// specified 2 ways: 1. declarations in cbuffer {} block can have a + /// packoffset annotation (translates to HLSLPackOffsetAttr) 2. default + /// constant buffer declarations at global scope can have register(c#) + /// annotations (translates to HLSLResourceBindingAttr with RegisterType::C) + /// It is not guaranteed that all declarations in a buffer have an annotation. + /// For those where it is not specified a `~0U` value is added to the Offsets + /// vector. In the final layout these declarations will be placed at the end + /// of the HLSL buffer after all of the elements with specified offset. + static CGHLSLOffsetInfo fromDecl(const HLSLBufferDecl &BufDecl); + + /// Get the given offset, or `~0U` if there is no offset for the member. + uint32_t operator[](size_t I) const { + if (Offsets.empty()) + return Unspecified; + return Offsets[I]; + } +}; + class CGHLSLRuntime { public: //===----------------------------------------------------------------------===// @@ -167,9 +194,11 @@ public: CGHLSLRuntime(CodeGenModule &CGM) : CGM(CGM) {} virtual ~CGHLSLRuntime() {} - llvm::Type * - convertHLSLSpecificType(const Type *T, - SmallVector<int32_t> *Packoffsets = nullptr); + llvm::Type *convertHLSLSpecificType(const Type *T, + const CGHLSLOffsetInfo &OffsetInfo); + llvm::Type *convertHLSLSpecificType(const Type *T) { + return convertHLSLSpecificType(T, CGHLSLOffsetInfo()); + } void generateGlobalCtorDtorCalls(); diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index 98d59b7..f303550 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -1512,6 +1512,9 @@ void CodeGenModule::Release() { case CodeGenOptions::FramePointerKind::Reserved: getModule().setFramePointer(llvm::FramePointerKind::Reserved); break; + case CodeGenOptions::FramePointerKind::NonLeafNoReserve: + getModule().setFramePointer(llvm::FramePointerKind::NonLeafNoReserve); + break; case CodeGenOptions::FramePointerKind::NonLeaf: getModule().setFramePointer(llvm::FramePointerKind::NonLeaf); break; diff --git a/clang/lib/CodeGen/HLSLBufferLayoutBuilder.cpp b/clang/lib/CodeGen/HLSLBufferLayoutBuilder.cpp index 838903c..4bc6d56 100644 --- a/clang/lib/CodeGen/HLSLBufferLayoutBuilder.cpp +++ b/clang/lib/CodeGen/HLSLBufferLayoutBuilder.cpp @@ -66,8 +66,9 @@ namespace CodeGen { // annotation though. For those that don't, the PackOffsets array will contain // -1 value instead. These elements must be placed at the end of the layout // after all of the elements with specific offset. -llvm::TargetExtType *HLSLBufferLayoutBuilder::createLayoutType( - const RecordType *RT, const llvm::SmallVector<int32_t> *PackOffsets) { +llvm::TargetExtType * +HLSLBufferLayoutBuilder::createLayoutType(const RecordType *RT, + const CGHLSLOffsetInfo &OffsetInfo) { // check if we already have the layout type for this struct if (llvm::TargetExtType *Ty = @@ -101,14 +102,10 @@ llvm::TargetExtType *HLSLBufferLayoutBuilder::createLayoutType( const CXXRecordDecl *RD = RecordDecls.pop_back_val(); for (const auto *FD : RD->fields()) { - assert((!PackOffsets || Index < PackOffsets->size()) && - "number of elements in layout struct does not match number of " - "packoffset annotations"); - // No PackOffset info at all, or have a valid packoffset/register(c#) // annotations value -> layout the field. - const int PO = PackOffsets ? (*PackOffsets)[Index++] : -1; - if (!PackOffsets || PO != -1) { + const uint32_t PO = OffsetInfo[Index++]; + if (PO != CGHLSLOffsetInfo::Unspecified) { if (!layoutField(FD, EndOffset, FieldOffset, FieldType, PO)) return nullptr; Layout.push_back(FieldOffset); @@ -175,7 +172,7 @@ bool HLSLBufferLayoutBuilder::layoutField(const FieldDecl *FD, unsigned &EndOffset, unsigned &FieldOffset, llvm::Type *&FieldType, - int Packoffset) { + uint32_t Packoffset) { // Size of element; for arrays this is a size of a single element in the // array. Total array size of calculated as (ArrayCount-1) * ArrayStride + @@ -201,8 +198,9 @@ bool HLSLBufferLayoutBuilder::layoutField(const FieldDecl *FD, // For array of structures, create a new array with a layout type // instead of the structure type. if (Ty->isStructureOrClassType()) { + CGHLSLOffsetInfo EmptyOffsets; llvm::Type *NewTy = cast<llvm::TargetExtType>( - createLayoutType(Ty->getAsCanonical<RecordType>())); + createLayoutType(Ty->getAsCanonical<RecordType>(), EmptyOffsets)); if (!NewTy) return false; assert(isa<llvm::TargetExtType>(NewTy) && "expected target type"); @@ -216,17 +214,20 @@ bool HLSLBufferLayoutBuilder::layoutField(const FieldDecl *FD, ElemLayoutTy = CGM.getTypes().ConvertTypeForMem(FieldTy); } ArrayStride = llvm::alignTo(ElemSize, CBufferRowSizeInBytes); - ElemOffset = (Packoffset != -1) ? Packoffset : NextRowOffset; + ElemOffset = (Packoffset != CGHLSLOffsetInfo::Unspecified) ? Packoffset + : NextRowOffset; } else if (FieldTy->isStructureOrClassType()) { // Create a layout type for the structure + CGHLSLOffsetInfo EmptyOffsets; ElemLayoutTy = createLayoutType( - cast<RecordType>(FieldTy->getAsCanonical<RecordType>())); + cast<RecordType>(FieldTy->getAsCanonical<RecordType>()), EmptyOffsets); if (!ElemLayoutTy) return false; assert(isa<llvm::TargetExtType>(ElemLayoutTy) && "expected target type"); ElemSize = cast<llvm::TargetExtType>(ElemLayoutTy)->getIntParameter(0); - ElemOffset = (Packoffset != -1) ? Packoffset : NextRowOffset; + ElemOffset = (Packoffset != CGHLSLOffsetInfo::Unspecified) ? Packoffset + : NextRowOffset; } else { // scalar or vector - find element size and alignment @@ -246,7 +247,7 @@ bool HLSLBufferLayoutBuilder::layoutField(const FieldDecl *FD, } // calculate or get element offset for the vector or scalar - if (Packoffset != -1) { + if (Packoffset != CGHLSLOffsetInfo::Unspecified) { ElemOffset = Packoffset; } else { ElemOffset = llvm::alignTo(EndOffset, Align); @@ -269,5 +270,13 @@ bool HLSLBufferLayoutBuilder::layoutField(const FieldDecl *FD, return true; } +bool HLSLBufferLayoutBuilder::layoutField(const FieldDecl *FD, + unsigned &EndOffset, + unsigned &FieldOffset, + llvm::Type *&FieldType) { + return layoutField(FD, EndOffset, FieldOffset, FieldType, + CGHLSLOffsetInfo::Unspecified); +} + } // namespace CodeGen } // namespace clang diff --git a/clang/lib/CodeGen/HLSLBufferLayoutBuilder.h b/clang/lib/CodeGen/HLSLBufferLayoutBuilder.h index 61240b2..916e60e 100644 --- a/clang/lib/CodeGen/HLSLBufferLayoutBuilder.h +++ b/clang/lib/CodeGen/HLSLBufferLayoutBuilder.h @@ -14,6 +14,7 @@ class RecordType; class FieldDecl; namespace CodeGen { +class CGHLSLOffsetInfo; class CodeGenModule; //===----------------------------------------------------------------------===// @@ -33,14 +34,15 @@ public: // Returns LLVM target extension type with the name LayoutTypeName // for given structure type and layout data. The first number in // the Layout is the size followed by offsets for each struct element. - llvm::TargetExtType * - createLayoutType(const RecordType *StructType, - const llvm::SmallVector<int32_t> *Packoffsets = nullptr); + llvm::TargetExtType *createLayoutType(const RecordType *StructType, + const CGHLSLOffsetInfo &OffsetInfo); private: bool layoutField(const clang::FieldDecl *FD, unsigned &EndOffset, unsigned &FieldOffset, llvm::Type *&FieldType, - int Packoffset = -1); + uint32_t Packoffset); + bool layoutField(const clang::FieldDecl *FD, unsigned &EndOffset, + unsigned &FieldOffset, llvm::Type *&FieldType); }; } // namespace CodeGen diff --git a/clang/lib/CodeGen/TargetInfo.h b/clang/lib/CodeGen/TargetInfo.h index f63e900..383f52f 100644 --- a/clang/lib/CodeGen/TargetInfo.h +++ b/clang/lib/CodeGen/TargetInfo.h @@ -39,6 +39,7 @@ class ABIInfo; class CallArgList; class CodeGenFunction; class CGBlockInfo; +class CGHLSLOffsetInfo; class SwiftABIInfo; /// TargetCodeGenInfo - This class organizes various target-specific @@ -442,9 +443,8 @@ public: } /// Return an LLVM type that corresponds to a HLSL type - virtual llvm::Type * - getHLSLType(CodeGenModule &CGM, const Type *T, - const SmallVector<int32_t> *Packoffsets = nullptr) const { + virtual llvm::Type *getHLSLType(CodeGenModule &CGM, const Type *T, + const CGHLSLOffsetInfo &OffsetInfo) const { return nullptr; } diff --git a/clang/lib/CodeGen/Targets/DirectX.cpp b/clang/lib/CodeGen/Targets/DirectX.cpp index b4cebb9..f30b302 100644 --- a/clang/lib/CodeGen/Targets/DirectX.cpp +++ b/clang/lib/CodeGen/Targets/DirectX.cpp @@ -29,14 +29,13 @@ public: DirectXTargetCodeGenInfo(CodeGen::CodeGenTypes &CGT) : TargetCodeGenInfo(std::make_unique<DefaultABIInfo>(CGT)) {} - llvm::Type * - getHLSLType(CodeGenModule &CGM, const Type *T, - const SmallVector<int32_t> *Packoffsets = nullptr) const override; + llvm::Type *getHLSLType(CodeGenModule &CGM, const Type *T, + const CGHLSLOffsetInfo &OffsetInfo) const override; }; llvm::Type *DirectXTargetCodeGenInfo::getHLSLType( CodeGenModule &CGM, const Type *Ty, - const SmallVector<int32_t> *Packoffsets) const { + const CGHLSLOffsetInfo &OffsetInfo) const { auto *ResType = dyn_cast<HLSLAttributedResourceType>(Ty); if (!ResType) return nullptr; @@ -78,7 +77,7 @@ llvm::Type *DirectXTargetCodeGenInfo::getHLSLType( llvm::Type *BufferLayoutTy = HLSLBufferLayoutBuilder(CGM, "dx.Layout") .createLayoutType(ContainedTy->castAsCanonical<RecordType>(), - Packoffsets); + OffsetInfo); if (!BufferLayoutTy) return nullptr; diff --git a/clang/lib/CodeGen/Targets/SPIR.cpp b/clang/lib/CodeGen/Targets/SPIR.cpp index abd049a..be7e9cc 100644 --- a/clang/lib/CodeGen/Targets/SPIR.cpp +++ b/clang/lib/CodeGen/Targets/SPIR.cpp @@ -53,9 +53,8 @@ public: unsigned getDeviceKernelCallingConv() const override; llvm::Type *getOpenCLType(CodeGenModule &CGM, const Type *T) const override; - llvm::Type * - getHLSLType(CodeGenModule &CGM, const Type *Ty, - const SmallVector<int32_t> *Packoffsets = nullptr) const override; + llvm::Type *getHLSLType(CodeGenModule &CGM, const Type *Ty, + const CGHLSLOffsetInfo &OffsetInfo) const override; llvm::Type *getSPIRVImageTypeFromHLSLResource( const HLSLAttributedResourceType::Attributes &attributes, QualType SampledType, CodeGenModule &CGM) const; @@ -260,8 +259,16 @@ CommonSPIRTargetCodeGenInfo::getNullPointer(const CodeGen::CodeGenModule &CGM, LangAS AS = QT->getUnqualifiedDesugaredType()->isNullPtrType() ? LangAS::Default : QT->getPointeeType().getAddressSpace(); + unsigned ASAsInt = static_cast<unsigned>(AS); + unsigned FirstTargetASAsInt = + static_cast<unsigned>(LangAS::FirstTargetAddressSpace); + unsigned CodeSectionINTELAS = FirstTargetASAsInt + 9; + // As per SPV_INTEL_function_pointers, it is illegal to addrspacecast + // function pointers to/from the generic AS. + bool IsFunctionPtrAS = + CGM.getTriple().isSPIRV() && ASAsInt == CodeSectionINTELAS; if (AS == LangAS::Default || AS == LangAS::opencl_generic || - AS == LangAS::opencl_constant) + AS == LangAS::opencl_constant || IsFunctionPtrAS) return llvm::ConstantPointerNull::get(PT); auto &Ctx = CGM.getContext(); @@ -510,7 +517,7 @@ static llvm::Type *getInlineSpirvType(CodeGenModule &CGM, llvm::Type *CommonSPIRTargetCodeGenInfo::getHLSLType( CodeGenModule &CGM, const Type *Ty, - const SmallVector<int32_t> *Packoffsets) const { + const CGHLSLOffsetInfo &OffsetInfo) const { llvm::LLVMContext &Ctx = CGM.getLLVMContext(); if (auto *SpirvType = dyn_cast<HLSLInlineSpirvType>(Ty)) @@ -559,7 +566,7 @@ llvm::Type *CommonSPIRTargetCodeGenInfo::getHLSLType( llvm::Type *BufferLayoutTy = HLSLBufferLayoutBuilder(CGM, "spirv.Layout") .createLayoutType(ContainedTy->castAsCanonical<RecordType>(), - Packoffsets); + OffsetInfo); uint32_t StorageClass = /* Uniform storage class */ 2; return llvm::TargetExtType::get(Ctx, "spirv.VulkanBuffer", {BufferLayoutTy}, {StorageClass, false}); |
