Skip to content

Commit

Permalink
Use the eq-bytecode even without optimizations.
Browse files Browse the repository at this point in the history
Also add more tests and a schedule that runs tests during the night.
  • Loading branch information
floitsch committed Oct 11, 2024
1 parent 4890e79 commit e3b2e33
Show file tree
Hide file tree
Showing 15 changed files with 189 additions and 42 deletions.
52 changes: 42 additions & 10 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
name: CI

on:
schedule:
- cron: '00 2 * * *' # 02:00 UTC
- cron: '30 2 * * *'
- cron: '00 3 * * *'
push:
branches-ignore:
- "wip/**"
Expand Down Expand Up @@ -47,6 +51,11 @@ on:
required: false
type: boolean
default: true
test-more:
description: "Run more tests"
required: false
type: boolean
default: false
run-esp32-flow:
description: "Run the ESP32 flow"
required: false
Expand All @@ -61,6 +70,7 @@ on:
env:
TOIT_VERSION: ${{ github.event.inputs.do-release || github.event.release.tag_name || '' }}
DO_RELEASE: ${{ github.event_name == 'release' || startsWith(github.event.inputs.do-release, 'v') }}
DO_MORE_TESTS: ${{ github.event_name == 'schedule' || github.event.inputs.test-more == 'true' }}

jobs:
prereqs:
Expand Down Expand Up @@ -180,19 +190,25 @@ jobs:
# compute the version from git.
run: |
make sdk
if [[ "$RUNNER_OS" == "Linux" ]]; then
make HOST=host32 BUILD_TYPE=Debug sdk
make HOST=host-ctp TOOLCHAIN=host TOIT_CHECK_PROPAGATED_TYPES=1 sdk
fi
- name: Ccache stats
run: ccache -s

# Build 64-bit debug if we are comitting to master.
- name: Build 64-bit debug
if: runner.os == 'Linux' && github.event_name == 'push' && github.ref == 'refs/heads/master'
- name: Build test SDKS - Linux only
if: env.DO_MORE_TESTS && runner.os == 'Linux'
run: |
make HOST=host32 BUILD_TYPE=Debug sdk
make HOST=host-ctp TOOLCHAIN=host TOIT_CHECK_PROPAGATED_TYPES=1 sdk
- name: Build test SDKS
shell: bash
if: env.DO_MORE_TESTS
run: |
make BUILD=build-debug BUILD_TYPE=Debug sdk
# It's wasteful to rebuild the SDK just to change the optimization level and assert, but
# it's the easiest way to make sure all tests are run in that configuration.
TOIT_OPTIMIZATION_OVERRIDE=0 TOIT_ASSERT_OVERRIDE=0 make HOST=host-O0 TOOLCHAIN=host sdk
TOIT_OPTIMIZATION_OVERRIDE=2 TOIT_ASSERT_OVERRIDE=1 make HOST=host-O2 TOOLCHAIN=host sdk
- name: Ccache stats
run: ccache -s
Expand Down Expand Up @@ -239,20 +255,36 @@ jobs:
echo success > ${{ steps.constants.outputs.flaky_result }}
- name: Test type propagator
if: ${{ runner.os == 'Linux' && github.event.inputs.run-tests != 'false' }}
if: env.DO_MORE_TESTS == 'true' && runner.os == 'Linux'
run: |
make HOST=host-ctp TOIT_CHECK_PROPAGATED_TYPES=1 test
- name: Test 32-bit debug
if: ${{ runner.os == 'Linux' && github.event.inputs.run-tests != 'false' }}
if: env.DO_MORE_TESTS == 'true' && runner.os == 'Linux'
run: |
make HOST=host32 BUILD_TYPE=Debug test
- name: Test 64-bit debug
if: runner.os == 'Linux' && github.event_name == 'push' && github.ref == 'refs/heads/master'
shell: bash
# TODO(florian): fix Windows.
if: env.DO_MORE_TESTS == 'true' && runner.os != 'Windows'
run: |
make BUILD=build-debug BUILD_TYPE=Debug test
- name: Test -O0 no asserts
shell: bash
# TODO(florian): Windows is currently too flaky with -O0.
if: env.DO_MORE_TESTS == 'true' && runner.os != 'Windows'
run: |
TOIT_OPTIMIZATION_OVERRIDE=0 TOIT_ASSERT_OVERRIDE=0 make HOST=host-O0 TOOLCHAIN=host test
- name: Test -O2 with asserts
shell: bash
# TODO(florian): fix Windows.
if: env.DO_MORE_TESTS == 'true' && runner.os != 'Windows'
run: |
TOIT_OPTIMIZATION_OVERRIDE=2 TOIT_ASSERT_OVERRIDE=1 make HOST=host-O2 TOOLCHAIN=host test
- name: Test install
if : matrix.shard == 1
shell: bash
Expand Down
10 changes: 5 additions & 5 deletions lib/core/numbers.toit
Original file line number Diff line number Diff line change
Expand Up @@ -1746,21 +1746,21 @@ class float extends num:
// here.
equals-from-large-integer_ other:
if other is int: unreachable
if other is int: unreachable // See comment above.
return other.to-float == this

less-than-from-large-integer_ other:
if other is int: unreachable
if other is int: unreachable // See comment above.
return other.to-float < this

less-than-or-equal-from-large-integer_ other:
if other is int: unreachable
if other is int: unreachable // See comment above.
return other.to-float <= this

greater-than-from-large-integer_ other:
if other is int: unreachable
if other is int: unreachable // See comment above.
return other.to-float > this

greater-than-or-equal-from-large-integer_ other:
if other is int: unreachable
if other is int: unreachable // See comment above.
return other.to-float >= this
11 changes: 11 additions & 0 deletions src/compiler/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,17 @@ set_source_files_properties(propagation/type_propagator.cc PROPERTIES COMPILE_OP
set_source_files_properties(propagation/type_set.cc PROPERTIES COMPILE_OPTIONS "-O3")
set_source_files_properties(propagation/type_stack.cc PROPERTIES COMPILE_OPTIONS "-O3")

if (DEFINED ENV{TOIT_OPTIMIZATION_OVERRIDE})
# Use the optimization level from the environment and pass it in as define.
message("OVERRIDING OPTIMIZATION LEVEL")
target_compile_definitions(toit_compiler PRIVATE TOIT_OPTIMIZATION_OVERRIDE=$ENV{TOIT_OPTIMIZATION_OVERRIDE})
endif()
if (DEFINED ENV{TOIT_ASSERT_OVERRIDE})
# Use the optimization level from the environment and pass it in as define.
message("OVERRIDING ENABLE-ASSERT")
target_compile_definitions(toit_compiler PRIVATE TOIT_ASSERT_OVERRIDE=$ENV{TOIT_ASSERT_OVERRIDE})
endif()

if (${TOIT_IS_CROSS})
set(TOIT_COMPILER_STATIC -static)
endif()
Expand Down
11 changes: 10 additions & 1 deletion src/compiler/byte_gen.cc
Original file line number Diff line number Diff line change
Expand Up @@ -657,11 +657,20 @@ void ByteGen::visit_CallVirtual(CallVirtual* node) {
int arity = shape.arity();

auto compile_invocation = [&]() {
Selector<PlainShape> selector(node->target()->selector(), shape.to_plain_shape());
auto target_selector = node->target()->selector();
Selector<PlainShape> selector(target_selector, shape.to_plain_shape());
int offset = dispatch_table()->dispatch_offset_for(selector);
if (offset != -1) {
__ invoke_virtual(node->opcode(), offset, arity);
} else {
// If this isn't a binary, non-setter method, we just treat it as
// an ordinary virtual invocation.
if (target_selector == Symbol::for_invoke(INVOKE_EQ) &&
shape == CallShape(1).with_implicit_this()) {
// The equality checks must go through the opcode bytecode as
// it checks for identity and null.
UNREACHABLE();
}
// No method in the whole program implements that selector.
// Pop all arguments, and push the name of the method on the stack.
// Then call `lookup_failure`.
Expand Down
9 changes: 9 additions & 0 deletions src/compiler/compiler.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1659,6 +1659,15 @@ Pipeline::Result Pipeline::run(List<const char*> source_paths, bool propagate) {
Flags::enable_asserts = true;
}

#ifdef TOIT_OPTIMIZATION_OVERRIDE
configuration_.optimization_level = TOIT_OPTIMIZATION_OVERRIDE;
#endif
#if defined(TOIT_ASSERT_OVERRIDE) && TOIT_ASSERT_OVERRIDE == 0
Flags::enable_asserts = false;
#elif TOIT_ASSERT_OVERRIDE == 1
Flags::enable_asserts = true;
#endif

setup_lsp_selection_handler();

auto fs = configuration_.filesystem;
Expand Down
13 changes: 13 additions & 0 deletions src/compiler/resolver_method.cc
Original file line number Diff line number Diff line change
Expand Up @@ -4250,6 +4250,19 @@ ir::Expression* MethodResolver::_binary_operator(ast::Binary* node,
CallShape::for_instance_call_no_named(right_args),
right_args,
node->selection_range());

ASSERT(INVOKE_GTE - INVOKE_EQ == 4); // ==, <, <=, >, >=
// It is critical that we go through the EQ opcode, as it tests for identity and
// null. This must happen even if we have optimizations disabled.
// Similarly, we must go through the comparison opcodes, as they handle complicate
// corner cases that the source code doesn't.
for (int i = INVOKE_EQ; i <= INVOKE_GTE; i++) {
Opcode opcode = static_cast<Opcode>(i);
if (Symbol::for_invoke(opcode) == op) {
result->set_opcode(opcode);
break;
}
}
if (inverted) return _new ir::Not(result, node->selection_range());
return result;
}
Expand Down
10 changes: 10 additions & 0 deletions tests/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -80,11 +80,21 @@ endforeach()

include(fail.cmake OPTIONAL)

set(OPTIMIZATION_IS_OVERRIDDEN FALSE)
if (DEFINED ENV{TOIT_OPTIMIZATION_OVERRIDE})
set(OPTIMIZATION_IS_OVERRIDDEN TRUE)
endif()

foreach(file ${ALL_TESTS})
if("${file}" IN_LIST TOIT_SKIP_TESTS)
continue()
endif()

if(OPTIMIZATION_IS_OVERRIDDEN AND "${file}" IN_LIST TOIT_OPTIMIZATION_SKIP_TESTS)
message("Skipping ${file} as optimization is overridden")
continue()
endif()

set(TOIT_ARGS) # Arguments to toit.run.
set(TEST_ARGS) # Arguments to the test.

Expand Down
5 changes: 5 additions & 0 deletions tests/fail.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,11 @@ list(APPEND TOIT_FLAKY_TESTS
tests/tls-resume-session-test.toit
)

list(APPEND TOIT_OPTIMIZATION_SKIP_TESTS
# The following tests only work with standard optimizations.
tests/bytes-allocated-test.toit
)

if ("${CMAKE_SYSTEM_NAME}" STREQUAL "Windows" OR "${CMAKE_SYSTEM_NAME}" STREQUAL "MSYS")
list(APPEND TOIT_FAILING_TESTS
tests/time-test.toit # https://github.com/toitlang/toit/issues/1369
Expand Down
69 changes: 45 additions & 24 deletions tests/negative/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,24 @@

file(MAKE_DIRECTORY "${CMAKE_BINARY_DIR}/tmp")
file(GLOB TOIT_TESTS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "*-test.toit" "**/*-test.toit")
file(GLOB ASSERT_TESTS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "assert*-test.toit")

add_custom_target(update_gold)

set(NORMALIZE_GOLD ${CMAKE_CURRENT_SOURCE_DIR}/../tools/normalize_gold.cmake)

include(fail.cmake)

set(ASSERT_IS_ENABLED TRUE)
if ("$ENV{TOIT_ASSERT_OVERRIDE}" STREQUAL "0")
set(ASSERT_IS_ENABLED FALSE)
endif()

set(OPTIMIZATION_IS_OVERRIDDEN FALSE)
if (DEFINED ENV{TOIT_OPTIMIZATION_OVERRIDE})
set(OPTIMIZATION_IS_OVERRIDDEN TRUE)
endif()

foreach(file ${TOIT_TESTS})
get_filename_component(name ${file} NAME_WE)
set(lib_dir "./lib")
Expand All @@ -32,32 +43,42 @@ foreach(file ${TOIT_TESTS})
file(RELATIVE_PATH relative ${TOIT_SDK_SOURCE_DIR} ${toit_file})
string(REPLACE " " "__" test_name ${relative})

if(NOT "${test_name}" IN_LIST TOIT_SKIP_TESTS)
set(TEST_EXPECTATION_NAME "${test_name}")
if("${test_name}" IN_LIST TOIT_FAILING_TESTS)
set(TEST_EXPECTATION_NAME "${test_name}-expected-to-fail")
endif()
if ("${file}" IN_LIST ASSERT_TESTS AND NOT ASSERT_IS_ENABLED)
message("Skipping ${file} as asserts are disabled")
continue()
endif()
if(OPTIMIZATION_IS_OVERRIDDEN AND "${test_name}" IN_LIST TOIT_OPTIMIZATION_SKIP_TESTS)
message("Skipping ${file} as optimization is overridden")
continue()
endif()
if ("${test_name}" IN_LIST TOIT_SKIP_TESTS)
continue()
endif()

set(TEST_EXPECTATION_NAME "${test_name}")
if("${test_name}" IN_LIST TOIT_FAILING_TESTS)
set(TEST_EXPECTATION_NAME "${test_name}-expected-to-fail")
endif()

add_test(
NAME ${TEST_EXPECTATION_NAME}
COMMAND ${CMAKE_COMMAND}
-DTOITVM=$<TARGET_FILE:toit.run>
"-DTEST=${relative}"
"-DGOLD=${gold_file}"
"-DLIB_DIR=${lib_dir}"
"-DNORMALIZE_GOLD=${NORMALIZE_GOLD}"
"-DTEST_ROOT=${TOIT_SDK_SOURCE_DIR}"
"-DGIT_VERSION=${TOIT_GIT_VERSION}"
"-DTMP=${CMAKE_BINARY_DIR}/tmp"
"-DCMAKE_SYSTEM_NAME=${CMAKE_SYSTEM_NAME}"
-P "${CMAKE_CURRENT_SOURCE_DIR}/run.cmake"
WORKING_DIRECTORY ${TOIT_SDK_SOURCE_DIR}
)
set_tests_properties(${TEST_EXPECTATION_NAME} PROPERTIES TIMEOUT 40)
add_test(
NAME ${TEST_EXPECTATION_NAME}
COMMAND ${CMAKE_COMMAND}
-DTOITVM=$<TARGET_FILE:toit.run>
"-DTEST=${relative}"
"-DGOLD=${gold_file}"
"-DLIB_DIR=${lib_dir}"
"-DNORMALIZE_GOLD=${NORMALIZE_GOLD}"
"-DTEST_ROOT=${TOIT_SDK_SOURCE_DIR}"
"-DGIT_VERSION=${TOIT_GIT_VERSION}"
"-DTMP=${CMAKE_BINARY_DIR}/tmp"
"-DCMAKE_SYSTEM_NAME=${CMAKE_SYSTEM_NAME}"
-P "${CMAKE_CURRENT_SOURCE_DIR}/run.cmake"
WORKING_DIRECTORY ${TOIT_SDK_SOURCE_DIR}
)
set_tests_properties(${TEST_EXPECTATION_NAME} PROPERTIES TIMEOUT 40)

if("${test_name}" IN_LIST TOIT_FAILING_TESTS)
set_tests_properties(${TEST_EXPECTATION_NAME} PROPERTIES WILL_FAIL TRUE)
endif()
if("${test_name}" IN_LIST TOIT_FAILING_TESTS)
set_tests_properties(${TEST_EXPECTATION_NAME} PROPERTIES WILL_FAIL TRUE)
endif()

file(RELATIVE_PATH relative_gold ${TOIT_SDK_SOURCE_DIR} ${gold_file})
Expand Down
5 changes: 5 additions & 0 deletions tests/negative/fail.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,8 @@

set(TOIT_FAILING_TESTS
)

list(APPEND TOIT_OPTIMIZATION_SKIP_TESTS
# The following tests only work with standard optimizations.
tests/negative/field-type5-test.toit
)
9 changes: 9 additions & 0 deletions tests/optimizations/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,16 @@ file(GLOB TOIT_OPTIMIZATION_TESTS RELATIVE ${TOIT_SDK_SOURCE_DIR} "*-test.toit")

include(fail.cmake)

set(OPTIMIZATIONS_IS_OVERRIDEN)
if (DEFINED ENV{TOIT_OPTIMIZATION_OVERRIDE})
set(OPTIMIZATIONS_IS_OVERRIDEN TRUE)
endif()

foreach(file ${TOIT_OPTIMIZATION_TESTS})
if(OPTIMIZATIONS_IS_OVERRIDEN)
# Don't run optimization tests if the optimization level is overriden.
continue()
endif()
if("${file}" IN_LIST TOIT_SKIP_TESTS)
continue()
endif()
Expand Down
5 changes: 5 additions & 0 deletions tests/profiler/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,11 @@ file(GLOB PROFILER_TESTS "*-test.toit")

include(fail.cmake)

if (DEFINED ENV{TOIT_OPTIMIZATION_OVERRIDE})
# Don't run profiler tests if the optimization level is overridden.
set(PROFILER_TESTS)
endif()

foreach(profiler_test ${PROFILER_TESTS})
get_filename_component(base ${profiler_test} NAME_WE)
string(REGEX REPLACE "-test$" "" test_name ${base})
Expand Down
11 changes: 11 additions & 0 deletions tests/toit/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,26 @@
# directory of this repository.

file(GLOB TOIT_BIN_TESTS "*-test.toit")
file(GLOB ASSERT_TESTS "assert*-test.toit")

include(fail.cmake OPTIONAL)

set(TEST_SDK_DIR "${CMAKE_BINARY_DIR}/sdk")
set(TOIT_BIN_SOURCE "${TOIT_SDK_SOURCE_DIR}/tools/toit.toit")

set(ASSERT_IS_OVERRIDDEN FALSE)
if (DEFINED ENV{TOIT_ASSERT_OVERRIDE})
set(ASSERT_IS_OVERRIDDEN TRUE)
endif()

foreach(file ${TOIT_BIN_TESTS})
get_filename_component(base ${file} NAME_WE)

if (ASSERT_IS_OVERRIDDEN AND "${file}" IN_LIST ASSERT_TESTS)
message("Skipping ${file} as asserts are overridden")
continue()
endif()

file(RELATIVE_PATH toit_bin_test_name ${TOIT_SDK_SOURCE_DIR} ${file})
if (NOT "${toit_bin_test_name}" IN_LIST TOIT_SKIP_TESTS)
set(TEST_EXPECTATION_NAME "${toit_bin_test_name}")
Expand Down
Loading

0 comments on commit e3b2e33

Please sign in to comment.