diff --git a/include/swift/ClangImporter/ClangImporterOptions.h b/include/swift/ClangImporter/ClangImporterOptions.h index b3da68c7b8e..90847704678 100644 --- a/include/swift/ClangImporter/ClangImporterOptions.h +++ b/include/swift/ClangImporter/ClangImporterOptions.h @@ -47,6 +47,10 @@ public: /// header, place it in this directory. std::string PrecompiledHeaderOutputDir; + /// The optimizaton setting. This doesn't typically matter for + /// import, but it can affect Clang's IR generation of static functions. + std::string Optimization; + /// Disable validating the persistent PCH. bool PCHDisableValidation = false; diff --git a/lib/ClangImporter/ClangImporter.cpp b/lib/ClangImporter/ClangImporter.cpp index bb108427c58..3a41a476b0b 100644 --- a/lib/ClangImporter/ClangImporter.cpp +++ b/lib/ClangImporter/ClangImporter.cpp @@ -686,6 +686,10 @@ addCommonInvocationArguments(std::vector &invocationArgStrs, invocationArgStrs.push_back("-march=z196"); } + if (!importerOpts.Optimization.empty()) { + invocationArgStrs.push_back(importerOpts.Optimization); + } + const std::string &overrideResourceDir = importerOpts.OverrideResourceDir; if (overrideResourceDir.empty()) { llvm::SmallString<128> resourceDir(searchPathOpts.RuntimeResourcePath); @@ -868,6 +872,7 @@ ClangImporter::create(ASTContext &ctx, } std::vector invocationArgs; + invocationArgs.reserve(invocationArgStrs.size()); for (auto &argStr : invocationArgStrs) invocationArgs.push_back(argStr.c_str()); diff --git a/lib/Frontend/CompilerInvocation.cpp b/lib/Frontend/CompilerInvocation.cpp index 51b7e4e3771..40d261bdab3 100644 --- a/lib/Frontend/CompilerInvocation.cpp +++ b/lib/Frontend/CompilerInvocation.cpp @@ -1352,7 +1352,8 @@ static bool ParseSILArgs(SILOptions &Opts, ArgList &Args, IRGenOptions &IRGenOpts, FrontendOptions &FEOpts, DiagnosticEngine &Diags, - const llvm::Triple &Triple) { + const llvm::Triple &Triple, + ClangImporterOptions &ClangOpts) { using namespace options; if (const Arg *A = Args.getLastArg(OPT_sil_inline_threshold)) { @@ -1408,6 +1409,10 @@ static bool ParseSILArgs(SILOptions &Opts, ArgList &Args, IRGenOpts.Optimize = true; Opts.Optimization = SILOptions::SILOptMode::Optimize; } + + if (IRGenOpts.Optimize) { + ClangOpts.Optimization = "-Os"; + } } if (Args.getLastArg(OPT_AssumeSingleThreaded)) { @@ -1799,7 +1804,7 @@ bool CompilerInvocation::parseArgs(ArrayRef Args, } if (ParseSILArgs(SILOpts, ParsedArgs, IRGenOpts, FrontendOpts, Diags, - LangOpts.Target)) { + LangOpts.Target, ClangImporterOpts)) { return true; } diff --git a/test/IRGen/Inputs/c_functions.h b/test/IRGen/Inputs/c_functions.h index e0b423983de..b613f89e3b7 100644 --- a/test/IRGen/Inputs/c_functions.h +++ b/test/IRGen/Inputs/c_functions.h @@ -20,3 +20,7 @@ static inline void log_a_thing(const a_thing thing) { useInt(thing.val[0]); useInt(thing.val[7]); } + +static inline unsigned int return7(void) { + return 7; +} diff --git a/test/IRGen/clang_inline_opt.swift b/test/IRGen/clang_inline_opt.swift new file mode 100644 index 00000000000..11a91a91835 --- /dev/null +++ b/test/IRGen/clang_inline_opt.swift @@ -0,0 +1,14 @@ +// RUN: %target-swift-frontend -import-objc-header %S/Inputs/c_functions.h -primary-file %s -O -emit-ir -disable-llvm-optzns | %FileCheck %s + +func return10() -> UInt32 { + return return7() + 3 +} + +// Sanity check that we tell Clang to generate optimizable code when +// we're optimizing. + +// CHECK: define internal i32 @return7() [[CLANG_ATTRS:#[0-9]+]] { + +// CHECK: attributes [[CLANG_ATTRS]] = { +// CHECK-NOT: noinline +// CHECK-SAME: }