Skip to content

Commit

Permalink
Merge branch 'develop' into change_arena_end_ptr
Browse files Browse the repository at this point in the history
  • Loading branch information
stevenmeker authored Dec 9, 2024
2 parents aa1b445 + c362cf0 commit 7ecb011
Show file tree
Hide file tree
Showing 14 changed files with 191 additions and 10 deletions.
64 changes: 55 additions & 9 deletions INSTALL.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ python3 -m pip install pybind11 lit
```

## macOS / Homebrew

In order to install the dependencies on macOS, you must have Homebrew installed and on your `PATH`.
```shell
brew update
brew install \
Expand All @@ -40,19 +40,70 @@ brew install \
fmt \
git \
gmp \
grep \
jemalloc \
libffi
libyaml \
llvm@15 \
maven \
mpfr \
pkg-config \
python3 \
z3
```

To ensure that the backend can use pybind11 correctly, we must create an virtual
environment and install the `pybind11` package:
```shell
python3 -m venv venv
source venv/bin/activate
python3 -m pip install pybind11 lit
```

Guarantee that you have the JDK installed and on your `PATH`:
```shell
export PATH="/opt/homebrew/opt/openjdk/bin:$PATH"
```

Some tests rely on GNU Grep options, which are not available on macOS by
default. To ensure that the tests run correctly, you add the path of
GNU Grep to your `PATH` in your shell profile:
```shell
export PATH=/opt/homebrew/Cellar/grep/3.11/libexec/gnubin/:$PATH
```

# Building

## Environment Variables

If you're building on macOS, type the following command or epermanently
add it your `env` (`.zshrc`, `.bashrc`, etc.), so that the Homebrew
installation of LLVM gets picked up correctly. We recommend adding it to
your shell profile.
```shell
export LLVM_DIR=$($(brew --prefix llvm@15)/bin/llvm-config --cmakedir)
```

If you don't usually use the `clang` from your Homebrew installation as
your default compiler, you can set the following CMake flg to use these
`clang` and `clang++`:
```shell
-DCMAKE_C_COMPILER="$(brew --prefix llvm@15)/bin/clang" \
-DCMAKE_CXX_COMPILER="$(brew --prefix llvm@15)/bin/clang++"
```
Once again, we recommend adding them and other llvm binaries to your
`PATH` in your shell profile:
```shell
export PATH="$(brew --prefix llvm@15)/bin:$PATH"
```

Some tests rely on GNU Grep options, which are not available on macOS by
default. To ensure that the tests run correctly, you can create an alias
for GNU Grep:
```shell
alias grep=ggrep
```

Once the system dependencies have been installed, the backend can be built
locally with:
```shell
Expand All @@ -66,12 +117,6 @@ cmake .. \
make -j$(nproc) install
```

If you're building on macOS, add the following option to your CMake invocation
so that the Homebrew installation of LLVM gets picked up correctly.
```shell
-DLLVM_DIR=$($(brew --prefix llvm@15)/bin/llvm-config --cmakedir)
```

Additionally, to build the pattern-matching compiler, run:
```shell
cd matching
Expand All @@ -91,7 +136,8 @@ To run the integration tests, run:
```shell
lit test
```
from the root source directory.
from the root source directory. You can use `-v` to see which test is being executed
and the output of failling tests.

There is also a unit test suite for backend internals;
Add the following option to your CMake invocation to enable it:
Expand All @@ -113,7 +159,7 @@ and conform to best practices.

```shell
# Ubuntu
apt install shellcheck clang-format-12 iwyu
apt install shellcheck clang-format-15 iwyu

# macOS
brew install shellcheck clang-format iwyu
Expand Down
6 changes: 6 additions & 0 deletions bin/llvm-kompile
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ Options:
(immutable) that are enabled by default.
--hidden-visibility Set the visibility of all global symbols in generated code to
"hidden"
--use-gcstrategy Use GC strategy defined for the LLVM backend.
--profile-matching Instrument interpeter to emit a profile of time spent in
top-level rule matching on stderr.
--verify-ir Verify result of IR generation.
Expand Down Expand Up @@ -197,6 +198,11 @@ while [[ $# -gt 0 ]]; do
kompile_clang_flags+=("--hidden-visibility")
shift
;;
--use-gcstrategy)
codegen_flags+=("--use-gcstrategy")
kompile_clang_flags+=("--use-gcstrategy")
shift
;;
--profile-matching)
codegen_flags+=("--profile-matching")
codegen_verify_flags+=("--profile-matching")
Expand Down
8 changes: 8 additions & 0 deletions bin/llvm-kompile-clang
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ flags=()
llc_flags=()
llc_opt_flags="-O0"
visibility_hidden=false
use_gcstrategy=false
link=true
export verbose=false
export profile=false
Expand Down Expand Up @@ -101,6 +102,10 @@ while [[ $# -gt 0 ]]; do
visibility_hidden=true
shift
;;
--use-gcstrategy)
use_gcstrategy=true
shift
;;
*)
;;
esac
Expand Down Expand Up @@ -188,6 +193,9 @@ if [ "$main" != "python_ast" ]; then
run @OPT@ "$modopt" -load-pass-plugin "$passes" -set-visibility-hidden -o "$modhidden"
modopt="$modhidden"
fi
if $use_gcstrategy; then
llc_flags+=("-load="$passes"")
fi
run @LLC@ \
"$modopt" -mtriple=@BACKEND_TARGET_TRIPLE@ \
-filetype=obj "$llc_opt_flags" "${llc_flags[@]}" -o "$modasm"
Expand Down
10 changes: 10 additions & 0 deletions cmake/FixHomebrew.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -20,5 +20,15 @@ if(APPLE)
include_directories(AFTER SYSTEM "${BREW_PREFIX}/include")
link_directories(AFTER "${BREW_PREFIX}/lib")
set(ENV{PKG_CONFIG_PATH} "${BREW_PREFIX}/opt/libffi/lib/pkgconfig")

# Use LLD as the linker
# This is necessary as the default linker used by CMake on macOS is
# ld64, which currently has some incompatibilities with Homebrew and XCode15.
# See: https://github.com/orgs/Homebrew/discussions/4794#discussioncomment-7044468
# Adding this flag avoid the following errors:
# ld: warning: duplicate -rpath ... ignored
# ld: warning: ignoring duplicate libraries ...
add_link_options("-fuse-ld=lld")

endif() # USE_NIX
endif() # APPLE
37 changes: 37 additions & 0 deletions include/kllvm/codegen/GCStrategy.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
//===- Extend GCStrategy of llvm/CodeGen/GCStrategy.h ---------------------===//
//
// We extend the base GCStrategy as follows:
// - use gc.safepoints instead of (default) gc.roots.
// - specify that the RewriteStatepointsForGC pass should rewrite the calls of
// this function.
// - pointers with address space != 0 are pointing to GC-managed memory.
//===----------------------------------------------------------------------===//

// NOLINTBEGIN

#ifndef LLVM_BACKEND_GC_STRATEGY_H
#define LLVM_BACKEND_GC_STRATEGY_H

#include "llvm/IR/GCStrategy.h"
#include "llvm/IR/Type.h"

namespace kllvm {

/// The GCStrategy for the LLVM Backend
class LLVMBackendGCStrategy : public llvm::GCStrategy {
public:
LLVMBackendGCStrategy();

// Override
#if LLVM_VERSION_MAJOR == 15
llvm::Optional<bool> isGCManagedPointer(llvm::Type const *Ty) const override;
#else
std::optional<bool> isGCManagedPointer(llvm::Type const *Ty) const override;
#endif
};

} // namespace kllvm

#endif // LLVM_BACKEND_GC_STRATEGY_H

// NOLINTEND
1 change: 1 addition & 0 deletions include/kllvm/codegen/Options.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ extern llvm::cl::opt<bool> no_optimize;
extern llvm::cl::opt<bool> emit_object;
extern llvm::cl::opt<bool> binary_ir;
extern llvm::cl::opt<bool> force_binary;
extern llvm::cl::opt<bool> use_gcstrategy;
extern llvm::cl::opt<bool> proof_hint_instrumentation;
extern llvm::cl::opt<bool> proof_hint_instrumentation_slow;
extern llvm::cl::opt<bool> keep_frame_pointer;
Expand Down
1 change: 0 additions & 1 deletion include/runtime/alloc.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ extern "C" {

char youngspace_collection_id(void);
char oldspace_collection_id(void);
//size_t youngspace_size(void);

// allocates exactly requested bytes into the young generation
void *kore_alloc(size_t requested);
Expand Down
4 changes: 4 additions & 0 deletions lib/codegen/CreateTerm.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#include "kllvm/codegen/CreateTerm.h"
#include "kllvm/codegen/CreateStaticTerm.h"
#include "kllvm/codegen/Debug.h"
#include "kllvm/codegen/Options.h"
#include "kllvm/codegen/ProofEvent.h"
#include "kllvm/codegen/Util.h"

Expand Down Expand Up @@ -1224,6 +1225,9 @@ bool make_function(
= llvm::FunctionType::get(return_type, param_types, false);
llvm::Function *apply_rule = get_or_insert_function(module, name, func_type);
apply_rule->setLinkage(llvm::GlobalValue::InternalLinkage);
if (use_gcstrategy) {
apply_rule->setGC("gcs-llvm-backend");
}
init_debug_axiom(axiom->attributes());
std::string debug_name = name;
if (axiom->attributes().contains(attribute_set::key::Label)) {
Expand Down
4 changes: 4 additions & 0 deletions lib/codegen/Options.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,10 @@ cl::opt<bool> force_binary(
"f", cl::desc("Force binary bitcode output to stdout"), cl::Hidden,
cl::cat(codegen_lib_cat));

cl::opt<bool> use_gcstrategy(
"use-gcstrategy", cl::desc("Use GC strategy defined for the LLVM backend."),
cl::Hidden, cl::init(false), cl::cat(codegen_lib_cat));

namespace kllvm {

void validate_codegen_args(bool is_tty) {
Expand Down
2 changes: 2 additions & 0 deletions lib/passes/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,15 @@ add_library(KLLVMPassInternal
SetVisibilityHidden.cpp
RemoveDeadKFunctions.cpp
MustTailDeadArgElimination.cpp
GCStrategy.cpp
PluginInfo.cpp
)

add_library(KLLVMPass MODULE
SetVisibilityHidden.cpp
RemoveDeadKFunctions.cpp
MustTailDeadArgElimination.cpp
GCStrategy.cpp
PluginInfo.cpp
)

Expand Down
52 changes: 52 additions & 0 deletions lib/passes/GCStrategy.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
//===- Extend GCStrategy of llvm/CodeGen/GCStrategy.h ---------------------===//
//
// We extend the base GCStrategy as follows:
// - use gc.safepoints instead of (default) gc.roots.
// - specify that the RewriteStatepointsForGC pass should rewrite the calls of
// this function.
// - pointers with address space != 0 are pointing to GC-managed memory.
//===----------------------------------------------------------------------===//

// NOLINTBEGIN

#include "kllvm/codegen/GCStrategy.h"

#include "llvm/CodeGen/GCMetadata.h"
#include "llvm/IR/DerivedTypes.h"
#include "llvm/Support/Compiler.h"

using namespace llvm;
using namespace kllvm;

LLVMBackendGCStrategy::LLVMBackendGCStrategy() {
UseStatepoints = true; // Use gc.statepoints
#if LLVM_VERSION_MAJOR != 15
UseRS4GC = true; // Rewrite the calls of a function that has this GCStrategy
#endif
}

// Override
#if LLVM_VERSION_MAJOR == 15
llvm::Optional<bool>
LLVMBackendGCStrategy::isGCManagedPointer(Type const *Ty) const {
#else
std::optional<bool>
LLVMBackendGCStrategy::isGCManagedPointer(Type const *Ty) const {
#endif
// Return false for any non-pointer type
if (!Ty->isPointerTy()) {
return false;
}
// Any pointer with address space != 0 is to managed memory.
PointerType const *PTy = dyn_cast<PointerType>(Ty);
if (PTy->getAddressSpace()) {
return true;
}
return false;
}

// Add LLVMBackendGCStrategy to the global GCRegistry
static GCRegistry::Add<LLVMBackendGCStrategy>
X("gcs-llvm-backend", "GC Strategy for the LLVM Backend");

// NOLINTEND
2 changes: 2 additions & 0 deletions test/defn/imp.kore
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
// RUN: %interpreter
// RUN: %check-grep
// RUN: %check-statistics
// RUN: %gcs-interpreter
// RUN: %check-grep
// RUN: %proof-interpreter
// RUN: %check-proof-out
[topCellInitializer{}(LblinitGeneratedTopCell{}()), org'Stop'kframework'Stop'attributes'Stop'Source{}("Source(/home/robertorosmaninho/rv/k/llvm-backend/src/main/native/llvm-backend/test/defn/k-files/imp.md)")]
Expand Down
7 changes: 7 additions & 0 deletions test/lit.cfg.py
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,13 @@ def exclude_x86_and_llvm18(s):
exit 1
fi
''')),
('%gcs-interpreter', one_line('''
output=$(%kompile %s main --use-gcstrategy -o %t.interpreter 2>&1)
if [[ -n "$output" ]]; then
echo "llvm-kompile error or warning: $output"
exit 1
fi
''')),
('%proof-interpreter', one_line('''
output=$(%kompile %s main --proof-hint-instrumentation -o %t.interpreter 2>&1)
if [[ -n "$output" ]]; then
Expand Down
3 changes: 3 additions & 0 deletions tools/llvm-kompile-codegen/main.cpp
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
#include "kllvm/codegen/GCStrategy.h"
#include <kllvm/ast/AST.h>
#include <kllvm/codegen/ApplyPasses.h>
#include <kllvm/codegen/CreateTerm.h>
Expand Down Expand Up @@ -147,6 +148,8 @@ void emit_metadata(llvm::Module &mod) {

// NOLINTNEXTLINE(*-cognitive-complexity)
int main(int argc, char **argv) {
// NOLINTNEXTLINE(*-identifier-naming)
LLVMBackendGCStrategy _gcs; // Unused. This is needed to ensure linking.
initialize_llvm();

cl::HideUnrelatedOptions({&codegen_tool_cat, &codegen_lib_cat});
Expand Down

0 comments on commit 7ecb011

Please sign in to comment.