From 4e172067b2237dbe053c95a89945e03f70b75dd6 Mon Sep 17 00:00:00 2001 From: Quentin Colombet Date: Thu, 1 Nov 2012 23:55:47 +0000 Subject: [PATCH] Update the front end to use minsize attribute llvm-svn: 167266 --- clang/include/clang/Basic/Attr.td | 5 +++ clang/lib/CodeGen/CodeGenModule.cpp | 3 ++ clang/lib/Sema/SemaDeclAttr.cpp | 17 ++++++++ clang/test/CodeGen/attr-minsize.c | 26 ------------ clang/test/CodeGen/attr-minsize.cpp | 75 +++++++++++++++++++++++++++++++++++ clang/test/CodeGenObjC/attr-minsize.m | 12 ++++++ clang/test/Sema/attr-minsize.c | 5 +++ 7 files changed, 117 insertions(+), 26 deletions(-) delete mode 100644 clang/test/CodeGen/attr-minsize.c create mode 100644 clang/test/CodeGen/attr-minsize.cpp create mode 100644 clang/test/CodeGenObjC/attr-minsize.m create mode 100644 clang/test/Sema/attr-minsize.c diff --git a/clang/include/clang/Basic/Attr.td b/clang/include/clang/Basic/Attr.td index 738b460..bfe8093 100644 --- a/clang/include/clang/Basic/Attr.td +++ b/clang/include/clang/Basic/Attr.td @@ -341,6 +341,11 @@ def Final : InheritableAttr { let SemaHandler = 0; } +def MinSize : InheritableAttr { + let Spellings = [GNU<"minsize">]; + let Subjects = [Function]; +} + def Format : InheritableAttr { let Spellings = [GNU<"format">]; let Args = [StringArgument<"Type">, IntArgument<"FormatIdx">, diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index 9617de8..1199112 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -583,6 +583,9 @@ void CodeGenModule::SetLLVMFunctionAttributesForDefinition(const Decl *D, if (D->hasAttr()) F->addFnAttr(llvm::Attributes::OptimizeForSize); + if (D->hasAttr()) + F->addFnAttr(llvm::Attributes::MinSize); + if (isa(D) || isa(D)) F->setUnnamedAddr(true); diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp index df4757e..6db30be 100644 --- a/clang/lib/Sema/SemaDeclAttr.cpp +++ b/clang/lib/Sema/SemaDeclAttr.cpp @@ -1523,6 +1523,20 @@ static void handleAliasAttr(Sema &S, Decl *D, const AttributeList &Attr) { Str->getString())); } +static void handleMinSizeAttr(Sema &S, Decl *D, const AttributeList &Attr) { + // Check the attribute arguments. + if (!checkAttributeNumArgs(S, Attr, 0)) + return; + + if (!isa(D) && !isa(D)) { + S.Diag(Attr.getLoc(), diag::err_attribute_wrong_decl_type) + << Attr.getName() << ExpectedFunctionOrMethod; + return; + } + + D->addAttr(::new (S.Context) MinSizeAttr(Attr.getRange(), S.Context)); +} + static void handleColdAttr(Sema &S, Decl *D, const AttributeList &Attr) { // Check the attribute arguments. if (!checkAttributeNumArgs(S, Attr, 0)) @@ -4285,6 +4299,9 @@ static void ProcessInheritableDeclAttr(Sema &S, Scope *scope, Decl *D, case AttributeList::AT_ExtVectorType: handleExtVectorTypeAttr(S, scope, D, Attr); break; + case AttributeList::AT_MinSize: + handleMinSizeAttr(S, D, Attr); + break; case AttributeList::AT_Format: handleFormatAttr (S, D, Attr); break; case AttributeList::AT_FormatArg: handleFormatArgAttr (S, D, Attr); break; case AttributeList::AT_CUDAGlobal: handleGlobalAttr (S, D, Attr); break; diff --git a/clang/test/CodeGen/attr-minsize.c b/clang/test/CodeGen/attr-minsize.c deleted file mode 100644 index dd260e4..0000000 --- a/clang/test/CodeGen/attr-minsize.c +++ /dev/null @@ -1,26 +0,0 @@ -// RUN: %clang_cc1 -Oz -emit-llvm %s -o - | FileCheck %s -check-prefix=Oz -// RUN: %clang_cc1 -O0 -emit-llvm %s -o - | FileCheck %s -check-prefix=OTHER -// RUN: %clang_cc1 -O1 -emit-llvm %s -o - | FileCheck %s -check-prefix=OTHER -// RUN: %clang_cc1 -O2 -emit-llvm %s -o - | FileCheck %s -check-prefix=OTHER -// RUN: %clang_cc1 -O3 -emit-llvm %s -o - | FileCheck %s -check-prefix=OTHER -// RUN: %clang_cc1 -Os -emit-llvm %s -o - | FileCheck %s -check-prefix=OTHER -// Check that we set the minsize attribute on each function -// when Oz optimization level is set. - -int test1() { - return 42; -// Oz: @test1{{.*}}minsize -// Oz: ret -// OTHER: @test1 -// OTHER-NOT: minsize -// OTHER: ret -} - -int test2() { - return 42; -// Oz: @test2{{.*}}minsize -// Oz: ret -// OTHER: @test2 -// OTHER-NOT: minsize -// OTHER: ret -} diff --git a/clang/test/CodeGen/attr-minsize.cpp b/clang/test/CodeGen/attr-minsize.cpp new file mode 100644 index 0000000..a422a62 --- /dev/null +++ b/clang/test/CodeGen/attr-minsize.cpp @@ -0,0 +1,75 @@ +// RUN: %clang_cc1 -Oz -emit-llvm %s -o - | FileCheck %s -check-prefix=Oz +// RUN: %clang_cc1 -O0 -emit-llvm %s -o - | FileCheck %s -check-prefix=OTHER +// RUN: %clang_cc1 -O1 -emit-llvm %s -o - | FileCheck %s -check-prefix=OTHER +// RUN: %clang_cc1 -O2 -emit-llvm %s -o - | FileCheck %s -check-prefix=OTHER +// RUN: %clang_cc1 -O3 -emit-llvm %s -o - | FileCheck %s -check-prefix=OTHER +// RUN: %clang_cc1 -Os -emit-llvm %s -o - | FileCheck %s -check-prefix=OTHER +// Check that we set the minsize attribute on each function +// when Oz optimization level is set. + +int test1() { + return 42; +// Oz: @{{.*}}test1{{.*}}minsize +// Oz: ret +// OTHER: @{{.*}}test1 +// OTHER-NOT: minsize +// OTHER: ret +} + +int test2() { + return 42; +// Oz: @{{.*}}test2{{.*}}minsize +// Oz: ret +// OTHER: @{{.*}}test2 +// OTHER-NOT: minsize +// OTHER: ret +} + +__attribute__((minsize)) +int test3() { + return 42; +// Oz: @{{.*}}test3{{.*}}minsize +// OTHER: @{{.*}}test3{{.*}}minsize +} + +// Check that the minsize attribute is well propagated through +// template instantiation + +template +__attribute__((minsize)) +void test4(T arg) { + return; +} + +template +void test4(int arg); +// Oz: define{{.*}}void @{{.*}}test4 +// Oz: minsize +// OTHER: define{{.*}}void @{{.*}}test4 +// OTHER: minsize + +template +void test4(float arg); +// Oz: define{{.*}}void @{{.*}}test4 +// Oz: minsize +// OTHER: define{{.*}}void @{{.*}}test4 +// OTHER: minsize + +template +void test5(T arg) { + return; +} + +template +void test5(int arg); +// Oz: define{{.*}}void @{{.*}}test5 +// Oz: minsize +// OTHER: define{{.*}}void @{{.*}}test5 +// OTHER-NOT: minsize + +template +void test5(float arg); +// Oz: define{{.*}}void @{{.*}}test5 +// Oz: minsize +// OTHER: define{{.*}}void @{{.*}}test5 +// OTHER-NOT: minsize diff --git a/clang/test/CodeGenObjC/attr-minsize.m b/clang/test/CodeGenObjC/attr-minsize.m new file mode 100644 index 0000000..f46107e --- /dev/null +++ b/clang/test/CodeGenObjC/attr-minsize.m @@ -0,0 +1,12 @@ +// RUN: %clang_cc1 -emit-llvm -o - %s | FileCheck %s + +@interface Test +- (void)test; +@end + +@implementation Test +- (void)test __attribute__((minsize)) { + // CHECK: define{{.*}}Test test + // CHECK: minsize +} +@end diff --git a/clang/test/Sema/attr-minsize.c b/clang/test/Sema/attr-minsize.c new file mode 100644 index 0000000..7b1c6ae --- /dev/null +++ b/clang/test/Sema/attr-minsize.c @@ -0,0 +1,5 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s + +int foo() __attribute__((__minsize__)); + +int var1 __attribute__((__minsize__)); // expected-error{{'__minsize__' attribute only applies to functions and methods}} -- 2.7.4