Skip to content

Commit 5b2af16

Browse files
authored
[flang][Driver] Enables lto-partitions and fat-lto-object. (#158125)
1 parent f7b1b39 commit 5b2af16

File tree

9 files changed

+116
-27
lines changed

9 files changed

+116
-27
lines changed

clang/include/clang/Driver/Options.td

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3171,10 +3171,11 @@ def fthin_link_bitcode_EQ : Joined<["-"], "fthin-link-bitcode=">,
31713171
MarshallingInfoString<CodeGenOpts<"ThinLinkBitcodeFile">>;
31723172
defm fat_lto_objects : BoolFOption<"fat-lto-objects",
31733173
CodeGenOpts<"FatLTO">, DefaultFalse,
3174-
PosFlag<SetTrue, [], [ClangOption, CC1Option], "Enable">,
3175-
NegFlag<SetFalse, [], [ClangOption, CC1Option], "Disable">,
3174+
PosFlag<SetTrue, [], [ClangOption, CC1Option, FlangOption, FC1Option], "Enable">,
3175+
NegFlag<SetFalse, [], [ClangOption, CC1Option, FlangOption, FC1Option], "Disable">,
31763176
BothFlags<[], [ClangOption, CC1Option], " fat LTO object support">>;
31773177
def flto_partitions_EQ : Joined<["-"], "flto-partitions=">, Group<f_Group>,
3178+
Visibility<[ClangOption, FlangOption]>,
31783179
HelpText<"Number of partitions to use for parallel full LTO codegen, ld.lld only.">;
31793180
def fmacro_backtrace_limit_EQ : Joined<["-"], "fmacro-backtrace-limit=">,
31803181
Group<f_Group>, Visibility<[ClangOption, CC1Option, CLOption]>,

clang/lib/Driver/ToolChains/Flang.cpp

Lines changed: 20 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,25 @@ void Flang::addCodegenOptions(const ArgList &Args,
190190
CmdArgs.push_back("-fcoarray");
191191
}
192192

193+
void Flang::addLTOOptions(const ArgList &Args, ArgStringList &CmdArgs) const {
194+
const ToolChain &TC = getToolChain();
195+
const Driver &D = TC.getDriver();
196+
DiagnosticsEngine &Diags = D.getDiags();
197+
LTOKind LTOMode = D.getLTOMode();
198+
// LTO mode is parsed by the Clang driver library.
199+
assert(LTOMode != LTOK_Unknown && "Unknown LTO mode.");
200+
if (LTOMode == LTOK_Full)
201+
CmdArgs.push_back("-flto=full");
202+
else if (LTOMode == LTOK_Thin) {
203+
Diags.Report(
204+
Diags.getCustomDiagID(DiagnosticsEngine::Warning,
205+
"the option '-flto=thin' is a work in progress"));
206+
CmdArgs.push_back("-flto=thin");
207+
}
208+
Args.addAllArgs(CmdArgs, {options::OPT_ffat_lto_objects,
209+
options::OPT_fno_fat_lto_objects});
210+
}
211+
193212
void Flang::addPicOptions(const ArgList &Args, ArgStringList &CmdArgs) const {
194213
// ParsePICArgs parses -fPIC/-fPIE and their variants and returns a tuple of
195214
// (RelocationModel, PICLevel, IsPIE).
@@ -829,7 +848,6 @@ void Flang::ConstructJob(Compilation &C, const JobAction &JA,
829848

830849
const Driver &D = TC.getDriver();
831850
ArgStringList CmdArgs;
832-
DiagnosticsEngine &Diags = D.getDiags();
833851

834852
// Invoke ourselves in -fc1 mode.
835853
CmdArgs.push_back("-fc1");
@@ -892,17 +910,7 @@ void Flang::ConstructJob(Compilation &C, const JobAction &JA,
892910

893911
handleColorDiagnosticsArgs(D, Args, CmdArgs);
894912

895-
// LTO mode is parsed by the Clang driver library.
896-
LTOKind LTOMode = D.getLTOMode();
897-
assert(LTOMode != LTOK_Unknown && "Unknown LTO mode.");
898-
if (LTOMode == LTOK_Full)
899-
CmdArgs.push_back("-flto=full");
900-
else if (LTOMode == LTOK_Thin) {
901-
Diags.Report(
902-
Diags.getCustomDiagID(DiagnosticsEngine::Warning,
903-
"the option '-flto=thin' is a work in progress"));
904-
CmdArgs.push_back("-flto=thin");
905-
}
913+
addLTOOptions(Args, CmdArgs);
906914

907915
// -fPIC and related options.
908916
addPicOptions(Args, CmdArgs);

clang/lib/Driver/ToolChains/Flang.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,14 @@ class LLVM_LIBRARY_VISIBILITY Flang : public Tool {
4040
void addPreprocessingOptions(const llvm::opt::ArgList &Args,
4141
llvm::opt::ArgStringList &CmdArgs) const;
4242

43+
/// Extract LTO options from the driver arguments and add them to
44+
/// the command arguments.
45+
///
46+
/// \param [in] Args The list of input driver arguments
47+
/// \param [out] CmdArgs The list of output command arguments
48+
void addLTOOptions(const llvm::opt::ArgList &Args,
49+
llvm::opt::ArgStringList &CmdArgs) const;
50+
4351
/// Extract PIC options from the driver arguments and add them to
4452
/// the command arguments.
4553
///

flang/include/flang/Frontend/CodeGenOptions.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ CODEGENOPT(InstrumentFunctions, 1, 0) ///< Set when -finstrument_functions is
3535

3636
CODEGENOPT(IsPIE, 1, 0) ///< PIE level is the same as PIC Level.
3737
CODEGENOPT(PICLevel, 2, 0) ///< PIC level of the LLVM module.
38+
CODEGENOPT(PrepareForFatLTO , 1, 0) ///< Set when -ffat-lto-objects is enabled.
3839
CODEGENOPT(PrepareForFullLTO , 1, 0) ///< Set when -flto is enabled on the
3940
///< compile step.
4041
CODEGENOPT(PrepareForThinLTO , 1, 0) ///< Set when -flto=thin is enabled on the

flang/lib/Frontend/CompilerInvocation.cpp

Lines changed: 29 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -332,17 +332,6 @@ static void parseCodeGenArgs(Fortran::frontend::CodeGenOptions &opts,
332332
if (args.hasArg(clang::driver::options::OPT_finstrument_functions))
333333
opts.InstrumentFunctions = 1;
334334

335-
// -flto=full/thin option.
336-
if (const llvm::opt::Arg *a =
337-
args.getLastArg(clang::driver::options::OPT_flto_EQ)) {
338-
llvm::StringRef s = a->getValue();
339-
assert((s == "full" || s == "thin") && "Unknown LTO mode.");
340-
if (s == "full")
341-
opts.PrepareForFullLTO = true;
342-
else
343-
opts.PrepareForThinLTO = true;
344-
}
345-
346335
if (const llvm::opt::Arg *a = args.getLastArg(
347336
clang::driver::options::OPT_mcode_object_version_EQ)) {
348337
llvm::StringRef s = a->getValue();
@@ -1489,6 +1478,7 @@ static bool parseLinkerOptionsArgs(CompilerInvocation &invoc,
14891478
llvm::opt::ArgList &args,
14901479
clang::DiagnosticsEngine &diags) {
14911480
llvm::Triple triple = llvm::Triple(invoc.getTargetOpts().triple);
1481+
CodeGenOptions &opts = invoc.getCodeGenOpts();
14921482

14931483
// TODO: support --dependent-lib on other platforms when MLIR supports
14941484
// !llvm.dependent.lib
@@ -1501,8 +1491,35 @@ static bool parseLinkerOptionsArgs(CompilerInvocation &invoc,
15011491
return false;
15021492
}
15031493

1504-
invoc.getCodeGenOpts().DependentLibs =
1494+
opts.DependentLibs =
15051495
args.getAllArgValues(clang::driver::options::OPT_dependent_lib);
1496+
1497+
// -flto=full/thin option.
1498+
if (const llvm::opt::Arg *a =
1499+
args.getLastArg(clang::driver::options::OPT_flto_EQ)) {
1500+
llvm::StringRef s = a->getValue();
1501+
assert((s == "full" || s == "thin") && "Unknown LTO mode.");
1502+
if (s == "full")
1503+
opts.PrepareForFullLTO = true;
1504+
else
1505+
opts.PrepareForThinLTO = true;
1506+
}
1507+
1508+
// -ffat-lto-objects
1509+
if (const llvm::opt::Arg *arg =
1510+
args.getLastArg(clang::driver::options::OPT_ffat_lto_objects,
1511+
clang::driver::options::OPT_fno_fat_lto_objects)) {
1512+
opts.PrepareForFatLTO =
1513+
arg->getOption().matches(clang::driver::options::OPT_ffat_lto_objects);
1514+
if (opts.PrepareForFatLTO) {
1515+
assert((opts.PrepareForFullLTO || opts.PrepareForThinLTO) &&
1516+
"Unknown LTO mode");
1517+
1518+
if (!triple.isOSBinFormatELF())
1519+
diags.Report(clang::diag::err_drv_unsupported_opt_for_target)
1520+
<< arg->getAsString(args) << triple.getTriple();
1521+
}
1522+
}
15061523
return true;
15071524
}
15081525

flang/lib/Frontend/FrontendActions.cpp

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -996,7 +996,14 @@ void CodeGenAction::runOptimizationPipeline(llvm::raw_pwrite_stream &os) {
996996

997997
// Create the pass manager.
998998
llvm::ModulePassManager mpm;
999-
if (opts.PrepareForFullLTO)
999+
if (opts.PrepareForFatLTO) {
1000+
// The module summary should be emitted by default for regular LTO
1001+
// except for ld64 targets.
1002+
bool emitSummary = opts.PrepareForThinLTO || opts.PrepareForFullLTO ||
1003+
triple.getVendor() != llvm::Triple::Apple;
1004+
mpm = pb.buildFatLTODefaultPipeline(level, opts.PrepareForThinLTO,
1005+
emitSummary);
1006+
} else if (opts.PrepareForFullLTO)
10001007
mpm = pb.buildLTOPreLinkDefaultPipeline(level);
10011008
else if (opts.PrepareForThinLTO)
10021009
mpm = pb.buildThinLTOPreLinkDefaultPipeline(level);

flang/test/Driver/fatlto-err.f90

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
! RUN: not %flang_fc1 -triple x86_64-apple-macos10.13 -flto -ffat-lto-objects -emit-llvm-bc %s 2>&1 | FileCheck %s --check-prefix=ERROR
2+
! ERROR: error: unsupported option '-ffat-lto-objects' for target 'x86_64-apple-macos10.13'
3+
4+
parameter(i=1)
5+
integer :: j
6+
end program

flang/test/Driver/lto-fatlto.f90

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
! REQUIRES: x86-registered-target
2+
! checks fatlto objects: that valid bitcode is included in the object file generated.
3+
4+
! RUN: %flang -fc1 -triple x86_64-unknown-linux-gnu -flto -ffat-lto-objects -emit-obj %s -o %t.o
5+
! RUN: llvm-readelf -S %t.o | FileCheck %s --check-prefixes=ELF
6+
! RUN: llvm-objcopy --dump-section=.llvm.lto=%t.bc %t.o
7+
! RUN: llvm-dis %t.bc -o - | FileCheck %s --check-prefixes=DIS
8+
9+
! ELF: .llvm.lto
10+
! DIS: define void @_QQmain()
11+
! DIS-NEXT: ret void
12+
! DIS-NEXT: }
13+
14+
! RUN: %flang -fc1 -triple x86_64-unknown-linux-gnu -flto -ffat-lto-objects -S %s -o - | FileCheck %s --check-prefixes=ASM
15+
16+
! ASM: .section .llvm.lto,"e",@llvm_lto
17+
! ASM-NEXT: .Lllvm.embedded.object:
18+
! ASM-NEXT: .asciz "BC
19+
! ASM-NEXT: .size .Lllvm.embedded.object
20+
program test
21+
end program
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
! UNSUPPORTED: system-windows
2+
! check flto-partitions is passed to lld, and not to fc1
3+
! RUN: %flang -### -fuse-ld=lld -flto=full -flto-partitions=16 %s 2>&1 | FileCheck %s --check-prefixes=LLD-PART,FC1-PART
4+
5+
! FC1-PART: "-fc1"
6+
! FC1-PART-SAME: "-flto=full"
7+
! NOT-FC1-PART-SAME: "-flto-partitions=16"
8+
! LLD-PART: ld.lld
9+
! LLD-PART-SAME: "--lto-partitions=16"
10+
11+
! check fat-lto-objects is passed to lld, fc1
12+
! RUN: %flang -### -fuse-ld=lld -flto -ffat-lto-objects %s 2>&1 | FileCheck %s --check-prefixes=LLD-FAT,FC1-FAT
13+
14+
! FC1-FAT: "-fc1"
15+
! FC1-FAT-SAME: "-flto=full"
16+
! FC1-FAT-SAME: "-ffat-lto-objects"
17+
! LLD-FAT: ld.lld
18+
! LLD-FAT-SAME: "--fat-lto-objects"
19+
program test
20+
end program

0 commit comments

Comments
 (0)