https://github.com/heiher updated https://github.com/llvm/llvm-project/pull/72078
>From 323a8f851acb085a9464b3edca1206481f2aee23 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. Link: https://discourse.llvm.org/t/how-to-best-implement-code-model-overriding-for-certain-values/71816 Suggested-by: Arthur Eubanks <aeuba...@google.com> Signed-off-by: WANG Rui <wang...@loongson.cn> --- clang/include/clang/Basic/Attr.td | 8 ++++++++ clang/include/clang/Basic/AttrDocs.td | 9 +++++++++ .../clang/Basic/DiagnosticSemaKinds.td | 3 +++ 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, 81 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 31434565becaec67..0d3742080435142f 100644 --- a/clang/include/clang/Basic/Attr.td +++ b/clang/include/clang/Basic/Attr.td @@ -2694,6 +2694,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 fa6f6acd0c30e883..ca09e4acb113003b 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 4614324babb1c917..f9305e21bd6a39b3 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -3401,6 +3401,9 @@ 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 must be \"tiny\", " + "\"small\", \"kernel\", \"medium\" or \"large\"">; + 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 4c7f516e308ca003..f7347ab912aa7d74 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -4774,6 +4774,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 cdb769a883550d0f..3cf50284bb3bedfc 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 Model; + SourceLocation LiteralLoc; + // Check that it is a string. + if (!S.checkStringLiteralArgumentAttr(AL, 0, Model, &LiteralLoc)) + return; + + // Check that the value. + if (Model != "tiny" && Model != "small" && Model != "kernel" && + Model != "medium" && Model != "large") { + S.Diag(LiteralLoc, diag::err_attr_codemodel_arg); + return; + } + + D->addAttr(::new (S.Context) CodeModelAttr(S.Context, AL, Model)); +} + // 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, @@ -9274,6 +9291,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 5afef72b747afb11..7783d87b84c29c9b 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 969794073a5f2e80..7a0b4f20cb88a5c7 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 0000000000000000..90b9713f5f32cd26 --- /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("normal"))); // expected-error {{code_model must be "tiny", "small", "kernel", "medium" or "large"}} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits