Browse Source

Merge pull request #2850 from jcmdln/linux-llvm-17

Support LLVM >=17.0.1 on Darwin and Linux
gingerBill 1 year ago
parent
commit
6ee7b05b27
4 changed files with 99 additions and 157 deletions
  1. 70 152
      build_odin.sh
  2. 23 3
      src/llvm_backend.cpp
  3. 4 0
      src/llvm_backend.hpp
  4. 2 2
      src/main.cpp

+ 70 - 152
build_odin.sh

@@ -1,133 +1,87 @@
-#!/usr/bin/env bash
+#!/usr/bin/env sh
 set -eu
 
-: ${CXX=clang++}
 : ${CPPFLAGS=}
+: ${CXX=clang++}
 : ${CXXFLAGS=}
 : ${LDFLAGS=}
-: ${ODIN_VERSION=dev-$(date +"%Y-%m")}
-: ${GIT_SHA=}
+: ${LLVM_CONFIG=}
 
+CPPFLAGS="$CPPFLAGS -DODIN_VERSION_RAW=\"dev-$(date +"%Y-%m")\""
 CXXFLAGS="$CXXFLAGS -std=c++14"
+DISABLED_WARNINGS="-Wno-switch -Wno-macro-redefined -Wno-unused-value"
 LDFLAGS="$LDFLAGS -pthread -lm -lstdc++"
+OS_ARCH="$(uname -m)"
+OS_NAME="$(uname -s)"
 
-if [ -d ".git" ] && [ $(which git) ]; then
-	versionTag=( $(git show --pretty='%cd %h' --date=format:%Y-%m --no-patch --no-notes HEAD) )
-	if [ $? -eq 0 ]; then
-		ODIN_VERSION="dev-${versionTag[0]}"
-		GIT_SHA="${versionTag[1]}"
-		CPPFLAGS="$CPPFLAGS -DGIT_SHA=\"$GIT_SHA\""
-	fi
+if [ -d ".git" ] && [ -n "$(command -v git)" ]; then
+	GIT_SHA=$(git show --pretty='%h' --no-patch --no-notes HEAD)
+	CPPFLAGS="$CPPFLAGS -DGIT_SHA=\"$GIT_SHA\""
 fi
 
-CPPFLAGS="$CPPFLAGS -DODIN_VERSION_RAW=\"$ODIN_VERSION\""
-
-DISABLED_WARNINGS="-Wno-switch -Wno-macro-redefined -Wno-unused-value"
-OS=$(uname)
-
-panic() {
-	printf "%s\n" "$1"
+error() {
+	printf "ERROR: %s\n" "$1"
 	exit 1
 }
 
-version() { echo "$@" | awk -F. '{ printf("%d%03d%03d%03d\n", $1,$2,$3,$4); }'; }
-
-config_darwin() {
-	local ARCH=$(uname -m)
-	: ${LLVM_CONFIG=llvm-config}
-
-	# allow for arm only llvm's with version 13
-	if [ "${ARCH}" == "arm64" ]; then
-		MIN_LLVM_VERSION=("13.0.0")
+if [ -z "$LLVM_CONFIG" ]; then
+	# darwin, linux, openbsd
+	if   [ -n "$(command -v llvm-config-17)" ]; then LLVM_CONFIG="llvm-config-17"
+	elif [ -n "$(command -v llvm-config-13)" ]; then LLVM_CONFIG="llvm-config-13"
+	elif [ -n "$(command -v llvm-config-12)" ]; then LLVM_CONFIG="llvm-config-12"
+	elif [ -n "$(command -v llvm-config-11)" ]; then LLVM_CONFIG="llvm-config-11"
+	# freebsd
+	elif [ -n "$(command -v llvm-config17)" ]; then  LLVM_CONFIG="llvm-config-17"
+	elif [ -n "$(command -v llvm-config13)" ]; then  LLVM_CONFIG="llvm-config-13"
+	elif [ -n "$(command -v llvm-config12)" ]; then  LLVM_CONFIG="llvm-config-12"
+	elif [ -n "$(command -v llvm-config11)" ]; then  LLVM_CONFIG="llvm-config-11"
+	# fallback
+	elif [ -n "$(command -v llvm-config)" ]; then LLVM_CONFIG="llvm-config"
 	else
-		# allow for x86 / amd64 all llvm versions beginning from 11
-		MIN_LLVM_VERSION=("11.1.0")
-	fi
-
-	if [ $(version $($LLVM_CONFIG --version)) -lt $(version $MIN_LLVM_VERSION) ]; then
-		if [ "${ARCH}" == "arm64" ]; then
-			panic "Requirement: llvm-config must be base version 13 for arm64"
-		else
-			panic "Requirement: llvm-config must be base version greater than 11 for amd64/x86"
-		fi
-	fi
-
-	MAX_LLVM_VERSION=("14.999.999")
-	if [ $(version $($LLVM_CONFIG --version)) -gt $(version $MAX_LLVM_VERSION) ]; then
-		echo "Tried to use " $(which $LLVM_CONFIG) "version" $($LLVM_CONFIG --version)
-		panic "Requirement: llvm-config must be base version smaller than 15"
+		error "No llvm-config command found. Set LLVM_CONFIG to proceed."
 	fi
+fi
 
-	LDFLAGS="$LDFLAGS -liconv -ldl -framework System"
-	CXXFLAGS="$CXXFLAGS $($LLVM_CONFIG --cxxflags --ldflags)"
-	LDFLAGS="$LDFLAGS -lLLVM-C"
-}
+LLVM_VERSION="$($LLVM_CONFIG --version)"
+LLVM_VERSION_MAJOR="$(echo $LLVM_VERSION | awk -F. '{print $1}')"
+LLVM_VERSION_MINOR="$(echo $LLVM_VERSION | awk -F. '{print $2}')"
+LLVM_VERSION_PATCH="$(echo $LLVM_VERSION | awk -F. '{print $3}')"
 
-config_freebsd() {
-	: ${LLVM_CONFIG=}
+if [ $LLVM_VERSION_MAJOR -lt 11 ] ||
+	([ $LLVM_VERSION_MAJOR -gt 14 ] && [ $LLVM_VERSION_MAJOR -lt 17 ]); then
+	error "Invalid LLVM version $LLVM_VERSION: must be 11, 12, 13, 14 or 17"
+fi
 
-	if [ ! "$LLVM_CONFIG" ]; then
-		if [ -x "$(command -v llvm-config11)" ]; then
-			LLVM_CONFIG=llvm-config11
-		elif [ -x "$(command -v llvm-config12)" ]; then
-			LLVM_CONFIG=llvm-config12
-		elif [ -x "$(command -v llvm-config13)" ]; then
-			LLVM_CONFIG=llvm-config13
-		else
-			panic "Unable to find LLVM-config"
+case "$OS_NAME" in
+Darwin)
+	if [ "$OS_ARCH" == "arm64" ]; then
+		if [ $LLVM_VERSION_MAJOR -lt 13 ] || [ $LLVM_VERSION_MAJOR -gt 17 ]; then
+			error "Darwin Arm64 requires LLVM 13, 14 or 17"
 		fi
 	fi
 
 	CXXFLAGS="$CXXFLAGS $($LLVM_CONFIG --cxxflags --ldflags)"
-	LDFLAGS="$LDFLAGS $($LLVM_CONFIG --libs core native --system-libs)"
-}
-
-config_openbsd() {
-	: ${LLVM_CONFIG=/usr/local/bin/llvm-config}
-
-	LDFLAGS="$LDFLAGS -liconv"
+	LDFLAGS="$LDFLAGS -liconv -ldl -framework System"
+	LDFLAGS="$LDFLAGS -lLLVM-C"
+	;;
+FreeBSD)
 	CXXFLAGS="$CXXFLAGS $($LLVM_CONFIG --cxxflags --ldflags)"
 	LDFLAGS="$LDFLAGS $($LLVM_CONFIG --libs core native --system-libs)"
-}
-
-config_linux() {
-	: ${LLVM_CONFIG=}
-
-	if [ ! "$LLVM_CONFIG" ]; then
-		if [ -x "$(command -v llvm-config)" ]; then
-			LLVM_CONFIG=llvm-config
-		elif [ -x "$(command -v llvm-config-11)" ]; then
-			LLVM_CONFIG=llvm-config-11
-		elif [ -x "$(command -v llvm-config-11-64)" ]; then
-			LLVM_CONFIG=llvm-config-11-64
-		elif [ -x "$(command -v llvm-config-14)" ]; then
-			LLVM_CONFIG=llvm-config-14
-		else
-			panic "Unable to find LLVM-config"
-		fi
-	fi
-
-	MIN_LLVM_VERSION=("11.0.0")
-	if [ $(version $($LLVM_CONFIG --version)) -lt $(version $MIN_LLVM_VERSION) ]; then
-		echo "Tried to use " $(which $LLVM_CONFIG) "version" $($LLVM_CONFIG --version)
-		panic "Requirement: llvm-config must be base version greater than 11"
-	fi
-
-	MAX_LLVM_VERSION=("14.999.999")
-	if [ $(version $($LLVM_CONFIG --version)) -gt $(version $MAX_LLVM_VERSION) ]; then
-		echo "Tried to use " $(which $LLVM_CONFIG) "version" $($LLVM_CONFIG --version)
-		panic "Requirement: llvm-config must be base version smaller than 15"
-	fi
-
-	LDFLAGS="$LDFLAGS -ldl"
+	;;
+Linux)
 	CXXFLAGS="$CXXFLAGS $($LLVM_CONFIG --cxxflags --ldflags)"
-	LDFLAGS="$LDFLAGS $($LLVM_CONFIG --libs core native --system-libs --libfiles) -Wl,-rpath=\$ORIGIN"
-
-	# Creates a copy of the llvm library in the build dir, this is meant to support compiler explorer.
-	# The annoyance is that this copy can be cluttering the development folder. TODO: split staging folders
-	# for development and compiler explorer builds
-	cp $(readlink -f $($LLVM_CONFIG --libfiles)) ./
-}
+	LDFLAGS="$LDFLAGS -ldl -Wl,-rpath=$($LLVM_CONFIG --libdir)"
+	LDFLAGS="$LDFLAGS $($LLVM_CONFIG --libs core native --system-libs --libfiles)"
+	;;
+OpenBSD)
+	CXXFLAGS="$CXXFLAGS $($LLVM_CONFIG --cxxflags --ldflags)"
+	LDFLAGS="$LDFLAGS -liconv"
+	LDFLAGS="$LDFLAGS $($LLVM_CONFIG --libs core native --system-libs)"
+	;;
+*)
+	error "Platform \"$OS_NAME\" unsupported"
+	;;
+esac
 
 build_odin() {
 	case $1 in
@@ -138,20 +92,19 @@ build_odin() {
 		EXTRAFLAGS="-O3"
 		;;
 	release-native)
-		local ARCH=$(uname -m)
-        	if [ "${ARCH}" == "arm64" ]; then
-            		# Use preferred flag for Arm (ie arm64 / aarch64 / etc)
-            		EXTRAFLAGS="-O3 -mcpu=native"
-        	else
-            		# Use preferred flag for x86 / amd64
-            		EXTRAFLAGS="-O3 -march=native"
-        	fi
+		if [ "$OS_ARCH" == "arm64" ]; then
+			# Use preferred flag for Arm (ie arm64 / aarch64 / etc)
+			EXTRAFLAGS="-O3 -mcpu=native"
+		else
+			# Use preferred flag for x86 / amd64
+			EXTRAFLAGS="-O3 -march=native"
+		fi
 		;;
 	nightly)
 		EXTRAFLAGS="-DNIGHTLY -O3"
 		;;
 	*)
-		panic "Build mode unsupported!"
+		error "Build mode \"$1\" unsupported!"
 		;;
 	esac
 
@@ -164,55 +117,20 @@ run_demo() {
 	./odin run examples/demo/demo.odin -file
 }
 
-have_which() {
-	if ! command -v which > /dev/null 2>&1 ; then
-		panic "Could not find \`which\`"
-	fi
-}
-
-have_which
-
-case $OS in
-Linux)
-	config_linux
-	;;
-Darwin)
-	config_darwin
-	;;
-OpenBSD)
-	config_openbsd
-	;;
-FreeBSD)
-	config_freebsd
-	;;
-*)
-	panic "Platform unsupported!"
-	;;
-esac
-
-if [[ $# -eq 0 ]]; then
+if [ $# -eq 0 ]; then
 	build_odin debug
 	run_demo
-	exit 0
-fi
-
-if [[ $# -eq 1 ]]; then
+elif [ $# -eq 1 ]; then
 	case $1 in
 	report)
-		if [[ ! -f "./odin" ]]; then
-			build_odin debug
-		fi
-
+		[ ! -f "./odin" ] && build_odin debug
 		./odin report
-		exit 0
 		;;
 	*)
 		build_odin $1
 		;;
 	esac
-
 	run_demo
-	exit 0
 else
-	panic "Too many arguments!"
+	error "Too many arguments!"
 fi

+ 23 - 3
src/llvm_backend.cpp

@@ -2602,17 +2602,37 @@ gb_internal bool lb_generate_code(lbGenerator *gen) {
 
 
 	if (build_context.sanitizer_flags & SanitizerFlag_Address) {
-		auto paths = array_make<String>(heap_allocator(), 0, 1);
 		if (build_context.metrics.os == TargetOs_windows) {
+			auto paths = array_make<String>(heap_allocator(), 0, 1);
 			String path = concatenate_strings(permanent_allocator(), build_context.ODIN_ROOT, str_lit("\\bin\\llvm\\windows\\clang_rt.asan-x86_64.lib"));
 			array_add(&paths, path);
+			Entity *lib = alloc_entity_library_name(nullptr, make_token_ident("asan_lib"), nullptr, slice_from_array(paths), str_lit("asan_lib"));
+			array_add(&gen->foreign_libraries, lib);
+		} else if (build_context.metrics.os == TargetOs_darwin || build_context.metrics.os == TargetOs_linux) {
+			if (!build_context.extra_linker_flags.text) {
+				build_context.extra_linker_flags = str_lit("-fsanitize=address");
+			} else {
+				build_context.extra_linker_flags = concatenate_strings(permanent_allocator(), build_context.extra_linker_flags, str_lit(" -fsanitize=address"));
+			}
 		}
-		Entity *lib = alloc_entity_library_name(nullptr, make_token_ident("asan_lib"), nullptr, slice_from_array(paths), str_lit("asan_lib"));
-		array_add(&gen->foreign_libraries, lib);
 	}
 	if (build_context.sanitizer_flags & SanitizerFlag_Memory) {
+		if (build_context.metrics.os == TargetOs_darwin || build_context.metrics.os == TargetOs_linux) {
+			if (!build_context.extra_linker_flags.text) {
+				build_context.extra_linker_flags = str_lit("-fsanitize=memory");
+			} else {
+				build_context.extra_linker_flags = concatenate_strings(permanent_allocator(), build_context.extra_linker_flags, str_lit(" -fsanitize=memory"));
+			}
+		}
 	}
 	if (build_context.sanitizer_flags & SanitizerFlag_Thread) {
+		if (build_context.metrics.os == TargetOs_darwin || build_context.metrics.os == TargetOs_linux) {
+			if (!build_context.extra_linker_flags.text) {
+				build_context.extra_linker_flags = str_lit("-fsanitize=thread");
+			} else {
+				build_context.extra_linker_flags = concatenate_strings(permanent_allocator(), build_context.extra_linker_flags, str_lit(" -fsanitize=thread"));
+			}
+		}
 	}
 
 	gb_sort_array(gen->foreign_libraries.data, gen->foreign_libraries.count, foreign_library_cmp);

+ 4 - 0
src/llvm_backend.hpp

@@ -15,6 +15,9 @@
 #include <llvm-c/Object.h>
 #include <llvm-c/BitWriter.h>
 #include <llvm-c/DebugInfo.h>
+#if LLVM_VERSION_MAJOR >= 17
+#include <llvm-c/Transforms/PassBuilder.h>
+#else
 #include <llvm-c/Transforms/AggressiveInstCombine.h>
 #include <llvm-c/Transforms/InstCombine.h>
 #include <llvm-c/Transforms/IPO.h>
@@ -23,6 +26,7 @@
 #include <llvm-c/Transforms/Utils.h>
 #include <llvm-c/Transforms/Vectorize.h>
 #endif
+#endif
 
 #if LLVM_VERSION_MAJOR < 11
 #error "LLVM Version 11 is the minimum required"

+ 2 - 2
src/main.cpp

@@ -89,8 +89,8 @@ gb_global Timings global_timings = {0};
 	#if LLVM_VERSION_MAJOR < 11
 	#error LLVM Version 11+ is required => "brew install llvm@11"
 	#endif
-	#if LLVM_VERSION_MAJOR > 14
-	#error LLVM Version 11..=14 is required => "brew install llvm@14"
+	#if (LLVM_VERSION_MAJOR > 14 && LLVM_VERSION_MAJOR < 17) || LLVM_VERSION_MAJOR > 17
+	#error LLVM Version 11..=14 or =17 is required => "brew install llvm@14"
 	#endif
 #endif