diff --git a/clang/include/clang/Basic/Attr.td b/clang/include/clang/Basic/Attr.td index f79e9ef3fa10a963b652222cd951c13efb54559c..75bb40dc093e9ac1ba49a195c116abd06f045c91 100644 --- a/clang/include/clang/Basic/Attr.td +++ b/clang/include/clang/Basic/Attr.td @@ -2313,6 +2313,17 @@ def OptimizeNone : InheritableAttr { let Documentation = [OptnoneDocs]; } +// OHOS_LOCAL begin +def Optimize : InheritableAttr { + let Spellings = [GCC<"optimize">]; + let Args = [VariadicEnumArgument<"OptAttrs", "OptAttrKind", + ["omit-frame-pointer", "no-omit-frame-pointer"], + ["OmitFramePointer", "NoOmitFramePointer"]>]; + let Subjects = SubjectList<[Function]>; + let Documentation = [OptimizeDocs]; +} +// OHOS_LOCAL end + 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 74e76f42e04c95d00d0022d6fd4f778cb1271f51..9f68866b964f583dbda3f9545391246b65fbaa24 100644 --- a/clang/include/clang/Basic/AttrDocs.td +++ b/clang/include/clang/Basic/AttrDocs.td @@ -3493,6 +3493,24 @@ attributes. }]; } +// OHOS_LOCAL begin +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 than 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 one argument, doesn't support ``-f`` arguments, and also doesn't +support expressions or integers as arguments. Clang does not intend to fully +support the GCC semantics. Optimization attributes only "omit-frame-pointer/no-omit-frame-pointer" +are supported. + +Refer to: https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html + }]; +} +// OHOS_LOCAL end + def LoopHintDocs : Documentation { let Category = DocCatStmt; let Heading = "#pragma clang loop"; diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index a6531ecf17b313d14f090b6acdff3a51cb797f0f..a6240f32b0339b07473259a33da0ab9b54c28054 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -3018,6 +3018,14 @@ 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">; +// OHOS_LOCAL begin +def warn_invalid_optimize_attr_argument : Warning < + "bad option '%1' to attribute %0; " + "attribute ignored">, InGroup; +def warn_invalid_optimize_attr_type : Warning < + "%0 attribute only support string argument; " + "attribute ignored">, InGroup; +// OHOS_LOCAL end def err_attribute_invalid_vector_type : Error<"invalid vector element type %0">; def err_attribute_invalid_matrix_type : Error<"invalid matrix element type %0">; def err_attribute_bad_neon_vector_size : Error< diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp index 3848f10a6789f95090f406d6f0ff6bec7cf16a84..a334bb616d5345491eb2b68d8129703d1bd19b74 100644 --- a/clang/lib/CodeGen/CGCall.cpp +++ b/clang/lib/CodeGen/CGCall.cpp @@ -1780,6 +1780,31 @@ static void AddAttributesFromAssumes(llvm::AttrBuilder &FuncAttrs, llvm::join(Attrs.begin(), Attrs.end(), ",")); } +// OHOS_LOCAL begin +static void AddAttributesFromOptimize(llvm::AttrBuilder &FuncAttrs, + const Decl *Callee) { + if (!Callee) + return; + + const OptimizeAttr *OptAttrObj = Callee->getAttr(); + if (!OptAttrObj) + return; + + for (const auto &OA : OptAttrObj->optAttrs()) { + switch (OA) { + case OptimizeAttr::OmitFramePointer: + FuncAttrs.addAttribute("OPT-omit-frame-pointer"); + break; + case OptimizeAttr::NoOmitFramePointer: + FuncAttrs.addAttribute("OPT-no-omit-frame-pointer"); + break; + default: + llvm_unreachable("invalid enum"); + } + } +} +// OHOS_LOCAL end + bool CodeGenModule::MayDropFunctionReturn(const ASTContext &Context, QualType ReturnType) { // We can't just discard the return value for a record type with a @@ -1832,6 +1857,13 @@ void CodeGenModule::getDefaultFunctionAttributes(StringRef Name, FpKind = "all"; break; } + // OHOS_LOCAL begin + // optimize attr's priority is higher than command line args + if (FuncAttrs.contains("OPT-omit-frame-pointer")) + FpKind = "none"; + if (FuncAttrs.contains("OPT-no-omit-frame-pointer")) + FpKind = "all"; + // OHOS_LOCAL end FuncAttrs.addAttribute("frame-pointer", FpKind); if (CodeGenOpts.LessPreciseFPMAD) @@ -2090,6 +2122,7 @@ void CodeGenModule::ConstructAttributeList(StringRef Name, // Attach assumption attributes to the declaration. If this is a call // site, attach assumptions from the caller to the call as well. AddAttributesFromAssumes(FuncAttrs, TargetDecl); + AddAttributesFromOptimize(FuncAttrs, TargetDecl); // OHOS_LOCAL bool HasOptnone = false; // The NoBuiltinAttr attached to the target FunctionDecl. diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index e9635356e26f267248ced7f1bd5303ee1905bdcd..173437e231b3e8d4d6a9edf3cb7bab0a061abeb9 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -2160,6 +2160,21 @@ bool CodeGenModule::GetCPUAndFeaturesAttributes(GlobalDecl GD, llvm::StringMap FeatureMap; getContext().getFunctionFeatureMap(FeatureMap, GD); + // OHOS_LOCAL begin + auto TargetArch = getContext().getTargetInfo().getTriple().getArch(); + // Enable aarch64 target attribute: general-regs-only + if (TargetArch == llvm::Triple::aarch64 || + TargetArch == llvm::Triple::aarch64_be) { + auto EntryIt = FeatureMap.find("general-regs-only"); + if (EntryIt != FeatureMap.end() && EntryIt->getValue()) { + FeatureMap["neon"] = false; + FeatureMap["crypto"] = false; + FeatureMap["fp-armv8"] = false; + FeatureMap["sve"] = false; + FeatureMap.erase("general-regs-only"); + } + } + // OHOS_LOCAL end // Produce the canonical string for this set of features. for (const llvm::StringMap::value_type &Entry : FeatureMap) Features.push_back((Entry.getValue() ? "+" : "-") + Entry.getKey().str()); diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp index 00120cc54c4b646eb5502729f71deba275a90dde..8a105b988c466bae092ee520252d0a7b35bb93bb 100644 --- a/clang/lib/Sema/SemaDeclAttr.cpp +++ b/clang/lib/Sema/SemaDeclAttr.cpp @@ -4794,6 +4794,42 @@ static void handleOptimizeNoneAttr(Sema &S, Decl *D, const ParsedAttr &AL) { D->addAttr(Optnone); } +// OHOS_LOCAL begin +// 'optimize' attribute only accept string argument, just warning if invalid type +static void handleOptimizeAttr(Sema &S, Decl *D, const ParsedAttr &AL) { + if (!AL.checkAtLeastNumArgs(S, 1)) + return; + + SmallVector OptAttrs; + for (unsigned ArgIndex = 0; ArgIndex < AL.getNumArgs(); ++ArgIndex) { + if (AL.isArgIdent(ArgIndex)) { + S.Diag(AL.getLoc(), diag::warn_invalid_optimize_attr_type) << AL; + return; + } + + Expr *ArgExpr = AL.getArgAsExpr(ArgIndex); + SourceLocation Loc = ArgExpr->getBeginLoc(); + const auto *Literal = dyn_cast(ArgExpr->IgnoreParenCasts()); + if (!Literal) { + S.Diag(Loc, diag::warn_invalid_optimize_attr_type) << AL; + return; + } + + StringRef OptAttrStr = Literal->getString(); + OptimizeAttr::OptAttrKind OptAttr; + if (!OptimizeAttr::ConvertStrToOptAttrKind(OptAttrStr, OptAttr)) { + S.Diag(Loc, diag::warn_invalid_optimize_attr_argument) << AL << OptAttrStr; + return; + } + + OptAttrs.push_back(OptAttr); + } + + D->addAttr(::new (S.Context) + OptimizeAttr(S.Context, AL, OptAttrs.data(), OptAttrs.size())); +} +// OHOS_LOCAL end + static void handleConstantAttr(Sema &S, Decl *D, const ParsedAttr &AL) { const auto *VD = cast(D); if (VD->hasLocalStorage()) { @@ -8603,6 +8639,11 @@ ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D, const ParsedAttr &AL, case ParsedAttr::AT_OptimizeNone: handleOptimizeNoneAttr(S, D, AL); break; + // OHOS_LOCAL begin + case ParsedAttr::AT_Optimize: + handleOptimizeAttr(S, D, AL); + break; + // OHOS_LOCAL end case ParsedAttr::AT_EnumExtensibility: handleEnumExtensibilityAttr(S, D, AL); break; diff --git a/clang/test/CodeGen/attr-optimize.c b/clang/test/CodeGen/attr-optimize.c new file mode 100644 index 0000000000000000000000000000000000000000..46347cef8d8feca311f7d3f771af8dc096a5b658 --- /dev/null +++ b/clang/test/CodeGen/attr-optimize.c @@ -0,0 +1,12 @@ +// OHOS_LOCAL begin +// RUN: %clang_cc1 -S -emit-llvm %s -o - | FileCheck %s + +__attribute__((optimize("omit-frame-pointer"))) void f8(void) {} +// CHECK: @f8{{.*}}[[ATTR_omit_frame_pointer:#[0-9]+]] + +__attribute__((optimize("no-omit-frame-pointer"))) void f9(void) {} +// CHECK: @f9{{.*}}[[ATTR_no_omit_frame_pointer:#[0-9]+]] + +// CHECK: attributes [[ATTR_omit_frame_pointer]] = { {{.*}}OPT-omit-frame-pointer{{.*}}"frame-pointer"="none"{{.*}} } +// CHECK: attributes [[ATTR_no_omit_frame_pointer]] = { {{.*}}OPT-no-omit-frame-pointer{{.*}}"frame-pointer"="all"{{.*}} } +// OHOS_LOCAL end diff --git a/clang/test/CodeGen/attr-target-general-regs-only-aarch64.c b/clang/test/CodeGen/attr-target-general-regs-only-aarch64.c new file mode 100644 index 0000000000000000000000000000000000000000..11306b0a1ae5e45d1cefb88ad49c82c5c4264bdd --- /dev/null +++ b/clang/test/CodeGen/attr-target-general-regs-only-aarch64.c @@ -0,0 +1,11 @@ +// OHOS_LOCAL begin +// Test general-regs-only target attribute on aarch64 + +// RUN: %clang_cc1 -triple aarch64-linux-gnu -emit-llvm %s -o - | FileCheck %s +// RUN: %clang_cc1 -triple aarch64_be-linux-gnu -emit-llvm %s -o - | FileCheck %s + +// CHECK: define{{.*}} void @f() [[GPR_ATTRS:#[0-9]+]] +void __attribute__((target("general-regs-only"))) f(void) { } + +// CHECK: attributes [[GPR_ATTRS]] = { {{.*}} "target-features"="{{.*}}-crypto{{.*}}-fp-armv8{{.*}}-neon{{.*}}" +// OHOS_LOCAL end diff --git a/clang/test/Misc/pragma-attribute-supported-attributes-list.test b/clang/test/Misc/pragma-attribute-supported-attributes-list.test index 1a5775f4e14bf5cbb83b6276df8a93a234578e63..07cf0bdafc9fe6db4b2a6db8ca4d06f947d1bbc1 100644 --- a/clang/test/Misc/pragma-attribute-supported-attributes-list.test +++ b/clang/test/Misc/pragma-attribute-supported-attributes-list.test @@ -143,6 +143,9 @@ // CHECK-NEXT: ObjCSubclassingRestricted (SubjectMatchRule_objc_interface) // CHECK-NEXT: OpenCLIntelReqdSubGroupSize (SubjectMatchRule_function) // CHECK-NEXT: OpenCLNoSVM (SubjectMatchRule_variable) +// OHOS_LOCAL begin +// CHECK-NEXT: Optimize (SubjectMatchRule_function) +// OHOS_LOCAL end // 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 0000000000000000000000000000000000000000..25ba011b7ce3220113209e222511ead19223136a --- /dev/null +++ b/clang/test/Sema/attr-optimize.c @@ -0,0 +1,22 @@ +// OHOS_LOCAL begin +// RUN: %clang_cc1 -verify -fsyntax-only %s + +__attribute__((optimize())) // expected-error {{'optimize' attribute takes at least 1 argument}} +void f0() {} + +__attribute__((optimize(a))) // expected-warning {{'optimize' attribute only support string argument; attribute ignored}} +void f1() {} + +int b = 1; +__attribute__((optimize(b))) // expected-warning {{'optimize' attribute only support string argument; attribute ignored}} +void f2() {} + +__attribute__((optimize("omit-frame-pointer"))) // expected-no-error +void f3() {} + +__attribute__((optimize(1))) // expected-warning {{'optimize' attribute only support string argument; attribute ignored}} +void f12() {} + +__attribute__((optimize(0))) // expected-warning {{'optimize' attribute only support string argument; attribute ignored}} +void f13() {} +// OHOS_LOCAL end