Skip to content

Commit

Permalink
Merge pull request #2766 from kinke/wasm
Browse files Browse the repository at this point in the history
Add some rudimentary WebAssembly support
  • Loading branch information
kinke committed Jul 9, 2018
2 parents 0c8c0e6 + 8ec1840 commit 6148b8a
Show file tree
Hide file tree
Showing 10 changed files with 64 additions and 30 deletions.
4 changes: 2 additions & 2 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -263,7 +263,7 @@ jobs:
- image: ubuntu:14.04
environment:
- CI_OS: linux
- LLVM_VERSION: 6.0.1
- LLVM_VERSION: 6.0.1-2
- HOST_LDC_VERSION: 1.10.0
- EXTRA_CMAKE_FLAGS: "-DMULTILIB=ON -DBUILD_LTO_LIBS=ON -DD_FLAGS='-w;-flto=thin' -DCMAKE_EXE_LINKER_FLAGS=-static-libstdc++ -DLDC_INSTALL_LTOPLUGIN=ON -DLDC_INSTALL_LLVM_RUNTIME_LIBS=ON"
- DUB_VERSION: v1.9.0
Expand All @@ -275,7 +275,7 @@ jobs:
- CI_OS: osx
- MACOSX_DEPLOYMENT_TARGET: 10.8
- USE_LIBCPP: true
- LLVM_VERSION: 6.0.1
- LLVM_VERSION: 6.0.1-2
- HOST_LDC_VERSION: 1.10.0
- BOOTSTRAP_CMAKE_FLAGS: "-DCMAKE_CXX_FLAGS='-stdlib=libc++' -DCMAKE_EXE_LINKER_FLAGS=-lc++"
- EXTRA_CMAKE_FLAGS: "-DMULTILIB=ON -DBUILD_LTO_LIBS=ON -DD_FLAGS='-w;-flto=thin' -DCMAKE_CXX_FLAGS='-stdlib=libc++' -DCMAKE_EXE_LINKER_FLAGS=-lc++"
Expand Down
6 changes: 3 additions & 3 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -578,12 +578,12 @@ add_custom_target(${LDMD_EXE} ALL DEPENDS ${LDMD_EXE_FULL})
# LLVM flags into account.
set(LDC_LINKERFLAG_LIST ${SANITIZE_LDFLAGS} ${LLVM_LIBRARIES} ${LLVM_LDFLAGS})
if(LDC_WITH_LLD)
# ELF and Mach-O formats supported since LLD 6.0.0, otherwise just Windows COFF
# ELF, Mach-O, MinGW and WebAssembly formats supported since LLD 6.0.0, otherwise just Windows COFF
if(NOT (LDC_LLVM_VER LESS 600))
if(MSVC)
list(APPEND LDC_LINKERFLAG_LIST lldDriver.lib lldCOFF.lib lldELF.lib lldMachO.lib lldYAML.lib lldReaderWriter.lib lldCommon.lib lldCore.lib)
list(APPEND LDC_LINKERFLAG_LIST lldDriver.lib lldMinGW.lib lldCOFF.lib lldELF.lib lldMachO.lib lldWasm.lib lldYAML.lib lldReaderWriter.lib lldCommon.lib lldCore.lib)
else()
set(LDC_LINKERFLAG_LIST -llldDriver -llldCOFF -llldELF -llldMachO -llldYAML -llldReaderWriter -llldCommon -llldCore ${LDC_LINKERFLAG_LIST})
set(LDC_LINKERFLAG_LIST -llldDriver -llldMinGW -llldCOFF -llldELF -llldMachO -llldWasm -llldYAML -llldReaderWriter -llldCommon -llldCore ${LDC_LINKERFLAG_LIST})
endif()
if(APPLE) # bug, should be fixed in LLVM 6.0.1
list(APPEND LDC_LINKERFLAG_LIST -lxml2)
Expand Down
2 changes: 1 addition & 1 deletion appveyor.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ environment:
matrix:
- APPVEYOR_JOB_ARCH: x64
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
LLVM_VERSION: 6.0.1
LLVM_VERSION: 6.0.1-2
HOST_LDC_VERSION: 1.10.0
DUB_VERSION: v1.9.0
- APPVEYOR_JOB_ARCH: x86
Expand Down
6 changes: 5 additions & 1 deletion driver/linker-gcc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -656,7 +656,7 @@ int linkObjToBinaryGcc(llvm::StringRef outputPath,
argsBuilder.build(outputPath, defaultLibNames);

const auto fullArgs =
getFullArgs("ld.lld", argsBuilder.args, global.params.verbose);
getFullArgs("lld", argsBuilder.args, global.params.verbose);

// CanExitEarly == true means that LLD can and will call `exit()` when errors occur.
const bool CanExitEarly = false;
Expand All @@ -670,6 +670,10 @@ int linkObjToBinaryGcc(llvm::StringRef outputPath,
#else
success = lld::mach_o::link(fullArgs);
#endif
} else if (global.params.targetTriple->isOSBinFormatCOFF()) {
success = lld::mingw::link(fullArgs);
} else if (global.params.targetTriple->isOSBinFormatWasm()) {
success = lld::wasm::link(fullArgs, CanExitEarly);
} else {
error(Loc(), "unknown target binary format for internal linking");
}
Expand Down
3 changes: 3 additions & 0 deletions driver/linker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,9 @@ static std::string getOutputName() {
extension = global.dll_ext;
} else if (triple.isOSWindows()) {
extension = "exe";
} else if (triple.getArch() == llvm::Triple::wasm32 ||
triple.getArch() == llvm::Triple::wasm64) {
extension = "wasm";
}

if (global.params.exefile) {
Expand Down
48 changes: 26 additions & 22 deletions driver/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,8 @@ static cl::list<std::string, StringsAdapter>
// This function exits the program.
void printVersion(llvm::raw_ostream &OS) {
OS << "LDC - the LLVM D compiler (" << global.ldc_version << "):\n";
OS << " based on DMD " << global.version << " and LLVM " << global.llvm_version << "\n";
OS << " based on DMD " << global.version << " and LLVM "
<< global.llvm_version << "\n";
OS << " built with " << ldc::built_with_Dcompiler_version << "\n";
#if defined(__has_feature)
#if __has_feature(address_sanitizer)
Expand All @@ -124,9 +125,9 @@ void printVersion(llvm::raw_ostream &OS) {

llvm::TargetRegistry::printRegisteredTargetsForVersion(
#if LDC_LLVM_VER >= 600
OS
OS
#endif
);
);

exit(EXIT_SUCCESS);
}
Expand All @@ -137,7 +138,6 @@ void printVersionStdout() {
assert(false);
}


namespace {

// True when target triple has an uClibc environment
Expand Down Expand Up @@ -184,7 +184,8 @@ void processTransitions(std::vector<std::string> &list) {
" =field,3449 list all non-mutable fields which occupy an "
"object instance\n"
" =import,10378 revert to single phase name lookup\n"
" =intpromote,16997 fix integral promotions for unary + - ~ operators\n"
" =intpromote,16997 fix integral promotions for unary + - ~ "
"operators\n"
" =tls list all variables going into thread local "
"storage\n");
exit(EXIT_SUCCESS);
Expand Down Expand Up @@ -503,11 +504,14 @@ void parseCommandLine(int argc, char **argv, Strings &sourceFiles,

// -release downgrades default checks
if (global.params.useArrayBounds == CHECKENABLEdefault)
global.params.useArrayBounds = global.params.release ? CHECKENABLEsafeonly : CHECKENABLEon;
global.params.useArrayBounds =
global.params.release ? CHECKENABLEsafeonly : CHECKENABLEon;
if (global.params.useAssert == CHECKENABLEdefault)
global.params.useAssert = global.params.release ? CHECKENABLEoff : CHECKENABLEon;
global.params.useAssert =
global.params.release ? CHECKENABLEoff : CHECKENABLEon;
if (global.params.useSwitchError == CHECKENABLEdefault)
global.params.useSwitchError = global.params.release ? CHECKENABLEoff : CHECKENABLEon;
global.params.useSwitchError =
global.params.release ? CHECKENABLEoff : CHECKENABLEon;

// LDC output determination

Expand Down Expand Up @@ -602,8 +606,7 @@ static void registerMipsABI() {
}

// Check if triple environment name starts with "uclibc" and change it to "gnu"
void fixupUClibcEnv()
{
void fixupUClibcEnv() {
llvm::Triple triple(mTargetTriple);
if (triple.getEnvironmentName().find("uclibc") != 0)
return;
Expand Down Expand Up @@ -738,10 +741,15 @@ void registerPredefinedTargetVersions() {
"S390X"); // For backwards compatibility.
VersionCondition::addPredefinedGlobalIdent("D_HardFloat");
break;
case llvm::Triple::wasm32:
VersionCondition::addPredefinedGlobalIdent("WebAssembly32");
break;
case llvm::Triple::wasm64:
VersionCondition::addPredefinedGlobalIdent("WebAssembly64");
break;
default:
error(Loc(), "invalid cpu architecture specified: %s",
triple.getArchName().str().c_str());
fatal();
warning(Loc(), "unknown target CPU architecture: %s",
triple.getArchName().str().c_str());
}

// endianness
Expand Down Expand Up @@ -847,8 +855,8 @@ void registerPredefinedTargetVersions() {
default:
if (triple.getEnvironment() == llvm::Triple::Android) {
VersionCondition::addPredefinedGlobalIdent("Android");
} else {
warning(Loc(), "unknown OS for target '%s'", triple.str().c_str());
} else if (triple.getOSName() != "unknown") {
warning(Loc(), "unknown target OS: %s", triple.getOSName().str().c_str());
}
break;
}
Expand Down Expand Up @@ -1054,9 +1062,7 @@ int cppmain(int argc, char **argv) {
return mars_mainBody(files, libmodules);
}

void addDefaultVersionIdentifiers() {
registerPredefinedVersions();
}
void addDefaultVersionIdentifiers() { registerPredefinedVersions(); }

void codegenModules(Modules &modules) {
// Generate one or more object/IR/bitcode files/dcompute kernels.
Expand All @@ -1079,8 +1085,7 @@ void codegenModules(Modules &modules) {

const auto atCompute = hasComputeAttr(m);
if (atCompute == DComputeCompileFor::hostOnly ||
atCompute == DComputeCompileFor::hostAndDevice)
{
atCompute == DComputeCompileFor::hostAndDevice) {
cg.emit(m);
}
if (atCompute != DComputeCompileFor::hostOnly) {
Expand All @@ -1101,15 +1106,14 @@ void codegenModules(Modules &modules) {
}

if (!computeModules.empty()) {
for (auto& mod : computeModules)
for (auto &mod : computeModules)
dccg.emit(mod);

dccg.writeModules();
}
// We may have removed all object files, if so don't link.
if (global.params.objfiles.dim == 0)
global.params.link = false;

}

cache::pruneCache();
Expand Down
10 changes: 9 additions & 1 deletion gen/tollvm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -230,7 +230,15 @@ LinkageWithCOMDAT DtoLinkage(Dsymbol *sym) {
}

bool supportsCOMDAT() {
return !global.params.targetTriple->isOSBinFormatMachO();
const auto &triple = *global.params.targetTriple;
return !(triple.isOSBinFormatMachO() ||
#if LDC_LLVM_VER >= 500
triple.isOSBinFormatWasm()
#else
triple.getArch() == llvm::Triple::wasm32 ||
triple.getArch() == llvm::Triple::wasm64
#endif
);
}

void setLinkage(LinkageWithCOMDAT lwc, llvm::GlobalObject *obj) {
Expand Down
1 change: 1 addition & 0 deletions tests/baremetal/inputs/object.d
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
// empty
4 changes: 4 additions & 0 deletions tests/baremetal/lit.local.cfg
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# Define `%baremetal_args` as LDC args making sure
# * no ldc2.conf file is used (=> no implicit command-line args), and
# * the empty object.d in ./inputs is imported (=> no TypeInfo, ModuleInfo, Object...).
config.substitutions.append( ('%baremetal_args', '-conf= -I' + config.test_source_root + '/baremetal/inputs') )
10 changes: 10 additions & 0 deletions tests/baremetal/wasm.d
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
// Compile and link directly to WebAssembly.

// REQUIRES: target_WebAssembly
// RUN: %ldc -mtriple=wasm32-unknown-unknown-wasm -link-internally %s %baremetal_args

extern(C): // no mangling, no arguments order reversal

void _start() {}

double add(double a, double b) { return a + b; }

0 comments on commit 6148b8a

Please sign in to comment.