Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions clang/lib/Basic/Targets.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -628,6 +628,10 @@ TargetInfo *AllocateTarget(const llvm::Triple &Triple,
return new SPIRV64TargetInfo(Triple, Opts);
}
case llvm::Triple::wasm32:
// Use the Cheerp backend for CheerpOS, even if the
// externally visible target is upstream wasm32
if (Triple.isCheerpOS())
return new CheerpTargetInfo(Triple);
if (Triple.getSubArch() != llvm::Triple::NoSubArch ||
Triple.getVendor() != llvm::Triple::UnknownVendor ||
!Triple.isOSBinFormatWasm())
Expand Down
6 changes: 6 additions & 0 deletions clang/lib/Basic/Targets/WebAssembly.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -343,6 +343,12 @@ bool CheerpTargetInfo::handleTargetFeatures(
return true;
}

bool CheerpTargetInfo::isValidCPUName(StringRef Name) const
{
// Be compatible with the default CPU name of the Wasm target
return Name == "generic";
}

const Builtin::Info CheerpTargetInfo::BuiltinInfo[] = {
#define BUILTIN(ID, TYPE, ATTRS) { #ID, TYPE, ATTRS, 0, ALL_LANGUAGES, nullptr},
#define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) { #ID, TYPE, ATTRS, HEADER,\
Expand Down
10 changes: 9 additions & 1 deletion clang/lib/Basic/Targets/WebAssembly.h
Original file line number Diff line number Diff line change
Expand Up @@ -220,8 +220,14 @@ class CheerpTargetInfo : public TargetInfo {
private:
static const Builtin::Info BuiltinInfo[];
bool hasSIMD = false;
static llvm::Triple filterTriple(const llvm::Triple &triple) {
llvm::Triple ret(triple);
// Override the internal architecture when dealing with the wasm32-cheerpos-linux target
ret.setArch(llvm::Triple::cheerp);
return ret;
}
public:
CheerpTargetInfo(const llvm::Triple &triple) : TargetInfo(triple) {
CheerpTargetInfo(const llvm::Triple &triple) : TargetInfo(filterTriple(triple)) {
resetDataLayout("b-e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i24:8:8-i32:32:32-"
"i64:64:64-f32:32:32-f64:64:64-"
"a:0:32-f16:16:16-f32:32:32-f64:64:64-n8:16:32-S64");
Expand Down Expand Up @@ -284,6 +290,8 @@ class CheerpTargetInfo : public TargetInfo {
// Special handling for Cheerp, any name can be clobbered
return true;
}
bool isValidCPUName(StringRef Name) const final;
bool setCPU(const std::string &Name) final { return isValidCPUName(Name); }
};
} // namespace targets
} // namespace clang
Expand Down
9 changes: 9 additions & 0 deletions clang/lib/Driver/Driver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -696,6 +696,11 @@ static llvm::Triple computeTargetTriple(const Driver &D,
Target.setEnvironment(llvm::Triple::GenericJS);
}

// Force a full triple when targeting CheerpOS
if (Target.getVendor() == llvm::Triple::CheerpOS) {
Target.setEnvironment(llvm::Triple::WebAssembly);
}

return Target;
}

Expand Down Expand Up @@ -5946,6 +5951,10 @@ const ToolChain &Driver::getToolChain(const ArgList &Args,
Args);
else if (Target.getArch() == llvm::Triple::ve)
TC = std::make_unique<toolchains::VEToolChain>(*this, Target, Args);
// Take over control of the toolchain when targeting CheerpOS,
// we don't want to use system includes and libraries
else if ((Target.getVendor() == llvm::Triple::CheerpOS))
TC = std::make_unique<toolchains::Cheerp>(*this, Target, Args);

else
TC = std::make_unique<toolchains::Linux>(*this, Target, Args);
Expand Down
2 changes: 1 addition & 1 deletion clang/lib/Driver/ToolChains/Clang.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5925,7 +5925,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
}

// Pass cheerp-wasm-externref if anyref feature enabled
auto wasmFeatures = cheerp::getWasmFeatures(D, Args);
auto wasmFeatures = cheerp::getWasmFeatures(D, getToolChain().getTriple(), Args);
if (std::binary_search(wasmFeatures.begin(), wasmFeatures.end(), cheerp::ANYREF)) {
CmdArgs.push_back("-cheerp-wasm-externref");
}
Expand Down
39 changes: 26 additions & 13 deletions clang/lib/Driver/ToolChains/WebAssembly.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -562,8 +562,9 @@ void cheerp::Link::ConstructJob(Compilation &C, const JobAction &JA,
}

const Driver &D = getToolChain().getDriver();
const llvm::Triple& triple = getToolChain().getTriple();
bool hasUnalignedMemory = true;
auto features = getWasmFeatures(D, Args);
auto features = getWasmFeatures(D, triple, Args);
if(std::find(features.begin(), features.end(), UNALIGNEDMEM) == features.end())
hasUnalignedMemory = false;

Expand Down Expand Up @@ -591,7 +592,7 @@ void cheerp::Link::ConstructJob(Compilation &C, const JobAction &JA,
AddStdLib("libc.bc");
AddStdLib("crt1.bc");
}
if (getToolChain().getTriple().isCheerpWasi())
if (triple.isCheerpWasi())
AddStdLib("libwasi.bc");
else
AddStdLib("libsystem.bc");
Expand All @@ -607,7 +608,7 @@ void cheerp::Link::ConstructJob(Compilation &C, const JobAction &JA,
}

if(((CheerpLinearOutput && CheerpLinearOutput->getValue() == StringRef("wasm")) ||
(!CheerpLinearOutput && getToolChain().getTriple().isCheerpWasm())) &&
(!CheerpLinearOutput && triple.isCheerpWasm())) &&
hasUnalignedMemory && (!Sanitizers || !Sanitizers->containsValue("address")))
{
// We omit libwasm when building with AddressSanitizer, since it defines
Expand Down Expand Up @@ -680,6 +681,7 @@ void cheerp::CheerpOptimizer::ConstructJob(Compilation &C, const JobAction &JA,
const char *LinkingOutput) const {
ArgStringList CmdArgs;
const Driver &D = getToolChain().getDriver();
const llvm::Triple& triple = getToolChain().getTriple();

std::string optPasses = "";
auto addPass = [&optPasses](const std::string& passInvocation)->void{
Expand All @@ -699,7 +701,7 @@ void cheerp::CheerpOptimizer::ConstructJob(Compilation &C, const JobAction &JA,
cheerpFixFuncCasts->render(Args, CmdArgs);
if(Arg* cheerpUseBigInts = Args.getLastArg(options::OPT_cheerp_use_bigints))
cheerpUseBigInts->render(Args, CmdArgs);
else if (getToolChain().getTriple().isCheerpWasmStandalone())
else if (triple.isCheerpWasmStandalone())
CmdArgs.push_back("-cheerp-use-bigints");

// Malloc/Free are probably intercepted when using sanitizers, don't optimize
Expand All @@ -721,7 +723,7 @@ void cheerp::CheerpOptimizer::ConstructJob(Compilation &C, const JobAction &JA,
else
{
std::string linearOut("-cheerp-linear-output=");
if (getToolChain().getTriple().isCheerpWasm())
if (triple.isCheerpWasm())
{
linearOut += "wasm";
}
Expand All @@ -732,7 +734,7 @@ void cheerp::CheerpOptimizer::ConstructJob(Compilation &C, const JobAction &JA,
}
CmdArgs.push_back(Args.MakeArgString(linearOut));
}
auto features = getWasmFeatures(D, Args);
auto features = getWasmFeatures(D, triple, Args);
if(std::find(features.begin(), features.end(), EXPORTEDTABLE) != features.end())
CmdArgs.push_back("-cheerp-wasm-exported-table");
if(std::find(features.begin(), features.end(), EXPORTEDMEMORY) != features.end())
Expand Down Expand Up @@ -814,14 +816,20 @@ static cheerp::CheerpWasmOpt parseWasmOpt(StringRef opt)
.Default(cheerp::INVALID);
}

std::vector<cheerp::CheerpWasmOpt> cheerp::getWasmFeatures(const Driver& D, const ArgList& Args)
std::vector<cheerp::CheerpWasmOpt> cheerp::getWasmFeatures(const Driver& D, const llvm::Triple& triple, const ArgList& Args)
{
// Figure out which Wasm optional feature to enable/disable
std::vector<CheerpWasmOpt> features;
// We enable memory growth/globalization/unaligned memory accesses by default
// We enable memory growth and unaligned memory accesses by default
features.push_back(GROWMEM);
features.push_back(GLOBALIZATION);
features.push_back(UNALIGNEDMEM);
// For CheerpOS we also force the memory to be imported and shared
if(triple.isCheerpOS()) {
features.push_back(IMPORTEDMEMORY);
features.push_back(SHAREDMEM);
}

if(Arg* cheerpWasmEnable = Args.getLastArg(options::OPT_cheerp_wasm_enable_EQ)) {
for (StringRef opt: cheerpWasmEnable->getValues())
{
Expand Down Expand Up @@ -870,6 +878,7 @@ void cheerp::CheerpCompiler::ConstructJob(Compilation &C, const JobAction &JA,
const ArgList &Args,
const char *LinkingOutput) const {
const Driver &D = getToolChain().getDriver();
const llvm::Triple& triple = getToolChain().getTriple();

ArgStringList CmdArgs;

Expand All @@ -880,7 +889,7 @@ void cheerp::CheerpCompiler::ConstructJob(Compilation &C, const JobAction &JA,
CmdArgs.push_back(Output.getFilename());
}

bool isCheerpWasm = getToolChain().getTriple().isCheerpWasm();
bool isCheerpWasm = triple.isCheerpWasm();
Arg* cheerpLinearOutput = Args.getLastArg(options::OPT_cheerp_linear_output_EQ);
if (cheerpLinearOutput)
cheerpLinearOutput->render(Args, CmdArgs);
Expand Down Expand Up @@ -920,7 +929,7 @@ void cheerp::CheerpCompiler::ConstructJob(Compilation &C, const JobAction &JA,
if(Arg* cheerpSecondaryOutputFile = Args.getLastArg(options::OPT_cheerp_secondary_output_file_EQ))
cheerpSecondaryOutputFile->render(Args, CmdArgs);
else if(
((isCheerpWasm && !getToolChain().getTriple().isCheerpWasmStandalone() && !cheerpLinearOutput) ||
((isCheerpWasm && !triple.isCheerpWasmStandalone() && !cheerpLinearOutput) ||
(cheerpLinearOutput && cheerpLinearOutput->getValue() != StringRef("asmjs"))))
{
SmallString<64> path(Output.getFilename());
Expand Down Expand Up @@ -964,7 +973,7 @@ void cheerp::CheerpCompiler::ConstructJob(Compilation &C, const JobAction &JA,
}

// Figure out which Wasm optional feature to enable/disable
auto features = getWasmFeatures(D, Args);
auto features = getWasmFeatures(D, triple, Args);
bool noGrowMem = true;
bool noSIMD = true;
bool noGlobalization = true;
Expand All @@ -977,6 +986,7 @@ void cheerp::CheerpCompiler::ConstructJob(Compilation &C, const JobAction &JA,
{
case SHAREDMEM:
sharedMem = true;
noGlobalization = true;
break;
case GROWMEM:
noGrowMem = false;
Expand All @@ -1003,7 +1013,10 @@ void cheerp::CheerpCompiler::ConstructJob(Compilation &C, const JobAction &JA,
noSIMD = false;
break;
case GLOBALIZATION:
noGlobalization = false;
// It never make sense to use globalized constants with shared memory,
// we would get accidentally thread-local global variables
if (!sharedMem)
noGlobalization = false;
break;
case UNALIGNEDMEM:
noUnalignedMem = false;
Expand Down Expand Up @@ -1080,7 +1093,7 @@ void cheerp::CheerpCompiler::ConstructJob(Compilation &C, const JobAction &JA,
cheerpFixFuncCasts->render(Args, CmdArgs);
if(Arg* cheerpUseBigInts = Args.getLastArg(options::OPT_cheerp_use_bigints))
cheerpUseBigInts->render(Args, CmdArgs);
else if (getToolChain().getTriple().isCheerpWasmStandalone())
else if (triple.isCheerpWasmStandalone())
CmdArgs.push_back("-cheerp-use-bigints");
if(Arg* cheerpMakeDTS = Args.getLastArg(options::OPT_cheerp_make_dts))
cheerpMakeDTS->render(Args, CmdArgs);
Expand Down
2 changes: 1 addition & 1 deletion clang/lib/Driver/ToolChains/WebAssembly.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ namespace cheerp {
GLOBALIZATION,
UNALIGNEDMEM
};
std::vector<CheerpWasmOpt> getWasmFeatures(const Driver& D, const llvm::opt::ArgList& Args);
std::vector<CheerpWasmOpt> getWasmFeatures(const Driver& D, const llvm::Triple& triple, const llvm::opt::ArgList& Args);

class LLVM_LIBRARY_VISIBILITY Link : public Tool {
public:
Expand Down
13 changes: 9 additions & 4 deletions llvm/include/llvm/ADT/Triple.h
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,8 @@ class Triple {
SUSE,
OpenEmbedded,
Leaningtech,
LastVendorType = Leaningtech
CheerpOS,
LastVendorType = CheerpOS
};
enum OSType {
UnknownOS,
Expand Down Expand Up @@ -791,20 +792,24 @@ class Triple {

/// Tests whether the target is cheerp-wasm
bool isCheerpWasm() const {
return getArch() == Triple::cheerp && getEnvironment() == Triple::WebAssembly;
return (getArch() == Triple::cheerp && getEnvironment() == Triple::WebAssembly) || isCheerpOS();
}

bool isCheerpWasi() const {
return getArch() == Triple::cheerp && getOS() == Triple::WASI;
}

bool isCheerpOS() const {
return getVendor() == Triple::CheerpOS;
}

bool isCheerpWasmStandalone() const {
return isCheerpWasi();
return isCheerpWasi() || isCheerpOS();
}

/// Tests whether the target is cheerp (including cheerp-wasm and cheerp-genericjs)
bool isCheerp() const{
return getArch() == Triple::cheerp;
return getArch() == Triple::cheerp || isCheerpOS();
}

/// Tests whether the target supports the EHABI exception
Expand Down
2 changes: 2 additions & 0 deletions llvm/lib/Support/Triple.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,7 @@ StringRef Triple::getVendorTypeName(VendorType Kind) {
case SCEI: return "scei";
case SUSE: return "suse";
case Leaningtech: return "leaningtech";
case CheerpOS: return "cheerpos";
}

llvm_unreachable("Invalid VendorType!");
Expand Down Expand Up @@ -557,6 +558,7 @@ static Triple::VendorType parseVendor(StringRef VendorName) {
.Case("suse", Triple::SUSE)
.Case("oe", Triple::OpenEmbedded)
.Case("leaningtech", Triple::Leaningtech)
.Case("cheerpos", Triple::CheerpOS)
.Default(Triple::UnknownVendor);
}

Expand Down
Loading