Index: clang/include/clang/Driver/Options.td =================================================================== --- clang/include/clang/Driver/Options.td +++ clang/include/clang/Driver/Options.td @@ -2194,13 +2194,13 @@ def flimited_precision_EQ : Joined<["-"], "flimited-precision=">, Group; def fapple_link_rtlib : Flag<["-"], "fapple-link-rtlib">, Group, HelpText<"Force linking the clang builtins runtime library">; -def flto_EQ : Joined<["-"], "flto=">, Flags<[CoreOption, CC1Option]>, Group, +def flto_EQ : Joined<["-"], "flto=">, Flags<[CoreOption, CC1Option, FC1Option, FlangOption]>, Group, HelpText<"Set LTO mode">, Values<"thin,full">; def flto_EQ_jobserver : Flag<["-"], "flto=jobserver">, Group, Alias, AliasArgs<["full"]>, HelpText<"Enable LTO in 'full' mode">; def flto_EQ_auto : Flag<["-"], "flto=auto">, Group, Alias, AliasArgs<["full"]>, HelpText<"Enable LTO in 'full' mode">; -def flto : Flag<["-"], "flto">, Flags<[CoreOption, CC1Option]>, Group, +def flto : Flag<["-"], "flto">, Flags<[CoreOption, CC1Option, FC1Option, FlangOption]>, Group, Alias, AliasArgs<["full"]>, HelpText<"Enable LTO in 'full' mode">; def fno_lto : Flag<["-"], "fno-lto">, Flags<[CoreOption, CC1Option]>, Group, HelpText<"Disable LTO mode (default)">; Index: clang/lib/Driver/ToolChains/Flang.cpp =================================================================== --- clang/lib/Driver/ToolChains/Flang.cpp +++ clang/lib/Driver/ToolChains/Flang.cpp @@ -294,6 +294,13 @@ if (D.getDiags().getDiagnosticOptions().ShowColors) CmdArgs.push_back("-fcolor-diagnostics"); + LTOKind LTOMode = D.getLTOMode(/* IsOffload */ false); + assert(LTOMode != LTOK_Unknown && "Unknown LTO mode."); + if (LTOMode == LTOK_Full) + CmdArgs.push_back("-flto=full"); + else if (LTOMode == LTOK_Thin) + CmdArgs.push_back("-flto=thin"); + // -fPIC and related options. addPicOptions(Args, CmdArgs); Index: flang/include/flang/Frontend/CodeGenOptions.def =================================================================== --- flang/include/flang/Frontend/CodeGenOptions.def +++ flang/include/flang/Frontend/CodeGenOptions.def @@ -24,8 +24,13 @@ CODEGENOPT(DebugPassManager, 1, 0) ///< Prints debug information for the new ///< pass manager. -CODEGENOPT(PICLevel, 2, 0) ///< PIC level of the LLVM module. CODEGENOPT(IsPIE, 1, 0) ///< PIE level is the same as PIC Level. +CODEGENOPT(PICLevel, 2, 0) ///< PIC level of the LLVM module. + +CODEGENOPT(PrepareForFullLTO , 1, 0) ///< Set when -flto is enabled on the + ///< compile step. +CODEGENOPT(PrepareForThinLTO , 1, 0) ///< Set when -flto=thin is enabled on the + ///< compile step. ENUM_CODEGENOPT(RelocationModel, llvm::Reloc::Model, 3, llvm::Reloc::PIC_) ///< Name of the relocation model to use. Index: flang/lib/Frontend/CompilerInvocation.cpp =================================================================== --- flang/lib/Frontend/CompilerInvocation.cpp +++ flang/lib/Frontend/CompilerInvocation.cpp @@ -129,6 +129,19 @@ for (auto *a : args.filtered(clang::driver::options::OPT_fpass_plugin_EQ)) opts.LLVMPassPlugins.push_back(a->getValue()); + // -flto=full/thin option. + if (const llvm::opt::Arg *A = + args.getLastArg(clang::driver::options::OPT_flto_EQ)) { + llvm::StringRef S = A->getValue(); + if (S == "full") + opts.PrepareForFullLTO = true; + else if (S == "thin") + opts.PrepareForThinLTO = true; + else + diags.Report(clang::diag::err_drv_unsupported_option_argument) + << A->getAsString(args) << S; + } + // -mrelocation-model option. if (const llvm::opt::Arg *A = args.getLastArg(clang::driver::options::OPT_mrelocation_model)) { Index: flang/lib/Frontend/FrontendActions.cpp =================================================================== --- flang/lib/Frontend/FrontendActions.cpp +++ flang/lib/Frontend/FrontendActions.cpp @@ -714,7 +714,12 @@ // Create the pass manager. llvm::ModulePassManager mpm; if (opts.OptimizationLevel == 0) - mpm = pb.buildO0DefaultPipeline(level, false); + mpm = pb.buildO0DefaultPipeline(level, opts.PrepareForFullLTO || + opts.PrepareForThinLTO); + else if (opts.PrepareForFullLTO) + mpm = pb.buildLTOPreLinkDefaultPipeline(level); + else if (opts.PrepareForThinLTO) + mpm = pb.buildThinLTOPreLinkDefaultPipeline(level); else mpm = pb.buildPerModuleDefaultPipeline(level); Index: flang/test/Driver/default-optimization-pipelines.f90 =================================================================== --- flang/test/Driver/default-optimization-pipelines.f90 +++ flang/test/Driver/default-optimization-pipelines.f90 @@ -1,10 +1,18 @@ ! Verify that`-O{n}` is indeed taken into account when defining the LLVM optimization/middle-end pass pipeline. ! RUN: %flang -S -O0 %s -Xflang -fdebug-pass-manager -o /dev/null 2>&1 | FileCheck %s --check-prefix=CHECK-O0 +! RUN: %flang -S -O0 %s -flto -Xflang -fdebug-pass-manager -o /dev/null 2>&1 | FileCheck %s --check-prefix=CHECK-O0-ANYLTO +! RUN: %flang -S -O0 %s -flto=thin -Xflang -fdebug-pass-manager -o /dev/null 2>&1 | FileCheck %s --check-prefix=CHECK-O0-ANYLTO ! RUN: %flang_fc1 -S -O0 %s -fdebug-pass-manager -o /dev/null 2>&1 | FileCheck %s --check-prefix=CHECK-O0 +! RUN: %flang_fc1 -S -O0 %s -flto=full -fdebug-pass-manager -o /dev/null 2>&1 | FileCheck %s --check-prefix=CHECK-O0-ANYLTO +! RUN: %flang_fc1 -S -O0 %s -flto=thin -fdebug-pass-manager -o /dev/null 2>&1 | FileCheck %s --check-prefix=CHECK-O0-ANYLTO ! RUN: %flang -S -O2 %s -Xflang -fdebug-pass-manager -o /dev/null 2>&1 | FileCheck %s --check-prefix=CHECK-O2 +! RUN: %flang -S -O2 %s -flto -Xflang -fdebug-pass-manager -o /dev/null 2>&1 | FileCheck %s --check-prefix=CHECK-O2-LTO +! RUN: %flang -S -O2 %s -flto=thin -Xflang -fdebug-pass-manager -o /dev/null 2>&1 | FileCheck %s --check-prefix=CHECK-O2-THINLTO ! RUN: %flang_fc1 -S -O2 %s -fdebug-pass-manager -o /dev/null 2>&1 | FileCheck %s --check-prefix=CHECK-O2 +! RUN: %flang_fc1 -S -O2 %s -flto=full -fdebug-pass-manager -o /dev/null 2>&1 | FileCheck %s --check-prefix=CHECK-O2-LTO +! RUN: %flang_fc1 -S -O2 %s -flto=thin -fdebug-pass-manager -o /dev/null 2>&1 | FileCheck %s --check-prefix=CHECK-O2-THINLTO ! Verify that only the left-most `-O{n}` is used ! RUN: %flang -S -O2 -O0 %s -Xflang -fdebug-pass-manager -o /dev/null 2>&1 | FileCheck %s --check-prefix=CHECK-O0 @@ -12,9 +20,19 @@ ! CHECK-O0-NOT: Running pass: SimplifyCFGPass on simple_loop_ ! CHECK-O0: Running analysis: TargetLibraryAnalysis on simple_loop_ +! CHECK-O0-ANYLTO: Running pass: CanonicalizeAliasesPass on [module] +! CHECK-O0-ANYLTO: Running pass: NameAnonGlobalPass on [module] ! CHECK-O2: Running pass: SimplifyCFGPass on simple_loop_ +! CHECK-O2-LTO-NOT: Running pass: EliminateAvailableExternallyPass +! CHECK-O2-LTO: Running pass: CanonicalizeAliasesPass on [module] +! CHECK-O2-LTO: Running pass: NameAnonGlobalPass on [module] + +! CHECK-O2-THINLTO-NOT: Running pass: LoopVectorizePass +! CHECK-O2-THINLTO: Running pass: CanonicalizeAliasesPass on [module] +! CHECK-O2-THINLTO: Running pass: NameAnonGlobalPass on [module] + subroutine simple_loop integer :: i do i=1,5 Index: flang/test/Driver/driver-help-hidden.f90 =================================================================== --- flang/test/Driver/driver-help-hidden.f90 +++ flang/test/Driver/driver-help-hidden.f90 @@ -43,6 +43,8 @@ ! CHECK-NEXT: Enable support for generating executables (experimental) ! CHECK-NEXT: -flarge-sizes Use INTEGER(KIND=8) for the result type in size-related intrinsics ! CHECK-NEXT: -flogical-abbreviations Enable logical abbreviations +! CHECK-NEXT: -flto= Set LTO mode +! CHECK-NEXT: -flto Enable LTO in 'full' mode ! CHECK-NEXT: -fno-automatic Implies the SAVE attribute for non-automatic local objects in subprograms unless RECURSIVE ! CHECK-NEXT: -fno-color-diagnostics Disable colors in diagnostics ! CHECK-NEXT: -fno-integrated-as Disable the integrated assembler Index: flang/test/Driver/driver-help.f90 =================================================================== --- flang/test/Driver/driver-help.f90 +++ flang/test/Driver/driver-help.f90 @@ -41,6 +41,8 @@ ! HELP-NEXT: Specify where to find the compiled intrinsic modules ! HELP-NEXT: -flarge-sizes Use INTEGER(KIND=8) for the result type in size-related intrinsics ! HELP-NEXT: -flogical-abbreviations Enable logical abbreviations +! HELP-NEXT: -flto= Set LTO mode +! HELP-NEXT: -flto Enable LTO in 'full' mode ! HELP-NEXT: -fno-automatic Implies the SAVE attribute for non-automatic local objects in subprograms unless RECURSIVE ! HELP-NEXT: -fno-color-diagnostics Disable colors in diagnostics ! HELP-NEXT: -fno-integrated-as Disable the integrated assembler @@ -124,6 +126,8 @@ ! HELP-FC1-NEXT: Specify where to find the compiled intrinsic modules ! HELP-FC1-NEXT: -flarge-sizes Use INTEGER(KIND=8) for the result type in size-related intrinsics ! HELP-FC1-NEXT: -flogical-abbreviations Enable logical abbreviations +! HELP-FC1-NEXT: -flto= Set LTO mode +! HELP-FC1-NEXT: -flto Enable LTO in 'full' mode ! HELP-FC1-NEXT: -fno-analyzed-objects-for-unparse ! HELP-FC1-NEXT: Do not use the analyzed objects when unparsing ! HELP-FC1-NEXT: -fno-automatic Implies the SAVE attribute for non-automatic local objects in subprograms unless RECURSIVE Index: flang/test/Driver/lto-flags.f90 =================================================================== --- /dev/null +++ flang/test/Driver/lto-flags.f90 @@ -0,0 +1,19 @@ +! RUN: %flang -### -S -flto %s 2>&1 | FileCheck %s --check-prefix=FULL-LTO +! RUN: %flang -### -S -flto=full %s 2>&1 | FileCheck %s --check-prefix=FULL-LTO +! RUN: %flang -### -S -flto=thin %s 2>&1 | FileCheck %s --check-prefix=THIN-LTO +! RUN: %flang -### -S -flto=somelto %s 2>&1 | FileCheck %s --check-prefix=ERROR + +! Check that it does not crash. +! RUN: %flang_fc1 -S %s -flto -o /dev/null +! RUN: %flang_fc1 -S %s -flto=full -o /dev/null +! RUN: %flang_fc1 -S %s -flto=thin -o /dev/null + +! RUN: not %flang_fc1 -S %s -flto=somelto -o /dev/null 2>&1 | FileCheck %s --check-prefix=ERROR + +! FULL-LTO: "-fc1" +! FULL-LTO-SAME: "-flto=full" +! THIN-LTO: "-fc1" +! THIN-LTO-SAME: "-flto=thin" + + +! ERROR: error: unsupported argument 'somelto' to option '-flto=