https://github.com/heiher updated https://github.com/llvm/llvm-project/pull/72078
>From e3863873ab817dacf8680763bb42d91f005fe5ea Mon Sep 17 00:00:00 2001 From: WANG Rui <wang...@loongson.cn> Date: Fri, 10 Nov 2023 21:07:48 -0600 Subject: [PATCH] [clang] Add per-global code model attribute This patch adds a per-global code model attribute, which can override the target's code model to access global variables. Currently, the code model attribute is only supported on LoongArch. This patch also maps GCC's code model names to LLVM's, which allows for better compatibility between the two compilers. Suggested-by: Arthur Eubanks <aeuba...@google.com> Signed-off-by: WANG Rui <wang...@loongson.cn> Link: https://discourse.llvm.org/t/how-to-best-implement-code-model-overriding-for-certain-values/71816 Link: https://discourse.llvm.org/t/rfc-add-per-global-code-model-attribute/74944 --- clang/include/clang/Basic/Attr.td | 8 +++++ clang/include/clang/Basic/AttrDocs.td | 9 ++++++ .../clang/Basic/DiagnosticSemaKinds.td | 2 ++ clang/lib/CodeGen/CodeGenModule.cpp | 13 ++++++++ clang/lib/Sema/SemaDeclAttr.cpp | 30 +++++++++++++++++++ clang/test/CodeGen/LoongArch/attributes.c | 10 +++++++ ...a-attribute-supported-attributes-list.test | 1 + clang/test/Sema/loongarch-attr-model.c | 13 ++++++++ 8 files changed, 86 insertions(+) create mode 100644 clang/test/CodeGen/LoongArch/attributes.c create mode 100644 clang/test/Sema/loongarch-attr-model.c diff --git a/clang/include/clang/Basic/Attr.td b/clang/include/clang/Basic/Attr.td index 1800f584c7e10..d5b5717f3d77c 100644 --- a/clang/include/clang/Basic/Attr.td +++ b/clang/include/clang/Basic/Attr.td @@ -2718,6 +2718,14 @@ def PragmaClangTextSection : InheritableAttr { let Documentation = [InternalOnly]; } +def CodeModel : InheritableAttr { + let Spellings = [GCC<"model">]; + let Args = [StringArgument<"Model">]; + let Subjects = + SubjectList<[ GlobalVar ], ErrorDiag>; + let Documentation = [CodeModelDocs]; +} + def Sentinel : InheritableAttr { let Spellings = [GCC<"sentinel">]; let Args = [DefaultIntArgument<"Sentinel", 0>, diff --git a/clang/include/clang/Basic/AttrDocs.td b/clang/include/clang/Basic/AttrDocs.td index b45ec6bbb8d37..1d37c2da6bec0 100644 --- a/clang/include/clang/Basic/AttrDocs.td +++ b/clang/include/clang/Basic/AttrDocs.td @@ -57,6 +57,15 @@ global variable or function should be in after translation. let Heading = "section, __declspec(allocate)"; } +def CodeModelDocs : Documentation { + let Category = DocCatVariable; + let Content = [{ +The ``model`` attribute allows you to specify a specific code model a +global variable should be in after translation. + }]; + let Heading = "model"; +} + def UsedDocs : Documentation { let Category = DocCatFunction; let Content = [{ diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 6dfb2d7195203..d438fdde9ac7e 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -3408,6 +3408,8 @@ def warn_objc_redundant_literal_use : Warning< def err_attr_tlsmodel_arg : Error<"tls_model must be \"global-dynamic\", " "\"local-dynamic\", \"initial-exec\" or \"local-exec\"">; +def err_attr_codemodel_arg : Error<"code_model '%0' is not yet supported on this target">; + def err_aix_attr_unsupported_tls_model : Error<"TLS model '%0' is not yet supported on AIX">; def err_tls_var_aligned_over_maximum : Error< diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index dea58a7ff4146..1f49721e79ddc 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -4841,6 +4841,19 @@ CodeGenModule::GetOrCreateLLVMGlobal(StringRef MangledName, llvm::Type *Ty, isExternallyVisible(D->getLinkageAndVisibility().getLinkage())) GV->setSection(".cp.rodata"); + // Handle code model attribute + if (D->hasAttr<CodeModelAttr>()) { + if (const CodeModelAttr *CMA = D->getAttr<CodeModelAttr>()) { + auto CM = llvm::StringSwitch<llvm::CodeModel::Model>(CMA->getModel()) + .Case("tiny", llvm::CodeModel::Tiny) + .Case("kernel", llvm::CodeModel::Kernel) + .Case("medium", llvm::CodeModel::Medium) + .Case("large", llvm::CodeModel::Large) + .Default(llvm::CodeModel::Small); + GV->setCodeModel(CM); + } + } + // Check if we a have a const declaration with an initializer, we may be // able to emit it as available_externally to expose it's value to the // optimizer. diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp index 87c78d742d0ff..64aa242dbb04f 100644 --- a/clang/lib/Sema/SemaDeclAttr.cpp +++ b/clang/lib/Sema/SemaDeclAttr.cpp @@ -3369,6 +3369,33 @@ static void handleSectionAttr(Sema &S, Decl *D, const ParsedAttr &AL) { } } +static void handleCodeModelAttr(Sema &S, Decl *D, const ParsedAttr &AL) { + StringRef CM; + StringRef Str; + SourceLocation LiteralLoc; + bool Ok = false; + // Check that it is a string. + if (!S.checkStringLiteralArgumentAttr(AL, 0, Str, &LiteralLoc)) + return; + + CM = Str; + if (S.getASTContext().getTargetInfo().getTriple().isLoongArch()) { + Ok = CM == "normal" || CM == "medium" || CM == "extreme"; + CM = llvm::StringSwitch<StringRef>(CM) + .Case("normal", "small") + .Case("extreme", "large") + .Default(CM); + } + + // Check that the value. + if (!Ok) { + S.Diag(LiteralLoc, diag::err_attr_codemodel_arg) << Str; + return; + } + + D->addAttr(::new (S.Context) CodeModelAttr(S.Context, AL, CM)); +} + // This is used for `__declspec(code_seg("segname"))` on a decl. // `#pragma code_seg("segname")` uses checkSectionName() instead. static bool checkCodeSegName(Sema &S, SourceLocation LiteralLoc, @@ -9309,6 +9336,9 @@ ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D, const ParsedAttr &AL, case ParsedAttr::AT_Section: handleSectionAttr(S, D, AL); break; + case ParsedAttr::AT_CodeModel: + handleCodeModelAttr(S, D, AL); + break; case ParsedAttr::AT_RandomizeLayout: handleRandomizeLayoutAttr(S, D, AL); break; diff --git a/clang/test/CodeGen/LoongArch/attributes.c b/clang/test/CodeGen/LoongArch/attributes.c new file mode 100644 index 0000000000000..a6d086845e29b --- /dev/null +++ b/clang/test/CodeGen/LoongArch/attributes.c @@ -0,0 +1,10 @@ +// RUN: %clang_cc1 -emit-llvm -triple loongarch64 %s -o - | FileCheck %s + +// CHECK: @normal ={{.*}} global i32 0, code_model "small" +int normal __attribute__((model("normal"))); + +// CHECK: @medium ={{.*}} global i32 0, code_model "medium" +int medium __attribute__((model("medium"))); + +// CHECK: @extreme ={{.*}} global i32 0, code_model "large" +int extreme __attribute__((model("extreme"))); diff --git a/clang/test/Misc/pragma-attribute-supported-attributes-list.test b/clang/test/Misc/pragma-attribute-supported-attributes-list.test index dd91f4f88ad68..2b191abdac8b5 100644 --- a/clang/test/Misc/pragma-attribute-supported-attributes-list.test +++ b/clang/test/Misc/pragma-attribute-supported-attributes-list.test @@ -48,6 +48,7 @@ // CHECK-NEXT: CarriesDependency (SubjectMatchRule_variable_is_parameter, SubjectMatchRule_objc_method, SubjectMatchRule_function) // CHECK-NEXT: Cleanup (SubjectMatchRule_variable_is_local) // CHECK-NEXT: CmseNSEntry (SubjectMatchRule_function) +// CHECK-NEXT: CodeModel (SubjectMatchRule_variable_is_global) // CHECK-NEXT: Cold (SubjectMatchRule_function) // CHECK-NEXT: Common (SubjectMatchRule_variable) // CHECK-NEXT: ConstInit (SubjectMatchRule_variable_is_global) diff --git a/clang/test/Sema/loongarch-attr-model.c b/clang/test/Sema/loongarch-attr-model.c new file mode 100644 index 0000000000000..3f32f9fba8768 --- /dev/null +++ b/clang/test/Sema/loongarch-attr-model.c @@ -0,0 +1,13 @@ +// RUN: %clang_cc1 -triple loongarch64 -verify -fsyntax-only %s + +#if !__has_attribute(model) +#error "Should support model attribute" +#endif + +int a __attribute((model("tiny"))); // expected-error {{code_model 'tiny' is not yet supported on this target}} +int b __attribute((model("small"))); // expected-error {{code_model 'small' is not yet supported on this target}} +int c __attribute((model("normal"))); // no-warning +int d __attribute((model("kernel"))); // expected-error {{code_model 'kernel' is not yet supported on this target}} +int e __attribute((model("medium"))); // no-warning +int f __attribute((model("large"))); // expected-error {{code_model 'large' is not yet supported on this target}} +int g __attribute((model("extreme"))); // no-warning _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits