Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Basic support for builtins from compiler-rt #18734

Closed
wants to merge 3 commits into from
Closed
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
12 changes: 12 additions & 0 deletions Make.inc
Original file line number Diff line number Diff line change
Expand Up @@ -228,6 +228,11 @@ LLVM_DEBUG := 0
#LLVM_USE_CMAKE: defined in deps/llvm-ver.mk as it depends on LLVM_VER_SHORT
# set to 1 to get clang and compiler-rt
BUILD_LLVM_CLANG := 0
# set to 0 to disable building compiler-rt standalone.
# Currently compiler-rt can only be built alongside clang
# so we default to the standalone build
STANDALONE_COMPILER_RT := 1

# set to 1 to get lldb (often does not work, no chance with llvm3.2 and earlier)
# see http://lldb.llvm.org/build.html for dependencies
BUILD_LLDB := 0
Expand Down Expand Up @@ -483,10 +488,17 @@ OBJCOPY := $(CROSS_COMPILE)objcopy
# file extensions
ifeq ($(OS), WINNT)
SHLIB_EXT := dll
ifeq ($(USEMSVC),1)
STATICLIB_EXT := lib
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

only with msvc. where are you dealing with a lib file?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also under mingw64? ce33683 changed that we are now linking sys.so statically against compiler-rt.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no, mingw static libraries are .a extension. compiler-rt's build system is probably full of wrong windows==msvc assumptions that should be fixed rather than worked around the wrong way here

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay, I will fix this in the morning (It was my wrong assumption, not compiler-rts)

Is there a way of detecting the compiler from the Makefile?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

there's a USEMSVC or some flag like that but it's a hack, you probably shouldn't worry about it. if we ever support msvc properly it'll be via cmake anyway.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So just changing lib to a would be sufficient for now?

else
STATICLIB_EXT := a
endif
else ifeq ($(OS), Darwin)
SHLIB_EXT := dylib
STATICLIB_EXT := a
else
SHLIB_EXT := so
STATICLIB_EXT := a
endif

# On Windows, we want shared library files to end up in $(build_bindir), instead of $(build_libdir)
Expand Down
3 changes: 2 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,7 @@ $(build_datarootdir)/julia/julia-config.jl : $(JULIAHOME)/contrib/julia-config.j
$(build_private_libdir)/%.$(SHLIB_EXT): $(build_private_libdir)/%.o
@$(call PRINT_LINK, $(CXX) $(LDFLAGS) -shared $(fPIC) -L$(build_private_libdir) -L$(build_libdir) -L$(build_shlibdir) -o $@ $< \
$(if $(findstring -debug.$(SHLIB_EXT),$(notdir $@)),-ljulia-debug,-ljulia) \
$(build_private_libdir)/libcompiler-rt.$(STATICLIB_EXT) \
$$([ $(OS) = WINNT ] && echo '' -lssp))
@$(INSTALL_NAME_CMD)$(notdir $@) $@
@$(DSYMUTIL) $@
Expand Down Expand Up @@ -226,7 +227,7 @@ $(build_depsbindir)/stringreplace: $(JULIAHOME)/contrib/stringreplace.c | $(buil
JL_LIBS := julia julia-debug

# private libraries, that are installed in $(prefix)/lib/julia
JL_PRIVATE_LIBS := ccalltest
JL_PRIVATE_LIBS := ccalltest compiler-rt
ifeq ($(USE_GPL_LIBS), 1)
JL_PRIVATE_LIBS += suitesparse_wrapper
endif
Expand Down
2 changes: 1 addition & 1 deletion contrib/windows/msys_build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@ echo 'override LIBLAPACKNAME = $(LIBBLASNAME)' >> Make.user
# libuv since its static lib is no longer included in the binaries
# openlibm since we need it as a static library to work properly
# utf8proc since its headers are not in the binary download
echo 'override DEP_LIBS = libuv utf8proc' >> Make.user
echo 'override DEP_LIBS = compiler-rt libuv utf8proc' >> Make.user

if [ -n "$USEMSVC" ]; then
# Openlibm doesn't build well with MSVC right now
Expand Down
5 changes: 3 additions & 2 deletions deps/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ include $(SRCDIR)/tools/git-external.mk
# prevent installing libs into usr/lib64 on opensuse
unexport CONFIG_SITE

DEP_LIBS :=
DEP_LIBS := compiler-rt
Copy link
Contributor

@tkelman tkelman Sep 29, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

only ifeq($(BUILD_COMPILER_RT), 1), right?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is more complicated than that. As far as I can tell we will need to unconditionally build with compiler-rt (except for llvm-free builds).
BUILD_COMPILER_RT==1 means that we will try to build a standalone compiler-rt iff LLVM hasn't build one.


ifeq ($(USE_GPL_LIBS), 1)
DEP_LIBS += suitesparse-wrapper
Expand Down Expand Up @@ -175,9 +175,10 @@ uninstall: $(addprefix uninstall-, $(DEP_LIBS_STAGED))
cleanall: $(addprefix clean-, $(DEP_LIBS))
distcleanall: $(addprefix distclean-, $(DEP_LIBS))
rm -rf $(build_prefix)
getall: get-llvm get-libuv get-pcre get-openlibm get-openspecfun get-dsfmt get-openblas get-lapack get-fftw get-suitesparse get-arpack get-unwind get-osxunwind get-gmp get-mpfr get-patchelf get-utf8proc get-objconv get-mbedtls get-libssh2 get-curl get-libgit2
getall: get-llvm get-compiler-rt get-libuv get-pcre get-openlibm get-openspecfun get-dsfmt get-openblas get-lapack get-fftw get-suitesparse get-arpack get-unwind get-osxunwind get-gmp get-mpfr get-patchelf get-utf8proc get-objconv get-mbedtls get-libssh2 get-curl get-libgit2

include $(SRCDIR)/llvm.mk
include $(SRCDIR)/compiler-rt.mk
include $(SRCDIR)/libuv.mk
include $(SRCDIR)/pcre.mk
include $(SRCDIR)/openlibm.mk
Expand Down
149 changes: 149 additions & 0 deletions deps/compiler-rt.mk
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
##
# In order to support fallbacks within llvm we need to support
# compiler-rt. This means linking sys.so against it and resolving
# symbols during JIT compilation (see jitlayers.cpp). For the latter part we need to create
# a .so that we can load, but compiler-rt only comes in a .a.
#
# There are several configurations to take into account.
# 1. STANDALONE_COMPILER_RT == 1
# Download and install compiler_rt independently of llvm/clang.
# We still use the the LLVM_VER to pick the right compiler-rt.
# 2. STANDALONE_COMPILER_RT == 0
# On LLVM >= 3.8 we can build compiler-rt along side LLVM.
# 3. USE_SYSTEM_LLVM == 1 && STANDALONE_COMPILER_RT == 0
# Fallback definition.
# libclang_rt.builtins is distributed with clang and so
# we assume that USE_SYSTEM_LLVM == 1 means that clang is also
Copy link
Contributor

@tkelman tkelman Sep 29, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not sure this is a safe assumption to make

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes this adds an implicit dependency on clang...
We could relax this a bit by using a standalone build for USE_SYSTEM_LLVM == 1 && BUILD_COMPILER_RT == 1, but for USE_SYSTEM_LLVM == 1 && BUILD_COMPILER_RT == 0, we need to fall back onto a system version of compiler-rt and that comes at least on Archlinux with clang.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

At least for Fedora RPMs, I need USE_SYSTEM_LLVM=1 and I also have to build LLVM with gcc. Is that a problem, or is installing clang enough?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Installing clang will be enough or you can set STANDALONE_COMPILER_RT:=1

# installed.
# This is intended as a last ressort and if you use USE_SYSTEM_LLVM
# consider setting STANDALONE_COMPILER_RT:=1
#
# Since we need the shared objectfile for JIT, there is no USE_SYSTEM_COMPILER_RT
##
COMPILER_RT_BUILDDIR := $(BUILDDIR)/compiler-rt-$(LLVM_VER)
COMPILER_RT_SRCDIR := $(SRCDIR)/srccache/compiler-rt-$(LLVM_VER)
COMPILER_RT_LIBFILE := libcompiler-rt.$(SHLIB_EXT)
COMPILER_RT_STATICLIBFILE := libcompiler-rt.$(STATICLIB_EXT)

##
# The naming of the static file for compiler-rt is slightly weird
# and we have to figure out what the proper name is on the current
# platform.
#
# TODO:
# - Currently this build-mode is not supported on Windows.
##
CRT_OS := $(call lower,$(OS))
CRT_LDFLAGS :=
ifneq (,$(filter $(ARCH), powerpc64le ppc64le))
CRT_ARCH := ppc
else ifneq (,$(filter $(ARCH), armv7l armv6l))
CRT_ARCH := armhf
CRT_LDFLAGS += -Wl,--allow-multiple-definition
else
CRT_ARCH := $(call patsubst,i%86,i386,$(ARCH))
CRT_LDFLAGS :=
endif
CRT_STATIC_NAME := clang_rt.builtins-$(CRT_ARCH)

ifeq ($(STANDALONE_COMPILER_RT),1)
COMPILER_RT_TAR := $(SRCDIR)/srccache/compiler-rt-$(LLVM_TAR_EXT)
else
COMPILER_RT_TAR :=
ifeq ($(USE_SYSTEM_LLVM), 1)
CRT_VER:=$(word 1,$(subst svn-, ,$(shell llvm-config --version)))
CRT_DIR := $(shell llvm-config --libdir)/clang/$(CRT_VER)/lib/$(CRT_OS)
else ifeq ($(BUILD_LLVM_COMPILER_RT), 1)
CRT_DIR := $(LLVM_BUILDDIR_withtype)/lib/clang/$(LLVM_VER)/lib/$(CRT_OS)
$(CRT_DIR)/lib$(CRT_STATIC_NAME).$(STATICLIB_EXT): | $(LLVM_BUILDDIR_withtype)/build-compiled
else
$(error Compiler-rt is not available, please set STANDALONE_COMPILER_RT:=1)
endif
endif

$(COMPILER_RT_SRCDIR)/source-extracted: | $(COMPILER_RT_TAR)
mkdir -p $(COMPILER_RT_SRCDIR)
ifneq ($(COMPILER_RT_TAR),)
$(JLCHECKSUM) $(COMPILER_RT_TAR)
$(TAR) -C $(COMPILER_RT_SRCDIR) --strip-components 1 -xf $(COMPILER_RT_TAR)
endif
echo 1 > $@

$(COMPILER_RT_BUILDDIR):
mkdir -p $@
$(COMPILER_RT_BUILDDIR)/$(CRT_ARCH):
mkdir -p $@

ifeq ($(STANDALONE_COMPILER_RT),1)
$(COMPILER_RT_BUILDDIR)/Makefile: compiler-rt_standalone.mk | $(COMPILER_RT_BUILDDIR)
cp $< $@
$(COMPILER_RT_BUILDDIR)/build-configured: $(COMPILER_RT_BUILDDIR)/Makefile | $(COMPILER_RT_BUILDDIR)/$(CRT_ARCH)
echo 1 > $@

$(COMPILER_RT_BUILDDIR)/build-compiled: | $(COMPILER_RT_SRCDIR)/source-extracted $(COMPILER_RT_BUILDDIR)/build-configured
$(MAKE) -C $(COMPILER_RT_BUILDDIR) \
CC='$(CC)' \
AR='$(AR)' \
LIBFILE=$(COMPILER_RT_LIBFILE) \
SLIBFILE=$(COMPILER_RT_STATICLIBFILE) \
CRT_SRCDIR=$(COMPILER_RT_SRCDIR) \
OS=$(CRT_OS) \
ARCH=$(CRT_ARCH) \
USE_CLANG=$(USE_CLANG) \
fPIC=$(fPIC) all
$(COMPILER_RT_BUILDDIR)/$(COMPILER_RT_LIBFILE): | $(COMPILER_RT_BUILDDIR)/build-compiled
$(COMPILER_RT_BUILDDIR)/$(COMPILER_RT_STATICLIBFILE): | $(COMPILER_RT_BUILDDIR)/build-compiled
else
$(COMPILER_RT_BUILDDIR)/build-configured: $(COMPILER_RT_BUILDDIR)
echo 1 > $@
# Use compiler-rt from the clang installation
$(COMPILER_RT_BUILDDIR)/$(COMPILER_RT_LIBFILE): $(CRT_DIR)/lib$(CRT_STATIC_NAME).$(STATICLIB_EXT) | $(COMPILER_RT_BUILDDIR)/build-configured
$(CC) $(LDFLAGS) -nostdlib $(CRT_LDFLAGS) -shared $(fPIC) -o $@ $(WHOLE_ARCHIVE) -L$(dir $<) -l$(CRT_STATIC_NAME) $(WHOLE_NOARCHIVE)
$(COMPILER_RT_BUILDDIR)/$(COMPILER_RT_STATICLIBFILE): $(CRT_DIR)/lib$(CRT_STATIC_NAME).$(STATICLIB_EXT) | $(COMPILER_RT_BUILDDIR)/build-configured
cp $^ $@
endif

ifneq ($(COMPILER_RT_TAR),)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think this rule makes sense overall if COMPILER_RT_TAR is empty

ifeq ($(LLVM_COMPILER_RT_TAR),)
$(COMPILER_RT_TAR): | $(SRCDIR)/srccache
$(JLDOWNLOAD) $@ $(LLVM_SRC_URL)/$(notdir $@)
endif
endif

get-compiler-rt: $(COMPILER_RT_TAR)
ifeq ($(STANDALONE_COMPILER_RT), 0)
extract-compiler-rt: #NONE
else
extract-compiler-rt: $(COMPILER_RT_SRCDIR)/source-extracted
endif

$(build_shlibdir)/$(COMPILER_RT_LIBFILE): $(COMPILER_RT_BUILDDIR)/$(COMPILER_RT_LIBFILE)
mkdir -p $(dir $@)
cp $< $@
@$(INSTALL_NAME_CMD)$(notdir $@) $@
@$(DSYMUTIL) $@

$(build_private_libdir)/$(COMPILER_RT_STATICLIBFILE): $(COMPILER_RT_BUILDDIR)/$(COMPILER_RT_STATICLIBFILE)
mkdir -p $(dir $@)
cp $< $@

$(build_prefix)/manifest/compiler-rt: | $(build_prefix)/manifest
echo "compiler-rt-$(LLVM_VER)" > $@

check-compiler-rt: #NONE
fastcheck-compiler-rt: #NONE
configure-compiler-rt: $(COMPILER_RT_BUILDDIR)/build-configured
clean-compiler-rt:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think clean should depend on uninstall, most of the autogenerated ones do IIRC

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See L145.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

makefiles are awful

rm -rf $(COMPILER_RT_BUILDDIR)
distclean-compiler-rt: clean-compiler-rt
rm -f $(COMPILER_RT_TAR)
rm -rf $(COMPILER_RT_SRCDIR)
uninstall-compiler-rt:
rm -f $(build_prefix)/manifest/compiler-rt
rm -f $(build_shlibdir)/$(COMPILER_RT_LIBFILE)
rm -f $(build_private_libdir)/$(COMPILER_RT_STATICLIBFILE)
distclean-compiler-rt clean-compiler-rt: | uninstall-compiler-rt

compile-compiler-rt: $(COMPILER_RT_BUILDDIR)/$(COMPILER_RT_LIBFILE)
install-compiler-rt: $(build_shlibdir)/$(COMPILER_RT_LIBFILE) $(build_private_libdir)/$(COMPILER_RT_STATICLIBFILE) $(build_prefix)/manifest/compiler-rt

90 changes: 90 additions & 0 deletions deps/compiler-rt_standalone.mk
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
##
# This Makefile will be executed in $(BUILDDIR)/compiler-rt-$(LLVM_VER)
# Expected variables from the parent
# CRT_SRCDIR
# LIBFILE
# SLIBFILE
# OS (CRT_OS not JL_OS)
# ARCH (CRT_ARCH not JL_ARCH)
# USE_CLANG
# fPIC
##

# The standalone compiler-rt build is inspired by
# https://github.com/ReservedField/arm-compiler-rt
SRCDIR := $(CRT_SRCDIR)/lib/builtins

ifeq ($(ARCH), armhf)
ARCH_SRCDIR := $(SRCDIR)/arm
else ifeq ($(ARCH), aarch64)
ARCH_SRCDIR := $(SRCDIR)/arm64
else
ARCH_SRCDIR := $(SRCDIR)/$(ARCH)
endif

INCLUDES := -I$(SRCDIR) -I$(ARCH_SRCDIR)
# TODO(vchuravy) discover architecture flags
CRT_CFLAGS := $(CPPFLAGS) $(CFLAGS) -O2 -std=c11 \
$(fPIC) $(INCLUDES) \
-fno-builtin -ffreestanding
ifeq ($(USE_CLANG),1)
CRT_CFLAGS += -Wno-unknown-attributes -Wno-macro-redefined
endif

##
# Blacklist a few files we don't want to deal with
##
MAKEFLAGS := --no-builtin-rules
BLACKLIST := atomic.o atomic_flag_clear.o atomic_flag_clear_explicit.o \
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@tkelman the emutls failure means we need to update the blacklist to contain the related files

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

commit that and we could try throwing it at the buildbots again?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looks like that fixes the windows build (need to run tests locally, will see) but not whatever's wrong with the 32 bit linux buildbot

atomic_flag_test_and_set.o atomic_flag_test_and_set_explicit.o \
atomic_signal_fence.o atomic_thread_fence.o emutls.o

CRT_LDFLAGS :=
ifeq ($(ARCH),ppc)
BLACKLIST += saveFP.o restFP.o
else ifeq ($(ARCH), armhf)
CRT_LDFLAGS += -Wl,--allow-multiple-definition
endif


ifeq ($(OS),darwin)
# Which blacklist should we choose
BLACKLIST += $(shell cat $(SRCDIR)/Darwin-excludes/osx.txt)
else ifeq ($(OS), winnt)
CRT_CFLAGS += -D_WIN32
endif

CFILES := $(wildcard $(SRCDIR)/*.c)
GENERAL_OBJS1 := $(filter-out $(BLACKLIST), $(notdir $(CFILES:.c=.o)))

ARCH_CFILES := $(wildcard $(ARCH_SRCDIR)/*.c)
ARCH_SFILES := $(wildcard $(ARCH_SRCDIR)/*.S)
ARCH_OBJS := $(filter-out $(BLACKLIST), $(notdir $(join $(ARCH_CFILES:.c=.o),$(ARCH_SFILES:.S=.o))))

GENERAL_OBJS := $(filter-out $(ARCH_OBJS), $(GENERAL_OBJS1))

OBJS := $(GENERAL_OBJS) $(ARCH_OBJS)

%.o: $(SRCDIR)/%.c
$(CC) $(CRT_CFLAGS) -c $< -o $@

%.o: $(SRCDIR)/%.S
$(CC) $(CRT_CFLAGS) -c $< -o $@

%.o: $(ARCH_SRCDIR)/%.c
$(CC) $(CRT_CFLAGS) -c $< -o $@

%.o: $(ARCH_SRCDIR)/%.S
$(CC) $(CRT_CFLAGS) -c $< -o $@

$(LIBFILE): $(OBJS)
$(CC) $(CRT_LDFLAGS) $(CRT_CFLAGS) $(LDFLAGS) -shared -o $@ $^

$(SLIBFILE): $(OBJS)
$(AR) rs $@ $^

.PHONY: all
all: $(LIBFILE) $(SLIBFILE)
clean: $(OBJS) $(LIBFILE) $(SLIBFILE)
rm $^

Loading