https://github.com/heiher updated https://github.com/llvm/llvm-project/pull/72078
>From 478cbb52d3ed3c6311389dd48c8d187cb28de18d 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 adds a per-global code model attribute, which can override the target's code model to access global variables. 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 | 20 +++++++++++++++++++ clang/test/CodeGen/attributes.c | 15 ++++++++++++++ ...a-attribute-supported-attributes-list.test | 1 + clang/test/Sema/attr-model.c | 12 +++++++++++ 8 files changed, 80 insertions(+) create mode 100644 clang/test/Sema/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..a4dace539d096 100644 --- a/clang/lib/Sema/SemaDeclAttr.cpp +++ b/clang/lib/Sema/SemaDeclAttr.cpp @@ -3369,6 +3369,23 @@ static void handleSectionAttr(Sema &S, Decl *D, const ParsedAttr &AL) { } } +static void handleCodeModelAttr(Sema &S, Decl *D, const ParsedAttr &AL) { + StringRef CM; + SourceLocation LiteralLoc; + // Check that it is a string. + if (!S.checkStringLiteralArgumentAttr(AL, 0, CM, &LiteralLoc)) + return; + + // Check that the value. + if (CM != "tiny" && CM != "small" && CM != "kernel" && CM != "medium" && + CM != "large") { + S.Diag(LiteralLoc, diag::err_attr_codemodel_arg) << CM; + 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 +9326,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/attributes.c b/clang/test/CodeGen/attributes.c index 5afef72b747af..7783d87b84c29 100644 --- a/clang/test/CodeGen/attributes.c +++ b/clang/test/CodeGen/attributes.c @@ -25,6 +25,21 @@ int t6 __attribute__((visibility("protected"))); // CHECK: @t12 ={{.*}} global i32 0, section "SECT" int t12 __attribute__((section("SECT"))); +// CHECK: @tiny ={{.*}} global i32 0, code_model "tiny" +int tiny __attribute__((model("tiny"))); + +// CHECK: @small ={{.*}} global i32 0, code_model "small" +int small __attribute__((model("small"))); + +// CHECK: @kernel ={{.*}} global i32 0, code_model "kernel" +int kernel __attribute__((model("kernel"))); + +// CHECK: @medium ={{.*}} global i32 0, code_model "medium" +int medium __attribute__((model("medium"))); + +// CHECK: @large ={{.*}} global i32 0, code_model "large" +int large __attribute__((model("large"))); + // CHECK: @t9 = weak{{.*}} alias void (...), ptr @__t8 void __t8() {} void t9() __attribute__((weak, alias("__t8"))); 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/attr-model.c b/clang/test/Sema/attr-model.c new file mode 100644 index 0000000000000..cc46a60e48935 --- /dev/null +++ b/clang/test/Sema/attr-model.c @@ -0,0 +1,12 @@ +// RUN: %clang_cc1 -triple x86_64 -verify -fsyntax-only %s + +#if !__has_attribute(model) +#error "Should support model attribute" +#endif + +int a __attribute((model("tiny"))); // no-warning +int b __attribute((model("small"))); // no-warning +int c __attribute((model("kernel"))); // no-warning +int d __attribute((model("medium"))); // no-warning +int e __attribute((model("large"))); // no-warning +int f __attribute((model("huge"))); // expected-error {{code_model 'huge' is not yet supported on this target}} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits