r209510 - Implemented support for "pragma clang optimize on/off", based on attribute 'optnone'.
Dario Domizioli
dario.domizioli at gmail.com
Fri May 23 05:13:25 PDT 2014
Author: ddomizioli
Date: Fri May 23 07:13:25 2014
New Revision: 209510
URL: http://llvm.org/viewvc/llvm-project?rev=209510&view=rev
Log:
Implemented support for "pragma clang optimize on/off", based on attribute 'optnone'.
This patch implements support for selectively disabling optimizations on a
range of function definitions through a pragma. The implementation is that
all function definitions in the range are decorated with attribute
'optnone'.
#pragma clang optimize off
// All function definitions in here are decorated with 'optnone'.
#pragma clang optimize on
// Compilation resumes as normal.
Added:
cfe/trunk/test/PCH/pragma-optimize.c
cfe/trunk/test/Parser/pragma-optimize-diagnostics.cpp
cfe/trunk/test/SemaCXX/pragma-optimize.cpp
Modified:
cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td
cfe/trunk/include/clang/Parse/Parser.h
cfe/trunk/include/clang/Sema/Sema.h
cfe/trunk/include/clang/Serialization/ASTBitCodes.h
cfe/trunk/include/clang/Serialization/ASTReader.h
cfe/trunk/include/clang/Serialization/ASTWriter.h
cfe/trunk/lib/Parse/ParsePragma.cpp
cfe/trunk/lib/Sema/SemaAttr.cpp
cfe/trunk/lib/Sema/SemaDecl.cpp
cfe/trunk/lib/Serialization/ASTReader.cpp
cfe/trunk/lib/Serialization/ASTWriter.cpp
Modified: cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td?rev=209510&r1=209509&r2=209510&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticParseKinds.td Fri May 23 07:13:25 2014
@@ -843,6 +843,14 @@ def err_pragma_detect_mismatch_malformed
def err_pragma_pointers_to_members_unknown_kind : Error<
"unexpected %0, expected to see one of %select{|'best_case', 'full_generality', }1"
"'single_inheritance', 'multiple_inheritance', or 'virtual_inheritance'">;
+// - #pragma clang optimize on/off
+def err_pragma_optimize_missing_argument : Error<
+ "missing argument to '#pragma clang optimize'; expected 'on' or 'off'">;
+def err_pragma_optimize_invalid_argument : Error<
+ "unexpected argument '%0' to '#pragma clang optimize'; "
+ "expected 'on' or 'off'">;
+def err_pragma_optimize_extra_argument : Error<
+ "unexpected extra argument '%0' to '#pragma clang optimize'">;
// OpenCL Section 6.8.g
def err_not_opencl_storage_class_specifier : Error<
Modified: cfe/trunk/include/clang/Parse/Parser.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/Parser.h?rev=209510&r1=209509&r2=209510&view=diff
==============================================================================
--- cfe/trunk/include/clang/Parse/Parser.h (original)
+++ cfe/trunk/include/clang/Parse/Parser.h Fri May 23 07:13:25 2014
@@ -160,6 +160,7 @@ class Parser : public CodeCompletionHand
std::unique_ptr<PragmaHandler> MSConstSeg;
std::unique_ptr<PragmaHandler> MSCodeSeg;
std::unique_ptr<PragmaHandler> MSSection;
+ std::unique_ptr<PragmaHandler> OptimizeHandler;
std::unique_ptr<CommentHandler> CommentSemaHandler;
Modified: cfe/trunk/include/clang/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=209510&r1=209509&r2=209510&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/Sema.h (original)
+++ cfe/trunk/include/clang/Sema/Sema.h Fri May 23 07:13:25 2014
@@ -333,6 +333,11 @@ public:
/// VisContext - Manages the stack for \#pragma GCC visibility.
void *VisContext; // Really a "PragmaVisStack*"
+ /// \brief This represents the last location of a "#pragma clang optimize off"
+ /// directive if such a directive has not been closed by an "on" yet. If
+ /// optimizations are currently "on", this is set to an invalid location.
+ SourceLocation OptimizeOffPragmaLocation;
+
/// \brief Flag indicating if Sema is building a recovery call expression.
///
/// This flag is used to avoid building recovery call expressions
@@ -7231,6 +7236,25 @@ public:
/// the appropriate attribute.
void AddCFAuditedAttribute(Decl *D);
+ /// \brief Called on well formed \#pragma clang optimize.
+ void ActOnPragmaOptimize(bool On, SourceLocation PragmaLoc);
+
+ /// \brief Get the location for the currently active "\#pragma clang optimize
+ /// off". If this location is invalid, then the state of the pragma is "on".
+ SourceLocation getOptimizeOffPragmaLocation() const {
+ return OptimizeOffPragmaLocation;
+ }
+
+ /// \brief Only called on function definitions; if there is a pragma in scope
+ /// with the effect of a range-based optnone, consider marking the function
+ /// with attribute optnone.
+ void AddRangeBasedOptnone(FunctionDecl *FD);
+
+ /// \brief Adds the 'optnone' attribute to the function declaration if there
+ /// are no conflicts; Loc represents the location causing the 'optnone'
+ /// attribute to be added (usually because of a pragma).
+ void AddOptnoneAttributeIfNoConflicts(FunctionDecl *FD, SourceLocation Loc);
+
/// AddAlignedAttr - Adds an aligned attribute to a particular declaration.
void AddAlignedAttr(SourceRange AttrRange, Decl *D, Expr *E,
unsigned SpellingListIndex, bool IsPackExpansion);
Modified: cfe/trunk/include/clang/Serialization/ASTBitCodes.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Serialization/ASTBitCodes.h?rev=209510&r1=209509&r2=209510&view=diff
==============================================================================
--- cfe/trunk/include/clang/Serialization/ASTBitCodes.h (original)
+++ cfe/trunk/include/clang/Serialization/ASTBitCodes.h Fri May 23 07:13:25 2014
@@ -542,7 +542,10 @@ namespace clang {
UNDEFINED_BUT_USED = 49,
/// \brief Record code for late parsed template functions.
- LATE_PARSED_TEMPLATE = 50
+ LATE_PARSED_TEMPLATE = 50,
+
+ /// \brief Record code for \#pragma optimize options.
+ OPTIMIZE_PRAGMA_OPTIONS = 51
};
/// \brief Record types used within a source manager block.
Modified: cfe/trunk/include/clang/Serialization/ASTReader.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Serialization/ASTReader.h?rev=209510&r1=209509&r2=209510&view=diff
==============================================================================
--- cfe/trunk/include/clang/Serialization/ASTReader.h (original)
+++ cfe/trunk/include/clang/Serialization/ASTReader.h Fri May 23 07:13:25 2014
@@ -768,6 +768,9 @@ private:
/// \brief The floating point pragma option settings.
SmallVector<uint64_t, 1> FPPragmaOptions;
+ /// \brief The pragma clang optimize location (if the pragma state is "off").
+ SourceLocation OptimizeOffPragmaLocation;
+
/// \brief The OpenCL extension settings.
SmallVector<uint64_t, 1> OpenCLExtensions;
Modified: cfe/trunk/include/clang/Serialization/ASTWriter.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Serialization/ASTWriter.h?rev=209510&r1=209509&r2=209510&view=diff
==============================================================================
--- cfe/trunk/include/clang/Serialization/ASTWriter.h (original)
+++ cfe/trunk/include/clang/Serialization/ASTWriter.h Fri May 23 07:13:25 2014
@@ -488,6 +488,7 @@ private:
void WriteRedeclarations();
void WriteMergedDecls();
void WriteLateParsedTemplates(Sema &SemaRef);
+ void WriteOptimizePragmaOptions(Sema &SemaRef);
unsigned DeclParmVarAbbrev;
unsigned DeclContextLexicalAbbrev;
Modified: cfe/trunk/lib/Parse/ParsePragma.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParsePragma.cpp?rev=209510&r1=209509&r2=209510&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParsePragma.cpp (original)
+++ cfe/trunk/lib/Parse/ParsePragma.cpp Fri May 23 07:13:25 2014
@@ -131,6 +131,16 @@ struct PragmaMSPragma : public PragmaHan
Token &FirstToken) override;
};
+/// PragmaOptimizeHandler - "\#pragma clang optimize on/off".
+struct PragmaOptimizeHandler : public PragmaHandler {
+ PragmaOptimizeHandler(Sema &S)
+ : PragmaHandler("optimize"), Actions(S) {}
+ void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,
+ Token &FirstToken) override;
+private:
+ Sema &Actions;
+};
+
} // end namespace
void Parser::initializePragmaHandlers() {
@@ -195,6 +205,9 @@ void Parser::initializePragmaHandlers()
MSSection.reset(new PragmaMSPragma("section"));
PP.AddPragmaHandler(MSSection.get());
}
+
+ OptimizeHandler.reset(new PragmaOptimizeHandler(Actions));
+ PP.AddPragmaHandler("clang", OptimizeHandler.get());
}
void Parser::resetPragmaHandlers() {
@@ -249,6 +262,9 @@ void Parser::resetPragmaHandlers() {
PP.RemovePragmaHandler("STDC", FPContractHandler.get());
FPContractHandler.reset();
+
+ PP.RemovePragmaHandler("clang", OptimizeHandler.get());
+ OptimizeHandler.reset();
}
/// \brief Handle the annotation token produced for #pragma unused(...)
@@ -1531,3 +1547,40 @@ void PragmaCommentHandler::HandlePragma(
Actions.ActOnPragmaMSComment(Kind, ArgumentString);
}
+
+// #pragma clang optimize off
+// #pragma clang optimize on
+void PragmaOptimizeHandler::HandlePragma(Preprocessor &PP,
+ PragmaIntroducerKind Introducer,
+ Token &FirstToken) {
+ Token Tok;
+ PP.Lex(Tok);
+ if (Tok.is(tok::eod)) {
+ PP.Diag(Tok.getLocation(), diag::err_pragma_optimize_missing_argument);
+ return;
+ }
+ if (Tok.isNot(tok::identifier)) {
+ PP.Diag(Tok.getLocation(), diag::err_pragma_optimize_invalid_argument)
+ << PP.getSpelling(Tok);
+ return;
+ }
+ const IdentifierInfo *II = Tok.getIdentifierInfo();
+ // The only accepted values are 'on' or 'off'.
+ bool IsOn = false;
+ if (II->isStr("on")) {
+ IsOn = true;
+ } else if (!II->isStr("off")) {
+ PP.Diag(Tok.getLocation(), diag::err_pragma_optimize_invalid_argument)
+ << PP.getSpelling(Tok);
+ return;
+ }
+ PP.Lex(Tok);
+
+ if (Tok.isNot(tok::eod)) {
+ PP.Diag(Tok.getLocation(), diag::err_pragma_optimize_extra_argument)
+ << PP.getSpelling(Tok);
+ return;
+ }
+
+ Actions.ActOnPragmaOptimize(IsOn, FirstToken.getLocation());
+}
Modified: cfe/trunk/lib/Sema/SemaAttr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaAttr.cpp?rev=209510&r1=209509&r2=209510&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaAttr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaAttr.cpp Fri May 23 07:13:25 2014
@@ -470,6 +470,34 @@ void Sema::AddCFAuditedAttribute(Decl *D
D->addAttr(CFAuditedTransferAttr::CreateImplicit(Context, Loc));
}
+void Sema::ActOnPragmaOptimize(bool On, SourceLocation PragmaLoc) {
+ if(On)
+ OptimizeOffPragmaLocation = SourceLocation();
+ else
+ OptimizeOffPragmaLocation = PragmaLoc;
+}
+
+void Sema::AddRangeBasedOptnone(FunctionDecl *FD) {
+ // In the future, check other pragmas if they're implemented (e.g. pragma
+ // optimize 0 will probably map to this functionality too).
+ if(OptimizeOffPragmaLocation.isValid())
+ AddOptnoneAttributeIfNoConflicts(FD, OptimizeOffPragmaLocation);
+}
+
+void Sema::AddOptnoneAttributeIfNoConflicts(FunctionDecl *FD,
+ SourceLocation Loc) {
+ // Don't add a conflicting attribute. No diagnostic is needed.
+ if (FD->hasAttr<MinSizeAttr>() || FD->hasAttr<AlwaysInlineAttr>())
+ return;
+
+ // Add attributes only if required. Optnone requires noinline as well, but if
+ // either is already present then don't bother adding them.
+ if (!FD->hasAttr<OptimizeNoneAttr>())
+ FD->addAttr(OptimizeNoneAttr::CreateImplicit(Context, Loc));
+ if (!FD->hasAttr<NoInlineAttr>())
+ FD->addAttr(NoInlineAttr::CreateImplicit(Context, Loc));
+}
+
typedef std::vector<std::pair<unsigned, SourceLocation> > VisStack;
enum : unsigned { NoVisibility = ~0U };
Modified: cfe/trunk/lib/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=209510&r1=209509&r2=209510&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDecl.cpp Fri May 23 07:13:25 2014
@@ -7373,6 +7373,11 @@ Sema::ActOnFunctionDeclarator(Scope *S,
// marking the function.
AddCFAuditedAttribute(NewFD);
+ // If this is a function definition, check if we have to apply optnone due to
+ // a pragma.
+ if(D.isFunctionDefinition())
+ AddRangeBasedOptnone(NewFD);
+
// If this is the first declaration of an extern C variable, update
// the map of such variables.
if (NewFD->isFirstDecl() && !NewFD->isInvalidDecl() &&
Modified: cfe/trunk/lib/Serialization/ASTReader.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReader.cpp?rev=209510&r1=209509&r2=209510&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTReader.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTReader.cpp Fri May 23 07:13:25 2014
@@ -3281,6 +3281,14 @@ ASTReader::ReadASTBlock(ModuleFile &F, u
LateParsedTemplates.append(Record.begin(), Record.end());
break;
}
+
+ case OPTIMIZE_PRAGMA_OPTIONS:
+ if (Record.size() != 1) {
+ Error("invalid pragma optimize record");
+ return Failure;
+ }
+ OptimizeOffPragmaLocation = ReadSourceLocation(F, Record[0]);
+ break;
}
}
}
@@ -6808,6 +6816,11 @@ void ASTReader::UpdateSema() {
}
SemaDeclRefs.clear();
}
+
+ // Update the state of 'pragma clang optimize'. Use the same API as if we had
+ // encountered the pragma in the source.
+ if(OptimizeOffPragmaLocation.isValid())
+ SemaObj->ActOnPragmaOptimize(/* IsOn = */ false, OptimizeOffPragmaLocation);
}
IdentifierInfo* ASTReader::get(const char *NameStart, const char *NameEnd) {
Modified: cfe/trunk/lib/Serialization/ASTWriter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTWriter.cpp?rev=209510&r1=209509&r2=209510&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTWriter.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTWriter.cpp Fri May 23 07:13:25 2014
@@ -866,6 +866,7 @@ void ASTWriter::WriteBlockInfoBlock() {
RECORD(MACRO_OFFSET);
RECORD(MACRO_TABLE);
RECORD(LATE_PARSED_TEMPLATE);
+ RECORD(OPTIMIZE_PRAGMA_OPTIONS);
// SourceManager Block.
BLOCK(SOURCE_MANAGER_BLOCK);
@@ -3850,6 +3851,14 @@ void ASTWriter::WriteLateParsedTemplates
Stream.EmitRecord(LATE_PARSED_TEMPLATE, Record);
}
+/// \brief Write the state of 'pragma clang optimize' at the end of the module.
+void ASTWriter::WriteOptimizePragmaOptions(Sema &SemaRef) {
+ RecordData Record;
+ SourceLocation PragmaLoc = SemaRef.getOptimizeOffPragmaLocation();
+ AddSourceLocation(PragmaLoc, Record);
+ Stream.EmitRecord(OPTIMIZE_PRAGMA_OPTIONS, Record);
+}
+
//===----------------------------------------------------------------------===//
// General Serialization Routines
//===----------------------------------------------------------------------===//
@@ -4466,6 +4475,8 @@ void ASTWriter::WriteASTCore(Sema &SemaR
WriteMergedDecls();
WriteObjCCategories();
WriteLateParsedTemplates(SemaRef);
+ if(!WritingModule)
+ WriteOptimizePragmaOptions(SemaRef);
// Some simple statistics
Record.clear();
Added: cfe/trunk/test/PCH/pragma-optimize.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/PCH/pragma-optimize.c?rev=209510&view=auto
==============================================================================
--- cfe/trunk/test/PCH/pragma-optimize.c (added)
+++ cfe/trunk/test/PCH/pragma-optimize.c Fri May 23 07:13:25 2014
@@ -0,0 +1,27 @@
+// Test this without pch.
+// RUN: %clang_cc1 %s -include %s -verify -fsyntax-only
+
+// Test with pch.
+// RUN: %clang_cc1 %s -emit-pch -o %t
+// RUN: %clang_cc1 %s -emit-llvm -include-pch %t -o - | FileCheck %s
+
+// expected-no-diagnostics
+
+#ifndef HEADER
+#define HEADER
+#pragma clang optimize off
+
+#else
+
+int a;
+
+void f() {
+ a = 12345;
+}
+
+// Check that the function is decorated with optnone
+
+// CHECK-DAG: @f() [[ATTRF:#[0-9]+]]
+// CHECK-DAG: attributes [[ATTRF]] = { {{.*}}noinline{{.*}}optnone{{.*}} }
+
+#endif
Added: cfe/trunk/test/Parser/pragma-optimize-diagnostics.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Parser/pragma-optimize-diagnostics.cpp?rev=209510&view=auto
==============================================================================
--- cfe/trunk/test/Parser/pragma-optimize-diagnostics.cpp (added)
+++ cfe/trunk/test/Parser/pragma-optimize-diagnostics.cpp Fri May 23 07:13:25 2014
@@ -0,0 +1,28 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+#pragma clang optimize off
+
+#pragma clang optimize on
+
+// Extra arguments
+#pragma clang optimize on top of spaghetti // expected-error {{unexpected extra argument 'top' to '#pragma clang optimize'}}
+
+// Wrong argument
+#pragma clang optimize something_wrong // expected-error {{unexpected argument 'something_wrong' to '#pragma clang optimize'; expected 'on' or 'off'}}
+
+// No argument
+#pragma clang optimize // expected-error {{missing argument to '#pragma clang optimize'; expected 'on' or 'off'}}
+
+// Check that macros can be used in the pragma
+#define OFF off
+#define ON on
+#pragma clang optimize OFF
+#pragma clang optimize ON
+
+// Check that _Pragma can also be used to address the use case where users want
+// to define optimization control macros to abstract out which compiler they are
+// using.
+#define OPT_OFF _Pragma("clang optimize off")
+#define OPT_ON _Pragma("clang optimize on")
+OPT_OFF
+OPT_ON
Added: cfe/trunk/test/SemaCXX/pragma-optimize.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/pragma-optimize.cpp?rev=209510&view=auto
==============================================================================
--- cfe/trunk/test/SemaCXX/pragma-optimize.cpp (added)
+++ cfe/trunk/test/SemaCXX/pragma-optimize.cpp Fri May 23 07:13:25 2014
@@ -0,0 +1,113 @@
+// RUN: %clang_cc1 -x c++ -std=c++11 -emit-llvm -O2 < %s | FileCheck %s
+
+#pragma clang optimize off
+
+// This is a macro definition and therefore its text is not present after
+// preprocessing. The pragma has no effect here.
+#define CREATE_FUNC(name) \
+int name (int param) { \
+ return param; \
+} \
+
+// This is a declaration and therefore it is not decorated with `optnone`.
+extern int foo(int a, int b);
+// CHECK-DAG: @_Z3fooii{{.*}} [[ATTRFOO:#[0-9]+]]
+
+// This is a definition and therefore it will be decorated with `optnone`.
+int bar(int x, int y) {
+ for(int i = 0; i < x; ++i)
+ y += x;
+ return y + foo(x, y);
+}
+// CHECK-DAG: @_Z3barii{{.*}} [[ATTRBAR:#[0-9]+]]
+
+// The function "int created (int param)" created by the macro invocation
+// is also decorated with the `optnone` attribute because it is within a
+// region of code affected by the functionality (not because of the position
+// of the macro definition).
+CREATE_FUNC (created)
+// CHECK-DAG: @_Z7createdi{{.*}} [[ATTRCREATED:#[0-9]+]]
+
+class MyClass {
+ public:
+ // The declaration of the method is not decorated with `optnone`.
+ int method(int blah);
+};
+
+// The definition of the method instead is decorated with `optnone`.
+int MyClass::method(int blah) {
+ return blah + 1;
+}
+// CHECK-DAG: @_ZN7MyClass6methodEi{{.*}} [[ATTRMETHOD:#[0-9]+]]
+
+// A template declaration will not be decorated with `optnone`.
+template <typename T> T twice (T param);
+
+// The template definition will be decorated with the attribute `optnone`.
+template <typename T> T thrice (T param) {
+ return 3 * param;
+}
+
+// This function definition will not be decorated with `optnone` because the
+// attribute would conflict with `always_inline`.
+int __attribute__((always_inline)) baz(int z) {
+ return foo(z, 2);
+}
+// CHECK-DAG: @_Z3bazi{{.*}} [[ATTRBAZ:#[0-9]+]]
+
+#pragma clang optimize on
+
+// The function "int wombat(int param)" created by the macro is not
+// decorated with `optnone`, because the pragma applies its effects only
+// after preprocessing. The position of the macro definition is not
+// relevant.
+CREATE_FUNC (wombat)
+// CHECK-DAG: @_Z6wombati{{.*}} [[ATTRWOMBAT:#[0-9]+]]
+
+// This instantiation of the "twice" template function with a "float" type
+// will not have an `optnone` attribute because the template declaration was
+// not affected by the pragma.
+float container (float par) {
+ return twice(par);
+}
+// CHECK-DAG: @_Z9containerf{{.*}} [[ATTRCONTAINER:#[0-9]+]]
+// CHECK-DAG: @_Z5twiceIfET_S0_{{.*}} [[ATTRTWICE:#[0-9]+]]
+
+// This instantiation of the "thrice" template function with a "float" type
+// will have an `optnone` attribute because the template definition was
+// affected by the pragma.
+float container2 (float par) {
+ return thrice(par);
+}
+// CHECK-DAG: @_Z10container2f{{.*}} [[ATTRCONTAINER2:#[0-9]+]]
+// CHECK-DAG: @_Z6thriceIfET_S0_{{.*}} [[ATTRTHRICEFLOAT:#[0-9]+]]
+
+
+// A template specialization is a new definition and it will not be
+// decorated with an `optnone` attribute because it is now outside of the
+// affected region.
+template<> int thrice(int par) {
+ return (par << 1) + par;
+}
+int container3 (int par) {
+ return thrice(par);
+}
+// CHECK-DAG: @_Z10container3i{{.*}} [[ATTRCONTAINER3:#[0-9]+]]
+// CHECK-DAG: @_Z6thriceIiET_S0_{{.*}} [[ATTRTHRICEINT:#[0-9]+]]
+
+
+// Check for both noinline and optnone on each function that should have them.
+// CHECK-DAG: attributes [[ATTRBAR]] = { {{.*}}noinline{{.*}}optnone{{.*}} }
+// CHECK-DAG: attributes [[ATTRCREATED]] = { {{.*}}noinline{{.*}}optnone{{.*}} }
+// CHECK-DAG: attributes [[ATTRMETHOD]] = { {{.*}}noinline{{.*}}optnone{{.*}} }
+// CHECK-DAG: attributes [[ATTRTHRICEFLOAT]] = { {{.*}}noinline{{.*}}optnone{{.*}} }
+
+// Check that the other functions do NOT have optnone.
+// CHECK-DAG-NOT: attributes [[ATTRFOO]] = { {{.*}}optnone{{.*}} }
+// CHECK-DAG-NOT: attributes [[ATTRBAZ]] = { {{.*}}optnone{{.*}} }
+// CHECK-DAG-NOT: attributes [[ATTRWOMBAT]] = { {{.*}}optnone{{.*}} }
+// CHECK-DAG-NOT: attributes [[ATTRCONTAINER]] = { {{.*}}optnone{{.*}} }
+// CHECK-DAG-NOT: attributes [[ATTRTWICE]] = { {{.*}}optnone{{.*}} }
+// CHECK-DAG-NOT: attributes [[ATTRCONTAINER2]] = { {{.*}}optnone{{.*}} }
+// CHECK-DAG-NOT: attributes [[ATTRCONTAINER3]] = { {{.*}}optnone{{.*}} }
+// CHECK-DAG-NOT: attributes [[ATTRTHRICEINT]] = { {{.*}}optnone{{.*}} }
More information about the cfe-commits
mailing list