Skip to content
Merged
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
22 changes: 22 additions & 0 deletions .github/actions/build.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#!/bin/bash

cd ${GITHUB_WORKSPACE}
mkdir $MAVIS_BUILD_TYPE
cd $MAVIS_BUILD_TYPE

CXX_COMPILER=${COMPILER/clang/clang++}
CXX_COMPILER=${CXX_COMPILER/gcc/g++}

cmake .. -DCMAKE_C_COMPILER=$COMPILER -DCMAKE_CXX_COMPILER=$CXX_COMPILER -DCMAKE_BUILD_TYPE=$MAVIS_BUILD_TYPE -DMAVIS_CXX_STANDARD=$MAVIS_CXX_STANDARD

if [ $? -ne 0 ]; then
echo "ERROR: CMake for mavis failed"
exit 1
fi

make -j$(nproc --all)

if [ $? -ne 0 ]; then
echo "ERROR: build of mavis failed"
exit 1
fi
10 changes: 10 additions & 0 deletions .github/actions/regress.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#!/bin/bash

cd ${GITHUB_WORKSPACE}
cd $MAVIS_BUILD_TYPE
make -j$(nproc --all) regress

if [ $? -ne 0 ]; then
echo "ERROR: regress of mavis failed"
exit 1
fi
75 changes: 75 additions & 0 deletions .github/workflows/build-regress.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
on:
pull_request:
branches:
- main

name: Run Mavis regression on Ubuntu
jobs:
check_json_job:
name: Ubuntu-check-json
runs-on: ubuntu-latest

steps:
# Install jq
- name: Install jq
run: sudo apt-get update && sudo apt-get install -y jq

# Get Mavis
- name: Clone Mavis
uses: actions/checkout@v4
with:
submodules: recursive

# Run JSON check script
- name: Check JSONs
run: ./scripts/check_jsons

regress:
strategy:
# Strategy is a matrix of debug and release builds/regression
matrix:
BUILD_TYPE: [Debug,Release]
COMPILER: [gcc,clang]
MAVIS_CXX_STANDARD: [20, 23]

name: Ubuntu-regress
runs-on: ubuntu-latest

env:
MAVIS_BUILD_TYPE: ${{ matrix.BUILD_TYPE }}
COMPILER: ${{ matrix.COMPILER }}
MAVIS_CXX_STANDARD: ${{ matrix.MAVIS_CXX_STANDARD }}

steps:
- name: Setup Git Identity
run: |
git config --global user.email "runner@github.com"
git config --global user.name "Github Runner"

# Install packages
- name: Install packages
run: |
sudo apt-get update --fix-missing
sudo apt-get install libboost-all-dev llvm lld

# Get Mavis
- name: Clone Mavis
uses: actions/checkout@v4
with:
submodules: recursive

# Build
- name: Build
run: ./.github/actions/build.sh

# Regress
- name: Regress
run: ./.github/actions/regress.sh

# Save error logs, etc
- name: Save artifacts
if: failure()
uses: actions/upload-artifact@main
with:
name: ErrorLogs-${{matrix.BUILD_TYPE}}-${{matrix.COMPILER}}
path: ${{matrix.BUILD_TYPE}}/
25 changes: 0 additions & 25 deletions .github/workflows/check-json.yml

This file was deleted.

37 changes: 37 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,12 @@ endif()

add_subdirectory(elfio)

if (CMAKE_CXX_COMPILER_ID MATCHES "GNU")
if(CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 14.0)
add_compile_options(-Wno-template-id-cdtor)
endif()
endif()

add_library(mavis
impl/ExtractorRegistry.cpp
impl/FormRegistry.cpp
Expand Down Expand Up @@ -72,6 +78,35 @@ if(NOT COMPILER_SUPPORTS_CONSTEXPR_BITSET)
target_include_directories(mavis PUBLIC "${bitset2_SOURCE_DIR}")
endif()

# Set up test infrastructure
# Only enable tests if Mavis is the top-level project
if (PROJECT_IS_TOP_LEVEL)
include(CTest)
include(ProcessorCount)
ProcessorCount(NUM_CORES)

if (NUM_CORES GREATER 8) # Max of 8 cores
set(NUM_CORE, 8)
endif()
if (NOT NUM_CORES EQUAL 0)
set(CTEST_BUILD_FLAGS -j${NUM_CORES})
set(ctest_test_args ${ctest_test_args} PARALLEL_LEVEL ${NUM_CORES})
endif()

add_custom_target(regress)
add_custom_command(TARGET regress POST_BUILD COMMAND ${CMAKE_CTEST_COMMAND})
set(ENABLE_MAVIS_TESTS True)
else()
set(ENABLE_MAVIS_TESTS False)
endif()

function (mavis_test name target)
if (ENABLE_MAVIS_TESTS)
add_dependencies(regress ${target})
add_test(NAME ${name} COMMAND ${ARGN})
endif()
endfunction (mavis_test)

# Setup common compiler options for the tests and examples
add_library(mavis_test_lib INTERFACE)
target_link_libraries (mavis_test_lib INTERFACE mavis)
Expand Down Expand Up @@ -100,6 +135,8 @@ target_compile_options(mavis PUBLIC -fPIC)
set(CMAKE_CXX_FLAGS_DEBUG "-U_FORTIFY_SOURCE -O0 -g")
set(CMAKE_CXX_FLAGS_FASTDEBUG "-O3 -g")

include(${CMAKE_CURRENT_SOURCE_DIR}/cmake/internal.cmake OPTIONAL)

if(NOT CLANGFORMAT_EXECUTABLE)
set(CLANGFORMAT_EXECUTABLE clang-format)
endif()
Expand Down
10 changes: 2 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -197,15 +197,9 @@ cmake ..
cmake .. -DMAVIS_CXX_STANDARD=23
make -j8
```
* Build the basic tester; output program is `Mavis`
* Run regression
```
cd build/test/basic
make -j8
```
* Execute the basic tester and compare golden `out`
```
./Mavis > test.out
diff -s test.out golden.out
make -j8 regress
```

* Build and test with a directed program; output program is
Expand Down
22 changes: 22 additions & 0 deletions cmake/internal.cmake.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# This is an example CMake config for including internal-only instruction definitions
# Edit this file as needed and rename it to cmake/internal.cmake

add_library(internal_instructions
internal/InternalForms.cpp
)

get_target_property(MAVIS_INCLUDES mavis INCLUDE_DIRECTORIES)
target_include_directories(internal_instructions PRIVATE ${MAVIS_INCLUDES})

get_target_property(MAVIS_LIBRARIES mavis LINK_LIBRARIES)
target_link_libraries(internal_instructions PRIVATE ${MAVIS_LIBRARIES})

target_compile_definitions(mavis PRIVATE
INTERNAL_EXTRACTOR_REGISTRY=InternalExtractorRegistry
INTERNAL_EXTRACTOR_REGISTRY_HEADER="internal/InternalExtractorRegistry.h"
INTERNAL_FORM_REGISTRY=InternalFormRegistry
INTERNAL_FORM_REGISTRY_HEADER="internal/InternalFormRegistry.h"
)
target_link_libraries(mavis PRIVATE internal_instructions)

add_subdirectory(internal/test EXCLUDE_FROM_ALL)
62 changes: 33 additions & 29 deletions impl/DTable.tcc
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ namespace mavis
if (const auto it = inst.find("xform"); it != inst.end())
{
override_extractor =
extractors_.getExtractor(boost::json::value_to<std::string>(it->value()));
ExtractorRegistry::getExtractor(boost::json::value_to<std::string>(it->value()));
}

// Parse the factory name override, if present
Expand Down Expand Up @@ -88,36 +88,39 @@ namespace mavis
else
{
const std::string form = boost::json::value_to<std::string>(inst.at("form"));
const FormBase* form_wrap = forms_.findFormWrapper(form);
if (form_wrap == nullptr)
{
throw BuildErrorUnknownForm(jfile, mnemonic, form);
}

InstMetaData::PtrType meta =
builder_->makeInstMetaData(mnemonic, inst, !xpand_name.empty(), tags);
try
{
typename IFactoryIF<InstType, AnnotationType>::PtrType ifact =
build_(form_wrap, mnemonic, istencil, flist, ignore_set, factory_name,
xpand_name, override_extractor, meta);
const auto & form_wrap = FormRegistry::findFormWrapper(form);

// Check for encoding aliases for this factory and add them to the tree
StringListType alias_stencils;
if (const auto alias_it = inst.find("alias"); alias_it != inst.end())
InstMetaData::PtrType meta =
builder_->makeInstMetaData(mnemonic, inst, !xpand_name.empty(), tags);
try
{
alias_stencils = boost::json::value_to<StringListType>(alias_it->value());
for (const auto & astencil : alias_stencils)
typename IFactoryIF<InstType, AnnotationType>::PtrType ifact =
build_(form_wrap, mnemonic, istencil, flist, ignore_set, factory_name,
xpand_name, override_extractor, meta);

// Check for encoding aliases for this factory and add them to the tree
StringListType alias_stencils;
if (const auto alias_it = inst.find("alias"); alias_it != inst.end())
{
Opcode opc = stoll(astencil, nullptr, 16);
build_(form_wrap, mnemonic, opc, flist, ignore_set, factory_name,
xpand_name, override_extractor, meta, ifact);
alias_stencils = boost::json::value_to<StringListType>(alias_it->value());
for (const auto & astencil : alias_stencils)
{
Opcode opc = stoll(astencil, nullptr, 16);
build_(form_wrap, mnemonic, opc, flist, ignore_set, factory_name,
xpand_name, override_extractor, meta, ifact);
}
}
}
catch (const BuildErrorInstructionAlias & ex)
{
std::cerr << ex.what() << std::endl;
}
}
catch (const BuildErrorInstructionAlias & ex)
catch (const RegistryNotFoundException &)
{
std::cerr << ex.what() << std::endl;
throw BuildErrorUnknownForm(jfile, mnemonic, form);
}
}
}
Expand Down Expand Up @@ -256,7 +259,7 @@ namespace mavis
template <typename InstType, typename AnnotationType, typename AnnotationTypeAllocator>
typename IFactoryIF<InstType, AnnotationType>::PtrType
DTable<InstType, AnnotationType, AnnotationTypeAllocator>::buildLeaf_(
const FormBase* form,
const FormBase::PtrType & form,
const typename IFactoryIF<InstType, AnnotationType>::PtrType & curr_node,
const std::string & mnemonic, const Opcode istencil, const FieldNameListType & flist,
const std::string & factory_name, const std::string & xpand_name,
Expand All @@ -279,7 +282,7 @@ namespace mavis
// the form specified by the FormType template parameter
if (override_extractor == nullptr)
{
override_extractor = extractors_.getExtractor(form->getName());
override_extractor = ExtractorRegistry::getExtractor(form->getName());
}

// IFactorySpecialCaseComposite<InstType, AnnotationType> *parent = // just for now...
Expand Down Expand Up @@ -349,7 +352,7 @@ namespace mavis
template <typename InstType, typename AnnotationType, typename AnnotationTypeAllocator>
typename IFactoryIF<InstType, AnnotationType>::PtrType
DTable<InstType, AnnotationType, AnnotationTypeAllocator>::build_(
const FormBase* form, const std::string & mnemonic, const Opcode istencil,
const FormBase::PtrType & form, const std::string & mnemonic, const Opcode istencil,
const FieldNameListType & flist, const FieldNameSetType & ignore_set,
const std::string & factory_name, const std::string & xpand_name,
const ExtractorIF::PtrType & override_extractor, InstMetaData::PtrType & einfo,
Expand All @@ -370,7 +373,7 @@ namespace mavis
{
curr_node->addIFactory(
istencil, typename IFactoryIF<InstType, AnnotationType>::PtrType(
new IFactoryDenseComposite<InstType, AnnotationType>(fields[0])));
new IFactoryDenseComposite<InstType, AnnotationType>(fields[0])));
}
curr_node = curr_node->getNode(istencil); // Advance...
if (!mavis::utils::notNull(curr_node->getField())->isEquivalent(fields[0]))
Expand Down Expand Up @@ -420,8 +423,9 @@ namespace mavis
{
if (curr_node->getDefault() == nullptr)
{
curr_node->addDefaultIFactory(typename IFactoryIF<InstType, AnnotationType>::PtrType(
new IFactorySpecialCaseComposite<InstType, AnnotationType>()));
curr_node->addDefaultIFactory(
typename IFactoryIF<InstType, AnnotationType>::PtrType(
new IFactorySpecialCaseComposite<InstType, AnnotationType>()));
}
curr_node = curr_node->getDefault(); // Advance...
}
Expand All @@ -431,7 +435,7 @@ namespace mavis
{
curr_node->addIFactory(
istencil, typename IFactoryIF<InstType, AnnotationType>::PtrType(
new IFactorySpecialCaseComposite<InstType, AnnotationType>()));
new IFactorySpecialCaseComposite<InstType, AnnotationType>()));
}
curr_node = curr_node->getNode(istencil); // Advance...
}
Expand Down
Loading
Loading