mirror of
https://github.com/ldc-developers/ldc.git
synced 2025-05-05 17:43:35 +03:00
Merge remote-tracking branch 'origin/master' into merge-2.102
This commit is contained in:
commit
2f44a281f9
12 changed files with 161 additions and 62 deletions
|
@ -3,6 +3,7 @@
|
|||
#### Big news
|
||||
- Frontend, druntime and Phobos are at version [2.102.1](https://dlang.org/changelog/2.102.0.html). (#4323)
|
||||
- Vector comparisons (==, !=, <, <=, >, >=) now yield a vector mask. Identity comparisons (`is`, `!is`) still yield a scalar `bool`. (#4323)
|
||||
- Linker-level dead code elimination is enabled by default for Apple, wasm and *all* ELF targets too now. (#4320)
|
||||
|
||||
#### Platform support
|
||||
|
||||
|
|
|
@ -635,33 +635,6 @@ if(LDC_WITH_LLD)
|
|||
endif()
|
||||
endif()
|
||||
|
||||
# Plugin support
|
||||
if(UNIX)
|
||||
set(LDC_ENABLE_PLUGINS_DEFAULT ON)
|
||||
else()
|
||||
set(LDC_ENABLE_PLUGINS_DEFAULT OFF)
|
||||
endif()
|
||||
set(LDC_ENABLE_PLUGINS ${LDC_ENABLE_PLUGINS_DEFAULT} CACHE BOOL "Build LDC with plugin support (increases binary size)")
|
||||
if(LDC_ENABLE_PLUGINS)
|
||||
add_definitions(-DLDC_ENABLE_PLUGINS)
|
||||
|
||||
if(APPLE)
|
||||
# No extra link flags needed.
|
||||
elseif(UNIX)
|
||||
# For plugin support, we need to link with --export-dynamic on Unix.
|
||||
# Make sure the linker supports --export-dynamic (on Solaris it is not supported and also not needed).
|
||||
set(CMAKE_REQUIRED_QUIET_BAK ${CMAKE_REQUIRED_QUIET})
|
||||
set(CMAKE_REQUIRED_QUIET ON) # suppress status messages
|
||||
CHECK_LINK_FLAG("--export-dynamic" LINKER_ACCEPTS_EXPORT_DYNAMIC_FLAG)
|
||||
set(CMAKE_REQUIRED_QUIET ${CMAKE_REQUIRED_QUIET_BAK})
|
||||
|
||||
if(LINKER_ACCEPTS_EXPORT_DYNAMIC_FLAG)
|
||||
set(LDC_LINKERFLAG_LIST "${LDC_LINKERFLAG_LIST};-Wl,--export-dynamic")
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
message(STATUS "-- Building LDC with plugin support (LDC_ENABLE_PLUGINS): ${LDC_ENABLE_PLUGINS}")
|
||||
|
||||
if(NOT DEFINED LDC_LINK_MANUALLY)
|
||||
if(MSVC)
|
||||
# Use the D host compiler for linking D executables.
|
||||
|
@ -678,6 +651,42 @@ if(LDC_LINK_MANUALLY AND NOT DEFINED D_LINKER_ARGS)
|
|||
message(STATUS "Host D compiler linker flags: ${D_LINKER_ARGS}")
|
||||
endif()
|
||||
|
||||
# Plugin support
|
||||
if(UNIX)
|
||||
set(LDC_ENABLE_PLUGINS_DEFAULT ON)
|
||||
else()
|
||||
set(LDC_ENABLE_PLUGINS_DEFAULT OFF)
|
||||
endif()
|
||||
set(LDC_ENABLE_PLUGINS ${LDC_ENABLE_PLUGINS_DEFAULT} CACHE BOOL "Build LDC with plugin support (increases binary size)")
|
||||
if(LDC_ENABLE_PLUGINS)
|
||||
add_definitions(-DLDC_ENABLE_PLUGINS)
|
||||
|
||||
if(APPLE)
|
||||
# Need to disable dead_strip with LDC host compilers.
|
||||
if("${D_COMPILER_ID}" STREQUAL "LDMD")
|
||||
if(LDC_LINK_MANUALLY)
|
||||
# suboptimal - applies to all D executables (incl. ldmd2, ldc-build-runtime, ldc-prune-cache)
|
||||
list(REMOVE_ITEM D_LINKER_ARGS "-Wl,-dead_strip")
|
||||
else()
|
||||
# just for ldc2 (and ldc2-unittest)
|
||||
append("-disable-linker-strip-dead" DFLAGS_LDC)
|
||||
endif()
|
||||
endif()
|
||||
elseif(UNIX)
|
||||
# For plugin support, we need to link with --export-dynamic on Unix.
|
||||
# Make sure the linker supports --export-dynamic (on Solaris it is not supported and also not needed).
|
||||
set(CMAKE_REQUIRED_QUIET_BAK ${CMAKE_REQUIRED_QUIET})
|
||||
set(CMAKE_REQUIRED_QUIET ON) # suppress status messages
|
||||
CHECK_LINK_FLAG("--export-dynamic" LINKER_ACCEPTS_EXPORT_DYNAMIC_FLAG)
|
||||
set(CMAKE_REQUIRED_QUIET ${CMAKE_REQUIRED_QUIET_BAK})
|
||||
|
||||
if(LINKER_ACCEPTS_EXPORT_DYNAMIC_FLAG)
|
||||
set(LDC_LINKERFLAG_LIST "${LDC_LINKERFLAG_LIST};-Wl,--export-dynamic")
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
message(STATUS "-- Building LDC with plugin support (LDC_ENABLE_PLUGINS): ${LDC_ENABLE_PLUGINS}")
|
||||
|
||||
build_d_executable(
|
||||
"${LDC_EXE}"
|
||||
"${LDC_EXE_FULL}"
|
||||
|
|
|
@ -419,7 +419,7 @@ cl::opt<std::string> mTargetTriple("mtriple", cl::ZeroOrMore,
|
|||
cl::desc("Override target triple"));
|
||||
|
||||
cl::opt<std::string>
|
||||
mABI("mabi", cl::ZeroOrMore, cl::Hidden, cl::init(""),
|
||||
mABI("mabi", cl::ZeroOrMore, cl::init(""),
|
||||
cl::desc("The name of the ABI to be targeted from the backend"));
|
||||
|
||||
static Strings *pModFileAliasStrings = &global.params.modFileAliasStrings;
|
||||
|
|
|
@ -479,6 +479,8 @@ void ArgsBuilder::addSanitizers(const llvm::Triple &triple) {
|
|||
|
||||
void ArgsBuilder::build(llvm::StringRef outputPath,
|
||||
const std::vector<std::string> &defaultLibNames) {
|
||||
const auto &triple = *global.params.targetTriple;
|
||||
|
||||
// object files
|
||||
for (auto objfile : global.params.objfiles) {
|
||||
args.push_back(objfile);
|
||||
|
@ -494,7 +496,7 @@ void ArgsBuilder::build(llvm::StringRef outputPath,
|
|||
|
||||
// Link with profile-rt library when generating an instrumented binary.
|
||||
if (opts::isInstrumentingForPGO()) {
|
||||
addProfileRuntimeLinkFlags(*global.params.targetTriple);
|
||||
addProfileRuntimeLinkFlags(triple);
|
||||
}
|
||||
|
||||
if (opts::enableDynamicCompile) {
|
||||
|
@ -521,10 +523,10 @@ void ArgsBuilder::build(llvm::StringRef outputPath,
|
|||
args.push_back("-o");
|
||||
args.push_back(std::string(outputPath));
|
||||
|
||||
addSanitizers(*global.params.targetTriple);
|
||||
addSanitizers(triple);
|
||||
|
||||
if (opts::fXRayInstrument) {
|
||||
addXRayLinkFlags(*global.params.targetTriple);
|
||||
addXRayLinkFlags(triple);
|
||||
}
|
||||
|
||||
// Add LTO link flags before adding the user link switches, such that the user
|
||||
|
@ -559,16 +561,14 @@ void ArgsBuilder::build(llvm::StringRef outputPath,
|
|||
addLdFlag("-rpath", rpath);
|
||||
}
|
||||
|
||||
if (global.params.targetTriple->getOS() == llvm::Triple::Linux ||
|
||||
(global.params.targetTriple->getOS() == llvm::Triple::FreeBSD &&
|
||||
(useInternalLLDForLinking() ||
|
||||
(!opts::linker.empty() && opts::linker != "bfd") ||
|
||||
(opts::linker.empty() && isLldDefaultLinker())))) {
|
||||
// Make sure we don't do --gc-sections when generating a profile-
|
||||
// instrumented binary. The runtime relies on magic sections, which
|
||||
// would be stripped by gc-section on older version of ld, see bug:
|
||||
// https://sourceware.org/bugzilla/show_bug.cgi?id=19161
|
||||
if (!opts::disableLinkerStripDead && !opts::isInstrumentingForPGO()) {
|
||||
if (triple.isOSBinFormatMachO()) {
|
||||
addLdFlag("-dead_strip");
|
||||
} else {
|
||||
addLdFlag("--gc-sections");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -57,7 +57,7 @@ static llvm::cl::opt<bool, true> preserveDwarfLineSection(
|
|||
llvm::cl::init(false));
|
||||
#endif
|
||||
|
||||
static const char *getABI(const llvm::Triple &triple) {
|
||||
const char *getABI(const llvm::Triple &triple) {
|
||||
llvm::StringRef ABIName(opts::mABI);
|
||||
if (ABIName != "") {
|
||||
switch (triple.getArch()) {
|
||||
|
@ -88,6 +88,22 @@ static const char *getABI(const llvm::Triple &triple) {
|
|||
if (ABIName.startswith("elfv2"))
|
||||
return "elfv2";
|
||||
break;
|
||||
case llvm::Triple::riscv64:
|
||||
if (ABIName.startswith("lp64f"))
|
||||
return "lp64f";
|
||||
if (ABIName.startswith("lp64d"))
|
||||
return "lp64d";
|
||||
if (ABIName.startswith("lp64"))
|
||||
return "lp64";
|
||||
break;
|
||||
case llvm::Triple::riscv32:
|
||||
if (ABIName.startswith("ilp32f"))
|
||||
return "ilp32f";
|
||||
if (ABIName.startswith("ilp32d"))
|
||||
return "ilp32d";
|
||||
if (ABIName.startswith("ilp32"))
|
||||
return "ilp32";
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -104,7 +120,9 @@ static const char *getABI(const llvm::Triple &triple) {
|
|||
case llvm::Triple::ppc64le:
|
||||
return "elfv2";
|
||||
case llvm::Triple::riscv64:
|
||||
return "lp64d";
|
||||
return "lp64";
|
||||
case llvm::Triple::riscv32:
|
||||
return "ilp32";
|
||||
default:
|
||||
return "";
|
||||
}
|
||||
|
@ -421,11 +439,6 @@ createTargetMachine(const std::string targetTriple, const std::string arch,
|
|||
features.push_back("+cx16");
|
||||
}
|
||||
|
||||
if (triple.getArch() == llvm::Triple::riscv64 && !hasFeature("d")) {
|
||||
// Support Double-Precision Floating-Point by default.
|
||||
features.push_back("+d");
|
||||
}
|
||||
|
||||
// Handle cases where LLVM picks wrong default relocModel
|
||||
#if LDC_LLVM_VER >= 1600
|
||||
if (relocModel.has_value()) {}
|
||||
|
@ -492,14 +505,14 @@ createTargetMachine(const std::string targetTriple, const std::string arch,
|
|||
break;
|
||||
}
|
||||
|
||||
// Right now, we only support linker-level dead code elimination on Linux
|
||||
// and FreeBSD using GNU or LLD linkers (based on the --gc-sections flag).
|
||||
// The Apple ld on OS X supports a similar flag (-dead_strip) that doesn't
|
||||
// require emitting the symbols into different sections. The MinGW ld doesn't
|
||||
// seem to support --gc-sections at all.
|
||||
if (!noLinkerStripDead && (triple.getOS() == llvm::Triple::Linux ||
|
||||
triple.getOS() == llvm::Triple::FreeBSD ||
|
||||
triple.getOS() == llvm::Triple::Win32)) {
|
||||
// Linker-level dead code elimination for ELF/wasm binaries using GNU or LLD
|
||||
// linkers (based on the --gc-sections flag) requires a separate section per
|
||||
// symbol.
|
||||
// The Apple ld64 on macOS supports a similar flag (-dead_strip) that doesn't
|
||||
// require emitting the symbols into different sections.
|
||||
// On Windows, the MSVC link.exe / lld-link.exe has `/REF`; LLD enforces
|
||||
// separate sections with LTO, so do the same here.
|
||||
if (!noLinkerStripDead && !triple.isOSBinFormatMachO()) {
|
||||
targetOptions.FunctionSections = true;
|
||||
targetOptions.DataSections = true;
|
||||
}
|
||||
|
|
|
@ -72,3 +72,5 @@ MipsABI::Type getMipsABI();
|
|||
// Looks up a target based on an arch name and a target triple.
|
||||
const llvm::Target *lookupTarget(const std::string &arch, llvm::Triple &triple,
|
||||
std::string &errorMsg);
|
||||
|
||||
const char *getABI(const llvm::Triple &triple);
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#include "llvm/Support/FileSystem.h"
|
||||
#include "llvm/Support/MemoryBuffer.h"
|
||||
#include "llvm/Support/Path.h"
|
||||
#include "llvm/Target/TargetMachine.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <Windows.h>
|
||||
|
@ -121,12 +122,61 @@ void appendTargetArgsForGcc(std::vector<std::string> &args) {
|
|||
return;
|
||||
|
||||
case Triple::riscv64:
|
||||
if (triple.isArch64Bit()) {
|
||||
args.push_back("-march=rv64gc");
|
||||
args.push_back("-mabi=lp64d");
|
||||
{
|
||||
std::string mabi = getABI(triple);
|
||||
args.push_back("-mabi=" + mabi);
|
||||
|
||||
extern llvm::TargetMachine* gTargetMachine;
|
||||
auto featuresStr = gTargetMachine->getTargetFeatureString();
|
||||
llvm::SmallVector<llvm::StringRef, 8> features;
|
||||
featuresStr.split(features, ",", -1, false);
|
||||
|
||||
// Returns true if 'feature' is enabled and false otherwise. Handles the
|
||||
// case where the feature is specified multiple times ('+m,-m'), and
|
||||
// takes the last occurrence.
|
||||
auto hasFeature = [&features](llvm::StringRef feature) {
|
||||
for (int i = features.size() - 1; i >= 0; i--) {
|
||||
auto f = features[i];
|
||||
if (f.substr(1) == feature) {
|
||||
return f[0] == '+';
|
||||
}
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
std::string march;
|
||||
if (triple.isArch64Bit())
|
||||
march = "rv64";
|
||||
else
|
||||
march = "rv32";
|
||||
bool m = hasFeature("m");
|
||||
bool a = hasFeature("a");
|
||||
bool f = hasFeature("f");
|
||||
bool d = hasFeature("d");
|
||||
bool c = hasFeature("c");
|
||||
bool g = false;
|
||||
|
||||
if (m && a && f && d) {
|
||||
march += "g";
|
||||
g = true;
|
||||
} else {
|
||||
march += "i";
|
||||
if (m)
|
||||
march += "m";
|
||||
if (a)
|
||||
march += "a";
|
||||
if (f)
|
||||
march += "f";
|
||||
if (d)
|
||||
march += "d";
|
||||
}
|
||||
if (c)
|
||||
march += "c";
|
||||
if (!g)
|
||||
march += "_zicsr_zifencei";
|
||||
args.push_back("-march=" + march);
|
||||
}
|
||||
return;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -150,7 +150,12 @@ void IrGlobal::define() {
|
|||
// If this global is used from a naked function, we need to create an
|
||||
// artificial "use" for it, or it could be removed by the optimizer if
|
||||
// the only reference to it is in inline asm.
|
||||
if (nakedUse) {
|
||||
// Also prevent linker-level dead-symbol-elimination from stripping
|
||||
// special `rt_*` druntime symbol overrides (e.g., from executables linked
|
||||
// against *shared* druntime; required at least for Apple's ld64 linker).
|
||||
const auto name = gvar->getName();
|
||||
if (nakedUse || name == "rt_options" || name == "rt_envvars_enabled" ||
|
||||
name == "rt_cmdline_enabled") {
|
||||
gIR->usedArray.push_back(gvar);
|
||||
}
|
||||
|
||||
|
|
|
@ -10,7 +10,8 @@ GREP:=grep
|
|||
.PHONY: all clean
|
||||
all: $(addprefix $(ROOT)/,$(addsuffix .done,$(TESTS)))
|
||||
|
||||
$(ROOT)/profile.done: DFLAGS+=-profile
|
||||
# LDC: enable assertions for BUILD=RELEASE (=> `-O -release`)
|
||||
$(ROOT)/profile.done: DFLAGS+=-profile -check=assert=on
|
||||
$(ROOT)/profile.done: $(ROOT)/%.done: $(ROOT)/%
|
||||
@echo Testing $*
|
||||
@rm -f $(ROOT)/mytrace.log $(ROOT)/mytrace.def
|
||||
|
|
6
tests/driver/riscv_abi1.d
Normal file
6
tests/driver/riscv_abi1.d
Normal file
|
@ -0,0 +1,6 @@
|
|||
// REQUIRES: target_RISCV
|
||||
|
||||
// RUN: %ldc %s -mtriple=riscv64-unknown-elf -mattr=+m,-m --gcc=echo > %t && FileCheck %s < %t
|
||||
// CHECK: -mabi=lp64 -march=rv64i_zicsr_zifencei
|
||||
|
||||
void main() {}
|
6
tests/driver/riscv_abi2.d
Normal file
6
tests/driver/riscv_abi2.d
Normal file
|
@ -0,0 +1,6 @@
|
|||
// REQUIRES: target_RISCV
|
||||
|
||||
// RUN: %ldc %s -mtriple=riscv64-unknown-elf -mattr=+m,+a,+d,+f,+c -mabi=lp64d --gcc=echo > %t && FileCheck %s < %t
|
||||
// CHECK: -mabi=lp64d -march=rv64gc
|
||||
|
||||
void main() {}
|
6
tests/driver/riscv_abi3.d
Normal file
6
tests/driver/riscv_abi3.d
Normal file
|
@ -0,0 +1,6 @@
|
|||
// REQUIRES: target_RISCV
|
||||
|
||||
// RUN: %ldc %s -mtriple=riscv32-unknown-elf -mattr=+c,+a,-a,+a,+m --gcc=echo > %t && FileCheck %s < %t
|
||||
// CHECK: -mabi=ilp32 -march=rv32imac_zicsr_zifencei
|
||||
|
||||
void main() {}
|
Loading…
Add table
Add a link
Reference in a new issue