Skip to content

Commit

Permalink
Merge pull request #20396 from mppf/chpl-llvm-support-var
Browse files Browse the repository at this point in the history
Add CHPL_LLVM_SUPPORT and adjust quickstart

Follow-up to PR #19565.

This PR takes two steps to improve the situation after PR #19565.

First, it adds `CHPL_LLVM_SUPPORT` as a `printchplenv` variable. This
variable indicates where to get the LLVM Support Library (which is
currently required to build the compiler). It can be `bundled` or
`system`. See issue #20380.

On the name of this variable, I wondered if `CHPL_LLVM_SUPPORT_LIBRARY`
would be a better name? `CHPL_LLVM_SUPPORT` could be interpreted as "does
Chapel build with LLVM support" but that is what `CHPL_LLVM` does. On the
other hand, since it appears in `printchplenv --all` within the
`CHPL_LLVM` block, I think `CHPL_LLVM_SUPPORT` is OK.

Second, it adjusts the quickstart scripts to set `CHPL_LLVM=system` if a
compatible system LLVM is detected. See issue #20273.

Reviewed by @daviditen - thanks!

- [x] full local testing
- [x] make check with CHPL_LLVM unset where no system LLVM exists produces "Please set the environment variable CHPL_LLVM to a supported value." error
- [x] make check with CHPL_LLVM=none where no system LLVM exists
- [x] make check with CHPL_LLVM=none where a system LLVM exists
- [x] make check with CHPL_LLVM=bundled
- [x] make check with  CHPL_LLVM=system
  • Loading branch information
mppf authored Aug 11, 2022
2 parents 9b9d360 + 884f5ca commit 454cdd0
Show file tree
Hide file tree
Showing 9 changed files with 115 additions and 43 deletions.
3 changes: 2 additions & 1 deletion test/setchplenv/verify_setchplenv_scripts.py
Original file line number Diff line number Diff line change
Expand Up @@ -151,11 +151,12 @@ def get_path_var(var_name):
self.assertEqual(os.stat(self.chpl_home), os.stat(actual_chpl_home))

if 'quickstart' in os.path.relpath(setchplenv_script, self.util_dir):
got_llvm = get_var('CHPL_LLVM')
self.assertEqual('none', get_var('CHPL_COMM'))
self.assertEqual('fifo', get_var('CHPL_TASKS'))
self.assertEqual('none', get_var('CHPL_GMP'))
self.assertEqual('none', get_var('CHPL_RE2'))
self.assertEqual('none', get_var('CHPL_LLVM'))
self.assertTrue('none' == got_llvm or 'system' == got_llvm)
self.assertEqual('cstdlib', get_var('CHPL_MEM'))

def check_scripts(self, shell, source_cmd, path_sep,
Expand Down
33 changes: 23 additions & 10 deletions third-party/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -131,17 +131,30 @@ $(LIBUNWIND_INSTALL_DIR): $(LIBUNWIND_DEPEND)
rm -rf $(LIBUNWIND_INSTALL_DIR) && rm -rf $(LIBUNWIND_BUILD_DIR)
cd libunwind && $(MAKE)

# Check for LLVM_SUPPORT_INSTALL_DIR or LLVM_INSTALL_DIR,
# depending on the configuration.
LLVM_CHECK_INSTALL_DIR := $(LLVM_INSTALL_DIR)
ifeq ($(CHPL_MAKE_LLVM), none)
LLVM_CHECK_INSTALL_DIR := $(LLVM_SUPPORT_INSTALL_DIR)
endif
ifeq ($(CHPL_MAKE_LLVM), unset)
# Print the error about needing to set CHPL_LLVM
llvm: FORCE
cd llvm && $(MAKE) unset

else ifeq ($(CHPL_MAKE_LLVM), bundled)
# build the bundled LLVM
llvm: $(LLVM_INSTALL_DIR)
$(LLVM_INSTALL_DIR): $(LLVM_DEPEND)
rm -rf $(LLVM_INSTALL_DIR)
cd llvm && $(MAKE) llvm

else ifeq ($(CHPL_MAKE_LLVM_SUPPORT), bundled)
# build the bundled LLVM support library
llvm: $(LLVM_SUPPORT_INSTALL_DIR)
$(LLVM_SUPPORT_INSTALL_DIR): $(LLVM_DEPEND)
rm -rf $(LLVM_SUPPORT_INSTALL_DIR)
cd llvm && $(MAKE) llvm-support

else

llvm: $(LLVM_CHECK_INSTALL_DIR)
$(LLVM_CHECK_INSTALL_DIR): $(LLVM_DEPEND)
rm -rf $(LLVM_CHECK_INSTALL_DIR)
cd llvm && $(MAKE) $(CHPL_MAKE_LLVM)
# nothing to do for CHPL_LLVM=system / CHPL_LLVM_SUPPORT=system
llvm:
endif

# Qthreads may use hwloc and/or jemalloc. Ensure they are built first.
ifeq ($(CHPL_MAKE_HWLOC), bundled)
Expand Down
4 changes: 2 additions & 2 deletions third-party/llvm/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -210,14 +210,14 @@ llvm: llvm-config llvm-build llvm-install

llvm-clang: llvm

# to build the LLVM support library even with CHPL_LLVM=none
# to build the LLVM support library only for use with CHPL_LLVM=none
llvm-support: llvm-config-support-only llvm-build-support-only llvm-install-support-only

bundled: llvm

system:

none: llvm-support
none:

unset:
@echo "Error: Please set the environment variable CHPL_LLVM to a supported value."
Expand Down
92 changes: 74 additions & 18 deletions util/chplenv/chpl_llvm.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ def llvm_versions():
return ('14','13','12','11',)

@memoize
def get_uniq_cfg_path_for(llvm_val):
if llvm_val == "bundled" or llvm_val == "none":
def get_uniq_cfg_path_for(llvm_val, llvm_support_val):
if llvm_val == "bundled" or llvm_support_val == "bundled":
# put platform-arch-compiler for included llvm
llvm_target_dir = chpl_bin_subdir.get('host')
else:
Expand All @@ -31,18 +31,19 @@ def get_uniq_cfg_path_for(llvm_val):
@memoize
def get_uniq_cfg_path():
llvm_val = get()
return get_uniq_cfg_path_for(llvm_val)
llvm_support_val = get_llvm_support()
return get_uniq_cfg_path_for(llvm_val, llvm_support_val)

def get_bundled_llvm_dir():
chpl_third_party = get_chpl_third_party()
llvm_target_dir = get_uniq_cfg_path_for('bundled')
llvm_target_dir = get_uniq_cfg_path_for('bundled', 'bundled')
llvm_subdir = os.path.join(chpl_third_party, 'llvm', 'install',
llvm_target_dir)
return llvm_subdir

def get_bundled_llvm_support_only_dir():
chpl_third_party = get_chpl_third_party()
llvm_target_dir = get_uniq_cfg_path_for('none')
llvm_target_dir = get_uniq_cfg_path_for('none', 'bundled')
llvm_subdir = os.path.join(chpl_third_party, 'llvm', 'install',
'support-only-' + llvm_target_dir)
return llvm_subdir
Expand All @@ -51,7 +52,7 @@ def is_included_llvm_built(llvm_val):
llvm_subdir = None
if llvm_val == 'bundled':
llvm_subdir = get_bundled_llvm_dir()
elif llvm_val == 'none':
else:
llvm_subdir = get_bundled_llvm_support_only_dir()

llvm_header = os.path.join(llvm_subdir, 'include', 'llvm',
Expand Down Expand Up @@ -216,9 +217,35 @@ def find_system_llvm_config():
return ''


# Returns whether to use the bundled or system LLVM for the
# LLVM support module.
# This corresponds to the CHPL_LLVM_SUPPORT variable.
# Since the LLVM support module is now required to build Chapel,
# this returns "bundled" or "system" even if CHPL_LLVM=none.
@memoize
def get_llvm_support():
llvm_val = get()

# If using CHPL_LLVM=bundled or CHPL_LLVM=system
# then CHPL_LLVM_SUPPORT needs to match
if llvm_val == 'bundled':
return 'bundled'
if llvm_val == 'system':
return 'system'

llvm_support_val = overrides.get('CHPL_LLVM_SUPPORT')
if not llvm_support_val:
if has_compatible_installed_llvm():
llvm_support_val = 'system'
else:
llvm_support_val = 'bundled'

return llvm_support_val

@memoize
def get_llvm_config():
llvm_val = get()
llvm_support_val = get_llvm_support()
llvm_config = overrides.get('CHPL_LLVM_CONFIG', 'none')

if llvm_val == 'bundled':
Expand All @@ -228,18 +255,20 @@ def get_llvm_config():
warning("CHPL_LLVM_CONFIG is ignored for CHPL_LLVM=bundled")
llvm_config = bundled_config

elif llvm_val == 'none':
elif llvm_support_val == 'bundled':
llvm_subdir = get_bundled_llvm_support_only_dir()
bundled_config = os.path.join(llvm_subdir, 'bin', 'llvm-config')
if llvm_config != 'none' and llvm_config != bundled_config:
warning("CHPL_LLVM_CONFIG is ignored for CHPL_LLVM=none")
warning("CHPL_LLVM_CONFIG is ignored for CHPL_LLVM_SUPPORT=bundled")
llvm_config = bundled_config

elif llvm_config == 'none' and llvm_val == 'system':
llvm_config = find_system_llvm_config()
elif llvm_config == 'none':
if llvm_val == 'system' or llvm_support_val == 'system':
llvm_config = find_system_llvm_config()

return llvm_config


@memoize
def get_llvm_version():
(llvm_version, _) = check_llvm_config(get_llvm_config())
Expand All @@ -248,6 +277,7 @@ def get_llvm_version():
@memoize
def validate_llvm_config():
llvm_val = get()
llvm_support_val = get_llvm_support()
llvm_config = get_llvm_config()

if llvm_val == 'system':
Expand All @@ -256,6 +286,12 @@ def validate_llvm_config():
" with one of the supported versions: {0}".format(
llvm_versions_string()))

if llvm_support_val == 'system':
if llvm_config == '' or llvm_config == 'none':
error("CHPL_LLVM_SUPPORT=system but could not find an installed "
"LLVM with one of the supported versions: {0}".format(
llvm_versions_string()))

if (llvm_val == 'system' or
(llvm_val == 'bundled' and os.path.exists(llvm_config))):
version, config_error = check_llvm_config(llvm_config)
Expand Down Expand Up @@ -363,6 +399,11 @@ def has_compatible_installed_llvm():
# otherwise, something went wrong, so return False
return False

# Returns the setting to use for CHPL_LLVM
# CHPL_LLVM=none means build the compiler without enabling LLVM and clang
# integration (but note the LLVM support library is still used)
# CHPL_LLVM=system means to use a system install of LLVM and clang
# CHPL_LLVM=bundled means to use the bundled version of LLVM and clang
@memoize
def get():
llvm_val = overrides.get('CHPL_LLVM')
Expand Down Expand Up @@ -726,9 +767,14 @@ def get_host_compile_args():
system = [ ]

llvm_val = get()
llvm_support_val = get_llvm_support()
llvm_config = get_llvm_config()

if llvm_val == 'system':
# quit early if the llvm value is unset
if llvm_val == 'unset':
return (bundled, system)

if llvm_support_val == 'system':
# On Mac OS X with Homebrew, apply a workaround for issue #19217.
# This avoids finding headers in the libc++ installed by llvm@12 e.g.
if use_system_libcxx_workaround():
Expand All @@ -748,9 +794,7 @@ def get_host_compile_args():
cxxflags = run_command([llvm_config, '--cxxflags'])
system.extend(filter_llvm_config_flags(cxxflags.split()))

elif llvm_val == 'bundled' or llvm_val == 'none':
# none is handled here to get the LLVMSupport library

elif llvm_support_val == 'bundled':
# don't try to run llvm-config if it's not built yet
if is_included_llvm_built(llvm_val):
# Note, the cxxflags should include the -I for the include dir
Expand All @@ -774,6 +818,7 @@ def get_host_link_args():

llvm_dynamic = True
llvm_val = get()
llvm_support_val = get_llvm_support()
llvm_config = get_llvm_config()
clang_static_libs = ['-lclangFrontend',
'-lclangSerialization',
Expand All @@ -799,12 +844,16 @@ def get_host_link_args():
'coroutines',
'lto']

# quit early if the llvm value is unset
if llvm_val == 'unset':
return (bundled, system)

# only use LLVMSupport for CHPL_LLVM=none
if llvm_val == 'none':
clang_static_libs = [ ]
llvm_components = ['support']

if llvm_val == 'system':
if llvm_support_val == 'system':
# On Mac OS X with Homebrew, apply a workaround for issue #19217.
# This avoids linking with the libc++ installed by llvm@12 e.g.
if use_system_libcxx_workaround():
Expand Down Expand Up @@ -846,9 +895,7 @@ def get_host_link_args():
system.extend(filter_llvm_link_flags(ldflags.split()))


elif llvm_val == 'bundled' or llvm_val == 'none':
# none is handled here to use the LLVM Support library

elif llvm_support_val == 'bundled':
# Link statically for now for the bundled configuration
# If this changes in the future:
# * check for problems finding libstdc++ with different PrgEnv compilers
Expand Down Expand Up @@ -927,6 +974,10 @@ def _main():
parser.add_option('--sdkroot', dest='action',
action='store_const',
const='sdkroot', default='')
parser.add_option('--quickstart', dest='action',
action='store_const',
const='quickstart', default='')



(options, args) = parser.parse_args()
Expand All @@ -946,6 +997,11 @@ def _main():
sys.stdout.write("{0}\n".format(llvm_versions))
elif options.action == 'sdkroot':
sys.stdout.write("{0}\n".format(get_clang_args_sdkroot()))
elif options.action == 'quickstart':
if has_compatible_installed_llvm():
sys.stdout.write("system\n")
else:
sys.stdout.write("none\n")
else:
sys.stdout.write("{0}\n".format(llvm_val))

Expand Down
6 changes: 2 additions & 4 deletions util/chplenv/printchplenv.py
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,7 @@
ChapelEnv('CHPL_RE2', RUNTIME | DEFAULT, 're2'),
ChapelEnv(' CHPL_RE2_IS_OVERRIDDEN', INTERNAL),
ChapelEnv('CHPL_LLVM', COMPILER | DEFAULT, 'llvm'),
ChapelEnv(' CHPL_LLVM_SUPPORT', COMPILER | NOPATH, 'llvm'),
ChapelEnv(' CHPL_LLVM_CONFIG', COMPILER | NOPATH),
ChapelEnv(' CHPL_LLVM_VERSION', COMPILER),
ChapelEnv(' CHPL_LLVM_CLANG_C', INTERNAL),
Expand Down Expand Up @@ -204,6 +205,7 @@ def compute_all_values():
ENV_VALS['CHPL_RE2'] = chpl_re2.get()
ENV_VALS[' CHPL_RE2_IS_OVERRIDDEN'] = chpl_re2.is_overridden()
ENV_VALS['CHPL_LLVM'] = chpl_llvm.get()
ENV_VALS[' CHPL_LLVM_SUPPORT'] = chpl_llvm.get_llvm_support()
ENV_VALS[' CHPL_LLVM_CONFIG'] = chpl_llvm.get_llvm_config()
ENV_VALS[' CHPL_LLVM_VERSION'] = chpl_llvm.get_llvm_version()
llvm_clang_c = chpl_llvm.get_llvm_clang('c')
Expand Down Expand Up @@ -318,10 +320,6 @@ def filter_tidy(chpl_env):
return comm == 'ofi'
elif chpl_env.name == ' CHPL_NETWORK_ATOMICS':
return comm != 'none'
elif chpl_env.name == ' CHPL_LLVM_CONFIG':
return llvm != 'none'
elif chpl_env.name == ' CHPL_LLVM_VERSION':
return llvm != 'none'
elif chpl_env.name == ' CHPL_CUDA_PATH':
return locale_model == 'gpu'
elif chpl_env.name == ' CHPL_CUDA_LIBDEVICE_PATH':
Expand Down
5 changes: 3 additions & 2 deletions util/quickstart/setchplenv.bash
Original file line number Diff line number Diff line change
Expand Up @@ -64,5 +64,6 @@ export CHPL_GMP=none
echo "Setting CHPL_RE2 to none"
export CHPL_RE2=none

echo "Setting CHPL_LLVM to none"
export CHPL_LLVM=none
USE_LLVM=`$CHPL_PYTHON $chpl_home/util/chplenv/chpl_llvm.py --quickstart`
echo "Setting CHPL_LLVM to $USE_LLVM"
export CHPL_LLVM=$USE_LLVM
5 changes: 3 additions & 2 deletions util/quickstart/setchplenv.csh
Original file line number Diff line number Diff line change
Expand Up @@ -53,5 +53,6 @@ setenv CHPL_GMP none
echo "Setting CHPL_RE2 to none"
setenv CHPL_RE2 none

echo "Setting CHPL_LLVM to none"
setenv CHPL_LLVM none
set USE_LLVM = `$CHPL_PYTHON "$CHPL_HOME"/util/chplenv/chpl_llvm.py --quickstart`
echo "Setting CHPL_LLVM to $USE_LLVM"
setenv CHPL_LLVM $USE_LLVM
5 changes: 3 additions & 2 deletions util/quickstart/setchplenv.fish
Original file line number Diff line number Diff line change
Expand Up @@ -57,5 +57,6 @@ set -x CHPL_GMP none
echo "Setting CHPL_RE2 to none"
set -x CHPL_RE2 none

echo "Setting CHPL_LLVM to none"
set -x CHPL_LLVM none
set -x USE_LLVM (eval "$CHPL_PYTHON" "$CHPL_HOME/util/chplenv/chpl_llvm.py" "--quickstart")
echo "Setting CHPL_LLVM to $USE_LLVM"
set -x CHPL_LLVM $USE_LLVM
5 changes: 3 additions & 2 deletions util/quickstart/setchplenv.sh
Original file line number Diff line number Diff line change
Expand Up @@ -75,8 +75,9 @@ export CHPL_RE2
echo " ...none"
echo " "

USE_LLVM=`$CHPL_PYTHON "$CHPL_HOME"/util/chplenv/chpl_llvm.py --quickstart`
echo "Setting CHPL_LLVM to..."
CHPL_LLVM=none
CHPL_LLVM=$USE_LLVM
export CHPL_LLVM
echo " ...none"
echo " ...$USE_LLVM"
echo " "

0 comments on commit 454cdd0

Please sign in to comment.