Skip to content

Commit ea6cf52

Browse files
committed
[flang-rt] Re-implement driver code of how flang-rt path is built.
1 parent 660ec19 commit ea6cf52

27 files changed

+206
-125
lines changed

clang/include/clang/Driver/ToolChain.h

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -216,8 +216,8 @@ class ToolChain {
216216

217217
virtual std::string buildCompilerRTBasename(const llvm::opt::ArgList &Args,
218218
StringRef Component,
219-
FileType Type,
220-
bool AddArch) const;
219+
FileType Type, bool AddArch,
220+
bool IsFortran = false) const;
221221

222222
/// Find the target-specific subdirectory for the current target triple under
223223
/// \p BaseDir, doing fallback triple searches as necessary.
@@ -509,11 +509,22 @@ class ToolChain {
509509

510510
virtual std::string getCompilerRT(const llvm::opt::ArgList &Args,
511511
StringRef Component,
512-
FileType Type = ToolChain::FT_Static) const;
512+
FileType Type = ToolChain::FT_Static,
513+
bool IsFortran = false) const;
514+
515+
/// Adds Fortran runtime libraries to \p CmdArgs.
516+
virtual void addFortranRuntimeLibs(const llvm::opt::ArgList &Args,
517+
llvm::opt::ArgStringList &CmdArgs) const;
518+
519+
/// Adds the path for the Fortran runtime libraries to \p CmdArgs.
520+
virtual void
521+
addFortranRuntimeLibraryPath(const llvm::opt::ArgList &Args,
522+
llvm::opt::ArgStringList &CmdArgs) const;
513523

514-
const char *
515-
getCompilerRTArgString(const llvm::opt::ArgList &Args, StringRef Component,
516-
FileType Type = ToolChain::FT_Static) const;
524+
const char *getCompilerRTArgString(const llvm::opt::ArgList &Args,
525+
StringRef Component,
526+
FileType Type = ToolChain::FT_Static,
527+
bool IsFortran = false) const;
517528

518529
std::string getCompilerRTBasename(const llvm::opt::ArgList &Args,
519530
StringRef Component,

clang/lib/Driver/ToolChain.cpp

Lines changed: 70 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -733,8 +733,8 @@ std::string ToolChain::getCompilerRTBasename(const ArgList &Args,
733733

734734
std::string ToolChain::buildCompilerRTBasename(const llvm::opt::ArgList &Args,
735735
StringRef Component,
736-
FileType Type,
737-
bool AddArch) const {
736+
FileType Type, bool AddArch,
737+
bool IsFortran) const {
738738
const llvm::Triple &TT = getTriple();
739739
bool IsITANMSVCWindows =
740740
TT.isWindowsMSVCEnvironment() || TT.isWindowsItaniumEnvironment();
@@ -762,14 +762,16 @@ std::string ToolChain::buildCompilerRTBasename(const llvm::opt::ArgList &Args,
762762
const char *Env = TT.isAndroid() ? "-android" : "";
763763
ArchAndEnv = ("-" + Arch + Env).str();
764764
}
765-
return (Prefix + Twine("clang_rt.") + Component + ArchAndEnv + Suffix).str();
765+
766+
std::string LibName = IsFortran ? "flang_rt." : "clang_rt.";
767+
return (Prefix + Twine(LibName) + Component + ArchAndEnv + Suffix).str();
766768
}
767769

768770
std::string ToolChain::getCompilerRT(const ArgList &Args, StringRef Component,
769-
FileType Type) const {
771+
FileType Type, bool IsFortran) const {
770772
// Check for runtime files in the new layout without the architecture first.
771-
std::string CRTBasename =
772-
buildCompilerRTBasename(Args, Component, Type, /*AddArch=*/false);
773+
std::string CRTBasename = buildCompilerRTBasename(
774+
Args, Component, Type, /*AddArch=*/false, IsFortran);
773775
SmallString<128> Path;
774776
for (const auto &LibPath : getLibraryPaths()) {
775777
SmallString<128> P(LibPath);
@@ -783,8 +785,8 @@ std::string ToolChain::getCompilerRT(const ArgList &Args, StringRef Component,
783785
Path.clear();
784786

785787
// Check the filename for the old layout if the new one does not exist.
786-
CRTBasename =
787-
buildCompilerRTBasename(Args, Component, Type, /*AddArch=*/true);
788+
CRTBasename = buildCompilerRTBasename(Args, Component, Type,
789+
/*AddArch=*/!IsFortran, IsFortran);
788790
SmallString<128> OldPath(getCompilerRTPath());
789791
llvm::sys::path::append(OldPath, CRTBasename);
790792
if (Path.empty() || getVFS().exists(OldPath))
@@ -798,8 +800,66 @@ std::string ToolChain::getCompilerRT(const ArgList &Args, StringRef Component,
798800

799801
const char *ToolChain::getCompilerRTArgString(const llvm::opt::ArgList &Args,
800802
StringRef Component,
801-
FileType Type) const {
802-
return Args.MakeArgString(getCompilerRT(Args, Component, Type));
803+
FileType Type,
804+
bool isFortran) const {
805+
return Args.MakeArgString(getCompilerRT(Args, Component, Type, isFortran));
806+
}
807+
808+
/// Add Fortran runtime libs
809+
void ToolChain::addFortranRuntimeLibs(const ArgList &Args,
810+
llvm::opt::ArgStringList &CmdArgs) const {
811+
// Link flang_rt.runtime
812+
// These are handled earlier on Windows by telling the frontend driver to
813+
// add the correct libraries to link against as dependents in the object
814+
// file.
815+
if (!getTriple().isKnownWindowsMSVCEnvironment()) {
816+
StringRef F128LibName = getDriver().getFlangF128MathLibrary();
817+
F128LibName.consume_front_insensitive("lib");
818+
if (!F128LibName.empty()) {
819+
bool AsNeeded = !getTriple().isOSAIX();
820+
CmdArgs.push_back("-lflang_rt.quadmath");
821+
if (AsNeeded)
822+
addAsNeededOption(*this, Args, CmdArgs, /*as_needed=*/true);
823+
CmdArgs.push_back(Args.MakeArgString("-l" + F128LibName));
824+
if (AsNeeded)
825+
addAsNeededOption(*this, Args, CmdArgs, /*as_needed=*/false);
826+
}
827+
if (const char *res = getCompilerRTArgString(
828+
Args, "runtime", ToolChain::FT_Static, getDriver().IsFlangMode()))
829+
CmdArgs.push_back(res);
830+
else
831+
CmdArgs.push_back("-lflang_rt.runtime");
832+
addArchSpecificRPath(*this, Args, CmdArgs);
833+
834+
// needs libexecinfo for backtrace functions
835+
if (getTriple().isOSFreeBSD() || getTriple().isOSNetBSD() ||
836+
getTriple().isOSOpenBSD() || getTriple().isOSDragonFly())
837+
CmdArgs.push_back("-lexecinfo");
838+
}
839+
840+
// libomp needs libatomic for atomic operations if using libgcc
841+
if (Args.hasFlag(options::OPT_fopenmp, options::OPT_fopenmp_EQ,
842+
options::OPT_fno_openmp, false)) {
843+
Driver::OpenMPRuntimeKind OMPRuntime = getDriver().getOpenMPRuntime(Args);
844+
ToolChain::RuntimeLibType RuntimeLib = GetRuntimeLibType(Args);
845+
if (OMPRuntime == Driver::OMPRT_OMP && RuntimeLib == ToolChain::RLT_Libgcc)
846+
CmdArgs.push_back("-latomic");
847+
}
848+
}
849+
850+
void ToolChain::addFortranRuntimeLibraryPath(const llvm::opt::ArgList &Args,
851+
ArgStringList &CmdArgs) const {
852+
// Default to the <driver-path>/../lib directory. This works fine on the
853+
// platforms that we have tested so far. We will probably have to re-fine
854+
// this in the future. In particular, on some platforms, we may need to use
855+
// lib64 instead of lib.
856+
SmallString<256> DefaultLibPath =
857+
llvm::sys::path::parent_path(getDriver().Dir);
858+
llvm::sys::path::append(DefaultLibPath, "lib");
859+
if (getTriple().isKnownWindowsMSVCEnvironment())
860+
CmdArgs.push_back(Args.MakeArgString("-libpath:" + DefaultLibPath));
861+
else
862+
CmdArgs.push_back(Args.MakeArgString("-L" + DefaultLibPath));
803863
}
804864

805865
// Android target triples contain a target version. If we don't have libraries

clang/lib/Driver/ToolChains/AIX.cpp

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,11 @@
1616
#include "llvm/Option/ArgList.h"
1717
#include "llvm/ProfileData/InstrProf.h"
1818
#include "llvm/Support/Path.h"
19+
#include "llvm/Support/VirtualFileSystem.h"
1920

21+
#include <iostream>
2022
#include <set>
23+
using namespace std;
2124

2225
using AIX = clang::driver::toolchains::AIX;
2326
using namespace clang::driver;
@@ -358,8 +361,8 @@ void aix::Linker::ConstructJob(Compilation &C, const JobAction &JA,
358361

359362
if (D.IsFlangMode() &&
360363
!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) {
361-
addFortranRuntimeLibraryPath(ToolChain, Args, CmdArgs);
362-
addFortranRuntimeLibs(ToolChain, Args, CmdArgs);
364+
ToolChain.addFortranRuntimeLibraryPath(Args, CmdArgs);
365+
// ToolChain.addFortranRuntimeLibs(Args, CmdArgs);
363366
CmdArgs.push_back("-lm");
364367
CmdArgs.push_back("-lpthread");
365368
}
@@ -608,6 +611,26 @@ void AIX::addProfileRTLibs(const llvm::opt::ArgList &Args,
608611
ToolChain::addProfileRTLibs(Args, CmdArgs);
609612
}
610613

614+
std::string AIX::getCompilerRT(const ArgList &Args, StringRef Component,
615+
FileType Type, bool IsFortran) const {
616+
// On AIX, build the filename for the layout as if
617+
// LLVM_ENABLE_PER_TARGET_RUNTIME_DIR=OFF (e.g. lib/${os_dirname})
618+
std::string CRTBasename =
619+
buildCompilerRTBasename(Args, Component, Type,
620+
/*AddArch=*/!IsFortran, IsFortran);
621+
SmallString<128> Path(getCompilerRTPath());
622+
llvm::sys::path::append(Path, CRTBasename);
623+
return std::string(Path);
624+
}
625+
626+
void AIX::addFortranRuntimeLibs(const ArgList &Args,
627+
llvm::opt::ArgStringList &CmdArgs) const {
628+
// Link flang_rt.runtime.a. On AIX, the static and shared library are all
629+
// named .a
630+
CmdArgs.push_back(getCompilerRTArgString(
631+
Args, "runtime", ToolChain::FT_Static, getDriver().IsFlangMode()));
632+
}
633+
611634
ToolChain::CXXStdlibType AIX::GetDefaultCXXStdlibType() const {
612635
return ToolChain::CST_Libcxx;
613636
}

clang/lib/Driver/ToolChains/AIX.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,13 @@ class LLVM_LIBRARY_VISIBILITY AIX : public ToolChain {
8787
void addProfileRTLibs(const llvm::opt::ArgList &Args,
8888
llvm::opt::ArgStringList &CmdArgs) const override;
8989

90+
std::string getCompilerRT(const llvm::opt::ArgList &Args, StringRef Component,
91+
FileType Type = ToolChain::FT_Static,
92+
bool IsFortran = false) const override;
93+
94+
void addFortranRuntimeLibs(const llvm::opt::ArgList &Args,
95+
llvm::opt::ArgStringList &CmdArgs) const override;
96+
9097
CXXStdlibType GetDefaultCXXStdlibType() const override;
9198

9299
RuntimeLibType GetDefaultRuntimeLibType() const override;

clang/lib/Driver/ToolChains/AVR.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -426,7 +426,8 @@ Tool *AVRToolChain::buildLinker() const {
426426

427427
std::string
428428
AVRToolChain::getCompilerRT(const llvm::opt::ArgList &Args, StringRef Component,
429-
FileType Type = ToolChain::FT_Static) const {
429+
FileType Type = ToolChain::FT_Static,
430+
bool IsFortran) const {
430431
assert(Type == ToolChain::FT_Static && "AVR only supports static libraries");
431432
// Since AVR can never be a host environment, its compiler-rt library files
432433
// should always have ".a" suffix, even on windows.

clang/lib/Driver/ToolChains/AVR.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,8 @@ class LLVM_LIBRARY_VISIBILITY AVRToolChain : public Generic_ELF {
3434
std::optional<std::string> findAVRLibcInstallation() const;
3535
StringRef getGCCInstallPath() const { return GCCInstallPath; }
3636
std::string getCompilerRT(const llvm::opt::ArgList &Args, StringRef Component,
37-
FileType Type) const override;
37+
FileType Type,
38+
bool IsFortran = false) const override;
3839

3940
bool HasNativeLLVMSupport() const override { return true; }
4041

clang/lib/Driver/ToolChains/CommonArgs.cpp

Lines changed: 0 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -1326,70 +1326,6 @@ void tools::addOpenMPHostOffloadingArgs(const Compilation &C,
13261326
Args.MakeArgString(Twine(Targets) + llvm::join(Triples, ",")));
13271327
}
13281328

1329-
/// Add Fortran runtime libs
1330-
void tools::addFortranRuntimeLibs(const ToolChain &TC, const ArgList &Args,
1331-
llvm::opt::ArgStringList &CmdArgs) {
1332-
// Link flang_rt.runtime
1333-
// These are handled earlier on Windows by telling the frontend driver to
1334-
// add the correct libraries to link against as dependents in the object
1335-
// file.
1336-
if (!TC.getTriple().isKnownWindowsMSVCEnvironment()) {
1337-
StringRef F128LibName = TC.getDriver().getFlangF128MathLibrary();
1338-
F128LibName.consume_front_insensitive("lib");
1339-
if (!F128LibName.empty()) {
1340-
bool AsNeeded = !TC.getTriple().isOSAIX();
1341-
CmdArgs.push_back("-lflang_rt.quadmath");
1342-
if (AsNeeded)
1343-
addAsNeededOption(TC, Args, CmdArgs, /*as_needed=*/true);
1344-
CmdArgs.push_back(Args.MakeArgString("-l" + F128LibName));
1345-
if (AsNeeded)
1346-
addAsNeededOption(TC, Args, CmdArgs, /*as_needed=*/false);
1347-
}
1348-
if (TC.getTriple().isOSAIX()) {
1349-
// On AIX, pass the whole path of flang_rt.runtime.a to be consistent
1350-
// with clang.
1351-
std::string CRTBasename = "libflang_rt.runtime.a";
1352-
SmallString<128> Path(TC.getCompilerRTPath());
1353-
llvm::sys::path::append(Path, CRTBasename);
1354-
if (TC.getVFS().exists(Path))
1355-
CmdArgs.push_back(Args.MakeArgString(std::string(Path)));
1356-
} else
1357-
CmdArgs.push_back("-lflang_rt.runtime");
1358-
addArchSpecificRPath(TC, Args, CmdArgs);
1359-
1360-
// needs libexecinfo for backtrace functions
1361-
if (TC.getTriple().isOSFreeBSD() || TC.getTriple().isOSNetBSD() ||
1362-
TC.getTriple().isOSOpenBSD() || TC.getTriple().isOSDragonFly())
1363-
CmdArgs.push_back("-lexecinfo");
1364-
}
1365-
1366-
// libomp needs libatomic for atomic operations if using libgcc
1367-
if (Args.hasFlag(options::OPT_fopenmp, options::OPT_fopenmp_EQ,
1368-
options::OPT_fno_openmp, false)) {
1369-
Driver::OpenMPRuntimeKind OMPRuntime =
1370-
TC.getDriver().getOpenMPRuntime(Args);
1371-
ToolChain::RuntimeLibType RuntimeLib = TC.GetRuntimeLibType(Args);
1372-
if (OMPRuntime == Driver::OMPRT_OMP && RuntimeLib == ToolChain::RLT_Libgcc)
1373-
CmdArgs.push_back("-latomic");
1374-
}
1375-
}
1376-
1377-
void tools::addFortranRuntimeLibraryPath(const ToolChain &TC,
1378-
const llvm::opt::ArgList &Args,
1379-
ArgStringList &CmdArgs) {
1380-
// Default to the <driver-path>/../lib directory. This works fine on the
1381-
// platforms that we have tested so far. We will probably have to re-fine
1382-
// this in the future. In particular, on some platforms, we may need to use
1383-
// lib64 instead of lib.
1384-
SmallString<256> DefaultLibPath =
1385-
llvm::sys::path::parent_path(TC.getDriver().Dir);
1386-
llvm::sys::path::append(DefaultLibPath, "lib");
1387-
if (TC.getTriple().isKnownWindowsMSVCEnvironment())
1388-
CmdArgs.push_back(Args.MakeArgString("-libpath:" + DefaultLibPath));
1389-
else
1390-
CmdArgs.push_back(Args.MakeArgString("-L" + DefaultLibPath));
1391-
}
1392-
13931329
static void addSanitizerRuntime(const ToolChain &TC, const ArgList &Args,
13941330
ArgStringList &CmdArgs, StringRef Sanitizer,
13951331
bool IsShared, bool IsWhole) {

clang/lib/Driver/ToolChains/CommonArgs.h

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -121,15 +121,6 @@ void addOpenMPHostOffloadingArgs(const Compilation &C, const JobAction &JA,
121121
const llvm::opt::ArgList &Args,
122122
llvm::opt::ArgStringList &CmdArgs);
123123

124-
/// Adds Fortran runtime libraries to \p CmdArgs.
125-
void addFortranRuntimeLibs(const ToolChain &TC, const llvm::opt::ArgList &Args,
126-
llvm::opt::ArgStringList &CmdArgs);
127-
128-
/// Adds the path for the Fortran runtime libraries to \p CmdArgs.
129-
void addFortranRuntimeLibraryPath(const ToolChain &TC,
130-
const llvm::opt::ArgList &Args,
131-
llvm::opt::ArgStringList &CmdArgs);
132-
133124
void addHIPRuntimeLibArgs(const ToolChain &TC, Compilation &C,
134125
const llvm::opt::ArgList &Args,
135126
llvm::opt::ArgStringList &CmdArgs);

clang/lib/Driver/ToolChains/Darwin.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -706,8 +706,8 @@ void darwin::Linker::ConstructJob(Compilation &C, const JobAction &JA,
706706
// to generate executables.
707707
if (getToolChain().getDriver().IsFlangMode() &&
708708
!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) {
709-
addFortranRuntimeLibraryPath(getToolChain(), Args, CmdArgs);
710-
addFortranRuntimeLibs(getToolChain(), Args, CmdArgs);
709+
getToolChain().addFortranRuntimeLibraryPath(Args, CmdArgs);
710+
getToolChain().addFortranRuntimeLibs(Args, CmdArgs);
711711
}
712712

713713
if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs))
@@ -1341,7 +1341,7 @@ void MachO::AddLinkRuntimeLib(const ArgList &Args, ArgStringList &CmdArgs,
13411341
}
13421342

13431343
std::string MachO::getCompilerRT(const ArgList &, StringRef Component,
1344-
FileType Type) const {
1344+
FileType Type, bool IsFortran) const {
13451345
assert(Type != ToolChain::FT_Object &&
13461346
"it doesn't make sense to ask for the compiler-rt library name as an "
13471347
"object file");
@@ -1360,7 +1360,7 @@ std::string MachO::getCompilerRT(const ArgList &, StringRef Component,
13601360
}
13611361

13621362
std::string Darwin::getCompilerRT(const ArgList &, StringRef Component,
1363-
FileType Type) const {
1363+
FileType Type, bool IsFortran) const {
13641364
assert(Type != ToolChain::FT_Object &&
13651365
"it doesn't make sense to ask for the compiler-rt library name as an "
13661366
"object file");

clang/lib/Driver/ToolChains/Darwin.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -229,7 +229,8 @@ class LLVM_LIBRARY_VISIBILITY MachO : public ToolChain {
229229
// <resourcedir>/lib/darwin/macho_embedded/<...>(.dylib|.a).
230230
std::string
231231
getCompilerRT(const llvm::opt::ArgList &Args, StringRef Component,
232-
FileType Type = ToolChain::FT_Static) const override;
232+
FileType Type = ToolChain::FT_Static,
233+
bool IsFortran = false) const override;
233234

234235
/// }
235236
/// @name ToolChain Implementation
@@ -409,7 +410,8 @@ class LLVM_LIBRARY_VISIBILITY Darwin : public AppleMachO {
409410
// Those are under <resourcedir>/lib/darwin/<...>(.dylib|.a).
410411
std::string
411412
getCompilerRT(const llvm::opt::ArgList &Args, StringRef Component,
412-
FileType Type = ToolChain::FT_Static) const override;
413+
FileType Type = ToolChain::FT_Static,
414+
bool IsFortran = false) const override;
413415

414416
protected:
415417
/// }

clang/lib/Driver/ToolChains/DragonFly.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -153,8 +153,8 @@ void dragonfly::Linker::ConstructJob(Compilation &C, const JobAction &JA,
153153
// AddRunTimeLibs).
154154
if (D.IsFlangMode() &&
155155
!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) {
156-
addFortranRuntimeLibraryPath(ToolChain, Args, CmdArgs);
157-
addFortranRuntimeLibs(ToolChain, Args, CmdArgs);
156+
ToolChain.addFortranRuntimeLibraryPath(Args, CmdArgs);
157+
ToolChain.addFortranRuntimeLibs(Args, CmdArgs);
158158
CmdArgs.push_back("-lm");
159159
}
160160

clang/lib/Driver/ToolChains/FreeBSD.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -319,8 +319,8 @@ void freebsd::Linker::ConstructJob(Compilation &C, const JobAction &JA,
319319
// AddRunTimeLibs).
320320
if (D.IsFlangMode() &&
321321
!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) {
322-
addFortranRuntimeLibraryPath(ToolChain, Args, CmdArgs);
323-
addFortranRuntimeLibs(ToolChain, Args, CmdArgs);
322+
ToolChain.addFortranRuntimeLibraryPath(Args, CmdArgs);
323+
ToolChain.addFortranRuntimeLibs(Args, CmdArgs);
324324
if (Profiling)
325325
CmdArgs.push_back("-lm_p");
326326
else

0 commit comments

Comments
 (0)