Skip to content

Commit 6bfff17

Browse files
committed
[Xtensa] Improve Xtensa multilib support in clang.
Use GCCInstallationDetector in Xtensa toolchain instead of XtensaGCCToolchainDetector for initialization of the gcc environment. Add xtensa toolchain test tree with multilib subdirectories.
1 parent 6655148 commit 6bfff17

File tree

17 files changed

+146
-136
lines changed

17 files changed

+146
-136
lines changed

clang/lib/Driver/ToolChains/Gnu.cpp

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1665,6 +1665,42 @@ static void findRISCVMultilibs(const Driver &D,
16651665
Result.Multilibs = RISCVMultilibs;
16661666
}
16671667

1668+
static void findXtensaMultilibs(const Driver &D,
1669+
const llvm::Triple &TargetTriple, StringRef Path,
1670+
const ArgList &Args, DetectedMultilibs &Result) {
1671+
1672+
MultilibSet XtensaMultilibs = MultilibSet();
1673+
bool IsESP32 = Args.getLastArgValue(options::OPT_mcpu_EQ, "esp32").equals("esp32");
1674+
1675+
XtensaMultilibs.push_back(Multilib());
1676+
if (IsESP32)
1677+
XtensaMultilibs.push_back(Multilib("esp32-psram", {}, {}, 2)
1678+
.flag("+mfix-esp32-psram-cache-issue"));
1679+
1680+
XtensaMultilibs.push_back(
1681+
Multilib("no-rtti", {}, {}, 1).flag("+fno-rtti").flag("-frtti"));
1682+
1683+
if (IsESP32)
1684+
XtensaMultilibs.push_back(Multilib("esp32-psram/no-rtti", {}, {}, 3)
1685+
.flag("+fno-rtti")
1686+
.flag("-frtti")
1687+
.flag("+mfix-esp32-psram-cache-issue"));
1688+
1689+
Multilib::flags_list Flags;
1690+
addMultilibFlag(
1691+
Args.hasFlag(options::OPT_frtti, options::OPT_fno_rtti, false), "frtti",
1692+
Flags);
1693+
1694+
if (IsESP32)
1695+
addMultilibFlag(Args.hasFlag(options::OPT_mfix_esp32_psram_cache_issue,
1696+
options::OPT_mfix_esp32_psram_cache_issue,
1697+
false),
1698+
"mfix-esp32-psram-cache-issue", Flags);
1699+
1700+
if (XtensaMultilibs.select(Flags, Result.SelectedMultilib))
1701+
Result.Multilibs = XtensaMultilibs;
1702+
}
1703+
16681704
static bool findBiarchMultilibs(const Driver &D,
16691705
const llvm::Triple &TargetTriple,
16701706
StringRef Path, const ArgList &Args,
@@ -2186,7 +2222,9 @@ void Generic_GCC::GCCInstallationDetector::AddDefaultGCCPrefixes(
21862222
"s390x-suse-linux", "s390x-redhat-linux"};
21872223

21882224
static const char *const XtensaLibDirs[] = {"/lib"};
2189-
static const char *const XtensaTriples[] = {"xtensa-unknown-elf"};
2225+
static const char *const XtensaTriples[] = {
2226+
"xtensa-unknown-elf", "xtensa-esp32-elf", "xtensa-esp32s2-elf",
2227+
"xtensa-esp32s3-elf"};
21902228

21912229
using std::begin;
21922230
using std::end;
@@ -2490,6 +2528,8 @@ bool Generic_GCC::GCCInstallationDetector::ScanGCCForMultilibs(
24902528
findMSP430Multilibs(D, TargetTriple, Path, Args, Detected);
24912529
} else if (TargetArch == llvm::Triple::avr) {
24922530
// AVR has no multilibs.
2531+
} else if (TargetArch == llvm::Triple::xtensa) {
2532+
findXtensaMultilibs(D, TargetTriple, Path, Args, Detected);
24932533
} else if (!findBiarchMultilibs(D, TargetTriple, Path, Args,
24942534
NeedsBiarchSuffix, Detected)) {
24952535
return false;

clang/lib/Driver/ToolChains/Xtensa.cpp

Lines changed: 56 additions & 118 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@
1010

1111
#include "Xtensa.h"
1212
#include "CommonArgs.h"
13-
#include "clang/Driver/InputInfo.h"
1413
#include "clang/Basic/Cuda.h"
1514
#include "clang/Config/config.h"
1615
#include "clang/Driver/Compilation.h"
@@ -32,58 +31,26 @@ using namespace llvm::opt;
3231

3332
using tools::addMultilibFlag;
3433

35-
XtensaGCCToolchainDetector::XtensaGCCToolchainDetector(
36-
const Driver &D, const llvm::Triple &HostTriple,
37-
const llvm::opt::ArgList &Args) {
38-
std::string InstalledDir;
39-
InstalledDir = D.getInstalledDir();
40-
StringRef CPUName = XtensaToolChain::GetTargetCPUVersion(Args);
41-
std::string Dir;
42-
std::string ToolchainName;
43-
std::string ToolchainDir;
44-
45-
if (CPUName.equals("esp32"))
46-
ToolchainName = "xtensa-esp32-elf";
47-
else if (CPUName.equals("esp32-s2") || CPUName.equals("esp32s2"))
48-
ToolchainName = "xtensa-esp32s2-elf";
49-
else if (CPUName.equals("esp32-s3") || CPUName.equals("esp32s3"))
50-
ToolchainName = "xtensa-esp32s3-elf";
51-
else if (CPUName.equals("esp8266"))
52-
ToolchainName = "xtensa-lx106-elf";
53-
54-
Slash = llvm::sys::path::get_separator().str();
55-
56-
ToolchainDir = InstalledDir + Slash + "..";
57-
Dir = ToolchainDir + Slash + "lib" + Slash + "gcc" + Slash + ToolchainName +
58-
Slash;
59-
GCCLibAndIncVersion = "";
60-
61-
if (D.getVFS().exists(Dir)) {
62-
std::error_code EC;
63-
for (llvm::vfs::directory_iterator LI = D.getVFS().dir_begin(Dir, EC), LE;
64-
!EC && LI != LE; LI = LI.increment(EC)) {
65-
StringRef VersionText = llvm::sys::path::filename(LI->path());
66-
auto GCCVersion = Generic_GCC::GCCVersion::Parse(VersionText);
67-
if (GCCVersion.Major == -1)
68-
continue;
69-
GCCLibAndIncVersion = GCCVersion.Text;
70-
}
71-
if (GCCLibAndIncVersion == "")
72-
llvm_unreachable("Unexpected Xtensa GCC toolchain version");
73-
74-
} else {
75-
// Unable to find Xtensa GCC toolchain;
76-
GCCToolchainName = "";
77-
return;
78-
}
79-
GCCToolchainDir = ToolchainDir;
80-
GCCToolchainName = ToolchainName;
81-
}
82-
8334
/// Xtensa Toolchain
8435
XtensaToolChain::XtensaToolChain(const Driver &D, const llvm::Triple &Triple,
8536
const ArgList &Args)
86-
: Generic_ELF(D, Triple, Args), XtensaGCCToolchain(D, getTriple(), Args) {
37+
: Generic_ELF(D, Triple, Args) {
38+
39+
GCCInstallation.init(Triple, Args);
40+
41+
if (!GCCInstallation.isValid()) {
42+
llvm_unreachable("Unexpected Xtensa GCC toolchain version");
43+
}
44+
45+
Multilibs = GCCInstallation.getMultilibs();
46+
SelectedMultilib = GCCInstallation.getMultilib();
47+
48+
GCCLibAndIncVersion = GCCInstallation.getVersion().Text;
49+
GCCToolchainName = GCCInstallation.getTriple().str();
50+
SmallString<128> Path(GCCInstallation.getParentLibPath());
51+
llvm::sys::path::append(Path, "..");
52+
GCCToolchainDir = Path.c_str();
53+
8754
for (auto *A : Args) {
8855
std::string Str = A->getAsString(Args);
8956
if (!Str.compare("-mlongcalls"))
@@ -110,45 +77,18 @@ XtensaToolChain::XtensaToolChain(const Driver &D, const llvm::Triple &Triple,
11077
IsIntegratedAsm = false;
11178
}
11279

113-
bool IsESP32 = XtensaToolChain::GetTargetCPUVersion(Args).equals("esp32");
114-
Multilibs.push_back(Multilib());
115-
if (IsESP32)
116-
Multilibs.push_back(Multilib("esp32-psram", {}, {}, 2)
117-
.flag("+mfix-esp32-psram-cache-issue"));
118-
119-
Multilibs.push_back(
120-
Multilib("no-rtti", {}, {}, 1).flag("+fno-rtti").flag("-frtti"));
121-
122-
if (IsESP32)
123-
Multilibs.push_back(Multilib("esp32-psram/no-rtti", {}, {}, 3)
124-
.flag("+fno-rtti")
125-
.flag("-frtti")
126-
.flag("+mfix-esp32-psram-cache-issue"));
127-
128-
Multilib::flags_list Flags;
129-
addMultilibFlag(
130-
Args.hasFlag(options::OPT_frtti, options::OPT_fno_rtti, false), "frtti",
131-
Flags);
132-
133-
if (IsESP32)
134-
addMultilibFlag(Args.hasFlag(options::OPT_mfix_esp32_psram_cache_issue,
135-
options::OPT_mfix_esp32_psram_cache_issue,
136-
false),
137-
"mfix-esp32-psram-cache-issue", Flags);
138-
139-
Multilibs.select(Flags, SelectedMultilib);
140-
141-
const std::string Slash = XtensaGCCToolchain.Slash;
142-
std::string Libs =
143-
XtensaGCCToolchain.GCCToolchainDir + Slash + "lib" + Slash + "gcc" +
144-
Slash + XtensaGCCToolchain.GCCToolchainName + Slash +
145-
XtensaGCCToolchain.GCCLibAndIncVersion + SelectedMultilib.gccSuffix();
146-
getFilePaths().push_back(Libs);
147-
148-
Libs = XtensaGCCToolchain.GCCToolchainDir + Slash +
149-
XtensaGCCToolchain.GCCToolchainName + Slash + "lib" +
150-
SelectedMultilib.gccSuffix();
151-
getFilePaths().push_back(Libs);
80+
SmallString<128> Libs1(GCCToolchainDir);
81+
llvm::sys::path::append(Libs1, "lib", "gcc", GCCToolchainName,
82+
GCCLibAndIncVersion);
83+
if (!SelectedMultilib.gccSuffix().empty())
84+
llvm::sys::path::append(Libs1, SelectedMultilib.gccSuffix());
85+
getFilePaths().push_back(Libs1.c_str());
86+
87+
SmallString<128> Libs2(GCCToolchainDir);
88+
llvm::sys::path::append(Libs2, GCCToolchainName, "lib");
89+
if (!SelectedMultilib.gccSuffix().empty())
90+
llvm::sys::path::append(Libs2, SelectedMultilib.gccSuffix());
91+
getFilePaths().push_back(Libs2.c_str());
15292
}
15393

15494
Tool *XtensaToolChain::buildLinker() const {
@@ -165,17 +105,15 @@ void XtensaToolChain::AddClangSystemIncludeArgs(const ArgList &DriverArgs,
165105
DriverArgs.hasArg(options::OPT_nostdlibinc))
166106
return;
167107

168-
if (!XtensaGCCToolchain.IsValid())
108+
if (!GCCInstallation.isValid())
169109
return;
170110

171-
std::string Slash = XtensaGCCToolchain.Slash;
172-
173-
std::string Path1 = getDriver().ResourceDir.c_str() + Slash + "include";
174-
std::string Path2 = XtensaGCCToolchain.GCCToolchainDir + Slash +
175-
XtensaGCCToolchain.GCCToolchainName + Slash +
176-
"sys-include";
177-
std::string Path3 = XtensaGCCToolchain.GCCToolchainDir + Slash +
178-
XtensaGCCToolchain.GCCToolchainName + Slash + "include";
111+
SmallString<128> Path1(getDriver().ResourceDir);
112+
llvm::sys::path::append(Path1, "include");
113+
SmallString<128> Path2(GCCToolchainDir);
114+
llvm::sys::path::append(Path2, GCCToolchainName, "sys-include");
115+
SmallString<128> Path3(GCCToolchainDir);
116+
llvm::sys::path::append(Path3, GCCToolchainName, "include");
179117

180118
const StringRef Paths[] = {Path1, Path2, Path3};
181119
addSystemIncludes(DriverArgs, CC1Args, Paths);
@@ -184,20 +122,20 @@ void XtensaToolChain::AddClangSystemIncludeArgs(const ArgList &DriverArgs,
184122
void XtensaToolChain::addLibStdCxxIncludePaths(
185123
const llvm::opt::ArgList &DriverArgs,
186124
llvm::opt::ArgStringList &CC1Args) const {
187-
if (!XtensaGCCToolchain.IsValid())
125+
if (!GCCInstallation.isValid())
188126
return;
189127

190-
std::string Slash = XtensaGCCToolchain.Slash;
128+
SmallString<128> BaseDir(GCCToolchainDir);
129+
llvm::sys::path::append(BaseDir, GCCToolchainName, "include", "c++",
130+
GCCLibAndIncVersion);
131+
SmallString<128> TargetDir(BaseDir);
132+
llvm::sys::path::append(TargetDir, GCCToolchainName);
133+
SmallString<128> TargetDirBackward(BaseDir);
134+
llvm::sys::path::append(TargetDirBackward, "backward");
191135

192-
std::string BaseDir = XtensaGCCToolchain.GCCToolchainDir + Slash +
193-
XtensaGCCToolchain.GCCToolchainName + Slash +
194-
"include" + Slash + "c++" + Slash +
195-
XtensaGCCToolchain.GCCLibAndIncVersion;
196-
std::string TargetDir = BaseDir + Slash + XtensaGCCToolchain.GCCToolchainName;
197136
addLibStdCXXIncludePaths(BaseDir, "", "", DriverArgs, CC1Args);
198137
addLibStdCXXIncludePaths(TargetDir, "", "", DriverArgs, CC1Args);
199-
TargetDir = BaseDir + Slash + "backward";
200-
addLibStdCXXIncludePaths(TargetDir, "", "", DriverArgs, CC1Args);
138+
addLibStdCXXIncludePaths(TargetDirBackward, "", "", DriverArgs, CC1Args);
201139
}
202140

203141
ToolChain::CXXStdlibType
@@ -229,7 +167,7 @@ void tools::xtensa::Assembler::ConstructJob(Compilation &C, const JobAction &JA,
229167
const auto &TC =
230168
static_cast<const toolchains::XtensaToolChain &>(getToolChain());
231169

232-
if (!TC.XtensaGCCToolchain.IsValid())
170+
if (TC.GCCToolchainName == "")
233171
llvm_unreachable("Unable to find Xtensa GCC assembler");
234172

235173
claimNoWarnArgs(Args);
@@ -256,13 +194,13 @@ void tools::xtensa::Assembler::ConstructJob(Compilation &C, const JobAction &JA,
256194
for (const auto &II : Inputs)
257195
CmdArgs.push_back(II.getFilename());
258196

259-
std::string Slash = TC.XtensaGCCToolchain.Slash;
197+
SmallString<128> Asm(TC.GCCToolchainDir);
198+
llvm::sys::path::append(Asm, "bin",
199+
TC.GCCToolchainName + "-" + getShortName());
260200

261-
const char *Asm =
262-
Args.MakeArgString(getToolChain().getDriver().Dir + Slash +
263-
TC.XtensaGCCToolchain.GCCToolchainName + "-as");
264-
C.addCommand(std::make_unique<Command>(
265-
JA, *this, ResponseFileSupport::AtFileCurCP(), Asm, CmdArgs, Inputs));
201+
C.addCommand(
202+
std::make_unique<Command>(JA, *this, ResponseFileSupport::AtFileCurCP(),
203+
Args.MakeArgString(Asm), CmdArgs, Inputs));
266204
}
267205

268206
void xtensa::Linker::ConstructJob(Compilation &C, const JobAction &JA,
@@ -272,13 +210,13 @@ void xtensa::Linker::ConstructJob(Compilation &C, const JobAction &JA,
272210
const char *LinkingOutput) const {
273211
const auto &TC =
274212
static_cast<const toolchains::XtensaToolChain &>(getToolChain());
275-
std::string Slash = TC.XtensaGCCToolchain.Slash;
276213

277-
if (!TC.XtensaGCCToolchain.IsValid())
214+
if (TC.GCCToolchainName == "")
278215
llvm_unreachable("Unable to find Xtensa GCC linker");
279216

280-
std::string Linker = getToolChain().getDriver().Dir + Slash +
281-
TC.XtensaGCCToolchain.GCCToolchainName + "-ld";
217+
SmallString<128> Linker(TC.GCCToolchainDir);
218+
llvm::sys::path::append(Linker, "bin",
219+
TC.GCCToolchainName + "-" + getShortName());
282220
ArgStringList CmdArgs;
283221

284222
Args.AddAllArgs(CmdArgs, options::OPT_L);

clang/lib/Driver/ToolChains/Xtensa.h

Lines changed: 6 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -20,19 +20,6 @@ namespace clang {
2020
namespace driver {
2121
namespace toolchains {
2222

23-
class XtensaGCCToolchainDetector {
24-
public:
25-
std::string GCCLibAndIncVersion;
26-
std::string GCCToolchainName;
27-
std::string GCCToolchainDir;
28-
std::string Slash;
29-
30-
XtensaGCCToolchainDetector(const Driver &D, const llvm::Triple &HostTriple,
31-
const llvm::opt::ArgList &Args);
32-
33-
bool IsValid() const { return GCCToolchainName != ""; }
34-
};
35-
3623
class LLVM_LIBRARY_VISIBILITY XtensaToolChain : public Generic_ELF {
3724
protected:
3825
Tool *buildLinker() const override;
@@ -49,13 +36,15 @@ class LLVM_LIBRARY_VISIBILITY XtensaToolChain : public Generic_ELF {
4936
llvm::opt::ArgStringList &CC1Args) const override;
5037
CXXStdlibType GetCXXStdlibType(const llvm::opt::ArgList &Args) const override;
5138
bool IsIntegratedAssemblerDefault() const override {
52-
return (IsIntegratedAsm || (XtensaGCCToolchain.GCCToolchainName == ""));
39+
return (IsIntegratedAsm || (GCCToolchainName == ""));
5340
}
5441

5542
static const StringRef GetTargetCPUVersion(const llvm::opt::ArgList &Args);
5643

57-
XtensaGCCToolchainDetector XtensaGCCToolchain;
5844
bool IsIntegratedAsm = true;
45+
std::string GCCLibAndIncVersion = "";
46+
std::string GCCToolchainName = "";
47+
std::string GCCToolchainDir = "";
5948
};
6049

6150
} // end namespace toolchains
@@ -65,7 +54,7 @@ namespace xtensa {
6554
class LLVM_LIBRARY_VISIBILITY Linker : public Tool {
6655
public:
6756
Linker(const ToolChain &TC)
68-
: Tool("Xtensa::Linker", "xtensa-esp32-elf-ld", TC) {}
57+
: Tool("Xtensa::Linker", "ld", TC) {}
6958
bool hasIntegratedCPP() const override { return false; }
7059
bool isLinkJob() const override { return true; }
7160
void ConstructJob(Compilation &C, const JobAction &JA,
@@ -77,7 +66,7 @@ class LLVM_LIBRARY_VISIBILITY Linker : public Tool {
7766
class LLVM_LIBRARY_VISIBILITY Assembler : public Tool {
7867
public:
7968
Assembler(const ToolChain &TC)
80-
: Tool("Xtensa::Assembler", "xtensa-esp32-elf-as", TC) {}
69+
: Tool("Xtensa::Assembler", "as", TC) {}
8170

8271
bool hasIntegratedCPP() const override { return false; }
8372
void ConstructJob(Compilation &C, const JobAction &JA,
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
#!/bin/true

clang/test/Driver/Inputs/multilib_xtensa_tree/lib/gcc/xtensa-esp32-elf/8.4.0/crtbegin.o

Whitespace-only changes.

clang/test/Driver/Inputs/multilib_xtensa_tree/lib/gcc/xtensa-esp32-elf/8.4.0/crtend.o

Whitespace-only changes.

clang/test/Driver/Inputs/multilib_xtensa_tree/lib/gcc/xtensa-esp32-elf/8.4.0/esp32-psram/crtbegin.o

Whitespace-only changes.

clang/test/Driver/Inputs/multilib_xtensa_tree/lib/gcc/xtensa-esp32-elf/8.4.0/esp32-psram/crtend.o

Whitespace-only changes.

clang/test/Driver/Inputs/multilib_xtensa_tree/lib/gcc/xtensa-esp32-elf/8.4.0/esp32-psram/no-rtti/crtbegin.o

Whitespace-only changes.

clang/test/Driver/Inputs/multilib_xtensa_tree/lib/gcc/xtensa-esp32-elf/8.4.0/esp32-psram/no-rtti/crtend.o

Whitespace-only changes.

0 commit comments

Comments
 (0)