From 4e32999642597c9b90c879947acfbf63e67d26a0 Mon Sep 17 00:00:00 2001 From: cf-zhao Date: Thu, 13 Feb 2025 10:15:13 +0800 Subject: [PATCH] [clang]Add support for optimize function attribute --- clang/include/clang/AST/CMakeLists.txt | 10 +++++ clang/include/clang/Basic/Attr.td | 9 +++++ clang/include/clang/Basic/AttrDocs.td | 13 +++++++ clang/include/clang/Basic/CMakeLists.txt | 4 ++ .../clang/Basic/DiagnosticSemaKinds.td | 12 ++++++ clang/include/clang/Sema/CMakeLists.txt | 10 +++++ .../clang/Serialization/CMakeLists.txt | 7 ++++ clang/lib/AST/CMakeLists.txt | 6 +++ clang/lib/Sema/SemaDeclAttr.cpp | 39 +++++++++++++++++++ clang/test/CodeGen/attr-optmize.c | 16 ++++++++ ...a-attribute-supported-attributes-list.test | 7 ++++ clang/test/Sema/attr-optimize.c | 24 ++++++++++++ 12 files changed, 157 insertions(+) create mode 100644 clang/test/CodeGen/attr-optmize.c create mode 100644 clang/test/Sema/attr-optimize.c diff --git a/clang/include/clang/AST/CMakeLists.txt b/clang/include/clang/AST/CMakeLists.txt index 3a6fddb02914..7d7133b32276 100644 --- a/clang/include/clang/AST/CMakeLists.txt +++ b/clang/include/clang/AST/CMakeLists.txt @@ -1,20 +1,30 @@ +set(CLANG_AST_OPTIONS) +if(BUILD_FOR_OPENEULER) + list(APPEND CLANG_AST_OPTIONS -DBUILD_FOR_OPENEULER) +endif() + clang_tablegen(Attrs.inc -gen-clang-attr-classes + ${CLANG_AST_OPTIONS} SOURCE ../Basic/Attr.td TARGET ClangAttrClasses) clang_tablegen(AttrImpl.inc -gen-clang-attr-impl + ${CLANG_AST_OPTIONS} SOURCE ../Basic/Attr.td TARGET ClangAttrImpl) clang_tablegen(AttrTextNodeDump.inc -gen-clang-attr-text-node-dump + ${CLANG_AST_OPTIONS} SOURCE ../Basic/Attr.td TARGET ClangAttrTextDump) clang_tablegen(AttrNodeTraverse.inc -gen-clang-attr-node-traverse + ${CLANG_AST_OPTIONS} SOURCE ../Basic/Attr.td TARGET ClangAttrTraverse) clang_tablegen(AttrVisitor.inc -gen-clang-attr-ast-visitor + ${CLANG_AST_OPTIONS} SOURCE ../Basic/Attr.td TARGET ClangAttrVisitor) diff --git a/clang/include/clang/Basic/Attr.td b/clang/include/clang/Basic/Attr.td index d5204b286966..1414fc60c6fe 100644 --- a/clang/include/clang/Basic/Attr.td +++ b/clang/include/clang/Basic/Attr.td @@ -2367,6 +2367,15 @@ def OptimizeNone : InheritableAttr { let Documentation = [OptnoneDocs]; } +#ifdef BUILD_FOR_OPENEULER +def Optimize : InheritableAttr { + let Spellings = [GCC<"optimize">]; + let Args = [StringArgument<"Level">]; + let Subjects = SubjectList<[Function]>; + let Documentation = [OptimizeDocs]; +} +#endif + def Overloadable : Attr { let Spellings = [Clang<"overloadable">]; let Subjects = SubjectList<[Function], ErrorDiag>; diff --git a/clang/include/clang/Basic/AttrDocs.td b/clang/include/clang/Basic/AttrDocs.td index 2c950231255d..540c797811d9 100644 --- a/clang/include/clang/Basic/AttrDocs.td +++ b/clang/include/clang/Basic/AttrDocs.td @@ -3618,6 +3618,19 @@ attributes. }]; } +#ifdef BUILD_FOR_OPENEULER +def OptimizeDocs : Documentation { + let Category = DocCatFunction; + let Content = [{ +The ``optimize`` attribute, when attached to a function, indicates that the +function should be compiled with a different optimization level then specified +on the command line. See the Function Attributes documentation on GCC's docs for +more information. Currently, the attribute differs from GCC in that Clang only +supports 'O0' and 0. +}]; +} +#endif + def LoopHintDocs : Documentation { let Category = DocCatStmt; let Heading = "#pragma clang loop"; diff --git a/clang/include/clang/Basic/CMakeLists.txt b/clang/include/clang/Basic/CMakeLists.txt index 691d14f013cf..de7d82358630 100644 --- a/clang/include/clang/Basic/CMakeLists.txt +++ b/clang/include/clang/Basic/CMakeLists.txt @@ -5,6 +5,9 @@ endif() if(BUILD_FOR_OPENEULER) list(APPEND CLANG_BASIC_OPTIONS "-DBUILD_FOR_OPENEULER") endif() +if(BUILD_FOR_OPENEULER) + list(APPEND CLANG_BASIC_OPTIONS "-DBUILD_FOR_OPENEULER") +endif() macro(clang_diag_gen component) clang_tablegen(Diagnostic${component}Kinds.inc @@ -50,6 +53,7 @@ clang_tablegen(AttrSubMatchRulesList.inc -gen-clang-attr-subject-match-rule-list clang_tablegen(AttrTokenKinds.inc -gen-clang-attr-token-kinds -I ${CMAKE_CURRENT_SOURCE_DIR}/../../ + ${CLANG_BASIC_OPTIONS} SOURCE Attr.td TARGET ClangAttrTokenKinds ) diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 0e97620945af..4a307fe8f230 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -3082,6 +3082,12 @@ def err_attribute_too_many_arguments : Error< "%0 attribute takes no more than %1 argument%s1">; def err_attribute_too_few_arguments : Error< "%0 attribute takes at least %1 argument%s1">; +#ifdef BUILD_FOR_OPENEULER +def warn_invalid_optimize_attr_level : Warning< + "invalid optimization level '%0' specified; only " + "0 and 'O0' are supported; attribute ignored">, + InGroup; +#endif def err_attribute_invalid_vector_type : Error<"invalid vector element type %0">; def err_attribute_invalid_bitint_vector_type : Error< "'_BitInt' vector element width must be %select{a power of 2|" @@ -3153,6 +3159,12 @@ def err_attribute_argument_n_type : Error< def err_attribute_argument_type : Error< "%0 attribute requires %select{int or bool|an integer " "constant|a string|an identifier}1">; +#ifdef BUILD_FOR_OPENEULER +def err_attribute_argument_either_type : Error< + "%0 attribute requires %select{int or bool|an integer " + "constant|a string|an identifier}1 or %select{int or " + "bool|an integer constant|a string|an identifier}2">; +#endif def err_attribute_argument_out_of_range : Error< "%0 attribute requires integer constant between %1 and %2 inclusive">; def err_init_priority_object_attr : Error< diff --git a/clang/include/clang/Sema/CMakeLists.txt b/clang/include/clang/Sema/CMakeLists.txt index 0b0e31ece319..f36a1f9d6213 100644 --- a/clang/include/clang/Sema/CMakeLists.txt +++ b/clang/include/clang/Sema/CMakeLists.txt @@ -1,24 +1,34 @@ +set(CLANG_SEMA_OPTIONS) +if (BUILD_FOR_OPENEULER) + list(APPEND CLANG_SEMA_OPTIONS "-DBUILD_FOR_OPENEULER") +endif() + clang_tablegen(AttrTemplateInstantiate.inc -gen-clang-attr-template-instantiate -I ${CMAKE_CURRENT_SOURCE_DIR}/../../ + ${CLANG_SEMA_OPTIONS} SOURCE ../Basic/Attr.td TARGET ClangAttrTemplateInstantiate) clang_tablegen(AttrParsedAttrList.inc -gen-clang-attr-parsed-attr-list -I ${CMAKE_CURRENT_SOURCE_DIR}/../../ + ${CLANG_SEMA_OPTIONS} SOURCE ../Basic/Attr.td TARGET ClangAttrParsedAttrList) clang_tablegen(AttrParsedAttrKinds.inc -gen-clang-attr-parsed-attr-kinds -I ${CMAKE_CURRENT_SOURCE_DIR}/../../ + ${CLANG_SEMA_OPTIONS} SOURCE ../Basic/Attr.td TARGET ClangAttrParsedAttrKinds) clang_tablegen(AttrSpellingListIndex.inc -gen-clang-attr-spelling-index -I ${CMAKE_CURRENT_SOURCE_DIR}/../../ + ${CLANG_SEMA_OPTIONS} SOURCE ../Basic/Attr.td TARGET ClangAttrSpellingListIndex) clang_tablegen(AttrParsedAttrImpl.inc -gen-clang-attr-parsed-attr-impl -I ${CMAKE_CURRENT_SOURCE_DIR}/../../ + ${CLANG_SEMA_OPTIONS} SOURCE ../Basic/Attr.td TARGET ClangAttrParsedAttrImpl) diff --git a/clang/include/clang/Serialization/CMakeLists.txt b/clang/include/clang/Serialization/CMakeLists.txt index d91513da9997..2fa4457f73df 100644 --- a/clang/include/clang/Serialization/CMakeLists.txt +++ b/clang/include/clang/Serialization/CMakeLists.txt @@ -1,9 +1,16 @@ +set(CLANG_SER_OPTIONS) +if(BUILD_FOR_OPENEULER) + list(APPEND CLANG_SER_OPTIONS "-DBUILD_FOR_OPENEULER") +endif() + clang_tablegen(AttrPCHRead.inc -gen-clang-attr-pch-read -I ${CMAKE_CURRENT_SOURCE_DIR}/../../ + ${CLANG_SER_OPTIONS} SOURCE ../Basic/Attr.td TARGET ClangAttrPCHRead) clang_tablegen(AttrPCHWrite.inc -gen-clang-attr-pch-write -I ${CMAKE_CURRENT_SOURCE_DIR}/../../ + ${CLANG_SER_OPTIONS} SOURCE ../Basic/Attr.td TARGET ClangAttrPCHWrite) diff --git a/clang/lib/AST/CMakeLists.txt b/clang/lib/AST/CMakeLists.txt index 0b737626a220..227a85f4da55 100644 --- a/clang/lib/AST/CMakeLists.txt +++ b/clang/lib/AST/CMakeLists.txt @@ -6,6 +6,11 @@ set(LLVM_LINK_COMPONENTS TargetParser ) +set(CLANG_AST_OPTIONS) +if (BUILD_FOR_OPENEULER) + list(APPEND CLANG_AST_OPTIONS -DBUILD_FOR_OPENEULER) +endif() + # FIXME: the entry points to the interpreter should be moved out of clangAST # into the parser or Sema in order to allow the interpreter to be moved to # another library which depends on clangAST. @@ -16,6 +21,7 @@ clang_tablegen(Opcodes.inc clang_tablegen(AttrDocTable.inc -gen-clang-attr-doc-table -I ${CMAKE_CURRENT_SOURCE_DIR}/../../include/ + ${CLANG_AST_OPTIONS} SOURCE ${CMAKE_CURRENT_SOURCE_DIR}/../../include/clang/Basic/Attr.td TARGET ClangAttrDocTable) diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp index ed69e802c95d..8717d3d2b1b0 100644 --- a/clang/lib/Sema/SemaDeclAttr.cpp +++ b/clang/lib/Sema/SemaDeclAttr.cpp @@ -5001,6 +5001,40 @@ static void handleOptimizeNoneAttr(Sema &S, Decl *D, const ParsedAttr &AL) { D->addAttr(Optnone); } +#ifdef BUILD_FOR_OPENEULER +static void handleOptimizeAttr(Sema &S, Decl *D, const ParsedAttr &AL) { + StringRef Arg; + Expr *ArgExpr = AL.getArgAsExpr(0); + const auto *SL = dyn_cast(ArgExpr->IgnoreParenCasts()); + if (!SL || !SL->isOrdinary()) { + llvm::APSInt ArgInt; + if (const auto *IL = dyn_cast(ArgExpr)) + ArgInt = IL->getValue(); + else { + S.Diag(ArgExpr->getBeginLoc(), diag::err_attribute_argument_either_type) + << AL << AANT_ArgumentString << AANT_ArgumentIntegerConstant; + return; + } + if (ArgInt.isZero()) { + if (OptimizeNoneAttr *Optnone = S.mergeOptimizeNoneAttr(D, AL)) + D->addAttr(Optnone); + } + else + S.Diag(AL.getLoc(), diag::warn_invalid_optimize_attr_level) + << toString(ArgInt, 10); + return; + } + Arg = SL->getString(); + if (Arg.str() == "O0") { + if (OptimizeNoneAttr *Optnone = S.mergeOptimizeNoneAttr(D, AL)) + D->addAttr(Optnone); + } + else + S.Diag(AL.getLoc(), diag::warn_invalid_optimize_attr_level) << Arg; + return; +} +#endif + static void handleConstantAttr(Sema &S, Decl *D, const ParsedAttr &AL) { const auto *VD = cast(D); if (VD->hasLocalStorage()) { @@ -8956,6 +8990,11 @@ ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D, const ParsedAttr &AL, case ParsedAttr::AT_OptimizeNone: handleOptimizeNoneAttr(S, D, AL); break; +#ifdef BUILD_FOR_OPENEULER + case ParsedAttr::AT_Optimize: + handleOptimizeAttr(S, D, AL); + break; +#endif case ParsedAttr::AT_EnumExtensibility: handleEnumExtensibilityAttr(S, D, AL); break; diff --git a/clang/test/CodeGen/attr-optmize.c b/clang/test/CodeGen/attr-optmize.c new file mode 100644 index 000000000000..d14b3c605008 --- /dev/null +++ b/clang/test/CodeGen/attr-optmize.c @@ -0,0 +1,16 @@ +// REQUIRES: build_for_openeuler +// RUN: %clang_cc1 -O2 -S -emit-llvm %s -o - | FileCheck %s --check-prefix=O2 +// RUN: %clang_cc1 -O0 -S -emit-llvm %s -o - | FileCheck %s --check-prefix=O0 + +__attribute__((optimize("O0"))) void f1(void) {} +// O2: @f1{{.*}}[[ATTR_OPTNONE:#[0-9]+]] +// O0: @f1{{.*}}[[ATTR_OPTNONE:#[0-9]+]] + +__attribute__((optimize(0))) void f2(void) {} +// O2: @f2{{.*}}[[ATTR_OPTNONE:#[0-9]+]] +// O0: @f2{{.*}}[[ATTR_OPTNONE:#[0-9]+]] + +// O2: attributes [[ATTR_OPTNONE]] = { {{.*}}optnone{{.*}} } + +// CHECK the O0 overrides the attribute +// O0: attributes [[ATTR_OPTNONE]] = { {{.*}}optnone{{.*}} } diff --git a/clang/test/Misc/pragma-attribute-supported-attributes-list.test b/clang/test/Misc/pragma-attribute-supported-attributes-list.test index eaf6d34421bb..9de78c842d7a 100644 --- a/clang/test/Misc/pragma-attribute-supported-attributes-list.test +++ b/clang/test/Misc/pragma-attribute-supported-attributes-list.test @@ -1,3 +1,7 @@ +// REQUIRES: build_for_openeuler +// RUN: clang-tblgen -gen-clang-test-pragma-attribute-supported-attributes -I%src_include_dir %src_include_dir/clang/Basic/Attr.td -DBUILD_FOR_OPENEULER -o - | FileCheck %s + +// XFAIL: build_for_openeuler // RUN: clang-tblgen -gen-clang-test-pragma-attribute-supported-attributes -I%src_include_dir %src_include_dir/clang/Basic/Attr.td -o - | FileCheck %s // The number of supported attributes should never go down! @@ -148,6 +152,9 @@ // CHECK-NEXT: ObjCSubclassingRestricted (SubjectMatchRule_objc_interface) // CHECK-NEXT: OpenCLIntelReqdSubGroupSize (SubjectMatchRule_function) // CHECK-NEXT: OpenCLNoSVM (SubjectMatchRule_variable) +#ifdef BUILD_FOR_OPENEULER +// CHECK-NEXT: Optimize (SubjectMatchRule_function) +#endif // CHECK-NEXT: OptimizeNone (SubjectMatchRule_function, SubjectMatchRule_objc_method) // CHECK-NEXT: Overloadable (SubjectMatchRule_function) // CHECK-NEXT: Owner (SubjectMatchRule_record_not_is_union) diff --git a/clang/test/Sema/attr-optimize.c b/clang/test/Sema/attr-optimize.c new file mode 100644 index 000000000000..04d1822d420a --- /dev/null +++ b/clang/test/Sema/attr-optimize.c @@ -0,0 +1,24 @@ +// REQUIRES: build_for_openeuler +// RUN: %clang_cc1 -verify -fsyntax-only %s + +__attribute__((optimize(0))) // expected-no-error +void f1() {} + +int a = 0; +__attribute__((optimize(a))) // expected-error {{'optimize' attribute requires a string or an integer constant}} +void f2() {} + +__attribute__((optimize(1))) // expected-warning {{invalid optimization level '1' specified; only 0 and 'O0' are supported; attribute ignored}} +void f3() {} + +__attribute__((optimize(c))) // expected-error {{use of undeclared identifier 'c'}} +void f4() {} + +__attribute__((optimize("O0"))) // expected-no-error +void f5() {} + +__attribute__((optimize("O0", "O1"))) // expected-error {{'optimize' attribute takes one argument}} +void f6() {} + +__attribute__((optimize("O1"))) // expected-warning {{invalid optimization level 'O1' specified; only 0 and 'O0' are supported; attribute ignored}} +void f7() {} -- Gitee