From b7ffded2dad8e7a5476da3c3ed334e592bd6d16c Mon Sep 17 00:00:00 2001 From: Flat Date: Fri, 10 Oct 2025 14:38:03 +0200 Subject: [PATCH 01/27] Fixed the linking of the uv library for Intel Macbooks --- effekt/jvm/src/main/scala/effekt/Runner.scala | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/effekt/jvm/src/main/scala/effekt/Runner.scala b/effekt/jvm/src/main/scala/effekt/Runner.scala index 5c0c3fe9c..a8ab10cf6 100644 --- a/effekt/jvm/src/main/scala/effekt/Runner.scala +++ b/effekt/jvm/src/main/scala/effekt/Runner.scala @@ -306,9 +306,15 @@ object LLVMRunner extends Runner[String] { def libuvArgs(using C: Context): Seq[String] = val OS = System.getProperty("os.name").toLowerCase + + // only relevant for macOS + val arch: String = System.getProperty("os.arch") + assert(!OS.contains("mac") || List("aarch64", "x86_64").contains(arch), "If you have a macbook -> It should have either an aarch64 or x86_64 architecture.") + val libraries = C.config.clangLibraries.toOption.map(file).orElse { OS match { - case os if os.contains("mac") => Some(file("/opt/homebrew/lib")) + case os if os.contains("mac") && arch.equals("aarch64") => Some(file("/opt/homebrew/lib")) + case os if os.contains("mac") => Some(file("/usr/local/lib")) case os if os.contains("win") => None case os if os.contains("linux") => Some(file("/usr/local/lib")) case os => None @@ -316,7 +322,8 @@ object LLVMRunner extends Runner[String] { } val includes = C.config.clangIncludes.toOption.map(file).orElse { OS match { - case os if os.contains("mac") => Some(file("/opt/homebrew/include")) + case os if os.contains("mac") && arch.equals("aarch64") => Some(file("/opt/homebrew/include")) + case os if os.contains("mac") => Some(file("/usr/local/include")) case os if os.contains("win") => None case os if os.contains("linux") => Some(file("/usr/local/include")) case os => None From ebb8b9cc34451d018d152adf94c5b397c705e514 Mon Sep 17 00:00:00 2001 From: Flat Date: Fri, 24 Oct 2025 18:39:57 +0200 Subject: [PATCH 02/27] df: Added benchmarks --- .../jvm/src/test/scala/effekt/FlatTests.scala | 24 + ...locate_first_then_release_flush_once.check | 65 + ...ocate_first_then_release_flush_once.effekt | 148 ++ ...ocate_first_then_release_flush_twice.check | 0 ...cate_first_then_release_flush_twice.effekt | 282 +++ examples/flat/nooptimized/array_record.check | 1 + examples/flat/nooptimized/array_record.effekt | 10 + .../flat/nooptimized/array_record_match.check | 1 + .../nooptimized/array_record_match.effekt | 21 + .../array_record_match_exhausted.check | 1 + .../array_record_match_exhausted.effekt | 21 + ...different_person_sizes_biggest_first.check | 3 + ...ifferent_person_sizes_biggest_first.effekt | 46 + ...ifferent_person_sizes_smallest_first.check | 3 + ...fferent_person_sizes_smallest_first.effekt | 46 + .../flat/nooptimized/nested_objects.check | 1 + .../flat/nooptimized/nested_objects.effekt | 16 + .../nooptimized/one_big_string_object.check | 1 + .../nooptimized/one_big_string_object.effekt | 9 + examples/flat/nooptimized/one_lg_object.check | 1 + .../flat/nooptimized/one_lg_object.effekt | 18 + examples/flat/nooptimized/one_md_object.check | 1 + .../flat/nooptimized/one_md_object.effekt | 15 + .../one_slot_one_person_list.check | 1 + .../one_slot_one_person_list.effekt | 27 + examples/flat/nooptimized/one_sm_object.check | 1 + .../flat/nooptimized/one_sm_object.effekt | 14 + .../nooptimized/one_small_string_object.check | 1 + .../one_small_string_object.effekt | 8 + examples/flat/nooptimized/one_xl_object.check | 1 + .../flat/nooptimized/one_xl_object.effekt | 19 + examples/flat/nooptimized/one_xs_object.check | 1 + .../flat/nooptimized/one_xs_object.effekt | 11 + .../one_xxl_object_all_fields.check | 100 ++ .../one_xxl_object_all_fields.effekt | 308 ++++ .../flat/nooptimized/one_xxxl_object.check | 1 + .../flat/nooptimized/one_xxxl_object.effekt | 1008 +++++++++++ examples/flat/nooptimized/primitive_ref.check | 1 + .../flat/nooptimized/primitive_ref.effekt | 9 + examples/flat/nooptimized/ref_allocate.check | 1 + examples/flat/nooptimized/ref_allocate.effekt | 19 + examples/flat/nooptimized/simple_list.check | 1 + examples/flat/nooptimized/simple_list.effekt | 15 + examples/flat/nooptimized/simple_ref.check | 1 + examples/flat/nooptimized/simple_ref.effekt | 20 + examples/flat/nooptimized/superperson.check | 2 + examples/flat/nooptimized/superperson.effekt | 33 + .../nooptimized/superperson_with_free.check | 1 + .../nooptimized/superperson_with_free.effekt | 30 + .../nooptimized/three_md_objects_direct.check | 3 + .../three_md_objects_direct.effekt | 20 + .../nooptimized/trigger_child_freeing.check | 0 .../nooptimized/trigger_child_freeing.effekt | 64 + .../flat/nooptimized/trigger_flush_once.check | 0 .../nooptimized/trigger_flush_once.effekt | 17 + .../nooptimized/trigger_flush_twice.check | 0 .../nooptimized/trigger_flush_twice.effekt | 17 + .../trigger_one_child_freeing.check | 0 .../trigger_one_child_freeing.effekt | 26 + .../trigger_two_child_freeing.check | 0 .../trigger_two_child_freeing.effekt | 28 + .../flat/nooptimized/two_lg_objects.check | 2 + .../flat/nooptimized/two_lg_objects.effekt | 20 + .../nooptimized/two_md_mixed_object.check | 2 + .../nooptimized/two_md_mixed_object.effekt | 17 + .../flat/nooptimized/two_md_objects.check | 2 + .../flat/nooptimized/two_md_objects.effekt | 17 + .../two_slot_one_person_list.check | 1 + .../two_slot_one_person_list.effekt | 23 + ...t_one_person_with_free_variable_list.check | 1 + ..._one_person_with_free_variable_list.effekt | 29 + .../two_slot_two_person_list.check | 1 + .../two_slot_two_person_list.effekt | 24 + ...wo_slot_two_person_list_continuation.check | 1 + ...o_slot_two_person_list_continuation.effekt | 27 + ..._person_list_continuation_allocation.check | 2 + ...person_list_continuation_allocation.effekt | 45 + ...o_person_list_continuation_exhausted.check | 1 + ..._person_list_continuation_exhausted.effekt | 27 + .../two_slot_two_person_list_exhausted.check | 1 + .../two_slot_two_person_list_exhausted.effekt | 24 + ...t_two_person_with_free_variable_list.check | 1 + ..._two_person_with_free_variable_list.effekt | 29 + .../nooptimized/two_sm_mixed_object.check | 2 + .../nooptimized/two_sm_mixed_object.effekt | 15 + .../flat/nooptimized/two_sm_objects.check | 2 + .../flat/nooptimized/two_sm_objects.effekt | 16 + .../flat/nooptimized/two_xl_objects.check | 2 + .../flat/nooptimized/two_xl_objects.effekt | 21 + .../flat/nooptimized/two_xs_objects.check | 2 + .../flat/nooptimized/two_xs_objects.effekt | 13 + .../two_xxl_object_all_fields.check | 100 ++ .../two_xxl_object_all_fields.effekt | 308 ++++ .../flat/nooptimized/two_xxl_objects.check | 2 + .../flat/nooptimized/two_xxl_objects.effekt | 312 ++++ .../flat/nooptimized/two_xxxl_objects.check | 2 + .../flat/nooptimized/two_xxxl_objects.effekt | 1512 +++++++++++++++++ 97 files changed, 5149 insertions(+) create mode 100644 effekt/jvm/src/test/scala/effekt/FlatTests.scala create mode 100644 examples/flat/nooptimized/allocate_first_then_release_flush_once.check create mode 100644 examples/flat/nooptimized/allocate_first_then_release_flush_once.effekt create mode 100644 examples/flat/nooptimized/allocate_first_then_release_flush_twice.check create mode 100644 examples/flat/nooptimized/allocate_first_then_release_flush_twice.effekt create mode 100644 examples/flat/nooptimized/array_record.check create mode 100644 examples/flat/nooptimized/array_record.effekt create mode 100644 examples/flat/nooptimized/array_record_match.check create mode 100644 examples/flat/nooptimized/array_record_match.effekt create mode 100644 examples/flat/nooptimized/array_record_match_exhausted.check create mode 100644 examples/flat/nooptimized/array_record_match_exhausted.effekt create mode 100644 examples/flat/nooptimized/different_person_sizes_biggest_first.check create mode 100644 examples/flat/nooptimized/different_person_sizes_biggest_first.effekt create mode 100644 examples/flat/nooptimized/different_person_sizes_smallest_first.check create mode 100644 examples/flat/nooptimized/different_person_sizes_smallest_first.effekt create mode 100644 examples/flat/nooptimized/nested_objects.check create mode 100644 examples/flat/nooptimized/nested_objects.effekt create mode 100644 examples/flat/nooptimized/one_big_string_object.check create mode 100644 examples/flat/nooptimized/one_big_string_object.effekt create mode 100644 examples/flat/nooptimized/one_lg_object.check create mode 100644 examples/flat/nooptimized/one_lg_object.effekt create mode 100644 examples/flat/nooptimized/one_md_object.check create mode 100644 examples/flat/nooptimized/one_md_object.effekt create mode 100644 examples/flat/nooptimized/one_slot_one_person_list.check create mode 100644 examples/flat/nooptimized/one_slot_one_person_list.effekt create mode 100644 examples/flat/nooptimized/one_sm_object.check create mode 100644 examples/flat/nooptimized/one_sm_object.effekt create mode 100644 examples/flat/nooptimized/one_small_string_object.check create mode 100644 examples/flat/nooptimized/one_small_string_object.effekt create mode 100644 examples/flat/nooptimized/one_xl_object.check create mode 100644 examples/flat/nooptimized/one_xl_object.effekt create mode 100644 examples/flat/nooptimized/one_xs_object.check create mode 100644 examples/flat/nooptimized/one_xs_object.effekt create mode 100644 examples/flat/nooptimized/one_xxl_object_all_fields.check create mode 100644 examples/flat/nooptimized/one_xxl_object_all_fields.effekt create mode 100644 examples/flat/nooptimized/one_xxxl_object.check create mode 100644 examples/flat/nooptimized/one_xxxl_object.effekt create mode 100644 examples/flat/nooptimized/primitive_ref.check create mode 100644 examples/flat/nooptimized/primitive_ref.effekt create mode 100644 examples/flat/nooptimized/ref_allocate.check create mode 100644 examples/flat/nooptimized/ref_allocate.effekt create mode 100644 examples/flat/nooptimized/simple_list.check create mode 100644 examples/flat/nooptimized/simple_list.effekt create mode 100644 examples/flat/nooptimized/simple_ref.check create mode 100644 examples/flat/nooptimized/simple_ref.effekt create mode 100644 examples/flat/nooptimized/superperson.check create mode 100644 examples/flat/nooptimized/superperson.effekt create mode 100644 examples/flat/nooptimized/superperson_with_free.check create mode 100644 examples/flat/nooptimized/superperson_with_free.effekt create mode 100644 examples/flat/nooptimized/three_md_objects_direct.check create mode 100644 examples/flat/nooptimized/three_md_objects_direct.effekt create mode 100644 examples/flat/nooptimized/trigger_child_freeing.check create mode 100644 examples/flat/nooptimized/trigger_child_freeing.effekt create mode 100644 examples/flat/nooptimized/trigger_flush_once.check create mode 100644 examples/flat/nooptimized/trigger_flush_once.effekt create mode 100644 examples/flat/nooptimized/trigger_flush_twice.check create mode 100644 examples/flat/nooptimized/trigger_flush_twice.effekt create mode 100644 examples/flat/nooptimized/trigger_one_child_freeing.check create mode 100644 examples/flat/nooptimized/trigger_one_child_freeing.effekt create mode 100644 examples/flat/nooptimized/trigger_two_child_freeing.check create mode 100644 examples/flat/nooptimized/trigger_two_child_freeing.effekt create mode 100644 examples/flat/nooptimized/two_lg_objects.check create mode 100644 examples/flat/nooptimized/two_lg_objects.effekt create mode 100644 examples/flat/nooptimized/two_md_mixed_object.check create mode 100644 examples/flat/nooptimized/two_md_mixed_object.effekt create mode 100644 examples/flat/nooptimized/two_md_objects.check create mode 100644 examples/flat/nooptimized/two_md_objects.effekt create mode 100644 examples/flat/nooptimized/two_slot_one_person_list.check create mode 100644 examples/flat/nooptimized/two_slot_one_person_list.effekt create mode 100644 examples/flat/nooptimized/two_slot_one_person_with_free_variable_list.check create mode 100644 examples/flat/nooptimized/two_slot_one_person_with_free_variable_list.effekt create mode 100644 examples/flat/nooptimized/two_slot_two_person_list.check create mode 100644 examples/flat/nooptimized/two_slot_two_person_list.effekt create mode 100644 examples/flat/nooptimized/two_slot_two_person_list_continuation.check create mode 100644 examples/flat/nooptimized/two_slot_two_person_list_continuation.effekt create mode 100644 examples/flat/nooptimized/two_slot_two_person_list_continuation_allocation.check create mode 100644 examples/flat/nooptimized/two_slot_two_person_list_continuation_allocation.effekt create mode 100644 examples/flat/nooptimized/two_slot_two_person_list_continuation_exhausted.check create mode 100644 examples/flat/nooptimized/two_slot_two_person_list_continuation_exhausted.effekt create mode 100644 examples/flat/nooptimized/two_slot_two_person_list_exhausted.check create mode 100644 examples/flat/nooptimized/two_slot_two_person_list_exhausted.effekt create mode 100644 examples/flat/nooptimized/two_slot_two_person_with_free_variable_list.check create mode 100644 examples/flat/nooptimized/two_slot_two_person_with_free_variable_list.effekt create mode 100644 examples/flat/nooptimized/two_sm_mixed_object.check create mode 100644 examples/flat/nooptimized/two_sm_mixed_object.effekt create mode 100644 examples/flat/nooptimized/two_sm_objects.check create mode 100644 examples/flat/nooptimized/two_sm_objects.effekt create mode 100644 examples/flat/nooptimized/two_xl_objects.check create mode 100644 examples/flat/nooptimized/two_xl_objects.effekt create mode 100644 examples/flat/nooptimized/two_xs_objects.check create mode 100644 examples/flat/nooptimized/two_xs_objects.effekt create mode 100644 examples/flat/nooptimized/two_xxl_object_all_fields.check create mode 100644 examples/flat/nooptimized/two_xxl_object_all_fields.effekt create mode 100644 examples/flat/nooptimized/two_xxl_objects.check create mode 100644 examples/flat/nooptimized/two_xxl_objects.effekt create mode 100644 examples/flat/nooptimized/two_xxxl_objects.check create mode 100644 examples/flat/nooptimized/two_xxxl_objects.effekt diff --git a/effekt/jvm/src/test/scala/effekt/FlatTests.scala b/effekt/jvm/src/test/scala/effekt/FlatTests.scala new file mode 100644 index 000000000..c0c0f6e5c --- /dev/null +++ b/effekt/jvm/src/test/scala/effekt/FlatTests.scala @@ -0,0 +1,24 @@ +package effekt + +import sbt.io.* +import sbt.io.syntax.* + +import java.io.File +import scala.language.implicitConversions +import scala.sys.process.Process + +// df: My own test class to run my requested tests automatically +class FlatTests extends EffektTests { + + def backendName = "llvm" + + override def valgrind = false // works on linux only + + override lazy val positives: Set[File] = Set( + examplesDir / "flat" / "optimized" + ) + + override lazy val withoutOptimizations: Set[File] = Set( + examplesDir / "flat" / "nooptimized", + ) +} diff --git a/examples/flat/nooptimized/allocate_first_then_release_flush_once.check b/examples/flat/nooptimized/allocate_first_then_release_flush_once.check new file mode 100644 index 000000000..90fa4d6e3 --- /dev/null +++ b/examples/flat/nooptimized/allocate_first_then_release_flush_once.check @@ -0,0 +1,65 @@ +1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +11 +12 +13 +14 +15 +16 +17 +18 +19 +20 +21 +22 +23 +24 +25 +26 +27 +28 +29 +30 +31 +32 +33 +34 +35 +36 +37 +38 +39 +40 +41 +42 +43 +44 +45 +46 +47 +48 +49 +50 +51 +52 +53 +54 +55 +56 +57 +58 +59 +60 +61 +62 +63 +64 +65 \ No newline at end of file diff --git a/examples/flat/nooptimized/allocate_first_then_release_flush_once.effekt b/examples/flat/nooptimized/allocate_first_then_release_flush_once.effekt new file mode 100644 index 000000000..4d1f729a1 --- /dev/null +++ b/examples/flat/nooptimized/allocate_first_then_release_flush_once.effekt @@ -0,0 +1,148 @@ + +record OneSlotPerson( + field1: Int, + field2: Int, + field3: Int, + field4: Int, + field5: Int, + field6: Int +) + +def allocate65SlotsAndReleaseThem() = { + var x1 = OneSlotPerson(1, 2, 3, 4, 5, 6) + var x2 = OneSlotPerson(2, 3, 4, 5, 6, 7) + var x3 = OneSlotPerson(3, 4, 5, 6, 7, 8) + var x4 = OneSlotPerson(4, 5, 6, 7, 8, 9) + var x5 = OneSlotPerson(5, 6, 7, 8, 9, 10) + var x6 = OneSlotPerson(6, 7, 8, 9, 10, 11) + var x7 = OneSlotPerson(7, 8, 9, 10, 11, 12) + var x8 = OneSlotPerson(8, 9, 10, 11, 12, 13) + var x9 = OneSlotPerson(9, 10, 11, 12, 13, 14) + var x10 = OneSlotPerson(10, 11, 12, 13, 14, 15) + var x11 = OneSlotPerson(11, 12, 13, 14, 15, 16) + var x12 = OneSlotPerson(12, 13, 14, 15, 16, 17) + var x13 = OneSlotPerson(13, 14, 15, 16, 17, 18) + var x14 = OneSlotPerson(14, 15, 16, 17, 18, 19) + var x15 = OneSlotPerson(15, 16, 17, 18, 19, 20) + var x16 = OneSlotPerson(16, 17, 18, 19, 20, 21) + var x17 = OneSlotPerson(17, 18, 19, 20, 21, 22) + var x18 = OneSlotPerson(18, 19, 20, 21, 22, 23) + var x19 = OneSlotPerson(19, 20, 21, 22, 23, 24) + var x20 = OneSlotPerson(20, 21, 22, 23, 24, 25) + var x21 = OneSlotPerson(21, 22, 23, 24, 25, 26) + var x22 = OneSlotPerson(22, 23, 24, 25, 26, 27) + var x23 = OneSlotPerson(23, 24, 25, 26, 27, 28) + var x24 = OneSlotPerson(24, 25, 26, 27, 28, 29) + var x25 = OneSlotPerson(25, 26, 27, 28, 29, 30) + var x26 = OneSlotPerson(26, 27, 28, 29, 30, 31) + var x27 = OneSlotPerson(27, 28, 29, 30, 31, 32) + var x28 = OneSlotPerson(28, 29, 30, 31, 32, 33) + var x29 = OneSlotPerson(29, 30, 31, 32, 33, 34) + var x30 = OneSlotPerson(30, 31, 32, 33, 34, 35) + var x31 = OneSlotPerson(31, 32, 33, 34, 35, 36) + var x32 = OneSlotPerson(32, 33, 34, 35, 36, 37) + var x33 = OneSlotPerson(33, 34, 35, 36, 37, 38) + var x34 = OneSlotPerson(34, 35, 36, 37, 38, 39) + var x35 = OneSlotPerson(35, 36, 37, 38, 39, 40) + var x36 = OneSlotPerson(36, 37, 38, 39, 40, 41) + var x37 = OneSlotPerson(37, 38, 39, 40, 41, 42) + var x38 = OneSlotPerson(38, 39, 40, 41, 42, 43) + var x39 = OneSlotPerson(39, 40, 41, 42, 43, 44) + var x40 = OneSlotPerson(40, 41, 42, 43, 44, 45) + var x41 = OneSlotPerson(41, 42, 43, 44, 45, 46) + var x42 = OneSlotPerson(42, 43, 44, 45, 46, 47) + var x43 = OneSlotPerson(43, 44, 45, 46, 47, 48) + var x44 = OneSlotPerson(44, 45, 46, 47, 48, 49) + var x45 = OneSlotPerson(45, 46, 47, 48, 49, 50) + var x46 = OneSlotPerson(46, 47, 48, 49, 50, 51) + var x47 = OneSlotPerson(47, 48, 49, 50, 51, 52) + var x48 = OneSlotPerson(48, 49, 50, 51, 52, 53) + var x49 = OneSlotPerson(49, 50, 51, 52, 53, 54) + var x50 = OneSlotPerson(50, 51, 52, 53, 54, 55) + var x51 = OneSlotPerson(51, 52, 53, 54, 55, 56) + var x52 = OneSlotPerson(52, 53, 54, 55, 56, 57) + var x53 = OneSlotPerson(53, 54, 55, 56, 57, 58) + var x54 = OneSlotPerson(54, 55, 56, 57, 58, 59) + var x55 = OneSlotPerson(55, 56, 57, 58, 59, 60) + var x56 = OneSlotPerson(56, 57, 58, 59, 60, 61) + var x57 = OneSlotPerson(57, 58, 59, 60, 61, 62) + var x58 = OneSlotPerson(58, 59, 60, 61, 62, 63) + var x59 = OneSlotPerson(59, 60, 61, 62, 63, 64) + var x60 = OneSlotPerson(60, 61, 62, 63, 64, 65) + var x61 = OneSlotPerson(61, 62, 63, 64, 65, 66) + var x62 = OneSlotPerson(62, 63, 64, 65, 66, 67) + var x63 = OneSlotPerson(63, 64, 65, 66, 67, 68) + var x64 = OneSlotPerson(64, 65, 66, 67, 68, 69) + var x65 = OneSlotPerson(65, 66, 67, 68, 69, 70) + + println(x1.field1) + println(x2.field1) + println(x3.field1) + println(x4.field1) + println(x5.field1) + println(x6.field1) + println(x7.field1) + println(x8.field1) + println(x9.field1) + println(x10.field1) + println(x11.field1) + println(x12.field1) + println(x13.field1) + println(x14.field1) + println(x15.field1) + println(x16.field1) + println(x17.field1) + println(x18.field1) + println(x19.field1) + println(x20.field1) + println(x21.field1) + println(x22.field1) + println(x23.field1) + println(x24.field1) + println(x25.field1) + println(x26.field1) + println(x27.field1) + println(x28.field1) + println(x29.field1) + println(x30.field1) + println(x31.field1) + println(x32.field1) + println(x33.field1) + println(x34.field1) + println(x35.field1) + println(x36.field1) + println(x37.field1) + println(x38.field1) + println(x39.field1) + println(x40.field1) + println(x41.field1) + println(x42.field1) + println(x43.field1) + println(x44.field1) + println(x45.field1) + println(x46.field1) + println(x47.field1) + println(x48.field1) + println(x49.field1) + println(x50.field1) + println(x51.field1) + println(x52.field1) + println(x53.field1) + println(x54.field1) + println(x55.field1) + println(x56.field1) + println(x57.field1) + println(x58.field1) + println(x59.field1) + println(x60.field1) + println(x61.field1) + println(x62.field1) + println(x63.field1) + println(x64.field1) + println(x65.field1) +} + +def main() = { + allocate65SlotsAndReleaseThem(); + var finalObjectThatTriggersFlushingTodoList = OneSlotPerson(1, 2, 3, 4, 5, 6) +} diff --git a/examples/flat/nooptimized/allocate_first_then_release_flush_twice.check b/examples/flat/nooptimized/allocate_first_then_release_flush_twice.check new file mode 100644 index 000000000..e69de29bb diff --git a/examples/flat/nooptimized/allocate_first_then_release_flush_twice.effekt b/examples/flat/nooptimized/allocate_first_then_release_flush_twice.effekt new file mode 100644 index 000000000..d9b4ccbb5 --- /dev/null +++ b/examples/flat/nooptimized/allocate_first_then_release_flush_twice.effekt @@ -0,0 +1,282 @@ + +record OneSlotPerson( + field1: Int, + field2: Int, + field3: Int, + field4: Int, + field5: Int, + field6: Int +) + +// we first allocate 128 slots and then release them all, such that we have exactly 128 slots on the to-do-list +// therefore, we have to flush the to-do list twice to clear it completely +def allocate128SlotsAndReleaseThem() = { + var x1 = OneSlotPerson(1, 2, 3, 4, 5, 6) + var x2 = OneSlotPerson(2, 3, 4, 5, 6, 7) + var x3 = OneSlotPerson(3, 4, 5, 6, 7, 8) + var x4 = OneSlotPerson(4, 5, 6, 7, 8, 9) + var x5 = OneSlotPerson(5, 6, 7, 8, 9, 10) + var x6 = OneSlotPerson(6, 7, 8, 9, 10, 11) + var x7 = OneSlotPerson(7, 8, 9, 10, 11, 12) + var x8 = OneSlotPerson(8, 9, 10, 11, 12, 13) + var x9 = OneSlotPerson(9, 10, 11, 12, 13, 14) + var x10 = OneSlotPerson(10, 11, 12, 13, 14, 15) + var x11 = OneSlotPerson(11, 12, 13, 14, 15, 16) + var x12 = OneSlotPerson(12, 13, 14, 15, 16, 17) + var x13 = OneSlotPerson(13, 14, 15, 16, 17, 18) + var x14 = OneSlotPerson(14, 15, 16, 17, 18, 19) + var x15 = OneSlotPerson(15, 16, 17, 18, 19, 20) + var x16 = OneSlotPerson(16, 17, 18, 19, 20, 21) + var x17 = OneSlotPerson(17, 18, 19, 20, 21, 22) + var x18 = OneSlotPerson(18, 19, 20, 21, 22, 23) + var x19 = OneSlotPerson(19, 20, 21, 22, 23, 24) + var x20 = OneSlotPerson(20, 21, 22, 23, 24, 25) + var x21 = OneSlotPerson(21, 22, 23, 24, 25, 26) + var x22 = OneSlotPerson(22, 23, 24, 25, 26, 27) + var x23 = OneSlotPerson(23, 24, 25, 26, 27, 28) + var x24 = OneSlotPerson(24, 25, 26, 27, 28, 29) + var x25 = OneSlotPerson(25, 26, 27, 28, 29, 30) + var x26 = OneSlotPerson(26, 27, 28, 29, 30, 31) + var x27 = OneSlotPerson(27, 28, 29, 30, 31, 32) + var x28 = OneSlotPerson(28, 29, 30, 31, 32, 33) + var x29 = OneSlotPerson(29, 30, 31, 32, 33, 34) + var x30 = OneSlotPerson(30, 31, 32, 33, 34, 35) + var x31 = OneSlotPerson(31, 32, 33, 34, 35, 36) + var x32 = OneSlotPerson(32, 33, 34, 35, 36, 37) + var x33 = OneSlotPerson(33, 34, 35, 36, 37, 38) + var x34 = OneSlotPerson(34, 35, 36, 37, 38, 39) + var x35 = OneSlotPerson(35, 36, 37, 38, 39, 40) + var x36 = OneSlotPerson(36, 37, 38, 39, 40, 41) + var x37 = OneSlotPerson(37, 38, 39, 40, 41, 42) + var x38 = OneSlotPerson(38, 39, 40, 41, 42, 43) + var x39 = OneSlotPerson(39, 40, 41, 42, 43, 44) + var x40 = OneSlotPerson(40, 41, 42, 43, 44, 45) + var x41 = OneSlotPerson(41, 42, 43, 44, 45, 46) + var x42 = OneSlotPerson(42, 43, 44, 45, 46, 47) + var x43 = OneSlotPerson(43, 44, 45, 46, 47, 48) + var x44 = OneSlotPerson(44, 45, 46, 47, 48, 49) + var x45 = OneSlotPerson(45, 46, 47, 48, 49, 50) + var x46 = OneSlotPerson(46, 47, 48, 49, 50, 51) + var x47 = OneSlotPerson(47, 48, 49, 50, 51, 52) + var x48 = OneSlotPerson(48, 49, 50, 51, 52, 53) + var x49 = OneSlotPerson(49, 50, 51, 52, 53, 54) + var x50 = OneSlotPerson(50, 51, 52, 53, 54, 55) + var x51 = OneSlotPerson(51, 52, 53, 54, 55, 56) + var x52 = OneSlotPerson(52, 53, 54, 55, 56, 57) + var x53 = OneSlotPerson(53, 54, 55, 56, 57, 58) + var x54 = OneSlotPerson(54, 55, 56, 57, 58, 59) + var x55 = OneSlotPerson(55, 56, 57, 58, 59, 60) + var x56 = OneSlotPerson(56, 57, 58, 59, 60, 61) + var x57 = OneSlotPerson(57, 58, 59, 60, 61, 62) + var x58 = OneSlotPerson(58, 59, 60, 61, 62, 63) + var x59 = OneSlotPerson(59, 60, 61, 62, 63, 64) + var x60 = OneSlotPerson(60, 61, 62, 63, 64, 65) + var x61 = OneSlotPerson(61, 62, 63, 64, 65, 66) + var x62 = OneSlotPerson(62, 63, 64, 65, 66, 67) + var x63 = OneSlotPerson(63, 64, 65, 66, 67, 68) + var x64 = OneSlotPerson(64, 65, 66, 67, 68, 69) + var x65 = OneSlotPerson(65, 66, 67, 68, 69, 70) + var x66 = OneSlotPerson(66, 67, 68, 69, 70, 71) + var x67 = OneSlotPerson(67, 68, 69, 70, 71, 72) + var x68 = OneSlotPerson(68, 69, 70, 71, 72, 73) + var x69 = OneSlotPerson(69, 70, 71, 72, 73, 74) + var x70 = OneSlotPerson(70, 71, 72, 73, 74, 75) + var x71 = OneSlotPerson(71, 72, 73, 74, 75, 76) + var x72 = OneSlotPerson(72, 73, 74, 75, 76, 77) + var x73 = OneSlotPerson(73, 74, 75, 76, 77, 78) + var x74 = OneSlotPerson(74, 75, 76, 77, 78, 79) + var x75 = OneSlotPerson(75, 76, 77, 78, 79, 80) + var x76 = OneSlotPerson(76, 77, 78, 79, 80, 81) + var x77 = OneSlotPerson(77, 78, 79, 80, 81, 82) + var x78 = OneSlotPerson(78, 79, 80, 81, 82, 83) + var x79 = OneSlotPerson(79, 80, 81, 82, 83, 84) + var x80 = OneSlotPerson(80, 81, 82, 83, 84, 85) + var x81 = OneSlotPerson(81, 82, 83, 84, 85, 86) + var x82 = OneSlotPerson(82, 83, 84, 85, 86, 87) + var x83 = OneSlotPerson(83, 84, 85, 86, 87, 88) + var x84 = OneSlotPerson(84, 85, 86, 87, 88, 89) + var x85 = OneSlotPerson(85, 86, 87, 88, 89, 90) + var x86 = OneSlotPerson(86, 87, 88, 89, 90, 91) + var x87 = OneSlotPerson(87, 88, 89, 90, 91, 92) + var x88 = OneSlotPerson(88, 89, 90, 91, 92, 93) + var x89 = OneSlotPerson(89, 90, 91, 92, 93, 94) + var x90 = OneSlotPerson(90, 91, 92, 93, 94, 95) + var x91 = OneSlotPerson(91, 92, 93, 94, 95, 96) + var x92 = OneSlotPerson(92, 93, 94, 95, 96, 97) + var x93 = OneSlotPerson(93, 94, 95, 96, 97, 98) + var x94 = OneSlotPerson(94, 95, 96, 97, 98, 99) + var x95 = OneSlotPerson(95, 96, 97, 98, 99, 100) + var x96 = OneSlotPerson(96, 97, 98, 99, 100, 101) + var x97 = OneSlotPerson(97, 98, 99, 100, 101, 102) + var x98 = OneSlotPerson(98, 99, 100, 101, 102, 103) + var x99 = OneSlotPerson(99, 100, 101, 102, 103, 104) + var x100 = OneSlotPerson(100, 101, 102, 103, 104, 105) + var x101 = OneSlotPerson(101, 102, 103, 104, 105, 106) + var x102 = OneSlotPerson(102, 103, 104, 105, 106, 107) + var x103 = OneSlotPerson(103, 104, 105, 106, 107, 108) + var x104 = OneSlotPerson(104, 105, 106, 107, 108, 109) + var x105 = OneSlotPerson(105, 106, 107, 108, 109, 110) + var x106 = OneSlotPerson(106, 107, 108, 109, 110, 111) + var x107 = OneSlotPerson(107, 108, 109, 110, 111, 112) + var x108 = OneSlotPerson(108, 109, 110, 111, 112, 113) + var x109 = OneSlotPerson(109, 110, 111, 112, 113, 114) + var x110 = OneSlotPerson(110, 111, 112, 113, 114, 115) + var x111 = OneSlotPerson(111, 112, 113, 114, 115, 116) + var x112 = OneSlotPerson(112, 113, 114, 115, 116, 117) + var x113 = OneSlotPerson(113, 114, 115, 116, 117, 118) + var x114 = OneSlotPerson(114, 115, 116, 117, 118, 119) + var x115 = OneSlotPerson(115, 116, 117, 118, 119, 120) + var x116 = OneSlotPerson(116, 117, 118, 119, 120, 121) + var x117 = OneSlotPerson(117, 118, 119, 120, 121, 122) + var x118 = OneSlotPerson(118, 119, 120, 121, 122, 123) + var x119 = OneSlotPerson(119, 120, 121, 122, 123, 124) + var x120 = OneSlotPerson(120, 121, 122, 123, 124, 125) + var x121 = OneSlotPerson(121, 122, 123, 124, 125, 126) + var x122 = OneSlotPerson(122, 123, 124, 125, 126, 127) + var x123 = OneSlotPerson(123, 124, 125, 126, 127, 128) + var x124 = OneSlotPerson(124, 125, 126, 127, 128, 129) + var x125 = OneSlotPerson(125, 126, 127, 128, 129, 130) + var x126 = OneSlotPerson(126, 127, 128, 129, 130, 131) + var x127 = OneSlotPerson(127, 128, 129, 130, 131, 132) + var x128 = OneSlotPerson(128, 129, 130, 131, 132, 133) + + println(x1.field1) + println(x2.field1) + println(x3.field1) + println(x4.field1) + println(x5.field1) + println(x6.field1) + println(x7.field1) + println(x8.field1) + println(x9.field1) + println(x10.field1) + println(x11.field1) + println(x12.field1) + println(x13.field1) + println(x14.field1) + println(x15.field1) + println(x16.field1) + println(x17.field1) + println(x18.field1) + println(x19.field1) + println(x20.field1) + println(x21.field1) + println(x22.field1) + println(x23.field1) + println(x24.field1) + println(x25.field1) + println(x26.field1) + println(x27.field1) + println(x28.field1) + println(x29.field1) + println(x30.field1) + println(x31.field1) + println(x32.field1) + println(x33.field1) + println(x34.field1) + println(x35.field1) + println(x36.field1) + println(x37.field1) + println(x38.field1) + println(x39.field1) + println(x40.field1) + println(x41.field1) + println(x42.field1) + println(x43.field1) + println(x44.field1) + println(x45.field1) + println(x46.field1) + println(x47.field1) + println(x48.field1) + println(x49.field1) + println(x50.field1) + println(x51.field1) + println(x52.field1) + println(x53.field1) + println(x54.field1) + println(x55.field1) + println(x56.field1) + println(x57.field1) + println(x58.field1) + println(x59.field1) + println(x60.field1) + println(x61.field1) + println(x62.field1) + println(x63.field1) + println(x64.field1) + println(x65.field1) + println(x66.field1) + println(x67.field1) + println(x68.field1) + println(x69.field1) + println(x70.field1) + println(x71.field1) + println(x72.field1) + println(x73.field1) + println(x74.field1) + println(x75.field1) + println(x76.field1) + println(x77.field1) + println(x78.field1) + println(x79.field1) + println(x80.field1) + println(x81.field1) + println(x82.field1) + println(x83.field1) + println(x84.field1) + println(x85.field1) + println(x86.field1) + println(x87.field1) + println(x88.field1) + println(x89.field1) + println(x90.field1) + println(x91.field1) + println(x92.field1) + println(x93.field1) + println(x94.field1) + println(x95.field1) + println(x96.field1) + println(x97.field1) + println(x98.field1) + println(x99.field1) + println(x100.field1) + println(x101.field1) + println(x102.field1) + println(x103.field1) + println(x104.field1) + println(x105.field1) + println(x106.field1) + println(x107.field1) + println(x108.field1) + println(x109.field1) + println(x110.field1) + println(x111.field1) + println(x112.field1) + println(x113.field1) + println(x114.field1) + println(x115.field1) + println(x116.field1) + println(x117.field1) + println(x118.field1) + println(x119.field1) + println(x120.field1) + println(x121.field1) + println(x122.field1) + println(x123.field1) + println(x124.field1) + println(x125.field1) + println(x126.field1) + println(x127.field1) + println(x128.field1) +} + +def main() = { + //allocate128SlotsAndReleaseThem(); + // allocate & flush to-do list twice + //var flushingTodoListFirstTime = OneSlotPerson(1, 2, 3, 4, 5, 6) + //var flushingTodoListSecondTime = OneSlotPerson(1, 2, 3, 4, 5, 7) + + // deallocate again + //println(flushingTodoListFirstTime.field1) + //println(flushingTodoListSecondTime.field1) +} diff --git a/examples/flat/nooptimized/array_record.check b/examples/flat/nooptimized/array_record.check new file mode 100644 index 000000000..56ea89185 --- /dev/null +++ b/examples/flat/nooptimized/array_record.check @@ -0,0 +1 @@ +Array(1, 2, 3) \ No newline at end of file diff --git a/examples/flat/nooptimized/array_record.effekt b/examples/flat/nooptimized/array_record.effekt new file mode 100644 index 000000000..0580fbeae --- /dev/null +++ b/examples/flat/nooptimized/array_record.effekt @@ -0,0 +1,10 @@ +record Person( + field1: Int, + field2: Array[Int] + ) + +def main() = { + val myArray: Array[Int] = build(3) { i => i + 1 } // Array(1, 2, 3) + val p = Person(1, myArray) + println(myArray) +} \ No newline at end of file diff --git a/examples/flat/nooptimized/array_record_match.check b/examples/flat/nooptimized/array_record_match.check new file mode 100644 index 000000000..56a6051ca --- /dev/null +++ b/examples/flat/nooptimized/array_record_match.check @@ -0,0 +1 @@ +1 \ No newline at end of file diff --git a/examples/flat/nooptimized/array_record_match.effekt b/examples/flat/nooptimized/array_record_match.effekt new file mode 100644 index 000000000..1af090a55 --- /dev/null +++ b/examples/flat/nooptimized/array_record_match.effekt @@ -0,0 +1,21 @@ +record Person( + field1: Int, + field2: Array[Int] + ) + +record OneSlotPerson( + field1: Int, + field2: Int, + field3: Int, + field4: Int, + field5: Int, + field6: Int +) + +def main() = { + val myArray: Array[Int] = array::allocate(1) + val p = Person(1, myArray) + p match { + case Person(f1, _) => println(f1) + } +} \ No newline at end of file diff --git a/examples/flat/nooptimized/array_record_match_exhausted.check b/examples/flat/nooptimized/array_record_match_exhausted.check new file mode 100644 index 000000000..56a6051ca --- /dev/null +++ b/examples/flat/nooptimized/array_record_match_exhausted.check @@ -0,0 +1 @@ +1 \ No newline at end of file diff --git a/examples/flat/nooptimized/array_record_match_exhausted.effekt b/examples/flat/nooptimized/array_record_match_exhausted.effekt new file mode 100644 index 000000000..772e5c8c2 --- /dev/null +++ b/examples/flat/nooptimized/array_record_match_exhausted.effekt @@ -0,0 +1,21 @@ +record Person( + field1: Int, + field2: Array[Int] + ) + +record OneSlotPerson( + field1: Int, + field2: Int, + field3: Int, + field4: Int, + field5: Int, + field6: Int +) + +def main() = { + val myArray: Array[Int] = array::allocate(1) + val p = Person(1, myArray) + p match { + case Person(f1, arr) => println(f1) + } +} \ No newline at end of file diff --git a/examples/flat/nooptimized/different_person_sizes_biggest_first.check b/examples/flat/nooptimized/different_person_sizes_biggest_first.check new file mode 100644 index 000000000..63ea17a09 --- /dev/null +++ b/examples/flat/nooptimized/different_person_sizes_biggest_first.check @@ -0,0 +1,3 @@ +24 +13 +6 \ No newline at end of file diff --git a/examples/flat/nooptimized/different_person_sizes_biggest_first.effekt b/examples/flat/nooptimized/different_person_sizes_biggest_first.effekt new file mode 100644 index 000000000..6a963c745 --- /dev/null +++ b/examples/flat/nooptimized/different_person_sizes_biggest_first.effekt @@ -0,0 +1,46 @@ +// this test is for debugging of the to-do-list approach. Here, we define multiple records that require different +// number of heap-slots (aka. 64 bytes). + +// here we allocate the biggest object at first and go to the smallest. + +record OneSlotPerson( + field1: Int, + field2: Int, + field3: Int, + field4: Int, + field5: Int, + field6: Int + ) + +record TwoSlotPerson( + field1: Int, + field2: Int, + field3: Int, + field4: Int, + field5: Int, + field6: Int, + field7: Int + ) + +record ThreeSlotPerson( + field1: Int, + field2: Int, + field3: Int, + field4: Int, + field5: Int, + field6: Int, + field7: Int, + field8: Int, + field9: Int, + field10: Int, + field11: Int + ) + +def main() = { + val p3 = ThreeSlotPerson(14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24) + println(p3.field11) + val p2 = TwoSlotPerson(7, 8, 9, 10, 11, 12, 13) + println(p2.field7) + val p1 = OneSlotPerson(1, 2, 3, 4, 5, 6) + println(p1.field6) +} \ No newline at end of file diff --git a/examples/flat/nooptimized/different_person_sizes_smallest_first.check b/examples/flat/nooptimized/different_person_sizes_smallest_first.check new file mode 100644 index 000000000..bdfbf007c --- /dev/null +++ b/examples/flat/nooptimized/different_person_sizes_smallest_first.check @@ -0,0 +1,3 @@ +6 +13 +26 \ No newline at end of file diff --git a/examples/flat/nooptimized/different_person_sizes_smallest_first.effekt b/examples/flat/nooptimized/different_person_sizes_smallest_first.effekt new file mode 100644 index 000000000..2a61b272d --- /dev/null +++ b/examples/flat/nooptimized/different_person_sizes_smallest_first.effekt @@ -0,0 +1,46 @@ +// this test is for debugging of the to-do-list approach. Here, we define multiple records that require different +// number of heap-slots (aka. 64 bytes). + +record OneSlotPerson( + field1: Int, + field2: Int, + field3: Int, + field4: Int, + field5: Int, + field6: Int + ) + +record TwoSlotPerson( + field1: Int, + field2: Int, + field3: Int, + field4: Int, + field5: Int, + field6: Int, + field7: Int + ) + +record ThreeSlotPerson( + field1: Int, + field2: Int, + field3: Int, + field4: Int, + field5: Int, + field6: Int, + field7: Int, + field8: Int, + field9: Int, + field10: Int, + field11: Int, + field12: Int, + field13: Int + ) + +def main() = { + val p1 = OneSlotPerson(1, 2, 3, 4, 5, 6) + println(p1.field6) + val p2 = TwoSlotPerson(7, 8, 9, 10, 11, 12, 13) + println(p2.field7) + val p3 = ThreeSlotPerson(14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26) + println(p3.field13) +} \ No newline at end of file diff --git a/examples/flat/nooptimized/nested_objects.check b/examples/flat/nooptimized/nested_objects.check new file mode 100644 index 000000000..e440e5c84 --- /dev/null +++ b/examples/flat/nooptimized/nested_objects.check @@ -0,0 +1 @@ +3 \ No newline at end of file diff --git a/examples/flat/nooptimized/nested_objects.effekt b/examples/flat/nooptimized/nested_objects.effekt new file mode 100644 index 000000000..27a274b5f --- /dev/null +++ b/examples/flat/nooptimized/nested_objects.effekt @@ -0,0 +1,16 @@ +record Person1( + field3: Int, + field4: Int +) + +record Person( + field1: Int, + field2: Int, + person1: Person1 + ) + +def main() = { + val p1 = Person1(3, 4) + val p = Person(1, 2, p1) + println(p.person1.field3) +} \ No newline at end of file diff --git a/examples/flat/nooptimized/one_big_string_object.check b/examples/flat/nooptimized/one_big_string_object.check new file mode 100644 index 000000000..41bfe81b8 --- /dev/null +++ b/examples/flat/nooptimized/one_big_string_object.check @@ -0,0 +1 @@ +Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. \ No newline at end of file diff --git a/examples/flat/nooptimized/one_big_string_object.effekt b/examples/flat/nooptimized/one_big_string_object.effekt new file mode 100644 index 000000000..492ee575c --- /dev/null +++ b/examples/flat/nooptimized/one_big_string_object.effekt @@ -0,0 +1,9 @@ +// contains one big lorem ipsum string with 100 words +record Person( + field1: String + ) + +def main() = { + val p = Person("Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.") + println(p.field1) +} \ No newline at end of file diff --git a/examples/flat/nooptimized/one_lg_object.check b/examples/flat/nooptimized/one_lg_object.check new file mode 100644 index 000000000..9a037142a --- /dev/null +++ b/examples/flat/nooptimized/one_lg_object.check @@ -0,0 +1 @@ +10 \ No newline at end of file diff --git a/examples/flat/nooptimized/one_lg_object.effekt b/examples/flat/nooptimized/one_lg_object.effekt new file mode 100644 index 000000000..18eff9264 --- /dev/null +++ b/examples/flat/nooptimized/one_lg_object.effekt @@ -0,0 +1,18 @@ +// lg = Person fills 2 saving slots completely +record Person( + field1: Int, + field2: Int, + field3: Int, + field4: Int, + field5: Int, + field6: Int, + field7: Int, + field8: Int, + field9: Int, + field10: Int + ) + +def main() = { + val p = Person(1, 2, 3, 4, 5, 6, 7, 8, 9, 10) + println(p.field10) +} \ No newline at end of file diff --git a/examples/flat/nooptimized/one_md_object.check b/examples/flat/nooptimized/one_md_object.check new file mode 100644 index 000000000..c7930257d --- /dev/null +++ b/examples/flat/nooptimized/one_md_object.check @@ -0,0 +1 @@ +7 \ No newline at end of file diff --git a/examples/flat/nooptimized/one_md_object.effekt b/examples/flat/nooptimized/one_md_object.effekt new file mode 100644 index 000000000..d68c5a960 --- /dev/null +++ b/examples/flat/nooptimized/one_md_object.effekt @@ -0,0 +1,15 @@ +// md = Person requires 2 saving slots +record Person( + field1: Int, + field2: Int, + field3: Int, + field4: Int, + field5: Int, + field6: Int, + field7: Int + ) + +def main() = { + val p = Person(1, 2, 3, 4, 5, 6, 7) + println(p.field7) +} \ No newline at end of file diff --git a/examples/flat/nooptimized/one_slot_one_person_list.check b/examples/flat/nooptimized/one_slot_one_person_list.check new file mode 100644 index 000000000..62f945751 --- /dev/null +++ b/examples/flat/nooptimized/one_slot_one_person_list.check @@ -0,0 +1 @@ +6 \ No newline at end of file diff --git a/examples/flat/nooptimized/one_slot_one_person_list.effekt b/examples/flat/nooptimized/one_slot_one_person_list.effekt new file mode 100644 index 000000000..e23065e8e --- /dev/null +++ b/examples/flat/nooptimized/one_slot_one_person_list.effekt @@ -0,0 +1,27 @@ +import list + +record OneSlotPerson( + field1: Int, + field2: Int, + field3: Int, + field4: Int, + field5: Int, + field6: Int +) + +def main() = { + val person1 = OneSlotPerson(1, 2, 3, 4, 5, 6) + var myList = [person1] + //myList = drop(myList, 1) + //val myList = Nil[OneSlotPerson]() + + // prints 6. If -1 is printed, there is a bug + myList match { + case Nil() => println(-1) + case Cons(x, _) => println(x.field6) + //case Cons(x, _) => println(-2) + } + + //myList = drop(myList, 1) + //val person3 = person1 +} diff --git a/examples/flat/nooptimized/one_sm_object.check b/examples/flat/nooptimized/one_sm_object.check new file mode 100644 index 000000000..62f945751 --- /dev/null +++ b/examples/flat/nooptimized/one_sm_object.check @@ -0,0 +1 @@ +6 \ No newline at end of file diff --git a/examples/flat/nooptimized/one_sm_object.effekt b/examples/flat/nooptimized/one_sm_object.effekt new file mode 100644 index 000000000..95ffb2305 --- /dev/null +++ b/examples/flat/nooptimized/one_sm_object.effekt @@ -0,0 +1,14 @@ +// sm = Person fills 1 saving slot completely +record Person( + field1: Int, + field2: Int, + field3: Int, + field4: Int, + field5: Int, + field6: Int + ) + +def main() = { + val p = Person(1, 2, 3, 4, 5, 6) + println(p.field6) +} \ No newline at end of file diff --git a/examples/flat/nooptimized/one_small_string_object.check b/examples/flat/nooptimized/one_small_string_object.check new file mode 100644 index 000000000..30d74d258 --- /dev/null +++ b/examples/flat/nooptimized/one_small_string_object.check @@ -0,0 +1 @@ +test \ No newline at end of file diff --git a/examples/flat/nooptimized/one_small_string_object.effekt b/examples/flat/nooptimized/one_small_string_object.effekt new file mode 100644 index 000000000..efe6e6fef --- /dev/null +++ b/examples/flat/nooptimized/one_small_string_object.effekt @@ -0,0 +1,8 @@ +record Person( + field1: String + ) + +def main() = { + val p = Person("test") + println(p.field1) +} \ No newline at end of file diff --git a/examples/flat/nooptimized/one_xl_object.check b/examples/flat/nooptimized/one_xl_object.check new file mode 100644 index 000000000..9d607966b --- /dev/null +++ b/examples/flat/nooptimized/one_xl_object.check @@ -0,0 +1 @@ +11 \ No newline at end of file diff --git a/examples/flat/nooptimized/one_xl_object.effekt b/examples/flat/nooptimized/one_xl_object.effekt new file mode 100644 index 000000000..bc45859ca --- /dev/null +++ b/examples/flat/nooptimized/one_xl_object.effekt @@ -0,0 +1,19 @@ +// xl = Person needs 3 saving slots +record Person( + field1: Int, + field2: Int, + field3: Int, + field4: Int, + field5: Int, + field6: Int, + field7: Int, + field8: Int, + field9: Int, + field10: Int, + field11: Int + ) + +def main() = { + val p = Person(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11) + println(p.field11) +} \ No newline at end of file diff --git a/examples/flat/nooptimized/one_xs_object.check b/examples/flat/nooptimized/one_xs_object.check new file mode 100644 index 000000000..e440e5c84 --- /dev/null +++ b/examples/flat/nooptimized/one_xs_object.check @@ -0,0 +1 @@ +3 \ No newline at end of file diff --git a/examples/flat/nooptimized/one_xs_object.effekt b/examples/flat/nooptimized/one_xs_object.effekt new file mode 100644 index 000000000..034c32ea5 --- /dev/null +++ b/examples/flat/nooptimized/one_xs_object.effekt @@ -0,0 +1,11 @@ +// xs = Person fits easily in 1 saving slot +record Person( + field1: Int, + field2: Int, + field3: Int + ) + +def main() = { + val p = Person(1, 2, 3) + println(p.field3) +} \ No newline at end of file diff --git a/examples/flat/nooptimized/one_xxl_object_all_fields.check b/examples/flat/nooptimized/one_xxl_object_all_fields.check new file mode 100644 index 000000000..6a0bcb871 --- /dev/null +++ b/examples/flat/nooptimized/one_xxl_object_all_fields.check @@ -0,0 +1,100 @@ +1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +11 +12 +13 +14 +15 +16 +17 +18 +19 +20 +21 +22 +23 +24 +25 +26 +27 +28 +29 +30 +31 +32 +33 +34 +35 +36 +37 +38 +39 +40 +41 +42 +43 +44 +45 +46 +47 +48 +49 +50 +51 +52 +53 +54 +55 +56 +57 +58 +59 +60 +61 +62 +63 +64 +65 +66 +67 +68 +69 +70 +71 +72 +73 +74 +75 +76 +77 +78 +79 +80 +81 +82 +83 +84 +85 +86 +87 +88 +89 +90 +91 +92 +93 +94 +95 +96 +97 +98 +99 +100 \ No newline at end of file diff --git a/examples/flat/nooptimized/one_xxl_object_all_fields.effekt b/examples/flat/nooptimized/one_xxl_object_all_fields.effekt new file mode 100644 index 000000000..824a4b603 --- /dev/null +++ b/examples/flat/nooptimized/one_xxl_object_all_fields.effekt @@ -0,0 +1,308 @@ +// xxl: Person has 100 fields -> need x slots +record Person( + field1: Int, + field2: Int, + field3: Int, + field4: Int, + field5: Int, + field6: Int, + field7: Int, + field8: Int, + field9: Int, + field10: Int, + field11: Int, + field12: Int, + field13: Int, + field14: Int, + field15: Int, + field16: Int, + field17: Int, + field18: Int, + field19: Int, + field20: Int, + field21: Int, + field22: Int, + field23: Int, + field24: Int, + field25: Int, + field26: Int, + field27: Int, + field28: Int, + field29: Int, + field30: Int, + field31: Int, + field32: Int, + field33: Int, + field34: Int, + field35: Int, + field36: Int, + field37: Int, + field38: Int, + field39: Int, + field40: Int, + field41: Int, + field42: Int, + field43: Int, + field44: Int, + field45: Int, + field46: Int, + field47: Int, + field48: Int, + field49: Int, + field50: Int, + field51: Int, + field52: Int, + field53: Int, + field54: Int, + field55: Int, + field56: Int, + field57: Int, + field58: Int, + field59: Int, + field60: Int, + field61: Int, + field62: Int, + field63: Int, + field64: Int, + field65: Int, + field66: Int, + field67: Int, + field68: Int, + field69: Int, + field70: Int, + field71: Int, + field72: Int, + field73: Int, + field74: Int, + field75: Int, + field76: Int, + field77: Int, + field78: Int, + field79: Int, + field80: Int, + field81: Int, + field82: Int, + field83: Int, + field84: Int, + field85: Int, + field86: Int, + field87: Int, + field88: Int, + field89: Int, + field90: Int, + field91: Int, + field92: Int, + field93: Int, + field94: Int, + field95: Int, + field96: Int, + field97: Int, + field98: Int, + field99: Int, + field100: Int +) + +def main() = { + val p1 = Person( + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, + 17, + 18, + 19, + 20, + 21, + 22, + 23, + 24, + 25, + 26, + 27, + 28, + 29, + 30, + 31, + 32, + 33, + 34, + 35, + 36, + 37, + 38, + 39, + 40, + 41, + 42, + 43, + 44, + 45, + 46, + 47, + 48, + 49, + 50, + 51, + 52, + 53, + 54, + 55, + 56, + 57, + 58, + 59, + 60, + 61, + 62, + 63, + 64, + 65, + 66, + 67, + 68, + 69, + 70, + 71, + 72, + 73, + 74, + 75, + 76, + 77, + 78, + 79, + 80, + 81, + 82, + 83, + 84, + 85, + 86, + 87, + 88, + 89, + 90, + 91, + 92, + 93, + 94, + 95, + 96, + 97, + 98, + 99, + 100 +) + println(p1.field1) + println(p1.field2) + println(p1.field3) + println(p1.field4) + println(p1.field5) + println(p1.field6) + println(p1.field7) + println(p1.field8) + println(p1.field9) + println(p1.field10) + println(p1.field11) + println(p1.field12) + println(p1.field13) + println(p1.field14) + println(p1.field15) + println(p1.field16) + println(p1.field17) + println(p1.field18) + println(p1.field19) + println(p1.field20) + println(p1.field21) + println(p1.field22) + println(p1.field23) + println(p1.field24) + println(p1.field25) + println(p1.field26) + println(p1.field27) + println(p1.field28) + println(p1.field29) + println(p1.field30) + println(p1.field31) + println(p1.field32) + println(p1.field33) + println(p1.field34) + println(p1.field35) + println(p1.field36) + println(p1.field37) + println(p1.field38) + println(p1.field39) + println(p1.field40) + println(p1.field41) + println(p1.field42) + println(p1.field43) + println(p1.field44) + println(p1.field45) + println(p1.field46) + println(p1.field47) + println(p1.field48) + println(p1.field49) + println(p1.field50) + println(p1.field51) + println(p1.field52) + println(p1.field53) + println(p1.field54) + println(p1.field55) + println(p1.field56) + println(p1.field57) + println(p1.field58) + println(p1.field59) + println(p1.field60) + println(p1.field61) + println(p1.field62) + println(p1.field63) + println(p1.field64) + println(p1.field65) + println(p1.field66) + println(p1.field67) + println(p1.field68) + println(p1.field69) + println(p1.field70) + println(p1.field71) + println(p1.field72) + println(p1.field73) + println(p1.field74) + println(p1.field75) + println(p1.field76) + println(p1.field77) + println(p1.field78) + println(p1.field79) + println(p1.field80) + println(p1.field81) + println(p1.field82) + println(p1.field83) + println(p1.field84) + println(p1.field85) + println(p1.field86) + println(p1.field87) + println(p1.field88) + println(p1.field89) + println(p1.field90) + println(p1.field91) + println(p1.field92) + println(p1.field93) + println(p1.field94) + println(p1.field95) + println(p1.field96) + println(p1.field97) + println(p1.field98) + println(p1.field99) + println(p1.field100) +} \ No newline at end of file diff --git a/examples/flat/nooptimized/one_xxxl_object.check b/examples/flat/nooptimized/one_xxxl_object.check new file mode 100644 index 000000000..eb1f49486 --- /dev/null +++ b/examples/flat/nooptimized/one_xxxl_object.check @@ -0,0 +1 @@ +500 \ No newline at end of file diff --git a/examples/flat/nooptimized/one_xxxl_object.effekt b/examples/flat/nooptimized/one_xxxl_object.effekt new file mode 100644 index 000000000..74211407a --- /dev/null +++ b/examples/flat/nooptimized/one_xxxl_object.effekt @@ -0,0 +1,1008 @@ +record Person( + field1: Int, + field2: Int, + field3: Int, + field4: Int, + field5: Int, + field6: Int, + field7: Int, + field8: Int, + field9: Int, + field10: Int, + field11: Int, + field12: Int, + field13: Int, + field14: Int, + field15: Int, + field16: Int, + field17: Int, + field18: Int, + field19: Int, + field20: Int, + field21: Int, + field22: Int, + field23: Int, + field24: Int, + field25: Int, + field26: Int, + field27: Int, + field28: Int, + field29: Int, + field30: Int, + field31: Int, + field32: Int, + field33: Int, + field34: Int, + field35: Int, + field36: Int, + field37: Int, + field38: Int, + field39: Int, + field40: Int, + field41: Int, + field42: Int, + field43: Int, + field44: Int, + field45: Int, + field46: Int, + field47: Int, + field48: Int, + field49: Int, + field50: Int, + field51: Int, + field52: Int, + field53: Int, + field54: Int, + field55: Int, + field56: Int, + field57: Int, + field58: Int, + field59: Int, + field60: Int, + field61: Int, + field62: Int, + field63: Int, + field64: Int, + field65: Int, + field66: Int, + field67: Int, + field68: Int, + field69: Int, + field70: Int, + field71: Int, + field72: Int, + field73: Int, + field74: Int, + field75: Int, + field76: Int, + field77: Int, + field78: Int, + field79: Int, + field80: Int, + field81: Int, + field82: Int, + field83: Int, + field84: Int, + field85: Int, + field86: Int, + field87: Int, + field88: Int, + field89: Int, + field90: Int, + field91: Int, + field92: Int, + field93: Int, + field94: Int, + field95: Int, + field96: Int, + field97: Int, + field98: Int, + field99: Int, + field100: Int, + field101: Int, + field102: Int, + field103: Int, + field104: Int, + field105: Int, + field106: Int, + field107: Int, + field108: Int, + field109: Int, + field110: Int, + field111: Int, + field112: Int, + field113: Int, + field114: Int, + field115: Int, + field116: Int, + field117: Int, + field118: Int, + field119: Int, + field120: Int, + field121: Int, + field122: Int, + field123: Int, + field124: Int, + field125: Int, + field126: Int, + field127: Int, + field128: Int, + field129: Int, + field130: Int, + field131: Int, + field132: Int, + field133: Int, + field134: Int, + field135: Int, + field136: Int, + field137: Int, + field138: Int, + field139: Int, + field140: Int, + field141: Int, + field142: Int, + field143: Int, + field144: Int, + field145: Int, + field146: Int, + field147: Int, + field148: Int, + field149: Int, + field150: Int, + field151: Int, + field152: Int, + field153: Int, + field154: Int, + field155: Int, + field156: Int, + field157: Int, + field158: Int, + field159: Int, + field160: Int, + field161: Int, + field162: Int, + field163: Int, + field164: Int, + field165: Int, + field166: Int, + field167: Int, + field168: Int, + field169: Int, + field170: Int, + field171: Int, + field172: Int, + field173: Int, + field174: Int, + field175: Int, + field176: Int, + field177: Int, + field178: Int, + field179: Int, + field180: Int, + field181: Int, + field182: Int, + field183: Int, + field184: Int, + field185: Int, + field186: Int, + field187: Int, + field188: Int, + field189: Int, + field190: Int, + field191: Int, + field192: Int, + field193: Int, + field194: Int, + field195: Int, + field196: Int, + field197: Int, + field198: Int, + field199: Int, + field200: Int, + field201: Int, + field202: Int, + field203: Int, + field204: Int, + field205: Int, + field206: Int, + field207: Int, + field208: Int, + field209: Int, + field210: Int, + field211: Int, + field212: Int, + field213: Int, + field214: Int, + field215: Int, + field216: Int, + field217: Int, + field218: Int, + field219: Int, + field220: Int, + field221: Int, + field222: Int, + field223: Int, + field224: Int, + field225: Int, + field226: Int, + field227: Int, + field228: Int, + field229: Int, + field230: Int, + field231: Int, + field232: Int, + field233: Int, + field234: Int, + field235: Int, + field236: Int, + field237: Int, + field238: Int, + field239: Int, + field240: Int, + field241: Int, + field242: Int, + field243: Int, + field244: Int, + field245: Int, + field246: Int, + field247: Int, + field248: Int, + field249: Int, + field250: Int, + field251: Int, + field252: Int, + field253: Int, + field254: Int, + field255: Int, + field256: Int, + field257: Int, + field258: Int, + field259: Int, + field260: Int, + field261: Int, + field262: Int, + field263: Int, + field264: Int, + field265: Int, + field266: Int, + field267: Int, + field268: Int, + field269: Int, + field270: Int, + field271: Int, + field272: Int, + field273: Int, + field274: Int, + field275: Int, + field276: Int, + field277: Int, + field278: Int, + field279: Int, + field280: Int, + field281: Int, + field282: Int, + field283: Int, + field284: Int, + field285: Int, + field286: Int, + field287: Int, + field288: Int, + field289: Int, + field290: Int, + field291: Int, + field292: Int, + field293: Int, + field294: Int, + field295: Int, + field296: Int, + field297: Int, + field298: Int, + field299: Int, + field300: Int, + field301: Int, + field302: Int, + field303: Int, + field304: Int, + field305: Int, + field306: Int, + field307: Int, + field308: Int, + field309: Int, + field310: Int, + field311: Int, + field312: Int, + field313: Int, + field314: Int, + field315: Int, + field316: Int, + field317: Int, + field318: Int, + field319: Int, + field320: Int, + field321: Int, + field322: Int, + field323: Int, + field324: Int, + field325: Int, + field326: Int, + field327: Int, + field328: Int, + field329: Int, + field330: Int, + field331: Int, + field332: Int, + field333: Int, + field334: Int, + field335: Int, + field336: Int, + field337: Int, + field338: Int, + field339: Int, + field340: Int, + field341: Int, + field342: Int, + field343: Int, + field344: Int, + field345: Int, + field346: Int, + field347: Int, + field348: Int, + field349: Int, + field350: Int, + field351: Int, + field352: Int, + field353: Int, + field354: Int, + field355: Int, + field356: Int, + field357: Int, + field358: Int, + field359: Int, + field360: Int, + field361: Int, + field362: Int, + field363: Int, + field364: Int, + field365: Int, + field366: Int, + field367: Int, + field368: Int, + field369: Int, + field370: Int, + field371: Int, + field372: Int, + field373: Int, + field374: Int, + field375: Int, + field376: Int, + field377: Int, + field378: Int, + field379: Int, + field380: Int, + field381: Int, + field382: Int, + field383: Int, + field384: Int, + field385: Int, + field386: Int, + field387: Int, + field388: Int, + field389: Int, + field390: Int, + field391: Int, + field392: Int, + field393: Int, + field394: Int, + field395: Int, + field396: Int, + field397: Int, + field398: Int, + field399: Int, + field400: Int, + field401: Int, + field402: Int, + field403: Int, + field404: Int, + field405: Int, + field406: Int, + field407: Int, + field408: Int, + field409: Int, + field410: Int, + field411: Int, + field412: Int, + field413: Int, + field414: Int, + field415: Int, + field416: Int, + field417: Int, + field418: Int, + field419: Int, + field420: Int, + field421: Int, + field422: Int, + field423: Int, + field424: Int, + field425: Int, + field426: Int, + field427: Int, + field428: Int, + field429: Int, + field430: Int, + field431: Int, + field432: Int, + field433: Int, + field434: Int, + field435: Int, + field436: Int, + field437: Int, + field438: Int, + field439: Int, + field440: Int, + field441: Int, + field442: Int, + field443: Int, + field444: Int, + field445: Int, + field446: Int, + field447: Int, + field448: Int, + field449: Int, + field450: Int, + field451: Int, + field452: Int, + field453: Int, + field454: Int, + field455: Int, + field456: Int, + field457: Int, + field458: Int, + field459: Int, + field460: Int, + field461: Int, + field462: Int, + field463: Int, + field464: Int, + field465: Int, + field466: Int, + field467: Int, + field468: Int, + field469: Int, + field470: Int, + field471: Int, + field472: Int, + field473: Int, + field474: Int, + field475: Int, + field476: Int, + field477: Int, + field478: Int, + field479: Int, + field480: Int, + field481: Int, + field482: Int, + field483: Int, + field484: Int, + field485: Int, + field486: Int, + field487: Int, + field488: Int, + field489: Int, + field490: Int, + field491: Int, + field492: Int, + field493: Int, + field494: Int, + field495: Int, + field496: Int, + field497: Int, + field498: Int, + field499: Int, + field500: Int +) + +def main() = { + val p1 = Person( + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, + 17, + 18, + 19, + 20, + 21, + 22, + 23, + 24, + 25, + 26, + 27, + 28, + 29, + 30, + 31, + 32, + 33, + 34, + 35, + 36, + 37, + 38, + 39, + 40, + 41, + 42, + 43, + 44, + 45, + 46, + 47, + 48, + 49, + 50, + 51, + 52, + 53, + 54, + 55, + 56, + 57, + 58, + 59, + 60, + 61, + 62, + 63, + 64, + 65, + 66, + 67, + 68, + 69, + 70, + 71, + 72, + 73, + 74, + 75, + 76, + 77, + 78, + 79, + 80, + 81, + 82, + 83, + 84, + 85, + 86, + 87, + 88, + 89, + 90, + 91, + 92, + 93, + 94, + 95, + 96, + 97, + 98, + 99, + 100, + 101, + 102, + 103, + 104, + 105, + 106, + 107, + 108, + 109, + 110, + 111, + 112, + 113, + 114, + 115, + 116, + 117, + 118, + 119, + 120, + 121, + 122, + 123, + 124, + 125, + 126, + 127, + 128, + 129, + 130, + 131, + 132, + 133, + 134, + 135, + 136, + 137, + 138, + 139, + 140, + 141, + 142, + 143, + 144, + 145, + 146, + 147, + 148, + 149, + 150, + 151, + 152, + 153, + 154, + 155, + 156, + 157, + 158, + 159, + 160, + 161, + 162, + 163, + 164, + 165, + 166, + 167, + 168, + 169, + 170, + 171, + 172, + 173, + 174, + 175, + 176, + 177, + 178, + 179, + 180, + 181, + 182, + 183, + 184, + 185, + 186, + 187, + 188, + 189, + 190, + 191, + 192, + 193, + 194, + 195, + 196, + 197, + 198, + 199, + 200, + 201, + 202, + 203, + 204, + 205, + 206, + 207, + 208, + 209, + 210, + 211, + 212, + 213, + 214, + 215, + 216, + 217, + 218, + 219, + 220, + 221, + 222, + 223, + 224, + 225, + 226, + 227, + 228, + 229, + 230, + 231, + 232, + 233, + 234, + 235, + 236, + 237, + 238, + 239, + 240, + 241, + 242, + 243, + 244, + 245, + 246, + 247, + 248, + 249, + 250, + 251, + 252, + 253, + 254, + 255, + 256, + 257, + 258, + 259, + 260, + 261, + 262, + 263, + 264, + 265, + 266, + 267, + 268, + 269, + 270, + 271, + 272, + 273, + 274, + 275, + 276, + 277, + 278, + 279, + 280, + 281, + 282, + 283, + 284, + 285, + 286, + 287, + 288, + 289, + 290, + 291, + 292, + 293, + 294, + 295, + 296, + 297, + 298, + 299, + 300, + 301, + 302, + 303, + 304, + 305, + 306, + 307, + 308, + 309, + 310, + 311, + 312, + 313, + 314, + 315, + 316, + 317, + 318, + 319, + 320, + 321, + 322, + 323, + 324, + 325, + 326, + 327, + 328, + 329, + 330, + 331, + 332, + 333, + 334, + 335, + 336, + 337, + 338, + 339, + 340, + 341, + 342, + 343, + 344, + 345, + 346, + 347, + 348, + 349, + 350, + 351, + 352, + 353, + 354, + 355, + 356, + 357, + 358, + 359, + 360, + 361, + 362, + 363, + 364, + 365, + 366, + 367, + 368, + 369, + 370, + 371, + 372, + 373, + 374, + 375, + 376, + 377, + 378, + 379, + 380, + 381, + 382, + 383, + 384, + 385, + 386, + 387, + 388, + 389, + 390, + 391, + 392, + 393, + 394, + 395, + 396, + 397, + 398, + 399, + 400, + 401, + 402, + 403, + 404, + 405, + 406, + 407, + 408, + 409, + 410, + 411, + 412, + 413, + 414, + 415, + 416, + 417, + 418, + 419, + 420, + 421, + 422, + 423, + 424, + 425, + 426, + 427, + 428, + 429, + 430, + 431, + 432, + 433, + 434, + 435, + 436, + 437, + 438, + 439, + 440, + 441, + 442, + 443, + 444, + 445, + 446, + 447, + 448, + 449, + 450, + 451, + 452, + 453, + 454, + 455, + 456, + 457, + 458, + 459, + 460, + 461, + 462, + 463, + 464, + 465, + 466, + 467, + 468, + 469, + 470, + 471, + 472, + 473, + 474, + 475, + 476, + 477, + 478, + 479, + 480, + 481, + 482, + 483, + 484, + 485, + 486, + 487, + 488, + 489, + 490, + 491, + 492, + 493, + 494, + 495, + 496, + 497, + 498, + 499, + 500 +) + println(p1.field500) +} \ No newline at end of file diff --git a/examples/flat/nooptimized/primitive_ref.check b/examples/flat/nooptimized/primitive_ref.check new file mode 100644 index 000000000..62f945751 --- /dev/null +++ b/examples/flat/nooptimized/primitive_ref.check @@ -0,0 +1 @@ +6 \ No newline at end of file diff --git a/examples/flat/nooptimized/primitive_ref.effekt b/examples/flat/nooptimized/primitive_ref.effekt new file mode 100644 index 000000000..6aa82602e --- /dev/null +++ b/examples/flat/nooptimized/primitive_ref.effekt @@ -0,0 +1,9 @@ +import ref + +def main() = { + val x = 5 + val y = 6 + val z = ref(x) + z.set(y) + println(z.get()) +} diff --git a/examples/flat/nooptimized/ref_allocate.check b/examples/flat/nooptimized/ref_allocate.check new file mode 100644 index 000000000..c7930257d --- /dev/null +++ b/examples/flat/nooptimized/ref_allocate.check @@ -0,0 +1 @@ +7 \ No newline at end of file diff --git a/examples/flat/nooptimized/ref_allocate.effekt b/examples/flat/nooptimized/ref_allocate.effekt new file mode 100644 index 000000000..2b46ceaa7 --- /dev/null +++ b/examples/flat/nooptimized/ref_allocate.effekt @@ -0,0 +1,19 @@ +import ref + +// md = Person requires 2 saving slots +record Person( + field1: Int, + field2: Int, + field3: Int, + field4: Int, + field5: Int, + field6: Int, + field7: Int + ) + +def main() = { + val p1 = ref::allocate() + val p2 = Person(1, 2, 3, 4, 5, 6, 7) + p1.set(p2) + println(p1.get().field7) +} diff --git a/examples/flat/nooptimized/simple_list.check b/examples/flat/nooptimized/simple_list.check new file mode 100644 index 000000000..cabf43b5d --- /dev/null +++ b/examples/flat/nooptimized/simple_list.check @@ -0,0 +1 @@ +24 \ No newline at end of file diff --git a/examples/flat/nooptimized/simple_list.effekt b/examples/flat/nooptimized/simple_list.effekt new file mode 100644 index 000000000..4a3187884 --- /dev/null +++ b/examples/flat/nooptimized/simple_list.effekt @@ -0,0 +1,15 @@ +import list +//import exception + + +def main() = { + // Creates a list with one element + val myList = [24] + + // print 24. If -1 is printed, there is a bug + myList match { + case Nil() => println(-1) + case Cons(x, Nil()) => println(x) + case Cons(x, xs) => println(-1) + } +} diff --git a/examples/flat/nooptimized/simple_ref.check b/examples/flat/nooptimized/simple_ref.check new file mode 100644 index 000000000..f11c82a4c --- /dev/null +++ b/examples/flat/nooptimized/simple_ref.check @@ -0,0 +1 @@ +9 \ No newline at end of file diff --git a/examples/flat/nooptimized/simple_ref.effekt b/examples/flat/nooptimized/simple_ref.effekt new file mode 100644 index 000000000..3549dea0f --- /dev/null +++ b/examples/flat/nooptimized/simple_ref.effekt @@ -0,0 +1,20 @@ +import ref + +// md = Person requires 2 saving slots +record Person( + field1: Int, + field2: Int, + field3: Int, + field4: Int, + field5: Int, + field6: Int, + field7: Int + ) + +def main() = { + val p1 = Person(1, 2, 3, 4, 5, 6, 7) + val p2 = Person(1, 2, 3, 4, 5, 6, 9) + val p3 = ref(p1) + p3.set(p2) + println(p3.get().field7) +} diff --git a/examples/flat/nooptimized/superperson.check b/examples/flat/nooptimized/superperson.check new file mode 100644 index 000000000..968f988c5 --- /dev/null +++ b/examples/flat/nooptimized/superperson.check @@ -0,0 +1,2 @@ +9 +25 \ No newline at end of file diff --git a/examples/flat/nooptimized/superperson.effekt b/examples/flat/nooptimized/superperson.effekt new file mode 100644 index 000000000..d1dbe0b5c --- /dev/null +++ b/examples/flat/nooptimized/superperson.effekt @@ -0,0 +1,33 @@ +import list + +record TwoSlotPerson( + field1: Int, + field2: Int, + field3: Int, + field4: Int, + field5: Int, + field6: Int, + field7: Int + ) + +record SuperPerson( + field1: TwoSlotPerson, + field2: TwoSlotPerson +) + +def main() = { + // Creates a list with one element + val person1 = TwoSlotPerson(1, 2, 3, 4, 5, 6, 7) + val person2 = TwoSlotPerson(8, 9, 10, 11, 12, 13, 14) + val y = TwoSlotPerson(25, 2, 3, 4, 5, 6, 7) + val superPerson = SuperPerson(person1, person2) + + + // prints 9. If -1 is printed, there is a bug + superPerson match { + case SuperPerson(x, z) => println(x.field1 + z.field1) + } + + // prints 25 + println(y.field1) +} diff --git a/examples/flat/nooptimized/superperson_with_free.check b/examples/flat/nooptimized/superperson_with_free.check new file mode 100644 index 000000000..410b14d2c --- /dev/null +++ b/examples/flat/nooptimized/superperson_with_free.check @@ -0,0 +1 @@ +25 \ No newline at end of file diff --git a/examples/flat/nooptimized/superperson_with_free.effekt b/examples/flat/nooptimized/superperson_with_free.effekt new file mode 100644 index 000000000..528fa3fc6 --- /dev/null +++ b/examples/flat/nooptimized/superperson_with_free.effekt @@ -0,0 +1,30 @@ +import list + +record TwoSlotPerson( + field1: Int, + field2: Int, + field3: Int, + field4: Int, + field5: Int, + field6: Int, + field7: Int + ) + +record SuperPerson( + field1: TwoSlotPerson, + field2: TwoSlotPerson +) + +def main() = { + // Creates a list with one element + val person1 = TwoSlotPerson(1, 2, 3, 4, 5, 6, 7) + val person2 = TwoSlotPerson(8, 9, 10, 11, 12, 13, 14) + val y = TwoSlotPerson(25, 2, 3, 4, 5, 6, 7) + val superPerson = SuperPerson(person1, person2) + + + // prints 25. If -1 is printed, there is a bug + superPerson match { + case SuperPerson(x, z) => println(y.field1) + } +} diff --git a/examples/flat/nooptimized/three_md_objects_direct.check b/examples/flat/nooptimized/three_md_objects_direct.check new file mode 100644 index 000000000..8fac22206 --- /dev/null +++ b/examples/flat/nooptimized/three_md_objects_direct.check @@ -0,0 +1,3 @@ +7 +10 +18 \ No newline at end of file diff --git a/examples/flat/nooptimized/three_md_objects_direct.effekt b/examples/flat/nooptimized/three_md_objects_direct.effekt new file mode 100644 index 000000000..ec0561e12 --- /dev/null +++ b/examples/flat/nooptimized/three_md_objects_direct.effekt @@ -0,0 +1,20 @@ +// md = Person requires 2 saving slots +// direct = create person and print field directly +record Person( + field1: Int, + field2: Int, + field3: Int, + field4: Int, + field5: Int, + field6: Int, + field7: Int + ) + +def main() = { + val p1 = Person(1, 2, 3, 4, 5, 6, 7) + println(p1.field7) + val p2 = Person(8, 9, 10, 11, 12, 13, 14) + val p3 = Person(15, 16, 17, 18, 19, 20, 21) + println(p2.field3) + println(p3.field4) +} \ No newline at end of file diff --git a/examples/flat/nooptimized/trigger_child_freeing.check b/examples/flat/nooptimized/trigger_child_freeing.check new file mode 100644 index 000000000..e69de29bb diff --git a/examples/flat/nooptimized/trigger_child_freeing.effekt b/examples/flat/nooptimized/trigger_child_freeing.effekt new file mode 100644 index 000000000..2f96672f0 --- /dev/null +++ b/examples/flat/nooptimized/trigger_child_freeing.effekt @@ -0,0 +1,64 @@ +// a simple program that creates a more complex object +// -> child1 +// parent +// -> child2 -> child3 +// -> child4 -> child5 -> child6 +// -> child7 -> child8 +// where child1 is OneSlotPerson and child2 and child3 are TwoSlotPerson and child4 and child5 and child6 are ThreeSlotPerson, and child7 and child8 are TwoSlotPerson + +record OneSlotPerson( + field1: Int, + field2: Int, + field3: Int, + field4: Int, + field5: Int, + field6: Int +) + +record TwoSlotPerson( + field1: Int, + field2: Int, + field3: Int, + field4: Int, + field5: Int, + field6: Int, + field7: Int +) + +record ThreeSlotPerson( + field1: Int, + field2: Int, + field3: Int, + field4: Int, + field5: Int, + field6: Int, + field7: Int, + field8: Int, + field9: Int, + field10: Int, + field11: Int, + field12: Int, + field13: Int +) + +record Person( + child1: OneSlotPerson, + child2: TwoSlotPerson, + child3: ThreeSlotPerson, + child4: TwoSlotPerson, + child5: OneSlotPerson +) + +def main() = { + var iters = 1 + while(iters <= 66) { + var x = Person( + OneSlotPerson(iters, iters + 1, iters + 2, iters + 3, iters + 4, iters + 5), + TwoSlotPerson(iters, iters + 1, iters + 2, iters + 3, iters + 4, iters + 5, iters + 6), + ThreeSlotPerson(iters, iters + 1, iters + 2, iters + 3, iters + 4, iters + 5, iters + 6, iters + 7, iters + 8, iters + 9, iters + 10, iters + 11, iters + 12), + TwoSlotPerson(iters, iters + 1, iters + 2, iters + 3, iters + 4, iters + 5, iters + 7), + OneSlotPerson(iters, iters + 1, iters + 2, iters + 3, iters + 4, iters + 6) + ) + iters = iters + 1 + } +} diff --git a/examples/flat/nooptimized/trigger_flush_once.check b/examples/flat/nooptimized/trigger_flush_once.check new file mode 100644 index 000000000..e69de29bb diff --git a/examples/flat/nooptimized/trigger_flush_once.effekt b/examples/flat/nooptimized/trigger_flush_once.effekt new file mode 100644 index 000000000..c1306808c --- /dev/null +++ b/examples/flat/nooptimized/trigger_flush_once.effekt @@ -0,0 +1,17 @@ +// a simple program that triggers flush to-do-list once +record OneSlotPerson( + field1: Int, + field2: Int, + field3: Int, + field4: Int, + field5: Int, + field6: Int +) + +def main() = { + var iters = 1 + while(iters <= 65) { + var x = OneSlotPerson(iters, iters + 1, iters + 2, iters + 3, iters + 4, iters + 5) + iters = iters + 1 + } +} diff --git a/examples/flat/nooptimized/trigger_flush_twice.check b/examples/flat/nooptimized/trigger_flush_twice.check new file mode 100644 index 000000000..e69de29bb diff --git a/examples/flat/nooptimized/trigger_flush_twice.effekt b/examples/flat/nooptimized/trigger_flush_twice.effekt new file mode 100644 index 000000000..b364f2fdf --- /dev/null +++ b/examples/flat/nooptimized/trigger_flush_twice.effekt @@ -0,0 +1,17 @@ +// a simple program that triggers flush to-do-list twice +record OneSlotPerson( + field1: Int, + field2: Int, + field3: Int, + field4: Int, + field5: Int, + field6: Int +) + +def main() = { + var iters = 1 + while(iters <= 129) { + var x = OneSlotPerson(iters, iters + 1, iters + 2, iters + 3, iters + 4, iters + 5) + iters = iters + 1 + } +} diff --git a/examples/flat/nooptimized/trigger_one_child_freeing.check b/examples/flat/nooptimized/trigger_one_child_freeing.check new file mode 100644 index 000000000..e69de29bb diff --git a/examples/flat/nooptimized/trigger_one_child_freeing.effekt b/examples/flat/nooptimized/trigger_one_child_freeing.effekt new file mode 100644 index 000000000..a44b4896c --- /dev/null +++ b/examples/flat/nooptimized/trigger_one_child_freeing.effekt @@ -0,0 +1,26 @@ +// a simple program that creates a more complex object +// parent -> child1 +// where child1 is OneSlotPerson + +record OneSlotPerson( + field1: Int, + field2: Int, + field3: Int, + field4: Int, + field5: Int, + field6: Int +) + +record Person( + child1: OneSlotPerson +) + +def main() = { + var iters = 1 + while(iters <= 65) { + var x = Person( + OneSlotPerson(iters, iters + 1, iters + 2, iters + 3, iters + 4, iters + 5) + ) + iters = iters + 1 + } +} diff --git a/examples/flat/nooptimized/trigger_two_child_freeing.check b/examples/flat/nooptimized/trigger_two_child_freeing.check new file mode 100644 index 000000000..e69de29bb diff --git a/examples/flat/nooptimized/trigger_two_child_freeing.effekt b/examples/flat/nooptimized/trigger_two_child_freeing.effekt new file mode 100644 index 000000000..e8eb31933 --- /dev/null +++ b/examples/flat/nooptimized/trigger_two_child_freeing.effekt @@ -0,0 +1,28 @@ +// a simple program that creates a more complex object +// parent -> child1 +// where child1 is OneSlotPerson + +record OneSlotPerson( + field1: Int, + field2: Int, + field3: Int, + field4: Int, + field5: Int, + field6: Int +) + +record Person( + child1: OneSlotPerson, + child2: OneSlotPerson +) + +def main() = { + var iters = 1 + while(iters <= 64) { + var x = Person( + OneSlotPerson(iters, iters + 1, iters + 2, iters + 3, iters + 4, iters + 5), + OneSlotPerson(iters + 6, iters + 7, iters + 8, iters + 9, iters + 10, iters + 11) + ) + iters = iters + 1 + } +} diff --git a/examples/flat/nooptimized/two_lg_objects.check b/examples/flat/nooptimized/two_lg_objects.check new file mode 100644 index 000000000..8f59f50a4 --- /dev/null +++ b/examples/flat/nooptimized/two_lg_objects.check @@ -0,0 +1,2 @@ +10 +16 \ No newline at end of file diff --git a/examples/flat/nooptimized/two_lg_objects.effekt b/examples/flat/nooptimized/two_lg_objects.effekt new file mode 100644 index 000000000..6393bd171 --- /dev/null +++ b/examples/flat/nooptimized/two_lg_objects.effekt @@ -0,0 +1,20 @@ +// lg = Person fills 2 saving slots completely +record Person( + field1: Int, + field2: Int, + field3: Int, + field4: Int, + field5: Int, + field6: Int, + field7: Int, + field8: Int, + field9: Int, + field10: Int + ) + +def main() = { + val p1 = Person(1, 2, 3, 4, 5, 6, 7, 8, 9, 10) + val p2 = Person(11, 12, 13, 14, 15, 16, 17, 18, 19, 20) + println(p1.field10) + println(p2.field6) +} \ No newline at end of file diff --git a/examples/flat/nooptimized/two_md_mixed_object.check b/examples/flat/nooptimized/two_md_mixed_object.check new file mode 100644 index 000000000..f21c60d7e --- /dev/null +++ b/examples/flat/nooptimized/two_md_mixed_object.check @@ -0,0 +1,2 @@ +P1Field2 +10 \ No newline at end of file diff --git a/examples/flat/nooptimized/two_md_mixed_object.effekt b/examples/flat/nooptimized/two_md_mixed_object.effekt new file mode 100644 index 000000000..4d67068e4 --- /dev/null +++ b/examples/flat/nooptimized/two_md_mixed_object.effekt @@ -0,0 +1,17 @@ +// md = Person needs 2 slots +// contains strings and integers. +// First slot contains field1, second slot contains field2, field3, field4, field5. +record Person( + field1: Int, + field2: String, + field3: String, + field4: String, + field5: Int + ) + +def main() = { + val p1 = Person(1, "P1Field2", "P1Field3", "P1Field4", 5) + val p2 = Person(6, "P2Field2", "P2Field3", "P2Field4", 10) + println(p1.field2) + println(p2.field5) +} \ No newline at end of file diff --git a/examples/flat/nooptimized/two_md_objects.check b/examples/flat/nooptimized/two_md_objects.check new file mode 100644 index 000000000..78bd7702c --- /dev/null +++ b/examples/flat/nooptimized/two_md_objects.check @@ -0,0 +1,2 @@ +7 +9 \ No newline at end of file diff --git a/examples/flat/nooptimized/two_md_objects.effekt b/examples/flat/nooptimized/two_md_objects.effekt new file mode 100644 index 000000000..d3bdb013f --- /dev/null +++ b/examples/flat/nooptimized/two_md_objects.effekt @@ -0,0 +1,17 @@ +// md = Person requires 2 saving slots +record Person( + field1: Int, + field2: Int, + field3: Int, + field4: Int, + field5: Int, + field6: Int, + field7: Int + ) + +def main() = { + val p1 = Person(1, 2, 3, 4, 5, 6, 7) + val p2 = Person(8, 9, 10, 11, 12, 13, 14) + println(p1.field7) + println(p2.field2) +} \ No newline at end of file diff --git a/examples/flat/nooptimized/two_slot_one_person_list.check b/examples/flat/nooptimized/two_slot_one_person_list.check new file mode 100644 index 000000000..c7930257d --- /dev/null +++ b/examples/flat/nooptimized/two_slot_one_person_list.check @@ -0,0 +1 @@ +7 \ No newline at end of file diff --git a/examples/flat/nooptimized/two_slot_one_person_list.effekt b/examples/flat/nooptimized/two_slot_one_person_list.effekt new file mode 100644 index 000000000..e15b30ef1 --- /dev/null +++ b/examples/flat/nooptimized/two_slot_one_person_list.effekt @@ -0,0 +1,23 @@ +import list + +record TwoSlotPerson( + field1: Int, + field2: Int, + field3: Int, + field4: Int, + field5: Int, + field6: Int, + field7: Int + ) + +def main() = { + // Creates a list with one element + val person1 = TwoSlotPerson(1, 2, 3, 4, 5, 6, 7) + var myList = [person1] + + // prints 7. If -1 is printed, there is a bug + myList match { + case Nil() => println(-1) + case Cons(x, _) => println(x.field7) + } +} diff --git a/examples/flat/nooptimized/two_slot_one_person_with_free_variable_list.check b/examples/flat/nooptimized/two_slot_one_person_with_free_variable_list.check new file mode 100644 index 000000000..410b14d2c --- /dev/null +++ b/examples/flat/nooptimized/two_slot_one_person_with_free_variable_list.check @@ -0,0 +1 @@ +25 \ No newline at end of file diff --git a/examples/flat/nooptimized/two_slot_one_person_with_free_variable_list.effekt b/examples/flat/nooptimized/two_slot_one_person_with_free_variable_list.effekt new file mode 100644 index 000000000..25bf64831 --- /dev/null +++ b/examples/flat/nooptimized/two_slot_one_person_with_free_variable_list.effekt @@ -0,0 +1,29 @@ +import list + +record TwoSlotPerson( + field1: Int, + field2: Int, + field3: Int, + field4: Int, + field5: Int, + field6: Int, + field7: Int + ) + +def main() = { + // Creates a list with one element + val person1 = TwoSlotPerson(1, 2, 3, 4, 5, 6, 7) + val y = TwoSlotPerson(25, 2, 3, 4, 5, 6, 7) + var myList = [person1] + + // prints 25. If -1 is printed, there is a bug + myList match { + case Nil() => println(-1) + //case Cons(x, _) => println(-2) + case Cons(x, _) => println(y.field1) + //case Cons(x, _) => println(person.field1) + } + + //myList = drop(myList, 1) + //val person3 = person1 +} diff --git a/examples/flat/nooptimized/two_slot_two_person_list.check b/examples/flat/nooptimized/two_slot_two_person_list.check new file mode 100644 index 000000000..bf0d87ab1 --- /dev/null +++ b/examples/flat/nooptimized/two_slot_two_person_list.check @@ -0,0 +1 @@ +4 \ No newline at end of file diff --git a/examples/flat/nooptimized/two_slot_two_person_list.effekt b/examples/flat/nooptimized/two_slot_two_person_list.effekt new file mode 100644 index 000000000..6946a2895 --- /dev/null +++ b/examples/flat/nooptimized/two_slot_two_person_list.effekt @@ -0,0 +1,24 @@ +import list + +record TwoSlotPerson( + field1: Int, + field2: Int, + field3: Int, + field4: Int, + field5: Int, + field6: Int, + field7: Int + ) + +def main() = { + // Creates a list with one element + val person1 = TwoSlotPerson(1, 2, 3, 4, 5, 6, 7) + val person2 = TwoSlotPerson(8, 9, 10, 11, 12, 13, 14) + val myList = [person1, person2] + + // print 4. If -1 is printed, there is a bug + myList match { + case Nil() => println(-1) + case Cons(p1, _) => println(p1.field4) + } +} diff --git a/examples/flat/nooptimized/two_slot_two_person_list_continuation.check b/examples/flat/nooptimized/two_slot_two_person_list_continuation.check new file mode 100644 index 000000000..bf0d87ab1 --- /dev/null +++ b/examples/flat/nooptimized/two_slot_two_person_list_continuation.check @@ -0,0 +1 @@ +4 \ No newline at end of file diff --git a/examples/flat/nooptimized/two_slot_two_person_list_continuation.effekt b/examples/flat/nooptimized/two_slot_two_person_list_continuation.effekt new file mode 100644 index 000000000..0e29c515c --- /dev/null +++ b/examples/flat/nooptimized/two_slot_two_person_list_continuation.effekt @@ -0,0 +1,27 @@ +import list + +record TwoSlotPerson( + field1: Int, + field2: Int, + field3: Int, + field4: Int, + field5: Int, + field6: Int, + field7: Int + ) + +def main() = { + // Creates a list with one element + val person1 = TwoSlotPerson(1, 2, 3, 4, 5, 6, 7) + val person2 = TwoSlotPerson(8, 9, 10, 11, 12, 13, 14) + val myList = [person1, person2] + + // print 4. If -1 is printed, there is a bug + myList match { + case Nil() => println(-1) + case Cons(p1, _) => println(p1.field4) // here, we shorten it to _ + } + + // we continue the program here, so the compiler does not erase myList immediately after the Switch statement + val isEmpty = isEmpty(myList) +} \ No newline at end of file diff --git a/examples/flat/nooptimized/two_slot_two_person_list_continuation_allocation.check b/examples/flat/nooptimized/two_slot_two_person_list_continuation_allocation.check new file mode 100644 index 000000000..a246a2d52 --- /dev/null +++ b/examples/flat/nooptimized/two_slot_two_person_list_continuation_allocation.check @@ -0,0 +1,2 @@ +4 +24 \ No newline at end of file diff --git a/examples/flat/nooptimized/two_slot_two_person_list_continuation_allocation.effekt b/examples/flat/nooptimized/two_slot_two_person_list_continuation_allocation.effekt new file mode 100644 index 000000000..03036c9c5 --- /dev/null +++ b/examples/flat/nooptimized/two_slot_two_person_list_continuation_allocation.effekt @@ -0,0 +1,45 @@ +import list + +record TwoSlotPerson( + field1: Int, + field2: Int, + field3: Int, + field4: Int, + field5: Int, + field6: Int, + field7: Int + ) + +record ThreeSlotPerson( + field1: Int, + field2: Int, + field3: Int, + field4: Int, + field5: Int, + field6: Int, + field7: Int, + field8: Int, + field9: Int, + field10: Int, + field11: Int + ) + +def main() = { + // Creates a list with one element + val person1 = TwoSlotPerson(1, 2, 3, 4, 5, 6, 7) + val person2 = TwoSlotPerson(8, 9, 10, 11, 12, 13, 14) + val myList = [person1, person2] + + // print 4. If -1 is printed, there is a bug + myList match { + case Nil() => println(-1) + case Cons(p1, _) => println(p1.field4) // here, we shorten it to _ + } + + // we continue the program here, so the compiler does not erase myList immediately after the Switch statement + val isEmpty = isEmpty(myList) + + // reuse the freed slots again to look how the storage looks like + val p3 = ThreeSlotPerson(14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24) + println(p3.field11) +} \ No newline at end of file diff --git a/examples/flat/nooptimized/two_slot_two_person_list_continuation_exhausted.check b/examples/flat/nooptimized/two_slot_two_person_list_continuation_exhausted.check new file mode 100644 index 000000000..bf0d87ab1 --- /dev/null +++ b/examples/flat/nooptimized/two_slot_two_person_list_continuation_exhausted.check @@ -0,0 +1 @@ +4 \ No newline at end of file diff --git a/examples/flat/nooptimized/two_slot_two_person_list_continuation_exhausted.effekt b/examples/flat/nooptimized/two_slot_two_person_list_continuation_exhausted.effekt new file mode 100644 index 000000000..d064888aa --- /dev/null +++ b/examples/flat/nooptimized/two_slot_two_person_list_continuation_exhausted.effekt @@ -0,0 +1,27 @@ +import list + +record TwoSlotPerson( + field1: Int, + field2: Int, + field3: Int, + field4: Int, + field5: Int, + field6: Int, + field7: Int + ) + +def main() = { + // Creates a list with one element + val person1 = TwoSlotPerson(1, 2, 3, 4, 5, 6, 7) + val person2 = TwoSlotPerson(8, 9, 10, 11, 12, 13, 14) + val myList = [person1, person2] + + // print 4. If -1 is printed, there is a bug + myList match { + case Nil() => println(-1) + case Cons(p1, cont) => println(p1.field4) // here, we declare cont. It makes a difference for the release function + } + + // we continue the program here, so the compiler does not erase myList immediately after the Switch statement + val isEmpty = isEmpty(myList) +} \ No newline at end of file diff --git a/examples/flat/nooptimized/two_slot_two_person_list_exhausted.check b/examples/flat/nooptimized/two_slot_two_person_list_exhausted.check new file mode 100644 index 000000000..bf0d87ab1 --- /dev/null +++ b/examples/flat/nooptimized/two_slot_two_person_list_exhausted.check @@ -0,0 +1 @@ +4 \ No newline at end of file diff --git a/examples/flat/nooptimized/two_slot_two_person_list_exhausted.effekt b/examples/flat/nooptimized/two_slot_two_person_list_exhausted.effekt new file mode 100644 index 000000000..66ee8acbe --- /dev/null +++ b/examples/flat/nooptimized/two_slot_two_person_list_exhausted.effekt @@ -0,0 +1,24 @@ +import list + +record TwoSlotPerson( + field1: Int, + field2: Int, + field3: Int, + field4: Int, + field5: Int, + field6: Int, + field7: Int + ) + +def main() = { + // Creates a list with one element + val person1 = TwoSlotPerson(1, 2, 3, 4, 5, 6, 7) + val person2 = TwoSlotPerson(8, 9, 10, 11, 12, 13, 14) + val myList = [person1, person2] + + // print 4. If -1 is printed, there is a bug + myList match { + case Nil() => println(-1) + case Cons(p1, cont) => println(p1.field4) + } +} diff --git a/examples/flat/nooptimized/two_slot_two_person_with_free_variable_list.check b/examples/flat/nooptimized/two_slot_two_person_with_free_variable_list.check new file mode 100644 index 000000000..410b14d2c --- /dev/null +++ b/examples/flat/nooptimized/two_slot_two_person_with_free_variable_list.check @@ -0,0 +1 @@ +25 \ No newline at end of file diff --git a/examples/flat/nooptimized/two_slot_two_person_with_free_variable_list.effekt b/examples/flat/nooptimized/two_slot_two_person_with_free_variable_list.effekt new file mode 100644 index 000000000..4e0df6426 --- /dev/null +++ b/examples/flat/nooptimized/two_slot_two_person_with_free_variable_list.effekt @@ -0,0 +1,29 @@ +import list + +record TwoSlotPerson( + field1: Int, + field2: Int, + field3: Int, + field4: Int, + field5: Int, + field6: Int, + field7: Int + ) + +def main() = { + // Creates a list with one element + val person1 = TwoSlotPerson(1, 2, 3, 4, 5, 6, 7) + val person2 = TwoSlotPerson(8, 9, 10, 11, 12, 13, 14) + val y = TwoSlotPerson(25, 2, 3, 4, 5, 6, 7) + var myList = [person1, person2] + + + // prints 25. If -1 is printed, there is a bug + myList match { + case Nil() => println(-1) + case Cons(x, xs) => xs match { + case Nil() => println(y.field2) + case Cons(z, _) => println(y.field1) + } + } +} diff --git a/examples/flat/nooptimized/two_sm_mixed_object.check b/examples/flat/nooptimized/two_sm_mixed_object.check new file mode 100644 index 000000000..ca3d17d48 --- /dev/null +++ b/examples/flat/nooptimized/two_sm_mixed_object.check @@ -0,0 +1,2 @@ +P1Field1 +8 \ No newline at end of file diff --git a/examples/flat/nooptimized/two_sm_mixed_object.effekt b/examples/flat/nooptimized/two_sm_mixed_object.effekt new file mode 100644 index 000000000..c07c2af92 --- /dev/null +++ b/examples/flat/nooptimized/two_sm_mixed_object.effekt @@ -0,0 +1,15 @@ +// sm = Person fills 1 saving slot completely +// contains strings and integers +record Person( + field1: String, + field2: Int, + field3: String, + field4: Int + ) + +def main() = { + val p1 = Person("P1Field1", 2, "P1Field3", 4) + val p2 = Person("P2Field1", 6, "P2Field3", 8) + println(p1.field1) + println(p2.field4) +} \ No newline at end of file diff --git a/examples/flat/nooptimized/two_sm_objects.check b/examples/flat/nooptimized/two_sm_objects.check new file mode 100644 index 000000000..b8a0ddcef --- /dev/null +++ b/examples/flat/nooptimized/two_sm_objects.check @@ -0,0 +1,2 @@ +6 +8 \ No newline at end of file diff --git a/examples/flat/nooptimized/two_sm_objects.effekt b/examples/flat/nooptimized/two_sm_objects.effekt new file mode 100644 index 000000000..a1d1d206c --- /dev/null +++ b/examples/flat/nooptimized/two_sm_objects.effekt @@ -0,0 +1,16 @@ +// sm = Person fills 1 saving slot completely +record Person( + field1: Int, + field2: Int, + field3: Int, + field4: Int, + field5: Int, + field6: Int + ) + +def main() = { + val p1 = Person(1, 2, 3, 4, 5, 6) + val p2 = Person(7, 8, 9, 10, 11, 12) + println(p1.field6) + println(p2.field2) +} \ No newline at end of file diff --git a/examples/flat/nooptimized/two_xl_objects.check b/examples/flat/nooptimized/two_xl_objects.check new file mode 100644 index 000000000..10afbfb7e --- /dev/null +++ b/examples/flat/nooptimized/two_xl_objects.check @@ -0,0 +1,2 @@ +11 +18 \ No newline at end of file diff --git a/examples/flat/nooptimized/two_xl_objects.effekt b/examples/flat/nooptimized/two_xl_objects.effekt new file mode 100644 index 000000000..e5628b0b7 --- /dev/null +++ b/examples/flat/nooptimized/two_xl_objects.effekt @@ -0,0 +1,21 @@ +// xl = Person needs 3 saving slots +record Person( + field1: Int, + field2: Int, + field3: Int, + field4: Int, + field5: Int, + field6: Int, + field7: Int, + field8: Int, + field9: Int, + field10: Int, + field11: Int + ) + +def main() = { + val p1 = Person(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11) + val p2 = Person(12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22) + println(p1.field11) + println(p2.field7) +} \ No newline at end of file diff --git a/examples/flat/nooptimized/two_xs_objects.check b/examples/flat/nooptimized/two_xs_objects.check new file mode 100644 index 000000000..69cc3abe5 --- /dev/null +++ b/examples/flat/nooptimized/two_xs_objects.check @@ -0,0 +1,2 @@ +3 +5 \ No newline at end of file diff --git a/examples/flat/nooptimized/two_xs_objects.effekt b/examples/flat/nooptimized/two_xs_objects.effekt new file mode 100644 index 000000000..02f18b3a9 --- /dev/null +++ b/examples/flat/nooptimized/two_xs_objects.effekt @@ -0,0 +1,13 @@ +// xs = Person fits easily in 1 saving slot +record Person( + field1: Int, + field2: Int, + field3: Int + ) + +def main() = { + val p1 = Person(1, 2, 3) + val p2 = Person(4, 5, 6) + println(p1.field3) + println(p2.field2) +} \ No newline at end of file diff --git a/examples/flat/nooptimized/two_xxl_object_all_fields.check b/examples/flat/nooptimized/two_xxl_object_all_fields.check new file mode 100644 index 000000000..6a0bcb871 --- /dev/null +++ b/examples/flat/nooptimized/two_xxl_object_all_fields.check @@ -0,0 +1,100 @@ +1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +11 +12 +13 +14 +15 +16 +17 +18 +19 +20 +21 +22 +23 +24 +25 +26 +27 +28 +29 +30 +31 +32 +33 +34 +35 +36 +37 +38 +39 +40 +41 +42 +43 +44 +45 +46 +47 +48 +49 +50 +51 +52 +53 +54 +55 +56 +57 +58 +59 +60 +61 +62 +63 +64 +65 +66 +67 +68 +69 +70 +71 +72 +73 +74 +75 +76 +77 +78 +79 +80 +81 +82 +83 +84 +85 +86 +87 +88 +89 +90 +91 +92 +93 +94 +95 +96 +97 +98 +99 +100 \ No newline at end of file diff --git a/examples/flat/nooptimized/two_xxl_object_all_fields.effekt b/examples/flat/nooptimized/two_xxl_object_all_fields.effekt new file mode 100644 index 000000000..824a4b603 --- /dev/null +++ b/examples/flat/nooptimized/two_xxl_object_all_fields.effekt @@ -0,0 +1,308 @@ +// xxl: Person has 100 fields -> need x slots +record Person( + field1: Int, + field2: Int, + field3: Int, + field4: Int, + field5: Int, + field6: Int, + field7: Int, + field8: Int, + field9: Int, + field10: Int, + field11: Int, + field12: Int, + field13: Int, + field14: Int, + field15: Int, + field16: Int, + field17: Int, + field18: Int, + field19: Int, + field20: Int, + field21: Int, + field22: Int, + field23: Int, + field24: Int, + field25: Int, + field26: Int, + field27: Int, + field28: Int, + field29: Int, + field30: Int, + field31: Int, + field32: Int, + field33: Int, + field34: Int, + field35: Int, + field36: Int, + field37: Int, + field38: Int, + field39: Int, + field40: Int, + field41: Int, + field42: Int, + field43: Int, + field44: Int, + field45: Int, + field46: Int, + field47: Int, + field48: Int, + field49: Int, + field50: Int, + field51: Int, + field52: Int, + field53: Int, + field54: Int, + field55: Int, + field56: Int, + field57: Int, + field58: Int, + field59: Int, + field60: Int, + field61: Int, + field62: Int, + field63: Int, + field64: Int, + field65: Int, + field66: Int, + field67: Int, + field68: Int, + field69: Int, + field70: Int, + field71: Int, + field72: Int, + field73: Int, + field74: Int, + field75: Int, + field76: Int, + field77: Int, + field78: Int, + field79: Int, + field80: Int, + field81: Int, + field82: Int, + field83: Int, + field84: Int, + field85: Int, + field86: Int, + field87: Int, + field88: Int, + field89: Int, + field90: Int, + field91: Int, + field92: Int, + field93: Int, + field94: Int, + field95: Int, + field96: Int, + field97: Int, + field98: Int, + field99: Int, + field100: Int +) + +def main() = { + val p1 = Person( + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, + 17, + 18, + 19, + 20, + 21, + 22, + 23, + 24, + 25, + 26, + 27, + 28, + 29, + 30, + 31, + 32, + 33, + 34, + 35, + 36, + 37, + 38, + 39, + 40, + 41, + 42, + 43, + 44, + 45, + 46, + 47, + 48, + 49, + 50, + 51, + 52, + 53, + 54, + 55, + 56, + 57, + 58, + 59, + 60, + 61, + 62, + 63, + 64, + 65, + 66, + 67, + 68, + 69, + 70, + 71, + 72, + 73, + 74, + 75, + 76, + 77, + 78, + 79, + 80, + 81, + 82, + 83, + 84, + 85, + 86, + 87, + 88, + 89, + 90, + 91, + 92, + 93, + 94, + 95, + 96, + 97, + 98, + 99, + 100 +) + println(p1.field1) + println(p1.field2) + println(p1.field3) + println(p1.field4) + println(p1.field5) + println(p1.field6) + println(p1.field7) + println(p1.field8) + println(p1.field9) + println(p1.field10) + println(p1.field11) + println(p1.field12) + println(p1.field13) + println(p1.field14) + println(p1.field15) + println(p1.field16) + println(p1.field17) + println(p1.field18) + println(p1.field19) + println(p1.field20) + println(p1.field21) + println(p1.field22) + println(p1.field23) + println(p1.field24) + println(p1.field25) + println(p1.field26) + println(p1.field27) + println(p1.field28) + println(p1.field29) + println(p1.field30) + println(p1.field31) + println(p1.field32) + println(p1.field33) + println(p1.field34) + println(p1.field35) + println(p1.field36) + println(p1.field37) + println(p1.field38) + println(p1.field39) + println(p1.field40) + println(p1.field41) + println(p1.field42) + println(p1.field43) + println(p1.field44) + println(p1.field45) + println(p1.field46) + println(p1.field47) + println(p1.field48) + println(p1.field49) + println(p1.field50) + println(p1.field51) + println(p1.field52) + println(p1.field53) + println(p1.field54) + println(p1.field55) + println(p1.field56) + println(p1.field57) + println(p1.field58) + println(p1.field59) + println(p1.field60) + println(p1.field61) + println(p1.field62) + println(p1.field63) + println(p1.field64) + println(p1.field65) + println(p1.field66) + println(p1.field67) + println(p1.field68) + println(p1.field69) + println(p1.field70) + println(p1.field71) + println(p1.field72) + println(p1.field73) + println(p1.field74) + println(p1.field75) + println(p1.field76) + println(p1.field77) + println(p1.field78) + println(p1.field79) + println(p1.field80) + println(p1.field81) + println(p1.field82) + println(p1.field83) + println(p1.field84) + println(p1.field85) + println(p1.field86) + println(p1.field87) + println(p1.field88) + println(p1.field89) + println(p1.field90) + println(p1.field91) + println(p1.field92) + println(p1.field93) + println(p1.field94) + println(p1.field95) + println(p1.field96) + println(p1.field97) + println(p1.field98) + println(p1.field99) + println(p1.field100) +} \ No newline at end of file diff --git a/examples/flat/nooptimized/two_xxl_objects.check b/examples/flat/nooptimized/two_xxl_objects.check new file mode 100644 index 000000000..2a817d143 --- /dev/null +++ b/examples/flat/nooptimized/two_xxl_objects.check @@ -0,0 +1,2 @@ +100 +151 \ No newline at end of file diff --git a/examples/flat/nooptimized/two_xxl_objects.effekt b/examples/flat/nooptimized/two_xxl_objects.effekt new file mode 100644 index 000000000..7258d179a --- /dev/null +++ b/examples/flat/nooptimized/two_xxl_objects.effekt @@ -0,0 +1,312 @@ +// xxl: Person has 100 fields -> need x slots +record Person( + field1: Int, + field2: Int, + field3: Int, + field4: Int, + field5: Int, + field6: Int, + field7: Int, + field8: Int, + field9: Int, + field10: Int, + field11: Int, + field12: Int, + field13: Int, + field14: Int, + field15: Int, + field16: Int, + field17: Int, + field18: Int, + field19: Int, + field20: Int, + field21: Int, + field22: Int, + field23: Int, + field24: Int, + field25: Int, + field26: Int, + field27: Int, + field28: Int, + field29: Int, + field30: Int, + field31: Int, + field32: Int, + field33: Int, + field34: Int, + field35: Int, + field36: Int, + field37: Int, + field38: Int, + field39: Int, + field40: Int, + field41: Int, + field42: Int, + field43: Int, + field44: Int, + field45: Int, + field46: Int, + field47: Int, + field48: Int, + field49: Int, + field50: Int, + field51: Int, + field52: Int, + field53: Int, + field54: Int, + field55: Int, + field56: Int, + field57: Int, + field58: Int, + field59: Int, + field60: Int, + field61: Int, + field62: Int, + field63: Int, + field64: Int, + field65: Int, + field66: Int, + field67: Int, + field68: Int, + field69: Int, + field70: Int, + field71: Int, + field72: Int, + field73: Int, + field74: Int, + field75: Int, + field76: Int, + field77: Int, + field78: Int, + field79: Int, + field80: Int, + field81: Int, + field82: Int, + field83: Int, + field84: Int, + field85: Int, + field86: Int, + field87: Int, + field88: Int, + field89: Int, + field90: Int, + field91: Int, + field92: Int, + field93: Int, + field94: Int, + field95: Int, + field96: Int, + field97: Int, + field98: Int, + field99: Int, + field100: Int +) + +def main() = { + val p1 = Person( + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, + 17, + 18, + 19, + 20, + 21, + 22, + 23, + 24, + 25, + 26, + 27, + 28, + 29, + 30, + 31, + 32, + 33, + 34, + 35, + 36, + 37, + 38, + 39, + 40, + 41, + 42, + 43, + 44, + 45, + 46, + 47, + 48, + 49, + 50, + 51, + 52, + 53, + 54, + 55, + 56, + 57, + 58, + 59, + 60, + 61, + 62, + 63, + 64, + 65, + 66, + 67, + 68, + 69, + 70, + 71, + 72, + 73, + 74, + 75, + 76, + 77, + 78, + 79, + 80, + 81, + 82, + 83, + 84, + 85, + 86, + 87, + 88, + 89, + 90, + 91, + 92, + 93, + 94, + 95, + 96, + 97, + 98, + 99, + 100 +) + val p2 = Person( + 101, + 102, + 103, + 104, + 105, + 106, + 107, + 108, + 109, + 110, + 111, + 112, + 113, + 114, + 115, + 116, + 117, + 118, + 119, + 120, + 121, + 122, + 123, + 124, + 125, + 126, + 127, + 128, + 129, + 130, + 131, + 132, + 133, + 134, + 135, + 136, + 137, + 138, + 139, + 140, + 141, + 142, + 143, + 144, + 145, + 146, + 147, + 148, + 149, + 150, + 151, + 152, + 153, + 154, + 155, + 156, + 157, + 158, + 159, + 160, + 161, + 162, + 163, + 164, + 165, + 166, + 167, + 168, + 169, + 170, + 171, + 172, + 173, + 174, + 175, + 176, + 177, + 178, + 179, + 180, + 181, + 182, + 183, + 184, + 185, + 186, + 187, + 188, + 189, + 190, + 191, + 192, + 193, + 194, + 195, + 196, + 197, + 198, + 199, + 200 +) + println(p1.field100) + println(p2.field51) +} \ No newline at end of file diff --git a/examples/flat/nooptimized/two_xxxl_objects.check b/examples/flat/nooptimized/two_xxxl_objects.check new file mode 100644 index 000000000..f10f03bb2 --- /dev/null +++ b/examples/flat/nooptimized/two_xxxl_objects.check @@ -0,0 +1,2 @@ +500 +999 \ No newline at end of file diff --git a/examples/flat/nooptimized/two_xxxl_objects.effekt b/examples/flat/nooptimized/two_xxxl_objects.effekt new file mode 100644 index 000000000..0e3ee0511 --- /dev/null +++ b/examples/flat/nooptimized/two_xxxl_objects.effekt @@ -0,0 +1,1512 @@ +// xxxl: Person has 500 fields -> need x slots +record Person( + field1: Int, + field2: Int, + field3: Int, + field4: Int, + field5: Int, + field6: Int, + field7: Int, + field8: Int, + field9: Int, + field10: Int, + field11: Int, + field12: Int, + field13: Int, + field14: Int, + field15: Int, + field16: Int, + field17: Int, + field18: Int, + field19: Int, + field20: Int, + field21: Int, + field22: Int, + field23: Int, + field24: Int, + field25: Int, + field26: Int, + field27: Int, + field28: Int, + field29: Int, + field30: Int, + field31: Int, + field32: Int, + field33: Int, + field34: Int, + field35: Int, + field36: Int, + field37: Int, + field38: Int, + field39: Int, + field40: Int, + field41: Int, + field42: Int, + field43: Int, + field44: Int, + field45: Int, + field46: Int, + field47: Int, + field48: Int, + field49: Int, + field50: Int, + field51: Int, + field52: Int, + field53: Int, + field54: Int, + field55: Int, + field56: Int, + field57: Int, + field58: Int, + field59: Int, + field60: Int, + field61: Int, + field62: Int, + field63: Int, + field64: Int, + field65: Int, + field66: Int, + field67: Int, + field68: Int, + field69: Int, + field70: Int, + field71: Int, + field72: Int, + field73: Int, + field74: Int, + field75: Int, + field76: Int, + field77: Int, + field78: Int, + field79: Int, + field80: Int, + field81: Int, + field82: Int, + field83: Int, + field84: Int, + field85: Int, + field86: Int, + field87: Int, + field88: Int, + field89: Int, + field90: Int, + field91: Int, + field92: Int, + field93: Int, + field94: Int, + field95: Int, + field96: Int, + field97: Int, + field98: Int, + field99: Int, + field100: Int, + field101: Int, + field102: Int, + field103: Int, + field104: Int, + field105: Int, + field106: Int, + field107: Int, + field108: Int, + field109: Int, + field110: Int, + field111: Int, + field112: Int, + field113: Int, + field114: Int, + field115: Int, + field116: Int, + field117: Int, + field118: Int, + field119: Int, + field120: Int, + field121: Int, + field122: Int, + field123: Int, + field124: Int, + field125: Int, + field126: Int, + field127: Int, + field128: Int, + field129: Int, + field130: Int, + field131: Int, + field132: Int, + field133: Int, + field134: Int, + field135: Int, + field136: Int, + field137: Int, + field138: Int, + field139: Int, + field140: Int, + field141: Int, + field142: Int, + field143: Int, + field144: Int, + field145: Int, + field146: Int, + field147: Int, + field148: Int, + field149: Int, + field150: Int, + field151: Int, + field152: Int, + field153: Int, + field154: Int, + field155: Int, + field156: Int, + field157: Int, + field158: Int, + field159: Int, + field160: Int, + field161: Int, + field162: Int, + field163: Int, + field164: Int, + field165: Int, + field166: Int, + field167: Int, + field168: Int, + field169: Int, + field170: Int, + field171: Int, + field172: Int, + field173: Int, + field174: Int, + field175: Int, + field176: Int, + field177: Int, + field178: Int, + field179: Int, + field180: Int, + field181: Int, + field182: Int, + field183: Int, + field184: Int, + field185: Int, + field186: Int, + field187: Int, + field188: Int, + field189: Int, + field190: Int, + field191: Int, + field192: Int, + field193: Int, + field194: Int, + field195: Int, + field196: Int, + field197: Int, + field198: Int, + field199: Int, + field200: Int, + field201: Int, + field202: Int, + field203: Int, + field204: Int, + field205: Int, + field206: Int, + field207: Int, + field208: Int, + field209: Int, + field210: Int, + field211: Int, + field212: Int, + field213: Int, + field214: Int, + field215: Int, + field216: Int, + field217: Int, + field218: Int, + field219: Int, + field220: Int, + field221: Int, + field222: Int, + field223: Int, + field224: Int, + field225: Int, + field226: Int, + field227: Int, + field228: Int, + field229: Int, + field230: Int, + field231: Int, + field232: Int, + field233: Int, + field234: Int, + field235: Int, + field236: Int, + field237: Int, + field238: Int, + field239: Int, + field240: Int, + field241: Int, + field242: Int, + field243: Int, + field244: Int, + field245: Int, + field246: Int, + field247: Int, + field248: Int, + field249: Int, + field250: Int, + field251: Int, + field252: Int, + field253: Int, + field254: Int, + field255: Int, + field256: Int, + field257: Int, + field258: Int, + field259: Int, + field260: Int, + field261: Int, + field262: Int, + field263: Int, + field264: Int, + field265: Int, + field266: Int, + field267: Int, + field268: Int, + field269: Int, + field270: Int, + field271: Int, + field272: Int, + field273: Int, + field274: Int, + field275: Int, + field276: Int, + field277: Int, + field278: Int, + field279: Int, + field280: Int, + field281: Int, + field282: Int, + field283: Int, + field284: Int, + field285: Int, + field286: Int, + field287: Int, + field288: Int, + field289: Int, + field290: Int, + field291: Int, + field292: Int, + field293: Int, + field294: Int, + field295: Int, + field296: Int, + field297: Int, + field298: Int, + field299: Int, + field300: Int, + field301: Int, + field302: Int, + field303: Int, + field304: Int, + field305: Int, + field306: Int, + field307: Int, + field308: Int, + field309: Int, + field310: Int, + field311: Int, + field312: Int, + field313: Int, + field314: Int, + field315: Int, + field316: Int, + field317: Int, + field318: Int, + field319: Int, + field320: Int, + field321: Int, + field322: Int, + field323: Int, + field324: Int, + field325: Int, + field326: Int, + field327: Int, + field328: Int, + field329: Int, + field330: Int, + field331: Int, + field332: Int, + field333: Int, + field334: Int, + field335: Int, + field336: Int, + field337: Int, + field338: Int, + field339: Int, + field340: Int, + field341: Int, + field342: Int, + field343: Int, + field344: Int, + field345: Int, + field346: Int, + field347: Int, + field348: Int, + field349: Int, + field350: Int, + field351: Int, + field352: Int, + field353: Int, + field354: Int, + field355: Int, + field356: Int, + field357: Int, + field358: Int, + field359: Int, + field360: Int, + field361: Int, + field362: Int, + field363: Int, + field364: Int, + field365: Int, + field366: Int, + field367: Int, + field368: Int, + field369: Int, + field370: Int, + field371: Int, + field372: Int, + field373: Int, + field374: Int, + field375: Int, + field376: Int, + field377: Int, + field378: Int, + field379: Int, + field380: Int, + field381: Int, + field382: Int, + field383: Int, + field384: Int, + field385: Int, + field386: Int, + field387: Int, + field388: Int, + field389: Int, + field390: Int, + field391: Int, + field392: Int, + field393: Int, + field394: Int, + field395: Int, + field396: Int, + field397: Int, + field398: Int, + field399: Int, + field400: Int, + field401: Int, + field402: Int, + field403: Int, + field404: Int, + field405: Int, + field406: Int, + field407: Int, + field408: Int, + field409: Int, + field410: Int, + field411: Int, + field412: Int, + field413: Int, + field414: Int, + field415: Int, + field416: Int, + field417: Int, + field418: Int, + field419: Int, + field420: Int, + field421: Int, + field422: Int, + field423: Int, + field424: Int, + field425: Int, + field426: Int, + field427: Int, + field428: Int, + field429: Int, + field430: Int, + field431: Int, + field432: Int, + field433: Int, + field434: Int, + field435: Int, + field436: Int, + field437: Int, + field438: Int, + field439: Int, + field440: Int, + field441: Int, + field442: Int, + field443: Int, + field444: Int, + field445: Int, + field446: Int, + field447: Int, + field448: Int, + field449: Int, + field450: Int, + field451: Int, + field452: Int, + field453: Int, + field454: Int, + field455: Int, + field456: Int, + field457: Int, + field458: Int, + field459: Int, + field460: Int, + field461: Int, + field462: Int, + field463: Int, + field464: Int, + field465: Int, + field466: Int, + field467: Int, + field468: Int, + field469: Int, + field470: Int, + field471: Int, + field472: Int, + field473: Int, + field474: Int, + field475: Int, + field476: Int, + field477: Int, + field478: Int, + field479: Int, + field480: Int, + field481: Int, + field482: Int, + field483: Int, + field484: Int, + field485: Int, + field486: Int, + field487: Int, + field488: Int, + field489: Int, + field490: Int, + field491: Int, + field492: Int, + field493: Int, + field494: Int, + field495: Int, + field496: Int, + field497: Int, + field498: Int, + field499: Int, + field500: Int +) + +def main() = { + val p1 = Person( + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, + 17, + 18, + 19, + 20, + 21, + 22, + 23, + 24, + 25, + 26, + 27, + 28, + 29, + 30, + 31, + 32, + 33, + 34, + 35, + 36, + 37, + 38, + 39, + 40, + 41, + 42, + 43, + 44, + 45, + 46, + 47, + 48, + 49, + 50, + 51, + 52, + 53, + 54, + 55, + 56, + 57, + 58, + 59, + 60, + 61, + 62, + 63, + 64, + 65, + 66, + 67, + 68, + 69, + 70, + 71, + 72, + 73, + 74, + 75, + 76, + 77, + 78, + 79, + 80, + 81, + 82, + 83, + 84, + 85, + 86, + 87, + 88, + 89, + 90, + 91, + 92, + 93, + 94, + 95, + 96, + 97, + 98, + 99, + 100, + 101, + 102, + 103, + 104, + 105, + 106, + 107, + 108, + 109, + 110, + 111, + 112, + 113, + 114, + 115, + 116, + 117, + 118, + 119, + 120, + 121, + 122, + 123, + 124, + 125, + 126, + 127, + 128, + 129, + 130, + 131, + 132, + 133, + 134, + 135, + 136, + 137, + 138, + 139, + 140, + 141, + 142, + 143, + 144, + 145, + 146, + 147, + 148, + 149, + 150, + 151, + 152, + 153, + 154, + 155, + 156, + 157, + 158, + 159, + 160, + 161, + 162, + 163, + 164, + 165, + 166, + 167, + 168, + 169, + 170, + 171, + 172, + 173, + 174, + 175, + 176, + 177, + 178, + 179, + 180, + 181, + 182, + 183, + 184, + 185, + 186, + 187, + 188, + 189, + 190, + 191, + 192, + 193, + 194, + 195, + 196, + 197, + 198, + 199, + 200, + 201, + 202, + 203, + 204, + 205, + 206, + 207, + 208, + 209, + 210, + 211, + 212, + 213, + 214, + 215, + 216, + 217, + 218, + 219, + 220, + 221, + 222, + 223, + 224, + 225, + 226, + 227, + 228, + 229, + 230, + 231, + 232, + 233, + 234, + 235, + 236, + 237, + 238, + 239, + 240, + 241, + 242, + 243, + 244, + 245, + 246, + 247, + 248, + 249, + 250, + 251, + 252, + 253, + 254, + 255, + 256, + 257, + 258, + 259, + 260, + 261, + 262, + 263, + 264, + 265, + 266, + 267, + 268, + 269, + 270, + 271, + 272, + 273, + 274, + 275, + 276, + 277, + 278, + 279, + 280, + 281, + 282, + 283, + 284, + 285, + 286, + 287, + 288, + 289, + 290, + 291, + 292, + 293, + 294, + 295, + 296, + 297, + 298, + 299, + 300, + 301, + 302, + 303, + 304, + 305, + 306, + 307, + 308, + 309, + 310, + 311, + 312, + 313, + 314, + 315, + 316, + 317, + 318, + 319, + 320, + 321, + 322, + 323, + 324, + 325, + 326, + 327, + 328, + 329, + 330, + 331, + 332, + 333, + 334, + 335, + 336, + 337, + 338, + 339, + 340, + 341, + 342, + 343, + 344, + 345, + 346, + 347, + 348, + 349, + 350, + 351, + 352, + 353, + 354, + 355, + 356, + 357, + 358, + 359, + 360, + 361, + 362, + 363, + 364, + 365, + 366, + 367, + 368, + 369, + 370, + 371, + 372, + 373, + 374, + 375, + 376, + 377, + 378, + 379, + 380, + 381, + 382, + 383, + 384, + 385, + 386, + 387, + 388, + 389, + 390, + 391, + 392, + 393, + 394, + 395, + 396, + 397, + 398, + 399, + 400, + 401, + 402, + 403, + 404, + 405, + 406, + 407, + 408, + 409, + 410, + 411, + 412, + 413, + 414, + 415, + 416, + 417, + 418, + 419, + 420, + 421, + 422, + 423, + 424, + 425, + 426, + 427, + 428, + 429, + 430, + 431, + 432, + 433, + 434, + 435, + 436, + 437, + 438, + 439, + 440, + 441, + 442, + 443, + 444, + 445, + 446, + 447, + 448, + 449, + 450, + 451, + 452, + 453, + 454, + 455, + 456, + 457, + 458, + 459, + 460, + 461, + 462, + 463, + 464, + 465, + 466, + 467, + 468, + 469, + 470, + 471, + 472, + 473, + 474, + 475, + 476, + 477, + 478, + 479, + 480, + 481, + 482, + 483, + 484, + 485, + 486, + 487, + 488, + 489, + 490, + 491, + 492, + 493, + 494, + 495, + 496, + 497, + 498, + 499, + 500 +) + val p2 = Person( + 501, + 502, + 503, + 504, + 505, + 506, + 507, + 508, + 509, + 510, + 511, + 512, + 513, + 514, + 515, + 516, + 517, + 518, + 519, + 520, + 521, + 522, + 523, + 524, + 525, + 526, + 527, + 528, + 529, + 530, + 531, + 532, + 533, + 534, + 535, + 536, + 537, + 538, + 539, + 540, + 541, + 542, + 543, + 544, + 545, + 546, + 547, + 548, + 549, + 550, + 551, + 552, + 553, + 554, + 555, + 556, + 557, + 558, + 559, + 560, + 561, + 562, + 563, + 564, + 565, + 566, + 567, + 568, + 569, + 570, + 571, + 572, + 573, + 574, + 575, + 576, + 577, + 578, + 579, + 580, + 581, + 582, + 583, + 584, + 585, + 586, + 587, + 588, + 589, + 590, + 591, + 592, + 593, + 594, + 595, + 596, + 597, + 598, + 599, + 600, + 601, + 602, + 603, + 604, + 605, + 606, + 607, + 608, + 609, + 610, + 611, + 612, + 613, + 614, + 615, + 616, + 617, + 618, + 619, + 620, + 621, + 622, + 623, + 624, + 625, + 626, + 627, + 628, + 629, + 630, + 631, + 632, + 633, + 634, + 635, + 636, + 637, + 638, + 639, + 640, + 641, + 642, + 643, + 644, + 645, + 646, + 647, + 648, + 649, + 650, + 651, + 652, + 653, + 654, + 655, + 656, + 657, + 658, + 659, + 660, + 661, + 662, + 663, + 664, + 665, + 666, + 667, + 668, + 669, + 670, + 671, + 672, + 673, + 674, + 675, + 676, + 677, + 678, + 679, + 680, + 681, + 682, + 683, + 684, + 685, + 686, + 687, + 688, + 689, + 690, + 691, + 692, + 693, + 694, + 695, + 696, + 697, + 698, + 699, + 700, + 701, + 702, + 703, + 704, + 705, + 706, + 707, + 708, + 709, + 710, + 711, + 712, + 713, + 714, + 715, + 716, + 717, + 718, + 719, + 720, + 721, + 722, + 723, + 724, + 725, + 726, + 727, + 728, + 729, + 730, + 731, + 732, + 733, + 734, + 735, + 736, + 737, + 738, + 739, + 740, + 741, + 742, + 743, + 744, + 745, + 746, + 747, + 748, + 749, + 750, + 751, + 752, + 753, + 754, + 755, + 756, + 757, + 758, + 759, + 760, + 761, + 762, + 763, + 764, + 765, + 766, + 767, + 768, + 769, + 770, + 771, + 772, + 773, + 774, + 775, + 776, + 777, + 778, + 779, + 780, + 781, + 782, + 783, + 784, + 785, + 786, + 787, + 788, + 789, + 790, + 791, + 792, + 793, + 794, + 795, + 796, + 797, + 798, + 799, + 800, + 801, + 802, + 803, + 804, + 805, + 806, + 807, + 808, + 809, + 810, + 811, + 812, + 813, + 814, + 815, + 816, + 817, + 818, + 819, + 820, + 821, + 822, + 823, + 824, + 825, + 826, + 827, + 828, + 829, + 830, + 831, + 832, + 833, + 834, + 835, + 836, + 837, + 838, + 839, + 840, + 841, + 842, + 843, + 844, + 845, + 846, + 847, + 848, + 849, + 850, + 851, + 852, + 853, + 854, + 855, + 856, + 857, + 858, + 859, + 860, + 861, + 862, + 863, + 864, + 865, + 866, + 867, + 868, + 869, + 870, + 871, + 872, + 873, + 874, + 875, + 876, + 877, + 878, + 879, + 880, + 881, + 882, + 883, + 884, + 885, + 886, + 887, + 888, + 889, + 890, + 891, + 892, + 893, + 894, + 895, + 896, + 897, + 898, + 899, + 900, + 901, + 902, + 903, + 904, + 905, + 906, + 907, + 908, + 909, + 910, + 911, + 912, + 913, + 914, + 915, + 916, + 917, + 918, + 919, + 920, + 921, + 922, + 923, + 924, + 925, + 926, + 927, + 928, + 929, + 930, + 931, + 932, + 933, + 934, + 935, + 936, + 937, + 938, + 939, + 940, + 941, + 942, + 943, + 944, + 945, + 946, + 947, + 948, + 949, + 950, + 951, + 952, + 953, + 954, + 955, + 956, + 957, + 958, + 959, + 960, + 961, + 962, + 963, + 964, + 965, + 966, + 967, + 968, + 969, + 970, + 971, + 972, + 973, + 974, + 975, + 976, + 977, + 978, + 979, + 980, + 981, + 982, + 983, + 984, + 985, + 986, + 987, + 988, + 989, + 990, + 991, + 992, + 993, + 994, + 995, + 996, + 997, + 998, + 999, + 1000 +) + println(p1.field500) + println(p2.field499) +} \ No newline at end of file From ca8394383d0a3913a68ef309f515f674541308aa Mon Sep 17 00:00:00 2001 From: Flat Date: Wed, 24 Sep 2025 15:12:29 +0200 Subject: [PATCH 03/27] Basic Bumb allocation --- .../effekt/generator/llvm/Transformer.scala | 2 ++ libraries/llvm/rts.ll | 24 +++++++++++++++++-- 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/effekt/shared/src/main/scala/effekt/generator/llvm/Transformer.scala b/effekt/shared/src/main/scala/effekt/generator/llvm/Transformer.scala index b7a572519..50a4d77fa 100644 --- a/effekt/shared/src/main/scala/effekt/generator/llvm/Transformer.scala +++ b/effekt/shared/src/main/scala/effekt/generator/llvm/Transformer.scala @@ -24,6 +24,7 @@ object Transformer { val entryInstructions = List( Call("stack", Ccc(), stackType, withEmptyStack, List()), + Call("", Ccc(), VoidType(), initializeMemory, List()), Call("_", Tailcc(false), VoidType(), transform(entry), List(LocalReference(stackType, "stack")))) val entryBlock = BasicBlock("entry", entryInstructions, RetVoid()) val entryFunction = Function(External(), Ccc(), VoidType(), "effektMain", List(), List(entryBlock)) @@ -715,6 +716,7 @@ object Transformer { emit(Load(returnAddressName, returnAddressType, returnAddressPointer, StackPointer)); } + val initializeMemory = ConstantGlobal("initializeMemory"); val newObject = ConstantGlobal("newObject"); val objectEnvironment = ConstantGlobal("objectEnvironment"); diff --git a/libraries/llvm/rts.ll b/libraries/llvm/rts.ll index a2bc718c5..2675e8680 100644 --- a/libraries/llvm/rts.ll +++ b/libraries/llvm/rts.ll @@ -136,10 +136,30 @@ define private %Prompt @freshPrompt() { ; Garbage collection + +@freeList = global ptr null + +define private %Object @myMalloc(i64 %size) { + %freeList = load ptr, ptr @freeList + %nextFree = getelementptr i8, ptr %freeList, i64 %size + store ptr %nextFree, ptr @freeList + ret ptr %freeList +} + +define private void @myFree(ptr %object) { + ret void +} + +define private void @initializeMemory() { + %freeList = call ptr @malloc(i64 4294967296) + store ptr %freeList, ptr @freeList + ret void +} + define private %Object @newObject(%Eraser %eraser, i64 %environmentSize) alwaysinline { %headerSize = ptrtoint ptr getelementptr (%Header, ptr null, i64 1) to i64 %size = add i64 %environmentSize, %headerSize - %object = call ptr @malloc(i64 %size) + %object = call ptr @myMalloc(i64 %size) %objectReferenceCount = getelementptr %Header, ptr %object, i64 0, i32 0 %objectEraser = getelementptr %Header, ptr %object, i64 0, i32 1 store %ReferenceCount 0, ptr %objectReferenceCount, !alias.scope !14, !noalias !24 @@ -199,7 +219,7 @@ define private void @eraseObject(%Object %object) alwaysinline { %eraser = load %Eraser, ptr %objectEraser, !alias.scope !14, !noalias !24 %environment = call %Environment @objectEnvironment(%Object %object) call void %eraser(%Environment %environment) - call void @free(%Object %object) + call void @myFree(%Object %object) br label %done done: From 0dd2a6c90a8dcb6d25c92d0af3842aa3e99b0ba1 Mon Sep 17 00:00:00 2001 From: Flat Date: Mon, 6 Oct 2025 11:30:14 +0200 Subject: [PATCH 04/27] First approach of a 2nd step of memory-management, but first done in C instead of LLVM because of better debug possibilities --- .../effekt/generator/llvm/Transformer.scala | 2 +- libraries/llvm/bytearray.c | 6 +- libraries/llvm/cMalloc.c | 124 ++++++++++++++++++ libraries/llvm/main.c | 1 + libraries/llvm/rts.ll | 83 ++++++++++-- 5 files changed, 201 insertions(+), 15 deletions(-) create mode 100644 libraries/llvm/cMalloc.c diff --git a/effekt/shared/src/main/scala/effekt/generator/llvm/Transformer.scala b/effekt/shared/src/main/scala/effekt/generator/llvm/Transformer.scala index 50a4d77fa..a3b5eb108 100644 --- a/effekt/shared/src/main/scala/effekt/generator/llvm/Transformer.scala +++ b/effekt/shared/src/main/scala/effekt/generator/llvm/Transformer.scala @@ -716,7 +716,7 @@ object Transformer { emit(Load(returnAddressName, returnAddressType, returnAddressPointer, StackPointer)); } - val initializeMemory = ConstantGlobal("initializeMemory"); + val initializeMemory = ConstantGlobal("cInitializeMemory"); val newObject = ConstantGlobal("newObject"); val objectEnvironment = ConstantGlobal("objectEnvironment"); diff --git a/libraries/llvm/bytearray.c b/libraries/llvm/bytearray.c index 4fef7999b..9aa8d9082 100644 --- a/libraries/llvm/bytearray.c +++ b/libraries/llvm/bytearray.c @@ -5,6 +5,9 @@ #include #include +extern void* cMalloc(uint8_t size); + + /** We represent bytearrays like positive types. * * - The field `tag` contains the size @@ -21,7 +24,8 @@ void c_bytearray_erase_noop(void *envPtr) { (void)envPtr; } struct Pos c_bytearray_new(const Int size) { - void *objPtr = malloc(sizeof(struct Header) + size); + int object_size = sizeof(struct Header) + size; + void *objPtr = cMalloc(object_size); struct Header *headerPtr = objPtr; *headerPtr = (struct Header) { .rc = 0, .eraser = c_bytearray_erase_noop, }; return (struct Pos) { diff --git a/libraries/llvm/cMalloc.c b/libraries/llvm/cMalloc.c new file mode 100644 index 000000000..f7dd07c87 --- /dev/null +++ b/libraries/llvm/cMalloc.c @@ -0,0 +1,124 @@ +#include +#include +#include + +// ----------------------------- +// Strukturdefinition +// ----------------------------- + +/** + * @brief Block-Struktur für die Freelist. + * + * Jeder freie Block zeigt auf den nächsten freien Block. + */ +typedef struct Block { + struct Block* next; +} Block; + +// ----------------------------- +// Globale Variablen +// ----------------------------- + +static Block* freeList = NULL; // Kopf der Freelist +static uint8_t* nextUnusedBlock = NULL; // Zeiger auf nächsten unbenutzten Block +static uint8_t* endOfChunk = NULL; // Ende des allokierten Speichers +static const int blockSize = 1024; // Größe jedes Blocks (1KB) + +// ----------------------------- +// Initialisierung +// ----------------------------- + +/** + * @brief Initialisiert den großen Speicherbereich (4GB). + */ +void cInitializeMemory(void) { + size_t chunkSize = (size_t)4294967296ULL; // 4GB + uint8_t* mem = (uint8_t*)malloc(chunkSize); + if (!mem) { + fprintf(stderr, "malloc() failed!\n"); + exit(1); + } + + nextUnusedBlock = mem; + endOfChunk = mem + chunkSize; + printf("[init] Memory initialized: %p - %p\n", (void*)mem, (void*)endOfChunk); +} + +// ----------------------------- +// Allokator +// ----------------------------- + +/** + * @brief Einfacher Speicher-Allocator. + * + * Wenn die Freelist leer ist, nimmt er den nächsten Block im Chunk. + * Wenn die Freelist nicht leer ist, nimmt er den ersten Eintrag daraus. + * + * @param size Ignoriert in diesem simplen Modell (wir geben immer 1KB). + * @return void* Zeiger auf den allokierten Block. + */ +void* cMalloc(uint8_t size) { + // 1. Falls Freelist leer ist → neuer Block + if (freeList == NULL) { + if (nextUnusedBlock + blockSize > endOfChunk) { + fprintf(stderr, "Out of memory!\n"); + return NULL; + } + + void* block = nextUnusedBlock; + nextUnusedBlock += blockSize; + printf("[malloc] New block: %p\n", block); + return block; + } + + + // 2. Falls Freelist nicht leer ist → wiederverwenden + Block* block = freeList; + freeList = block->next; + printf("[malloc] Reusing block: %p\n", (void*)block); + printf("[malloc] freeList: %p\n", (void*)freeList); + return (void*)block; +// return malloc(size); +} + +// ----------------------------- +// Free-Funktion +// ----------------------------- + +/** + * @brief Gibt einen Block zurück in die Freelist. + * + * @param ptr Zeiger auf den Block. + */ +void cFree(void* ptr) { + if (!ptr) return; + + Block* block = (Block*)ptr; + block->next = freeList; + freeList = block; + + printf("[free] Freed block: %p\n", ptr); +// free(ptr); +} + +void* cRealloc(void* ptr, uint8_t size) { + printf("cRealloc: %p, %d\n", ptr, size); + return realloc(ptr,size); +} + +// ----------------------------- +// Test / Demo +// ----------------------------- + +//int main(void) { +// cInitializeMemory(); +// +// void* a = cMalloc(1024); +// void* b = cMalloc(1024); +// cFree(a); +// void* c = cMalloc(1024); // sollte a wiederverwenden +// cFree(b); +// cFree(c); +// +// return 0; +//} diff --git a/libraries/llvm/main.c b/libraries/llvm/main.c index 0ea587ab3..89e94309d 100644 --- a/libraries/llvm/main.c +++ b/libraries/llvm/main.c @@ -11,6 +11,7 @@ #include "types.c" #include "bytearray.c" +#include "cMalloc.c" #include "io.c" #include "panic.c" diff --git a/libraries/llvm/rts.ll b/libraries/llvm/rts.ll index 2675e8680..a2750eed8 100644 --- a/libraries/llvm/rts.ll +++ b/libraries/llvm/rts.ll @@ -94,6 +94,11 @@ ; Foreign imports +declare void @cInitializeMemory() +declare ptr @cMalloc(i64) +declare void @cFree(ptr) +declare ptr @cRealloc(ptr, i64) + declare ptr @malloc(i64) declare void @free(ptr) declare ptr @realloc(ptr, i64) @@ -136,30 +141,82 @@ define private %Prompt @freshPrompt() { ; Garbage collection +; A type for the free list +%struct.Block = type { %struct.Block* } -@freeList = global ptr null +@freeList = global %struct.Block* null +@nextUnusedBlock = global i8* null +@endOfChunk = global i8* null +@blockSize = global i64 1024 ; each Block is 1KB -define private %Object @myMalloc(i64 %size) { - %freeList = load ptr, ptr @freeList - %nextFree = getelementptr i8, ptr %freeList, i64 %size - store ptr %nextFree, ptr @freeList - ret ptr %freeList -} +define private void @initializeMemory() { + ; Step 01: mem = malloc(4294967296) + %mem = call i8* @malloc(i64 4294967296) + + ; Step 02: nextUnusedBlock = mem + store i8* %mem, i8** @nextUnusedBlock + + ; Step 03: endOfChunk = mem + 4294967296 + %endPtr = getelementptr i8, i8* %mem, i64 4294967296 + store i8* %endPtr, i8** @endOfChunk -define private void @myFree(ptr %object) { ret void } -define private void @initializeMemory() { - %freeList = call ptr @malloc(i64 4294967296) - store ptr %freeList, ptr @freeList +define private %Object @myMalloc(i64 %size) { +entry: + ; Step 01: Check if the free list pointer is not null + %freeList = load %struct.Block*, %struct.Block** @freeList + %isNull = icmp eq %struct.Block* %freeList, null + br i1 %isNull, label %newAllocate, label %reuse + +; In case we can recycle a block from the free list, we do so and jump to the reuse label. +reuse: + ; Step 01: block = freeList + %block = load %struct.Block*, %struct.Block** @freeList + + ; Step 02: freeList = freeList.next + %nextPtr = getelementptr %struct.Block, %struct.Block* %block, i32 0, i32 0 + %nextBlock = load %struct.Block*, %struct.Block** %nextPtr + store %struct.Block* %nextBlock, %struct.Block** @freeList + + ; Step 03: Return + %ret = bitcast %struct.Block* %block to %Object + ret %Object %ret + +; In case we do not have a block to reuse +newAllocate: + %nu = load i8*, i8** @nextUnusedBlock + %end = load i8*, i8** @endOfChunk + %blockSize = load i64, i64* @blockSize + + ; block = next_unused + %next_plus = getelementptr i8, i8* %nu, i64 %blockSize + store i8* %next_plus, i8** @nextUnusedBlock + + %ret2 = bitcast i8* %nu to %Object + ret %Object %ret2 + +} + +define private void @myFree(%Object %object) { + ; block = (Block*)object + %block = bitcast %Object %object to %struct.Block* + + ; block.next = freeList + %nextField = getelementptr %struct.Block, %struct.Block* %block, i32 0, i32 0 + %freeList = load %struct.Block*, %struct.Block** @freeList + store %struct.Block* %freeList, %struct.Block** %nextField + + ; freeList = block + store %struct.Block* %block, %struct.Block** @freeList ; <- fails ret void } define private %Object @newObject(%Eraser %eraser, i64 %environmentSize) alwaysinline { %headerSize = ptrtoint ptr getelementptr (%Header, ptr null, i64 1) to i64 %size = add i64 %environmentSize, %headerSize - %object = call ptr @myMalloc(i64 %size) + %object = call ptr @cMalloc(i64 %size) %objectReferenceCount = getelementptr %Header, ptr %object, i64 0, i32 0 %objectEraser = getelementptr %Header, ptr %object, i64 0, i32 1 store %ReferenceCount 0, ptr %objectReferenceCount, !alias.scope !14, !noalias !24 @@ -219,7 +276,7 @@ define private void @eraseObject(%Object %object) alwaysinline { %eraser = load %Eraser, ptr %objectEraser, !alias.scope !14, !noalias !24 %environment = call %Environment @objectEnvironment(%Object %object) call void %eraser(%Environment %environment) - call void @myFree(%Object %object) + call void @cFree(%Object %object) br label %done done: From fe49498f49ab61e70f8c43f1a8a375d365f61cf4 Mon Sep 17 00:00:00 2001 From: Flat Date: Fri, 27 Feb 2026 10:38:01 +0100 Subject: [PATCH 05/27] df: Added ctrc for effekt (except for sender_receiver and server_client) --- .../{FlatTests.scala => CTRCTests.scala} | 7 +- .../effekt/generator/llvm/Transformer.scala | 535 ++++++++++++++++-- ...locate_first_then_release_flush_once.check | 0 ...ocate_first_then_release_flush_once.effekt | 0 ...ocate_first_then_release_flush_twice.check | 0 ...cate_first_then_release_flush_twice.effekt | 0 .../nooptimized/array_record.check | 0 .../nooptimized/array_record.effekt | 0 .../nooptimized/array_record_match.check | 0 .../nooptimized/array_record_match.effekt | 2 +- .../array_record_match_exhausted.check | 0 .../array_record_match_exhausted.effekt | 2 +- ...different_person_sizes_biggest_first.check | 0 ...ifferent_person_sizes_biggest_first.effekt | 0 ...ifferent_person_sizes_smallest_first.check | 0 ...fferent_person_sizes_smallest_first.effekt | 0 .../nooptimized/nested_objects.check | 0 .../nooptimized/nested_objects.effekt | 0 .../nooptimized/one_big_string_object.check | 0 .../nooptimized/one_big_string_object.effekt | 0 .../nooptimized/one_lg_object.check | 0 .../nooptimized/one_lg_object.effekt | 0 .../nooptimized/one_md_object.check | 0 .../nooptimized/one_md_object.effekt | 0 .../one_slot_one_person_list.check | 0 .../one_slot_one_person_list.effekt | 0 .../nooptimized/one_sm_object.check | 0 .../nooptimized/one_sm_object.effekt | 0 .../nooptimized/one_small_string_object.check | 0 .../one_small_string_object.effekt | 0 .../nooptimized/one_xl_object.check | 0 .../nooptimized/one_xl_object.effekt | 0 .../nooptimized/one_xs_object.check | 0 .../nooptimized/one_xs_object.effekt | 0 .../one_xxl_object_all_fields.check | 0 .../one_xxl_object_all_fields.effekt | 0 .../nooptimized/one_xxxl_object.check | 0 .../nooptimized/one_xxxl_object.effekt | 0 .../nooptimized/primitive_ref.check | 0 .../nooptimized/primitive_ref.effekt | 0 .../nooptimized/ref_allocate.check | 0 .../nooptimized/ref_allocate.effekt | 2 +- .../nooptimized/simple_list.check | 0 .../nooptimized/simple_list.effekt | 0 .../nooptimized/simple_ref.check | 0 .../nooptimized/simple_ref.effekt | 0 .../nooptimized/superperson.check | 0 .../nooptimized/superperson.effekt | 0 .../nooptimized/superperson_with_free.check | 0 .../nooptimized/superperson_with_free.effekt | 0 .../nooptimized/three_md_objects_direct.check | 0 .../three_md_objects_direct.effekt | 0 .../nooptimized/trigger_child_freeing.check | 0 .../nooptimized/trigger_child_freeing.effekt | 0 .../nooptimized/trigger_flush_once.check | 0 .../nooptimized/trigger_flush_once.effekt | 0 .../nooptimized/trigger_flush_twice.check | 0 .../nooptimized/trigger_flush_twice.effekt | 0 .../trigger_one_child_freeing.check | 0 .../trigger_one_child_freeing.effekt | 0 .../trigger_two_child_freeing.check | 0 .../trigger_two_child_freeing.effekt | 0 .../nooptimized/two_lg_objects.check | 0 .../nooptimized/two_lg_objects.effekt | 0 .../nooptimized/two_md_mixed_object.check | 0 .../nooptimized/two_md_mixed_object.effekt | 0 .../nooptimized/two_md_objects.check | 0 .../nooptimized/two_md_objects.effekt | 0 .../two_slot_one_person_list.check | 0 .../two_slot_one_person_list.effekt | 0 ...t_one_person_with_free_variable_list.check | 0 ..._one_person_with_free_variable_list.effekt | 0 .../two_slot_two_person_list.check | 0 .../two_slot_two_person_list.effekt | 0 ...wo_slot_two_person_list_continuation.check | 0 ...o_slot_two_person_list_continuation.effekt | 0 ..._person_list_continuation_allocation.check | 0 ...person_list_continuation_allocation.effekt | 0 ...o_person_list_continuation_exhausted.check | 0 ..._person_list_continuation_exhausted.effekt | 0 .../two_slot_two_person_list_exhausted.check | 0 .../two_slot_two_person_list_exhausted.effekt | 0 ...t_two_person_with_free_variable_list.check | 0 ..._two_person_with_free_variable_list.effekt | 0 .../nooptimized/two_sm_mixed_object.check | 0 .../nooptimized/two_sm_mixed_object.effekt | 0 .../nooptimized/two_sm_objects.check | 0 .../nooptimized/two_sm_objects.effekt | 0 .../nooptimized/two_xl_objects.check | 0 .../nooptimized/two_xl_objects.effekt | 0 .../nooptimized/two_xs_objects.check | 0 .../nooptimized/two_xs_objects.effekt | 0 .../two_xxl_object_all_fields.check | 0 .../two_xxl_object_all_fields.effekt | 0 .../nooptimized/two_xxl_objects.check | 0 .../nooptimized/two_xxl_objects.effekt | 0 .../nooptimized/two_xxxl_objects.check | 0 .../nooptimized/two_xxxl_objects.effekt | 0 libraries/common/array.effekt | 17 +- libraries/common/ref.effekt | 15 +- libraries/llvm/bytearray.c | 12 +- libraries/llvm/initialize-arena.c | 14 + libraries/llvm/main.c | 1 + libraries/llvm/rts.ll | 170 +++--- 104 files changed, 625 insertions(+), 152 deletions(-) rename effekt/jvm/src/test/scala/effekt/{FlatTests.scala => CTRCTests.scala} (66%) rename examples/{flat => ctrc}/nooptimized/allocate_first_then_release_flush_once.check (100%) rename examples/{flat => ctrc}/nooptimized/allocate_first_then_release_flush_once.effekt (100%) rename examples/{flat => ctrc}/nooptimized/allocate_first_then_release_flush_twice.check (100%) rename examples/{flat => ctrc}/nooptimized/allocate_first_then_release_flush_twice.effekt (100%) rename examples/{flat => ctrc}/nooptimized/array_record.check (100%) rename examples/{flat => ctrc}/nooptimized/array_record.effekt (100%) rename examples/{flat => ctrc}/nooptimized/array_record_match.check (100%) rename examples/{flat => ctrc}/nooptimized/array_record_match.effekt (83%) rename examples/{flat => ctrc}/nooptimized/array_record_match_exhausted.check (100%) rename examples/{flat => ctrc}/nooptimized/array_record_match_exhausted.effekt (83%) rename examples/{flat => ctrc}/nooptimized/different_person_sizes_biggest_first.check (100%) rename examples/{flat => ctrc}/nooptimized/different_person_sizes_biggest_first.effekt (100%) rename examples/{flat => ctrc}/nooptimized/different_person_sizes_smallest_first.check (100%) rename examples/{flat => ctrc}/nooptimized/different_person_sizes_smallest_first.effekt (100%) rename examples/{flat => ctrc}/nooptimized/nested_objects.check (100%) rename examples/{flat => ctrc}/nooptimized/nested_objects.effekt (100%) rename examples/{flat => ctrc}/nooptimized/one_big_string_object.check (100%) rename examples/{flat => ctrc}/nooptimized/one_big_string_object.effekt (100%) rename examples/{flat => ctrc}/nooptimized/one_lg_object.check (100%) rename examples/{flat => ctrc}/nooptimized/one_lg_object.effekt (100%) rename examples/{flat => ctrc}/nooptimized/one_md_object.check (100%) rename examples/{flat => ctrc}/nooptimized/one_md_object.effekt (100%) rename examples/{flat => ctrc}/nooptimized/one_slot_one_person_list.check (100%) rename examples/{flat => ctrc}/nooptimized/one_slot_one_person_list.effekt (100%) rename examples/{flat => ctrc}/nooptimized/one_sm_object.check (100%) rename examples/{flat => ctrc}/nooptimized/one_sm_object.effekt (100%) rename examples/{flat => ctrc}/nooptimized/one_small_string_object.check (100%) rename examples/{flat => ctrc}/nooptimized/one_small_string_object.effekt (100%) rename examples/{flat => ctrc}/nooptimized/one_xl_object.check (100%) rename examples/{flat => ctrc}/nooptimized/one_xl_object.effekt (100%) rename examples/{flat => ctrc}/nooptimized/one_xs_object.check (100%) rename examples/{flat => ctrc}/nooptimized/one_xs_object.effekt (100%) rename examples/{flat => ctrc}/nooptimized/one_xxl_object_all_fields.check (100%) rename examples/{flat => ctrc}/nooptimized/one_xxl_object_all_fields.effekt (100%) rename examples/{flat => ctrc}/nooptimized/one_xxxl_object.check (100%) rename examples/{flat => ctrc}/nooptimized/one_xxxl_object.effekt (100%) rename examples/{flat => ctrc}/nooptimized/primitive_ref.check (100%) rename examples/{flat => ctrc}/nooptimized/primitive_ref.effekt (100%) rename examples/{flat => ctrc}/nooptimized/ref_allocate.check (100%) rename examples/{flat => ctrc}/nooptimized/ref_allocate.effekt (89%) rename examples/{flat => ctrc}/nooptimized/simple_list.check (100%) rename examples/{flat => ctrc}/nooptimized/simple_list.effekt (100%) rename examples/{flat => ctrc}/nooptimized/simple_ref.check (100%) rename examples/{flat => ctrc}/nooptimized/simple_ref.effekt (100%) rename examples/{flat => ctrc}/nooptimized/superperson.check (100%) rename examples/{flat => ctrc}/nooptimized/superperson.effekt (100%) rename examples/{flat => ctrc}/nooptimized/superperson_with_free.check (100%) rename examples/{flat => ctrc}/nooptimized/superperson_with_free.effekt (100%) rename examples/{flat => ctrc}/nooptimized/three_md_objects_direct.check (100%) rename examples/{flat => ctrc}/nooptimized/three_md_objects_direct.effekt (100%) rename examples/{flat => ctrc}/nooptimized/trigger_child_freeing.check (100%) rename examples/{flat => ctrc}/nooptimized/trigger_child_freeing.effekt (100%) rename examples/{flat => ctrc}/nooptimized/trigger_flush_once.check (100%) rename examples/{flat => ctrc}/nooptimized/trigger_flush_once.effekt (100%) rename examples/{flat => ctrc}/nooptimized/trigger_flush_twice.check (100%) rename examples/{flat => ctrc}/nooptimized/trigger_flush_twice.effekt (100%) rename examples/{flat => ctrc}/nooptimized/trigger_one_child_freeing.check (100%) rename examples/{flat => ctrc}/nooptimized/trigger_one_child_freeing.effekt (100%) rename examples/{flat => ctrc}/nooptimized/trigger_two_child_freeing.check (100%) rename examples/{flat => ctrc}/nooptimized/trigger_two_child_freeing.effekt (100%) rename examples/{flat => ctrc}/nooptimized/two_lg_objects.check (100%) rename examples/{flat => ctrc}/nooptimized/two_lg_objects.effekt (100%) rename examples/{flat => ctrc}/nooptimized/two_md_mixed_object.check (100%) rename examples/{flat => ctrc}/nooptimized/two_md_mixed_object.effekt (100%) rename examples/{flat => ctrc}/nooptimized/two_md_objects.check (100%) rename examples/{flat => ctrc}/nooptimized/two_md_objects.effekt (100%) rename examples/{flat => ctrc}/nooptimized/two_slot_one_person_list.check (100%) rename examples/{flat => ctrc}/nooptimized/two_slot_one_person_list.effekt (100%) rename examples/{flat => ctrc}/nooptimized/two_slot_one_person_with_free_variable_list.check (100%) rename examples/{flat => ctrc}/nooptimized/two_slot_one_person_with_free_variable_list.effekt (100%) rename examples/{flat => ctrc}/nooptimized/two_slot_two_person_list.check (100%) rename examples/{flat => ctrc}/nooptimized/two_slot_two_person_list.effekt (100%) rename examples/{flat => ctrc}/nooptimized/two_slot_two_person_list_continuation.check (100%) rename examples/{flat => ctrc}/nooptimized/two_slot_two_person_list_continuation.effekt (100%) rename examples/{flat => ctrc}/nooptimized/two_slot_two_person_list_continuation_allocation.check (100%) rename examples/{flat => ctrc}/nooptimized/two_slot_two_person_list_continuation_allocation.effekt (100%) rename examples/{flat => ctrc}/nooptimized/two_slot_two_person_list_continuation_exhausted.check (100%) rename examples/{flat => ctrc}/nooptimized/two_slot_two_person_list_continuation_exhausted.effekt (100%) rename examples/{flat => ctrc}/nooptimized/two_slot_two_person_list_exhausted.check (100%) rename examples/{flat => ctrc}/nooptimized/two_slot_two_person_list_exhausted.effekt (100%) rename examples/{flat => ctrc}/nooptimized/two_slot_two_person_with_free_variable_list.check (100%) rename examples/{flat => ctrc}/nooptimized/two_slot_two_person_with_free_variable_list.effekt (100%) rename examples/{flat => ctrc}/nooptimized/two_sm_mixed_object.check (100%) rename examples/{flat => ctrc}/nooptimized/two_sm_mixed_object.effekt (100%) rename examples/{flat => ctrc}/nooptimized/two_sm_objects.check (100%) rename examples/{flat => ctrc}/nooptimized/two_sm_objects.effekt (100%) rename examples/{flat => ctrc}/nooptimized/two_xl_objects.check (100%) rename examples/{flat => ctrc}/nooptimized/two_xl_objects.effekt (100%) rename examples/{flat => ctrc}/nooptimized/two_xs_objects.check (100%) rename examples/{flat => ctrc}/nooptimized/two_xs_objects.effekt (100%) rename examples/{flat => ctrc}/nooptimized/two_xxl_object_all_fields.check (100%) rename examples/{flat => ctrc}/nooptimized/two_xxl_object_all_fields.effekt (100%) rename examples/{flat => ctrc}/nooptimized/two_xxl_objects.check (100%) rename examples/{flat => ctrc}/nooptimized/two_xxl_objects.effekt (100%) rename examples/{flat => ctrc}/nooptimized/two_xxxl_objects.check (100%) rename examples/{flat => ctrc}/nooptimized/two_xxxl_objects.effekt (100%) create mode 100644 libraries/llvm/initialize-arena.c diff --git a/effekt/jvm/src/test/scala/effekt/FlatTests.scala b/effekt/jvm/src/test/scala/effekt/CTRCTests.scala similarity index 66% rename from effekt/jvm/src/test/scala/effekt/FlatTests.scala rename to effekt/jvm/src/test/scala/effekt/CTRCTests.scala index c0c0f6e5c..76d65570b 100644 --- a/effekt/jvm/src/test/scala/effekt/FlatTests.scala +++ b/effekt/jvm/src/test/scala/effekt/CTRCTests.scala @@ -7,18 +7,17 @@ import java.io.File import scala.language.implicitConversions import scala.sys.process.Process -// df: My own test class to run my requested tests automatically -class FlatTests extends EffektTests { +class CTRCTests extends EffektTests { def backendName = "llvm" override def valgrind = false // works on linux only override lazy val positives: Set[File] = Set( - examplesDir / "flat" / "optimized" + examplesDir / "ctrc" / "optimized" ) override lazy val withoutOptimizations: Set[File] = Set( - examplesDir / "flat" / "nooptimized", + examplesDir / "ctrc" / "nooptimized", ) } diff --git a/effekt/shared/src/main/scala/effekt/generator/llvm/Transformer.scala b/effekt/shared/src/main/scala/effekt/generator/llvm/Transformer.scala index a3b5eb108..73edb0bdc 100644 --- a/effekt/shared/src/main/scala/effekt/generator/llvm/Transformer.scala +++ b/effekt/shared/src/main/scala/effekt/generator/llvm/Transformer.scala @@ -2,17 +2,23 @@ package effekt package generator package llvm +import effekt.generator.llvm.Type as LLVMType +import effekt.generator.llvm.Instruction.{Call, Load} +import effekt.generator.llvm.Transformer.{ModuleContext, createReleaseFunction, emit, environmentType, freshName, objectEnvironment} import effekt.machine +import effekt.machine.{Environment, Variable} +import effekt.machine.analysis.* import effekt.util.intercalate import effekt.util.messages.ErrorReporter -import effekt.machine.analysis.* import scala.annotation.tailrec import scala.collection.mutable +import scala.collection.mutable.ListBuffer object Transformer { val llvmFeatureFlags: List[String] = List("llvm") + val slotSize: Int = 64 // the size of a heap slot in bytes def transform(program: machine.Program)(using ErrorReporter): List[Definition] = program match { case machine.Program(declarations, definitions, entry) => @@ -24,8 +30,9 @@ object Transformer { val entryInstructions = List( Call("stack", Ccc(), stackType, withEmptyStack, List()), - Call("", Ccc(), VoidType(), initializeMemory, List()), - Call("_", Tailcc(false), VoidType(), transform(entry), List(LocalReference(stackType, "stack")))) + Call("", Ccc(), VoidType(), initializeMemory, List()), + Call("_", Tailcc(false), VoidType(), transform(entry), List(LocalReference(stackType, "stack"))), + ) val entryBlock = BasicBlock("entry", entryInstructions, RetVoid()) val entryFunction = Function(External(), Ccc(), VoidType(), "effektMain", List(), List(entryBlock)) @@ -58,26 +65,26 @@ object Transformer { """call void @hole() |unreachable |""".stripMargin - } + } def transform(template: Template[machine.Variable]): String = "; variable\n " ++ intercalate(template.strings, template.args.map { case machine.Variable(name, tpe) => PrettyPrinter.localName(name) }).mkString def transform(definition: machine.Definition)(using ModuleContext): Unit = definition match { - case machine.Definition(machine.Label(name, environment), body) => - val parameters = environment.map { case machine.Variable(name, tpe) => Parameter(transform(tpe), name) } - defineLabel(name, parameters) { - emit(Comment(s"definition $name, environment length ${environment.length}")) - eraseValues(environment, freeVariables(body)) - transform(body) - } + case machine.Definition(machine.Label(name, environment), body) => + val parameters = environment.map { case machine.Variable(name, tpe) => Parameter(transform(tpe), name) } + defineLabel(name, parameters) { + emit(Comment(s"definition $name, environment length ${environment.length}")) + eraseValues(environment, freeVariables(body)) + transform(body) + } } def transform(statement: machine.Statement)(using ModuleContext, FunctionContext, BlockContext): Terminator = statement match { - case machine.Jump(label, arguments) => + case machine.Jump(label, arguments) => emit(Comment(s"jump ${label.name}")) shareValues(arguments, Set()) emit(callLabel(transform(label), arguments.map(transform))) @@ -426,6 +433,8 @@ object Transformer { val resumptionType = NamedType("Resumption"); val promptType = NamedType("Prompt"); val referenceType = NamedType("Reference"); + val headerType = NamedType("Header"); + val referenceCountType = NamedType("ReferenceCount"); def transform(tpe: machine.Type): Type = tpe match { case machine.Positive() => positiveType @@ -516,16 +525,7 @@ object Transformer { C.erasers.getOrElseUpdate((types, kind), { kind match { case ObjectEraser => - val eraser = ConstantGlobal(freshName("eraser")); - defineFunction(eraser.name, List(Parameter(environmentType, "environment"))) { - emit(Comment(s"${kind} eraser, ${freshEnvironment.length} free variables")) - - // TODO avoid unnecessary loads - loadEnvironmentAt(LocalReference(environmentType, "environment"), freshEnvironment, Object); - eraseValues(freshEnvironment, Set()); - RetVoid() - }; - eraser + createEraserForNormalObjects(freshEnvironment) case StackEraser | StackFrameEraser => val eraser = ConstantGlobal(freshName("eraser")); defineFunction(eraser.name, List(Parameter(stackPointerType, "stackPointer"))) { @@ -570,32 +570,39 @@ object Transformer { }) } + /** + * Produces an Object. It is always ${slotSize} bytes long + */ def produceObject(role: String, environment: machine.Environment, freeInBody: Set[machine.Variable])(using ModuleContext, FunctionContext, BlockContext): Operand = { if (environment.isEmpty) { ConstantNull(objectType) + } else if (fitsInOneSavingSlot(environment)) { + produceSingleObject(role, environment, freeInBody) } else { - val objectReference = LocalReference(objectType, freshName(role)); - val environmentReference = LocalReference(environmentType, freshName("environment")); - val size = ConstantInt(environmentSize(environment)); - val eraser = getEraser(environment, ObjectEraser) - - emit(Call(objectReference.name, Ccc(), objectType, newObject, List(eraser, size))); - emit(Call(environmentReference.name, Ccc(), environmentType, objectEnvironment, List(objectReference))); - shareValues(environment, freeInBody); - storeEnvironment(environmentReference, environment, Object); - objectReference + produceShardedObject(role, environment, freeInBody) } } - def consumeObject(`object`: Operand, environment: machine.Environment, freeInBody: Set[machine.Variable])(using ModuleContext, FunctionContext, BlockContext): Unit = { + def consumeObject(`object`: LocalReference, environment: machine.Environment, freeInBody: Set[machine.Variable])(using ModuleContext, FunctionContext, BlockContext): Unit = { if (environment.isEmpty) { () } else { + // Step 01: We load the variables of the environment such that the continuation can continue val environmentReference = LocalReference(environmentType, freshName("environment")); emit(Call(environmentReference.name, Ccc(), environmentType, objectEnvironment, List(`object`))); - loadEnvironment(environmentReference, environment, Object); - shareValues(environment, freeInBody); - emit(Call("_", Ccc(), VoidType(), eraseObject, List(`object`))); + loadEnvironment(environmentReference, environment, Object) + + // Step 02: we create the release function for this object + val release = ConstantGlobal(freshName("release")); + defineFunction(release.name, List(Parameter(objectType, "object"))) { + createReleaseFunction(release.name, environment, freeInBody) + } + + // Step 03: we call the release function + emit(Call("_", Ccc(), VoidType(), release, List(`object`))); + +// shareValues(environment, freeInBody); +// emit(Call("_", Ccc(), VoidType(), eraseObject, List(`object`))); } } @@ -652,13 +659,88 @@ object Transformer { } } - def loadEnvironmentAt(pointer: Operand, environment: machine.Environment, alias: AliasInfo)(using ModuleContext, FunctionContext, BlockContext): Unit = { - val `type` = environmentType(environment) - environment.zipWithIndex.foreach { - case (machine.Variable(name, tpe), i) => - val field = LocalReference(PointerType(), freshName(name + "_pointer")); - emit(GetElementPtr(field.name, `type`, pointer, List(0, i))); - emit(Load(name, transform(tpe), field, alias)) + def loadEnvironmentAt(elementPointer: Operand, environment: machine.Environment, alias: AliasInfo)(using ModuleContext, FunctionContext, BlockContext): Unit = { + alias match { + // if we have a sharded object + case Object if !fitsInOneSavingSlot(environment) => + // Follow chained ${slotSize}-byte blocks created in produceObject + val chunkedEnvironments = splitEnvironment(environment) + var currentEnvironmentPtr: Operand = elementPointer + + // here we loop over all environments *in* order + chunkedEnvironments.zipWithIndex.foreach { case (chunk, idx) => + val isLast = idx == chunkedEnvironments.length - 1 + if (isLast) { + val tpe = environmentType(chunk) + loadAllVariables(currentEnvironmentPtr, chunk, alias, tpe) + } else { + // Here we do the same as for the normal slot plus some extra stuff + + // For non-last chunkedEnvironments, layout is chunk ++ [Pos link] + val tpe = StructureType(chunk.map { case machine.Variable(_, t) => transform(t) } :+ positiveType) // the same as for the normal case + positive Type for the link + loadAllVariables(currentEnvironmentPtr, chunk, alias, tpe) + + // Follow link to next block. The Link pointer is the last element of the chunk + val linkPtr = LocalReference(PointerType(), freshName("link_pointer")) + emit(GetElementPtr(linkPtr.name, tpe, currentEnvironmentPtr, List(0, chunk.length))) + + val linkVal = LocalReference(positiveType, freshName("link")) + emit(Load(linkVal.name, positiveType, linkPtr, alias)) + + val nextObj = LocalReference(objectType, freshName("next_object")) + emit(ExtractValue(nextObj.name, linkVal, 1)) + + val nextEnv = LocalReference(environmentType, freshName("environment")) + emit(Call(nextEnv.name, Ccc(), environmentType, objectEnvironment, List(nextObj))) + currentEnvironmentPtr = nextEnv + } + } + case _: AliasInfo => + val tpe = environmentType(environment) + loadAllVariables(elementPointer, environment, alias, tpe) + } + } + + def loadEnvironmentAtDirectly(elementPointer: Operand, environment: machine.Environment, alias: AliasInfo, allInstructions: mutable.ListBuffer[Instruction])(using ModuleContext, FunctionContext, BlockContext): Unit = { + alias match { + // if we have a sharded object + case Object if !fitsInOneSavingSlot(environment) => + // Follow chained ${slotSize}-byte blocks created in produceObject + val chunkedEnvironments = splitEnvironment(environment) + var currentEnvironmentPtr: Operand = elementPointer + + // here we loop over all environments *in* order + chunkedEnvironments.zipWithIndex.foreach { case (chunk, idx) => + val isLast = idx == chunkedEnvironments.length - 1 + if (isLast) { + val tpe = environmentType(chunk) + loadAllVariablesDirectly(currentEnvironmentPtr, chunk, alias, tpe, allInstructions) + } else { + // Here we do the same as for the normal slot plus some extra stuff + + // For non-last chunkedEnvironments, layout is chunk ++ [Pos link] + val tpe = StructureType(chunk.map { case machine.Variable(_, t) => transform(t) } :+ positiveType) // the same as for the normal case + positive Type for the link + loadAllVariablesDirectly(currentEnvironmentPtr, chunk, alias, tpe, allInstructions) + + // Follow link to next block. The Link pointer is the last element of the chunk + val linkPtr = LocalReference(PointerType(), freshName("link_pointer")) + allInstructions += GetElementPtr(linkPtr.name, tpe, currentEnvironmentPtr, List(0, chunk.length)) + + val linkVal = LocalReference(positiveType, freshName("link")) + allInstructions += Load(linkVal.name, positiveType, linkPtr, alias) + + val nextObj = LocalReference(objectType, freshName("next_object")) + allInstructions += ExtractValue(nextObj.name, linkVal, 1) + + val nextEnv = LocalReference(environmentType, freshName("environment")) + allInstructions += Call(nextEnv.name, Ccc(), environmentType, objectEnvironment, List(nextObj)) + currentEnvironmentPtr = nextEnv + } + } + case _: AliasInfo => + val tpe = environmentType(environment) + loadAllVariablesDirectly(elementPointer, environment, alias, tpe, allInstructions) + } } @@ -668,15 +750,38 @@ object Transformer { values match { case Nil => () case value :: values => - if values.contains(value) then { - shareValue(value); - loop(values) - } else if freeInBody.contains(value) then { - shareValue(value); - loop(values) - } else { - loop(values) - } + if values.contains(value) then { + shareValue(value); + loop(values) + } else if freeInBody.contains(value) then { + shareValue(value); + loop(values) + } else { + loop(values) + } + } + }; + loop(values) + } + + /* + * Adds all sharing functions to the allInstructions list + */ + def shareValuesDirectly(values: machine.Environment, freeInBody: Set[machine.Variable], allInstructions: ListBuffer[Instruction])(using FunctionContext, BlockContext): Unit = { + @tailrec + def loop(values: machine.Environment): Unit = { + values match { + case Nil => () + case value :: values => + if values.contains(value) then { + shareValueDirectly(value, allInstructions); + loop(values) + } else if freeInBody.contains(value) then { + shareValueDirectly(value, allInstructions); + loop(values) + } else { + loop(values) + } } }; loop(values) @@ -695,6 +800,17 @@ object Transformer { }.map(emit) } + /** + * adds the sharing Functions to the allInstructions list. + */ + def shareValueDirectly(value: machine.Variable, allInstructions: ListBuffer[Instruction])(using FunctionContext, BlockContext): Unit = { + Option(value.tpe).collect { + case machine.Positive() => allInstructions += (Call("_", Ccc(), VoidType(), sharePositive, List(transform(value)))) + case machine.Negative() => allInstructions += Call("_", Ccc(), VoidType(), shareNegative, List(transform(value))) + case machine.Type.Stack() => allInstructions += Call("_", Ccc(), VoidType(), shareResumption, List(transform(value))) + } + } + def eraseValue(value: machine.Variable)(using FunctionContext, BlockContext): Unit = { Option(value.tpe).collect { case machine.Positive() => Call("_", Ccc(), VoidType(), erasePositive, List(transform(value))) @@ -716,7 +832,7 @@ object Transformer { emit(Load(returnAddressName, returnAddressType, returnAddressPointer, StackPointer)); } - val initializeMemory = ConstantGlobal("cInitializeMemory"); + val initializeMemory = ConstantGlobal("initializeMemory"); val newObject = ConstantGlobal("newObject"); val objectEnvironment = ConstantGlobal("objectEnvironment"); @@ -794,4 +910,317 @@ object Transformer { case None => acc += c } }.toString() + + /** + * if we can fit our object in one single saving block -> Easiest case + * Else we have to split our environment into multiple saving slots and reference in a linked list fashion + */ + private def fitsInOneSavingSlot(environment: machine.Environment): Boolean = { + environmentSize(environment) > 0 && environmentSize(environment) <= 48 + } + + /** + * Splits the environment into multiple environment such that you can store one object in multiple saving slots. + * Is required to do fixed-sized-allocation. + */ + private def splitEnvironment(environment: machine.Environment): List[machine.Environment] = { + val headerSize = 16 // we use 16 byte for the last saving block only, the others are 32 bytes + val linkSize = 16 // how much bytes we need to store the link to the next block (%Pos object) + + // How much bytes do we need to reserve to save a slot? + // The last block only needs 16 bytes, because here we only need to store the header. + // For all other blocks we need 32 bytes, because we need to store the header and the link to the next block. + var reservedSpaceForSlot = headerSize + + var currentEnvironment = List[machine.Variable]() + var result = List[machine.Environment]() + var isLast = true + for (variable <- environment.reverse) { + val variableSize = typeSize(variable.tpe) + + if (reservedSpaceForSlot + (environmentSize(currentEnvironment) + variableSize) <= slotSize) { + currentEnvironment = currentEnvironment :+ variable + } + else { + if (isLast) { + reservedSpaceForSlot = headerSize + linkSize // normal header size + size of the positive type which is the reference to the next object + isLast = false + } + result = result :+ currentEnvironment.reverse + currentEnvironment = List(variable) + } + } + result = result :+ currentEnvironment.reverse + + result.reverse + } + + /** + * When you have a big object to produce, you shard it into multiple slots instead of one single big slot. + * The end of each slot references to the next one. + * Each slot is 64 byte long + */ + private def produceShardedObject(role: String, environment: machine.Environment, freeInBody: Set[machine.Variable])(using ModuleContext, FunctionContext, BlockContext): Operand = { + // Split into multiple 64-byte blocks and chain them via a boxed link (%Pos with tag 0 pointing to next %Object) + val shardedEnvironments = splitEnvironment(environment) + + // Allocate the last block first. + val lastEnvironment = shardedEnvironments.last + val lastObjectReference = LocalReference(objectType, freshName(role)) + val lastEnvPtr = LocalReference(environmentType, freshName("environment")) + val lastSize = ConstantInt(environmentSize(lastEnvironment)) + val lastEraser = getEraser(lastEnvironment, ObjectEraser) + + emit(Call(lastObjectReference.name, Ccc(), objectType, newObject, List(lastEraser, lastSize))) + emit(Call(lastEnvPtr.name, Ccc(), environmentType, objectEnvironment, List(lastObjectReference))) + shareValues(lastEnvironment, freeInBody) + storeEnvironment(lastEnvPtr, lastEnvironment, Object) + + // Chain preceding blocks, each storing a boxed link to the next object + var headObject: LocalReference = lastObjectReference + + // loop through all shardedEnvironments except the last one in reversed order + shardedEnvironments.init.reverse.foreach { envChunk => + val temporaryName = freshName("link_temporary") + val linkValName = freshName("link") + + // we create a new Positive Object with tag 0... + emit(InsertValue(temporaryName, ConstantAggregateZero(positiveType), ConstantInt(0), 0)) // we create a fake Link Tag 0 that we just use for store a tag in the Pos + emit(InsertValue(linkValName, LocalReference(positiveType, temporaryName), headObject, 1)) + + // ... and inject it into our environment... + val extendedEnv = envChunk :+ machine.Variable(linkValName, machine.Positive()) + + // ...finally, we do the usual behavior when we produce an object + headObject = produceSingleObject(role, extendedEnv, freeInBody) + } + headObject + } + + /** + * Creates a new object and stores its environment in it + */ + private def produceSingleObject(role: String, environment: machine.Environment, freeInBody: Set[machine.Variable])(using ModuleContext, FunctionContext, BlockContext): LocalReference = { + val objectReference = LocalReference(objectType, freshName(role)) + val environmentReference = LocalReference(environmentType, freshName("environment")) + val size = ConstantInt(environmentSize(environment)) + val eraser = getEraser(environment, ObjectEraser) + + emit(Call(objectReference.name, Ccc(), objectType, newObject, List(eraser, size))); + emit(Call(environmentReference.name, Ccc(), environmentType, objectEnvironment, List(objectReference))); + shareValues(environment, freeInBody); + storeEnvironment(environmentReference, environment, Object); + objectReference + } + + private def loadAllVariables(pointer: Operand, environment: machine.Environment, alias: AliasInfo, typ: Type)(using ModuleContext, FunctionContext, BlockContext): Unit = { + environment.zipWithIndex.foreach { + case (machine.Variable(name, tpe), i) => + val field = LocalReference(PointerType(), freshName(name + "_pointer")) + emit(GetElementPtr(field.name, typ, pointer, List(0, i))) + emit(Load(name, transform(tpe), field, alias)) + } + } + + private def loadAllVariablesDirectly(pointer: Operand, environment: machine.Environment, alias: AliasInfo, typ: Type, allInstructions: mutable.ListBuffer[Instruction])(using ModuleContext, FunctionContext, BlockContext): Unit = { + environment.zipWithIndex.foreach { + case (machine.Variable(name, tpe), i) => + val field = LocalReference(PointerType(), freshName(name + "_pointer")) + allInstructions += GetElementPtr(field.name, typ, pointer, List(0, i)) + allInstructions += Load(name, transform(tpe), field, alias) + } + } + + private def createReleaseFunction(releaseLabel: String, environment: machine.Environment, freeInBody: Set[machine.Variable])(using ModuleContext, FunctionContext, BlockContext): Terminator = { + val pushOntoFreeListLabel = freshName("pushOntoFreeList") + val shareChildrenAndEraseLabel = freshName("shareChildrenAndErase") + val objectReference = LocalReference(objectType, "object") + val environmentRef = LocalReference(environmentType, freshName("environment")) + + val referenceCountPtr = LocalReference(PointerType(), freshName("referenceCount_pointer")) + val referenceCount: LocalReference = LocalReference(referenceCountType, freshName("referenceCount")) + + // Step 01: Load the environment + emit(Call(environmentRef.name, Ccc(), environmentType, ConstantGlobal("objectEnvironment"), List(objectReference))) + + // Step 02: Load the reference count + emit(GetElementPtr(referenceCountPtr.name, headerType, LocalReference(objectType, "object"), List(0, 0))) + emit(Load(referenceCount.name, referenceCountType, referenceCountPtr, Object)) + + // Step 03: Create the branches for dealing with the given reference count + createReleasePushOntoFreeListBasicBlock(pushOntoFreeListLabel, environment, freeInBody, objectReference, environmentRef) + createReleaseShareChildrenAndEraseBasicBlock(shareChildrenAndEraseLabel, environment, freeInBody, objectReference, environmentRef) + + // Step 04: Check the reference count + Switch(referenceCount, shareChildrenAndEraseLabel, List((0, pushOntoFreeListLabel))) + } + + /** + * In this branch of the release function, we know that we can safely erase the object. + * It might be that an object consists of several slots. + * Each slot is pushed onto the free list. + */ + private def createReleasePushOntoFreeListBasicBlock(releaseLabel: String, environment: Environment, freeInBody: Set[machine.Variable], `object`: Operand, environmentRef: LocalReference)(using ModuleContext, FunctionContext, BlockContext): Unit = { + val allInstructions = mutable.ListBuffer[Instruction](Call("_", Ccc(), VoidType(), ConstantGlobal("pushOntoFreeList"), List(`object`))) + var currentEnvironmentPtr = environmentRef + val slottedEnvironment = splitEnvironment(environment) + + slottedEnvironment.zipWithIndex.foreach { case (slotEnv: Environment, index: Int) => + val isLastSlot = index == slottedEnvironment.length - 1 + val slotEnvTypes = if (isLastSlot) environmentType(slotEnv) else StructureType(slotEnv.map { case machine.Variable(_, t) => transform(t) } :+ positiveType) + + slotEnv.zipWithIndex.foreach { case (variable@machine.Variable(varName, tpe), i) => + val isHeapType = tpe match { + case machine.Positive() | machine.Negative() | machine.Type.Stack() => true + case _ => false + } + + if (isHeapType) { + val variableType = transform(tpe) + val fieldPtr = LocalReference(PointerType(), freshName(varName + "_pointer")) + val loadedVar = LocalReference(variableType, freshName(varName)) + + // Load the variable + allInstructions += GetElementPtr(fieldPtr.name, slotEnvTypes, currentEnvironmentPtr, List(0, i)) + allInstructions += Load(loadedVar.name, variableType, fieldPtr, Object) + + val isVariableFreeInBody = freeInBody.contains(variable) + + if (!isVariableFreeInBody) { + // Variable is used in the scope -> erase it + val erasingFunction = getErasingFunctionForType(variableType) + allInstructions += Call("_", Ccc(), VoidType(), erasingFunction, List(loadedVar)) + } + } + } + + if (!isLastSlot) { + // erase the link slot + val linkIndexOfSlot = slotEnv.length + val linkPtr = LocalReference(PointerType(), freshName("link_pointer")) + val linkVal = LocalReference(positiveType, freshName("link")) + val nextObj = LocalReference(objectType, freshName("next_object")) + val nextEnv = LocalReference(environmentType, freshName("environment")) + + // add all instructions + allInstructions += GetElementPtr(linkPtr.name, slotEnvTypes, currentEnvironmentPtr, List(0, linkIndexOfSlot)) + allInstructions += Load(linkVal.name, positiveType, linkPtr, Object) + allInstructions += ExtractValue(nextObj.name, linkVal, 1) + allInstructions += Call("_", Ccc(), VoidType(), ConstantGlobal("pushOntoFreeList"), List(nextObj)) + allInstructions += Call(nextEnv.name, Ccc(), environmentType, objectEnvironment, List(nextObj)) + + // now we have to follow the link to the next environment + currentEnvironmentPtr = nextEnv + } + } + + emit(BasicBlock(releaseLabel, allInstructions.toList, RetVoid())) + } + + private def createReleaseShareChildrenAndEraseBasicBlock(shareChildrenLabel: String, environment: machine.Environment, freeInBody: Set[machine.Variable], `object`: Operand, environmentRef: LocalReference)(using ModuleContext, FunctionContext, BlockContext): Unit = { + val allInstructions = mutable.ListBuffer[Instruction]() + // Step 02: Load all variables + loadEnvironmentAtDirectly(environmentRef, environment, Object, allInstructions) + shareValuesDirectly(environment, freeInBody, allInstructions) + allInstructions += (Call("_", Ccc(), VoidType(), eraseObject, List(`object`))) + emit(BasicBlock(shareChildrenLabel, allInstructions.toList, RetVoid())) + } + + /** + * Creates an eraser for normal objects (e.g. Pos and Neg). + * When @eraseObject is called, we also call the eraser. And for Pos and Neg objects, that is the eraser. + * The object is called 2 times. + * 1. Phase: When call @eraseObject -> We call release to prepend the object to our to-do-list. + * 2. Phase: When call acquire -> We call %erase on each child, so the object can be reused again. + * + * @param freshEnvironment the variables of the object + * @return the eraser + */ + private def createEraserForNormalObjects(freshEnvironment: machine.Environment)(using C: ModuleContext): Operand = { + val eraser = ConstantGlobal(freshName("eraser")) + defineFunction(eraser.name, List(Parameter(objectType, "object"))) { + val objectRefCountPtr = LocalReference(PointerType(), freshName("objectReferenceCount")) + val referenceCount = LocalReference(referenceCountType, freshName("referenceCount")) + val pushOntoTodoListLabel = freshName("pushOntoTodoList") + val eraseChildrenLabel = freshName("eraseChildren") + + // Entry block: Check reference count to determine phase + // Switch: if refCount == 0, go to "pushOntoTodoList" (first phase), else "eraseChildren" (second phase) + // Note: When refCount == 0, this is the first call from eraseObject -> just push onto to-do list + // When refCount != 0, this is the second call from acquire -> erase children + emit(GetElementPtr(objectRefCountPtr.name, headerType, LocalReference(objectType, "object"), List(0, 0))) + emit(Load(referenceCount.name, referenceCountType, objectRefCountPtr, Object)) + + createAndEmitPushOntoTodoBasicBasicBlock(pushOntoTodoListLabel) + createAndEmitEraseChildrenBasicBlock(freshEnvironment, eraseChildrenLabel) + + // Return switch terminator from entry block + Switch(referenceCount, eraseChildrenLabel, List((0, pushOntoTodoListLabel))) + } + + eraser + } + + private def createAndEmitPushOntoTodoBasicBasicBlock(releaseLabel: String)(using ModuleContext, FunctionContext): Unit = { + emit(BasicBlock(releaseLabel, List( + Call("", Ccc(), VoidType(), ConstantGlobal("pushOntoTodoList"), List(LocalReference(objectType, "object"))) + ), RetVoid())) + } + + private def createAndEmitEraseChildrenBasicBlock(freshEnvironment: Environment, eraseChildrenLabel: String)(using ModuleContext, FunctionContext): Unit = { + val environmentRef = LocalReference(environmentType, freshName("environment")) + val eraseChildrenInstructions = mutable.ListBuffer[Instruction]() + + // Load environment variables and erase them + val envType = environmentType(freshEnvironment) + + val isAtLeastOneObjectToRelease: Boolean = + freshEnvironment.exists { + case machine.Variable(_, tpe) => + tpe match { + case machine.Positive() | machine.Negative() | machine.Type.Stack() => true + case _ => false + } + } + + if (isAtLeastOneObjectToRelease) { + // Get environment pointer + eraseChildrenInstructions += Call(environmentRef.name, Ccc(), environmentType, ConstantGlobal("objectEnvironment"), List(LocalReference(objectType, "object"))) + + freshEnvironment.zipWithIndex.foreach { case (machine.Variable(varName, tpe), i) => + val fieldPtr = LocalReference(PointerType(), freshName(varName + "_pointer")) + val loadedVarName = freshName(varName) + // Erase the value based on its type + tpe match { + case machine.Positive() => + emitElementPtrAndLoadOfEnvironmentVariable(environmentRef, eraseChildrenInstructions, envType, tpe, i, fieldPtr, loadedVarName, erasePositive) + case machine.Negative() => + emitElementPtrAndLoadOfEnvironmentVariable(environmentRef, eraseChildrenInstructions, envType, tpe, i, fieldPtr, loadedVarName, eraseNegative) + case machine.Type.Stack() => + emitElementPtrAndLoadOfEnvironmentVariable(environmentRef, eraseChildrenInstructions, envType, tpe, i, fieldPtr, loadedVarName, eraseResumption) + case _ => // Int, Byte, Double, Reference, etc. don't need erasing + } + } + emit(BasicBlock(eraseChildrenLabel, eraseChildrenInstructions.toList, RetVoid())) + } else { + // If not: we can return immediately, since we don't need to erase anything + emit(BasicBlock(eraseChildrenLabel, eraseChildrenInstructions.toList, RetVoid())) + } + } + + private def emitElementPtrAndLoadOfEnvironmentVariable(environmentRef: LocalReference, eraseChildrenInstructions: ListBuffer[Instruction], envType: LLVMType, tpe: machine.Type, i: Int, fieldPtr: LocalReference, loadedVarName: String, eraserFunction: ConstantGlobal) = { + eraseChildrenInstructions += GetElementPtr(fieldPtr.name, envType, environmentRef, List(0, i)) + eraseChildrenInstructions += Load(loadedVarName, transform(tpe), fieldPtr, Object) + eraseChildrenInstructions += Call("_", Ccc(), VoidType(), eraserFunction, List(LocalReference(transform(tpe), loadedVarName))) + } + + /** + * Loads the right erasing function for the given type + */ + private def getErasingFunctionForType(tpe: Type) = tpe match { + case NamedType("Pos") => erasePositive + case NamedType("Neg") => eraseNegative + case NamedType("Stack") => eraseResumption + case _ => ??? + } } diff --git a/examples/flat/nooptimized/allocate_first_then_release_flush_once.check b/examples/ctrc/nooptimized/allocate_first_then_release_flush_once.check similarity index 100% rename from examples/flat/nooptimized/allocate_first_then_release_flush_once.check rename to examples/ctrc/nooptimized/allocate_first_then_release_flush_once.check diff --git a/examples/flat/nooptimized/allocate_first_then_release_flush_once.effekt b/examples/ctrc/nooptimized/allocate_first_then_release_flush_once.effekt similarity index 100% rename from examples/flat/nooptimized/allocate_first_then_release_flush_once.effekt rename to examples/ctrc/nooptimized/allocate_first_then_release_flush_once.effekt diff --git a/examples/flat/nooptimized/allocate_first_then_release_flush_twice.check b/examples/ctrc/nooptimized/allocate_first_then_release_flush_twice.check similarity index 100% rename from examples/flat/nooptimized/allocate_first_then_release_flush_twice.check rename to examples/ctrc/nooptimized/allocate_first_then_release_flush_twice.check diff --git a/examples/flat/nooptimized/allocate_first_then_release_flush_twice.effekt b/examples/ctrc/nooptimized/allocate_first_then_release_flush_twice.effekt similarity index 100% rename from examples/flat/nooptimized/allocate_first_then_release_flush_twice.effekt rename to examples/ctrc/nooptimized/allocate_first_then_release_flush_twice.effekt diff --git a/examples/flat/nooptimized/array_record.check b/examples/ctrc/nooptimized/array_record.check similarity index 100% rename from examples/flat/nooptimized/array_record.check rename to examples/ctrc/nooptimized/array_record.check diff --git a/examples/flat/nooptimized/array_record.effekt b/examples/ctrc/nooptimized/array_record.effekt similarity index 100% rename from examples/flat/nooptimized/array_record.effekt rename to examples/ctrc/nooptimized/array_record.effekt diff --git a/examples/flat/nooptimized/array_record_match.check b/examples/ctrc/nooptimized/array_record_match.check similarity index 100% rename from examples/flat/nooptimized/array_record_match.check rename to examples/ctrc/nooptimized/array_record_match.check diff --git a/examples/flat/nooptimized/array_record_match.effekt b/examples/ctrc/nooptimized/array_record_match.effekt similarity index 83% rename from examples/flat/nooptimized/array_record_match.effekt rename to examples/ctrc/nooptimized/array_record_match.effekt index 1af090a55..e6856cf32 100644 --- a/examples/flat/nooptimized/array_record_match.effekt +++ b/examples/ctrc/nooptimized/array_record_match.effekt @@ -13,7 +13,7 @@ record OneSlotPerson( ) def main() = { - val myArray: Array[Int] = array::allocate(1) + val myArray: Array[Int] = array::unsafeAllocate(1) val p = Person(1, myArray) p match { case Person(f1, _) => println(f1) diff --git a/examples/flat/nooptimized/array_record_match_exhausted.check b/examples/ctrc/nooptimized/array_record_match_exhausted.check similarity index 100% rename from examples/flat/nooptimized/array_record_match_exhausted.check rename to examples/ctrc/nooptimized/array_record_match_exhausted.check diff --git a/examples/flat/nooptimized/array_record_match_exhausted.effekt b/examples/ctrc/nooptimized/array_record_match_exhausted.effekt similarity index 83% rename from examples/flat/nooptimized/array_record_match_exhausted.effekt rename to examples/ctrc/nooptimized/array_record_match_exhausted.effekt index 772e5c8c2..66ebfc8e3 100644 --- a/examples/flat/nooptimized/array_record_match_exhausted.effekt +++ b/examples/ctrc/nooptimized/array_record_match_exhausted.effekt @@ -13,7 +13,7 @@ record OneSlotPerson( ) def main() = { - val myArray: Array[Int] = array::allocate(1) + val myArray: Array[Int] = array::unsafeAllocate(1) val p = Person(1, myArray) p match { case Person(f1, arr) => println(f1) diff --git a/examples/flat/nooptimized/different_person_sizes_biggest_first.check b/examples/ctrc/nooptimized/different_person_sizes_biggest_first.check similarity index 100% rename from examples/flat/nooptimized/different_person_sizes_biggest_first.check rename to examples/ctrc/nooptimized/different_person_sizes_biggest_first.check diff --git a/examples/flat/nooptimized/different_person_sizes_biggest_first.effekt b/examples/ctrc/nooptimized/different_person_sizes_biggest_first.effekt similarity index 100% rename from examples/flat/nooptimized/different_person_sizes_biggest_first.effekt rename to examples/ctrc/nooptimized/different_person_sizes_biggest_first.effekt diff --git a/examples/flat/nooptimized/different_person_sizes_smallest_first.check b/examples/ctrc/nooptimized/different_person_sizes_smallest_first.check similarity index 100% rename from examples/flat/nooptimized/different_person_sizes_smallest_first.check rename to examples/ctrc/nooptimized/different_person_sizes_smallest_first.check diff --git a/examples/flat/nooptimized/different_person_sizes_smallest_first.effekt b/examples/ctrc/nooptimized/different_person_sizes_smallest_first.effekt similarity index 100% rename from examples/flat/nooptimized/different_person_sizes_smallest_first.effekt rename to examples/ctrc/nooptimized/different_person_sizes_smallest_first.effekt diff --git a/examples/flat/nooptimized/nested_objects.check b/examples/ctrc/nooptimized/nested_objects.check similarity index 100% rename from examples/flat/nooptimized/nested_objects.check rename to examples/ctrc/nooptimized/nested_objects.check diff --git a/examples/flat/nooptimized/nested_objects.effekt b/examples/ctrc/nooptimized/nested_objects.effekt similarity index 100% rename from examples/flat/nooptimized/nested_objects.effekt rename to examples/ctrc/nooptimized/nested_objects.effekt diff --git a/examples/flat/nooptimized/one_big_string_object.check b/examples/ctrc/nooptimized/one_big_string_object.check similarity index 100% rename from examples/flat/nooptimized/one_big_string_object.check rename to examples/ctrc/nooptimized/one_big_string_object.check diff --git a/examples/flat/nooptimized/one_big_string_object.effekt b/examples/ctrc/nooptimized/one_big_string_object.effekt similarity index 100% rename from examples/flat/nooptimized/one_big_string_object.effekt rename to examples/ctrc/nooptimized/one_big_string_object.effekt diff --git a/examples/flat/nooptimized/one_lg_object.check b/examples/ctrc/nooptimized/one_lg_object.check similarity index 100% rename from examples/flat/nooptimized/one_lg_object.check rename to examples/ctrc/nooptimized/one_lg_object.check diff --git a/examples/flat/nooptimized/one_lg_object.effekt b/examples/ctrc/nooptimized/one_lg_object.effekt similarity index 100% rename from examples/flat/nooptimized/one_lg_object.effekt rename to examples/ctrc/nooptimized/one_lg_object.effekt diff --git a/examples/flat/nooptimized/one_md_object.check b/examples/ctrc/nooptimized/one_md_object.check similarity index 100% rename from examples/flat/nooptimized/one_md_object.check rename to examples/ctrc/nooptimized/one_md_object.check diff --git a/examples/flat/nooptimized/one_md_object.effekt b/examples/ctrc/nooptimized/one_md_object.effekt similarity index 100% rename from examples/flat/nooptimized/one_md_object.effekt rename to examples/ctrc/nooptimized/one_md_object.effekt diff --git a/examples/flat/nooptimized/one_slot_one_person_list.check b/examples/ctrc/nooptimized/one_slot_one_person_list.check similarity index 100% rename from examples/flat/nooptimized/one_slot_one_person_list.check rename to examples/ctrc/nooptimized/one_slot_one_person_list.check diff --git a/examples/flat/nooptimized/one_slot_one_person_list.effekt b/examples/ctrc/nooptimized/one_slot_one_person_list.effekt similarity index 100% rename from examples/flat/nooptimized/one_slot_one_person_list.effekt rename to examples/ctrc/nooptimized/one_slot_one_person_list.effekt diff --git a/examples/flat/nooptimized/one_sm_object.check b/examples/ctrc/nooptimized/one_sm_object.check similarity index 100% rename from examples/flat/nooptimized/one_sm_object.check rename to examples/ctrc/nooptimized/one_sm_object.check diff --git a/examples/flat/nooptimized/one_sm_object.effekt b/examples/ctrc/nooptimized/one_sm_object.effekt similarity index 100% rename from examples/flat/nooptimized/one_sm_object.effekt rename to examples/ctrc/nooptimized/one_sm_object.effekt diff --git a/examples/flat/nooptimized/one_small_string_object.check b/examples/ctrc/nooptimized/one_small_string_object.check similarity index 100% rename from examples/flat/nooptimized/one_small_string_object.check rename to examples/ctrc/nooptimized/one_small_string_object.check diff --git a/examples/flat/nooptimized/one_small_string_object.effekt b/examples/ctrc/nooptimized/one_small_string_object.effekt similarity index 100% rename from examples/flat/nooptimized/one_small_string_object.effekt rename to examples/ctrc/nooptimized/one_small_string_object.effekt diff --git a/examples/flat/nooptimized/one_xl_object.check b/examples/ctrc/nooptimized/one_xl_object.check similarity index 100% rename from examples/flat/nooptimized/one_xl_object.check rename to examples/ctrc/nooptimized/one_xl_object.check diff --git a/examples/flat/nooptimized/one_xl_object.effekt b/examples/ctrc/nooptimized/one_xl_object.effekt similarity index 100% rename from examples/flat/nooptimized/one_xl_object.effekt rename to examples/ctrc/nooptimized/one_xl_object.effekt diff --git a/examples/flat/nooptimized/one_xs_object.check b/examples/ctrc/nooptimized/one_xs_object.check similarity index 100% rename from examples/flat/nooptimized/one_xs_object.check rename to examples/ctrc/nooptimized/one_xs_object.check diff --git a/examples/flat/nooptimized/one_xs_object.effekt b/examples/ctrc/nooptimized/one_xs_object.effekt similarity index 100% rename from examples/flat/nooptimized/one_xs_object.effekt rename to examples/ctrc/nooptimized/one_xs_object.effekt diff --git a/examples/flat/nooptimized/one_xxl_object_all_fields.check b/examples/ctrc/nooptimized/one_xxl_object_all_fields.check similarity index 100% rename from examples/flat/nooptimized/one_xxl_object_all_fields.check rename to examples/ctrc/nooptimized/one_xxl_object_all_fields.check diff --git a/examples/flat/nooptimized/one_xxl_object_all_fields.effekt b/examples/ctrc/nooptimized/one_xxl_object_all_fields.effekt similarity index 100% rename from examples/flat/nooptimized/one_xxl_object_all_fields.effekt rename to examples/ctrc/nooptimized/one_xxl_object_all_fields.effekt diff --git a/examples/flat/nooptimized/one_xxxl_object.check b/examples/ctrc/nooptimized/one_xxxl_object.check similarity index 100% rename from examples/flat/nooptimized/one_xxxl_object.check rename to examples/ctrc/nooptimized/one_xxxl_object.check diff --git a/examples/flat/nooptimized/one_xxxl_object.effekt b/examples/ctrc/nooptimized/one_xxxl_object.effekt similarity index 100% rename from examples/flat/nooptimized/one_xxxl_object.effekt rename to examples/ctrc/nooptimized/one_xxxl_object.effekt diff --git a/examples/flat/nooptimized/primitive_ref.check b/examples/ctrc/nooptimized/primitive_ref.check similarity index 100% rename from examples/flat/nooptimized/primitive_ref.check rename to examples/ctrc/nooptimized/primitive_ref.check diff --git a/examples/flat/nooptimized/primitive_ref.effekt b/examples/ctrc/nooptimized/primitive_ref.effekt similarity index 100% rename from examples/flat/nooptimized/primitive_ref.effekt rename to examples/ctrc/nooptimized/primitive_ref.effekt diff --git a/examples/flat/nooptimized/ref_allocate.check b/examples/ctrc/nooptimized/ref_allocate.check similarity index 100% rename from examples/flat/nooptimized/ref_allocate.check rename to examples/ctrc/nooptimized/ref_allocate.check diff --git a/examples/flat/nooptimized/ref_allocate.effekt b/examples/ctrc/nooptimized/ref_allocate.effekt similarity index 89% rename from examples/flat/nooptimized/ref_allocate.effekt rename to examples/ctrc/nooptimized/ref_allocate.effekt index 2b46ceaa7..011684f47 100644 --- a/examples/flat/nooptimized/ref_allocate.effekt +++ b/examples/ctrc/nooptimized/ref_allocate.effekt @@ -12,7 +12,7 @@ record Person( ) def main() = { - val p1 = ref::allocate() + val p1 = ref::unsafeAllocate() val p2 = Person(1, 2, 3, 4, 5, 6, 7) p1.set(p2) println(p1.get().field7) diff --git a/examples/flat/nooptimized/simple_list.check b/examples/ctrc/nooptimized/simple_list.check similarity index 100% rename from examples/flat/nooptimized/simple_list.check rename to examples/ctrc/nooptimized/simple_list.check diff --git a/examples/flat/nooptimized/simple_list.effekt b/examples/ctrc/nooptimized/simple_list.effekt similarity index 100% rename from examples/flat/nooptimized/simple_list.effekt rename to examples/ctrc/nooptimized/simple_list.effekt diff --git a/examples/flat/nooptimized/simple_ref.check b/examples/ctrc/nooptimized/simple_ref.check similarity index 100% rename from examples/flat/nooptimized/simple_ref.check rename to examples/ctrc/nooptimized/simple_ref.check diff --git a/examples/flat/nooptimized/simple_ref.effekt b/examples/ctrc/nooptimized/simple_ref.effekt similarity index 100% rename from examples/flat/nooptimized/simple_ref.effekt rename to examples/ctrc/nooptimized/simple_ref.effekt diff --git a/examples/flat/nooptimized/superperson.check b/examples/ctrc/nooptimized/superperson.check similarity index 100% rename from examples/flat/nooptimized/superperson.check rename to examples/ctrc/nooptimized/superperson.check diff --git a/examples/flat/nooptimized/superperson.effekt b/examples/ctrc/nooptimized/superperson.effekt similarity index 100% rename from examples/flat/nooptimized/superperson.effekt rename to examples/ctrc/nooptimized/superperson.effekt diff --git a/examples/flat/nooptimized/superperson_with_free.check b/examples/ctrc/nooptimized/superperson_with_free.check similarity index 100% rename from examples/flat/nooptimized/superperson_with_free.check rename to examples/ctrc/nooptimized/superperson_with_free.check diff --git a/examples/flat/nooptimized/superperson_with_free.effekt b/examples/ctrc/nooptimized/superperson_with_free.effekt similarity index 100% rename from examples/flat/nooptimized/superperson_with_free.effekt rename to examples/ctrc/nooptimized/superperson_with_free.effekt diff --git a/examples/flat/nooptimized/three_md_objects_direct.check b/examples/ctrc/nooptimized/three_md_objects_direct.check similarity index 100% rename from examples/flat/nooptimized/three_md_objects_direct.check rename to examples/ctrc/nooptimized/three_md_objects_direct.check diff --git a/examples/flat/nooptimized/three_md_objects_direct.effekt b/examples/ctrc/nooptimized/three_md_objects_direct.effekt similarity index 100% rename from examples/flat/nooptimized/three_md_objects_direct.effekt rename to examples/ctrc/nooptimized/three_md_objects_direct.effekt diff --git a/examples/flat/nooptimized/trigger_child_freeing.check b/examples/ctrc/nooptimized/trigger_child_freeing.check similarity index 100% rename from examples/flat/nooptimized/trigger_child_freeing.check rename to examples/ctrc/nooptimized/trigger_child_freeing.check diff --git a/examples/flat/nooptimized/trigger_child_freeing.effekt b/examples/ctrc/nooptimized/trigger_child_freeing.effekt similarity index 100% rename from examples/flat/nooptimized/trigger_child_freeing.effekt rename to examples/ctrc/nooptimized/trigger_child_freeing.effekt diff --git a/examples/flat/nooptimized/trigger_flush_once.check b/examples/ctrc/nooptimized/trigger_flush_once.check similarity index 100% rename from examples/flat/nooptimized/trigger_flush_once.check rename to examples/ctrc/nooptimized/trigger_flush_once.check diff --git a/examples/flat/nooptimized/trigger_flush_once.effekt b/examples/ctrc/nooptimized/trigger_flush_once.effekt similarity index 100% rename from examples/flat/nooptimized/trigger_flush_once.effekt rename to examples/ctrc/nooptimized/trigger_flush_once.effekt diff --git a/examples/flat/nooptimized/trigger_flush_twice.check b/examples/ctrc/nooptimized/trigger_flush_twice.check similarity index 100% rename from examples/flat/nooptimized/trigger_flush_twice.check rename to examples/ctrc/nooptimized/trigger_flush_twice.check diff --git a/examples/flat/nooptimized/trigger_flush_twice.effekt b/examples/ctrc/nooptimized/trigger_flush_twice.effekt similarity index 100% rename from examples/flat/nooptimized/trigger_flush_twice.effekt rename to examples/ctrc/nooptimized/trigger_flush_twice.effekt diff --git a/examples/flat/nooptimized/trigger_one_child_freeing.check b/examples/ctrc/nooptimized/trigger_one_child_freeing.check similarity index 100% rename from examples/flat/nooptimized/trigger_one_child_freeing.check rename to examples/ctrc/nooptimized/trigger_one_child_freeing.check diff --git a/examples/flat/nooptimized/trigger_one_child_freeing.effekt b/examples/ctrc/nooptimized/trigger_one_child_freeing.effekt similarity index 100% rename from examples/flat/nooptimized/trigger_one_child_freeing.effekt rename to examples/ctrc/nooptimized/trigger_one_child_freeing.effekt diff --git a/examples/flat/nooptimized/trigger_two_child_freeing.check b/examples/ctrc/nooptimized/trigger_two_child_freeing.check similarity index 100% rename from examples/flat/nooptimized/trigger_two_child_freeing.check rename to examples/ctrc/nooptimized/trigger_two_child_freeing.check diff --git a/examples/flat/nooptimized/trigger_two_child_freeing.effekt b/examples/ctrc/nooptimized/trigger_two_child_freeing.effekt similarity index 100% rename from examples/flat/nooptimized/trigger_two_child_freeing.effekt rename to examples/ctrc/nooptimized/trigger_two_child_freeing.effekt diff --git a/examples/flat/nooptimized/two_lg_objects.check b/examples/ctrc/nooptimized/two_lg_objects.check similarity index 100% rename from examples/flat/nooptimized/two_lg_objects.check rename to examples/ctrc/nooptimized/two_lg_objects.check diff --git a/examples/flat/nooptimized/two_lg_objects.effekt b/examples/ctrc/nooptimized/two_lg_objects.effekt similarity index 100% rename from examples/flat/nooptimized/two_lg_objects.effekt rename to examples/ctrc/nooptimized/two_lg_objects.effekt diff --git a/examples/flat/nooptimized/two_md_mixed_object.check b/examples/ctrc/nooptimized/two_md_mixed_object.check similarity index 100% rename from examples/flat/nooptimized/two_md_mixed_object.check rename to examples/ctrc/nooptimized/two_md_mixed_object.check diff --git a/examples/flat/nooptimized/two_md_mixed_object.effekt b/examples/ctrc/nooptimized/two_md_mixed_object.effekt similarity index 100% rename from examples/flat/nooptimized/two_md_mixed_object.effekt rename to examples/ctrc/nooptimized/two_md_mixed_object.effekt diff --git a/examples/flat/nooptimized/two_md_objects.check b/examples/ctrc/nooptimized/two_md_objects.check similarity index 100% rename from examples/flat/nooptimized/two_md_objects.check rename to examples/ctrc/nooptimized/two_md_objects.check diff --git a/examples/flat/nooptimized/two_md_objects.effekt b/examples/ctrc/nooptimized/two_md_objects.effekt similarity index 100% rename from examples/flat/nooptimized/two_md_objects.effekt rename to examples/ctrc/nooptimized/two_md_objects.effekt diff --git a/examples/flat/nooptimized/two_slot_one_person_list.check b/examples/ctrc/nooptimized/two_slot_one_person_list.check similarity index 100% rename from examples/flat/nooptimized/two_slot_one_person_list.check rename to examples/ctrc/nooptimized/two_slot_one_person_list.check diff --git a/examples/flat/nooptimized/two_slot_one_person_list.effekt b/examples/ctrc/nooptimized/two_slot_one_person_list.effekt similarity index 100% rename from examples/flat/nooptimized/two_slot_one_person_list.effekt rename to examples/ctrc/nooptimized/two_slot_one_person_list.effekt diff --git a/examples/flat/nooptimized/two_slot_one_person_with_free_variable_list.check b/examples/ctrc/nooptimized/two_slot_one_person_with_free_variable_list.check similarity index 100% rename from examples/flat/nooptimized/two_slot_one_person_with_free_variable_list.check rename to examples/ctrc/nooptimized/two_slot_one_person_with_free_variable_list.check diff --git a/examples/flat/nooptimized/two_slot_one_person_with_free_variable_list.effekt b/examples/ctrc/nooptimized/two_slot_one_person_with_free_variable_list.effekt similarity index 100% rename from examples/flat/nooptimized/two_slot_one_person_with_free_variable_list.effekt rename to examples/ctrc/nooptimized/two_slot_one_person_with_free_variable_list.effekt diff --git a/examples/flat/nooptimized/two_slot_two_person_list.check b/examples/ctrc/nooptimized/two_slot_two_person_list.check similarity index 100% rename from examples/flat/nooptimized/two_slot_two_person_list.check rename to examples/ctrc/nooptimized/two_slot_two_person_list.check diff --git a/examples/flat/nooptimized/two_slot_two_person_list.effekt b/examples/ctrc/nooptimized/two_slot_two_person_list.effekt similarity index 100% rename from examples/flat/nooptimized/two_slot_two_person_list.effekt rename to examples/ctrc/nooptimized/two_slot_two_person_list.effekt diff --git a/examples/flat/nooptimized/two_slot_two_person_list_continuation.check b/examples/ctrc/nooptimized/two_slot_two_person_list_continuation.check similarity index 100% rename from examples/flat/nooptimized/two_slot_two_person_list_continuation.check rename to examples/ctrc/nooptimized/two_slot_two_person_list_continuation.check diff --git a/examples/flat/nooptimized/two_slot_two_person_list_continuation.effekt b/examples/ctrc/nooptimized/two_slot_two_person_list_continuation.effekt similarity index 100% rename from examples/flat/nooptimized/two_slot_two_person_list_continuation.effekt rename to examples/ctrc/nooptimized/two_slot_two_person_list_continuation.effekt diff --git a/examples/flat/nooptimized/two_slot_two_person_list_continuation_allocation.check b/examples/ctrc/nooptimized/two_slot_two_person_list_continuation_allocation.check similarity index 100% rename from examples/flat/nooptimized/two_slot_two_person_list_continuation_allocation.check rename to examples/ctrc/nooptimized/two_slot_two_person_list_continuation_allocation.check diff --git a/examples/flat/nooptimized/two_slot_two_person_list_continuation_allocation.effekt b/examples/ctrc/nooptimized/two_slot_two_person_list_continuation_allocation.effekt similarity index 100% rename from examples/flat/nooptimized/two_slot_two_person_list_continuation_allocation.effekt rename to examples/ctrc/nooptimized/two_slot_two_person_list_continuation_allocation.effekt diff --git a/examples/flat/nooptimized/two_slot_two_person_list_continuation_exhausted.check b/examples/ctrc/nooptimized/two_slot_two_person_list_continuation_exhausted.check similarity index 100% rename from examples/flat/nooptimized/two_slot_two_person_list_continuation_exhausted.check rename to examples/ctrc/nooptimized/two_slot_two_person_list_continuation_exhausted.check diff --git a/examples/flat/nooptimized/two_slot_two_person_list_continuation_exhausted.effekt b/examples/ctrc/nooptimized/two_slot_two_person_list_continuation_exhausted.effekt similarity index 100% rename from examples/flat/nooptimized/two_slot_two_person_list_continuation_exhausted.effekt rename to examples/ctrc/nooptimized/two_slot_two_person_list_continuation_exhausted.effekt diff --git a/examples/flat/nooptimized/two_slot_two_person_list_exhausted.check b/examples/ctrc/nooptimized/two_slot_two_person_list_exhausted.check similarity index 100% rename from examples/flat/nooptimized/two_slot_two_person_list_exhausted.check rename to examples/ctrc/nooptimized/two_slot_two_person_list_exhausted.check diff --git a/examples/flat/nooptimized/two_slot_two_person_list_exhausted.effekt b/examples/ctrc/nooptimized/two_slot_two_person_list_exhausted.effekt similarity index 100% rename from examples/flat/nooptimized/two_slot_two_person_list_exhausted.effekt rename to examples/ctrc/nooptimized/two_slot_two_person_list_exhausted.effekt diff --git a/examples/flat/nooptimized/two_slot_two_person_with_free_variable_list.check b/examples/ctrc/nooptimized/two_slot_two_person_with_free_variable_list.check similarity index 100% rename from examples/flat/nooptimized/two_slot_two_person_with_free_variable_list.check rename to examples/ctrc/nooptimized/two_slot_two_person_with_free_variable_list.check diff --git a/examples/flat/nooptimized/two_slot_two_person_with_free_variable_list.effekt b/examples/ctrc/nooptimized/two_slot_two_person_with_free_variable_list.effekt similarity index 100% rename from examples/flat/nooptimized/two_slot_two_person_with_free_variable_list.effekt rename to examples/ctrc/nooptimized/two_slot_two_person_with_free_variable_list.effekt diff --git a/examples/flat/nooptimized/two_sm_mixed_object.check b/examples/ctrc/nooptimized/two_sm_mixed_object.check similarity index 100% rename from examples/flat/nooptimized/two_sm_mixed_object.check rename to examples/ctrc/nooptimized/two_sm_mixed_object.check diff --git a/examples/flat/nooptimized/two_sm_mixed_object.effekt b/examples/ctrc/nooptimized/two_sm_mixed_object.effekt similarity index 100% rename from examples/flat/nooptimized/two_sm_mixed_object.effekt rename to examples/ctrc/nooptimized/two_sm_mixed_object.effekt diff --git a/examples/flat/nooptimized/two_sm_objects.check b/examples/ctrc/nooptimized/two_sm_objects.check similarity index 100% rename from examples/flat/nooptimized/two_sm_objects.check rename to examples/ctrc/nooptimized/two_sm_objects.check diff --git a/examples/flat/nooptimized/two_sm_objects.effekt b/examples/ctrc/nooptimized/two_sm_objects.effekt similarity index 100% rename from examples/flat/nooptimized/two_sm_objects.effekt rename to examples/ctrc/nooptimized/two_sm_objects.effekt diff --git a/examples/flat/nooptimized/two_xl_objects.check b/examples/ctrc/nooptimized/two_xl_objects.check similarity index 100% rename from examples/flat/nooptimized/two_xl_objects.check rename to examples/ctrc/nooptimized/two_xl_objects.check diff --git a/examples/flat/nooptimized/two_xl_objects.effekt b/examples/ctrc/nooptimized/two_xl_objects.effekt similarity index 100% rename from examples/flat/nooptimized/two_xl_objects.effekt rename to examples/ctrc/nooptimized/two_xl_objects.effekt diff --git a/examples/flat/nooptimized/two_xs_objects.check b/examples/ctrc/nooptimized/two_xs_objects.check similarity index 100% rename from examples/flat/nooptimized/two_xs_objects.check rename to examples/ctrc/nooptimized/two_xs_objects.check diff --git a/examples/flat/nooptimized/two_xs_objects.effekt b/examples/ctrc/nooptimized/two_xs_objects.effekt similarity index 100% rename from examples/flat/nooptimized/two_xs_objects.effekt rename to examples/ctrc/nooptimized/two_xs_objects.effekt diff --git a/examples/flat/nooptimized/two_xxl_object_all_fields.check b/examples/ctrc/nooptimized/two_xxl_object_all_fields.check similarity index 100% rename from examples/flat/nooptimized/two_xxl_object_all_fields.check rename to examples/ctrc/nooptimized/two_xxl_object_all_fields.check diff --git a/examples/flat/nooptimized/two_xxl_object_all_fields.effekt b/examples/ctrc/nooptimized/two_xxl_object_all_fields.effekt similarity index 100% rename from examples/flat/nooptimized/two_xxl_object_all_fields.effekt rename to examples/ctrc/nooptimized/two_xxl_object_all_fields.effekt diff --git a/examples/flat/nooptimized/two_xxl_objects.check b/examples/ctrc/nooptimized/two_xxl_objects.check similarity index 100% rename from examples/flat/nooptimized/two_xxl_objects.check rename to examples/ctrc/nooptimized/two_xxl_objects.check diff --git a/examples/flat/nooptimized/two_xxl_objects.effekt b/examples/ctrc/nooptimized/two_xxl_objects.effekt similarity index 100% rename from examples/flat/nooptimized/two_xxl_objects.effekt rename to examples/ctrc/nooptimized/two_xxl_objects.effekt diff --git a/examples/flat/nooptimized/two_xxxl_objects.check b/examples/ctrc/nooptimized/two_xxxl_objects.check similarity index 100% rename from examples/flat/nooptimized/two_xxxl_objects.check rename to examples/ctrc/nooptimized/two_xxxl_objects.check diff --git a/examples/flat/nooptimized/two_xxxl_objects.effekt b/examples/ctrc/nooptimized/two_xxxl_objects.effekt similarity index 100% rename from examples/flat/nooptimized/two_xxxl_objects.effekt rename to examples/ctrc/nooptimized/two_xxxl_objects.effekt diff --git a/libraries/common/array.effekt b/libraries/common/array.effekt index a2c345c1f..758e7a717 100644 --- a/libraries/common/array.effekt +++ b/libraries/common/array.effekt @@ -19,10 +19,15 @@ extern type Array[T] */ extern llvm """ -define void @array_erase_fields(ptr %array_pointer) { +define void @array_erase(%Object %object) { entry: - %data_pointer = getelementptr inbounds i64, ptr %array_pointer, i64 1 - %size = load i64, ptr %array_pointer, align 8 + ; header of arrays looks like that: rc (0), eraser (1), size (2), data (3) + %size_pointer = getelementptr inbounds i64, ptr %object, i64 2 + %size = load i64, ptr %size_pointer, align 8 + + ; data starts after 3 entries in our object + %data_pointer = getelementptr inbounds ptr, ptr %object, i64 3 + %size_eq_0 = icmp eq i64 %size, 0 br i1 %size_eq_0, label %exit, label %loop loop: @@ -31,11 +36,13 @@ loop: %element_pointer = getelementptr inbounds %Pos, ptr %data_pointer, i64 %loop_phi %element = load %Pos, ptr %element_pointer - call void @erasePositive(%Pos %element) + call void @erasePositive(%Pos %element) ; we erase each child of the array + %inc = add nuw i64 %loop_phi, 1 %cmp = icmp ult i64 %inc, %size br i1 %cmp, label %loop, label %exit exit: + call void @free(%Object %object) ; we delete the array ret void } """ @@ -52,7 +59,7 @@ extern def unsafeAllocate[T](size: Int) at global: Array[T] = %eraser_pointer = getelementptr ptr, ptr %calloc, i64 1 %size_pointer = getelementptr ptr, ptr %calloc, i64 2 store i64 0, ptr %calloc - store ptr @array_erase_fields, ptr %eraser_pointer + store ptr @array_erase, ptr %eraser_pointer store i64 ${size}, ptr %size_pointer %ret_pos = insertvalue %Pos { i64 0, ptr poison }, ptr %calloc, 1 ret %Pos %ret_pos diff --git a/libraries/common/ref.effekt b/libraries/common/ref.effekt index 5d6de8e09..f24e01bbb 100644 --- a/libraries/common/ref.effekt +++ b/libraries/common/ref.effekt @@ -10,9 +10,12 @@ extern js """ """ extern llvm """ -define void @c_ref_erase_field(ptr %0) { - %field = load %Pos, ptr %0, align 8 - tail call void @erasePositive(%Pos %field) +define void @c_ref_erase(%Object %object) { + %headerSize = ptrtoint ptr getelementptr (%Header, ptr null, i64 1) to i64 + %environment = getelementptr i8, ptr %object, i64 %headerSize + %field = load %Pos, ptr %environment, align 8 + call void @free(%Object %object) + call void @erasePositive(%Pos %field) ret void } """ @@ -41,9 +44,9 @@ extern def unsafeAllocate[T]() at global: Ref[T] = %fieldData_pointer = getelementptr ptr, ptr %ref, i64 3 store i64 0, ptr %ref, align 8 - store ptr @c_ref_erase_field, ptr %refEraser, align 8 + store ptr @c_ref_erase, ptr %refEraser, align 8 store i64 0, ptr %fieldTag, align 8 - store ptr null, ptr %fieldData_pointer, align 8 + store ptr null, ptr %fieldData_pointer, align 8 %refWrap = insertvalue %Pos { i64 0, ptr poison }, ptr %ref, 1 ret %Pos %refWrap @@ -62,7 +65,7 @@ extern def ref[T](init: T) at global: Ref[T] = %refField = getelementptr ptr, ptr %ref, i64 2 store i64 0, ptr %ref, align 8 - store ptr @c_ref_erase_field, ptr %refEraser, align 8 + store ptr @c_ref_erase, ptr %refEraser, align 8 store %Pos ${init}, ptr %refField, align 8 %refWrap = insertvalue %Pos { i64 0, ptr poison }, ptr %ref, 1 diff --git a/libraries/llvm/bytearray.c b/libraries/llvm/bytearray.c index 9aa8d9082..e3a1fc766 100644 --- a/libraries/llvm/bytearray.c +++ b/libraries/llvm/bytearray.c @@ -2,11 +2,7 @@ #define EFFEKT_BYTEARRAY_C #include // For memcopy -#include -#include - -extern void* cMalloc(uint8_t size); - +#include /** We represent bytearrays like positive types. * @@ -21,11 +17,13 @@ extern void* cMalloc(uint8_t size); */ -void c_bytearray_erase_noop(void *envPtr) { (void)envPtr; } +void c_bytearray_erase_noop(void* object) { + free(object); +} struct Pos c_bytearray_new(const Int size) { int object_size = sizeof(struct Header) + size; - void *objPtr = cMalloc(object_size); + void *objPtr = malloc(object_size); struct Header *headerPtr = objPtr; *headerPtr = (struct Header) { .rc = 0, .eraser = c_bytearray_erase_noop, }; return (struct Pos) { diff --git a/libraries/llvm/initialize-arena.c b/libraries/llvm/initialize-arena.c new file mode 100644 index 000000000..df635bdce --- /dev/null +++ b/libraries/llvm/initialize-arena.c @@ -0,0 +1,14 @@ +#include + +// Initialize a 4 GiB arena via mmap. +// Does not work in LLVM properly, therefore it is done in C. +void* initializeArena(void) { + return mmap( + NULL, // no specific start adress + 4294967296ULL, // 4 GiB + PROT_READ | PROT_WRITE, // Can read and write + MAP_PRIVATE | MAP_ANONYMOUS, // isolated, clean arena + -1, // No file descriptor + 0 // Offset + ); +} \ No newline at end of file diff --git a/libraries/llvm/main.c b/libraries/llvm/main.c index 89e94309d..70d4c5db9 100644 --- a/libraries/llvm/main.c +++ b/libraries/llvm/main.c @@ -14,6 +14,7 @@ #include "cMalloc.c" #include "io.c" #include "panic.c" +#include "initialize-arena.c" extern void effektMain(); diff --git a/libraries/llvm/rts.ll b/libraries/llvm/rts.ll index a2750eed8..bc5ee758e 100644 --- a/libraries/llvm/rts.ll +++ b/libraries/llvm/rts.ll @@ -93,11 +93,7 @@ %String = type %Pos ; Foreign imports - -declare void @cInitializeMemory() -declare ptr @cMalloc(i64) -declare void @cFree(ptr) -declare ptr @cRealloc(ptr, i64) +declare ptr @initializeArena() declare ptr @malloc(i64) declare void @free(ptr) @@ -124,99 +120,127 @@ declare void @exit(i64) declare void @llvm.assume(i1) -; Prompts +; typedef struct Slot +; { +; struct Slot* next; +; void (*eraser)(void *object); +; } Slot; +%struct.Slot = type { %struct.Slot*, %Eraser } -define private %Prompt @currentPrompt(%Stack %stack) { - %prompt_pointer = getelementptr %StackValue, %Stack %stack, i64 0, i32 3 - %prompt = load %Prompt, ptr %prompt_pointer, !alias.scope !11, !noalias !21 - ret %Prompt %prompt -} +; initializes the todoList with a sentinel slot. +; Sentinel Slot: Fakes a block with a RC=1. It is used to mark the end of the To-Do-List. +; But it is not a real heap-object, because it is not 8-byte aligned. +@freeList = private unnamed_addr global %struct.Slot* null, align 8 +@todoList = private unnamed_addr global %struct.Slot* inttoptr (i64 1 to %struct.Slot*), align 8 +@nextUnusedSlot = private unnamed_addr global i8* null, align 8 ; Pointer to the next unused Slot -define private %Prompt @freshPrompt() { - %promptSize = ptrtoint ptr getelementptr (%PromptValue, ptr null, i64 1) to i64 - %prompt = call %Prompt @malloc(i64 %promptSize) - store %PromptValue zeroinitializer, %Prompt %prompt, !alias.scope !13, !noalias !23 - ret %Prompt %prompt + +; Initializes the memory for our effekt-objects that are created by newObject and deleted by eraseObject. +define private void @initializeMemory() nounwind { +entry: + %startAddress = call noalias ptr @initializeArena() ;How much storage do we allocate at the beginning of a program? =4GB + store i8* %startAddress, i8** @nextUnusedSlot + ret void } -; Garbage collection -; A type for the free list -%struct.Block = type { %struct.Block* } +define private %struct.Slot* @acquire() nounwind { +entry: + %freeHead = load %struct.Slot*, %struct.Slot** @freeList + %isEmpty = icmp eq %struct.Slot* %freeHead, null + br i1 %isEmpty, label %checkTodo, label %freeReuse -@freeList = global %struct.Block* null -@nextUnusedBlock = global i8* null -@endOfChunk = global i8* null -@blockSize = global i64 1024 ; each Block is 1KB +; 1. Fast Path: Reuse block from freeList +freeReuse: + %freeNextPtr = getelementptr %struct.Slot, %struct.Slot* %freeHead, i32 0, i32 0 + %freeNext = load %struct.Slot*, %struct.Slot** %freeNextPtr, align 8 + store %struct.Slot* %freeNext, %struct.Slot** @freeList, align 8 -define private void @initializeMemory() { - ; Step 01: mem = malloc(4294967296) - %mem = call i8* @malloc(i64 4294967296) + ret %struct.Slot* %freeHead - ; Step 02: nextUnusedBlock = mem - store i8* %mem, i8** @nextUnusedBlock +checkTodo: + %todoHead = load %struct.Slot*, %struct.Slot** @todoList + %isSentinel = icmp eq %struct.Slot* %todoHead, inttoptr (i64 1 to %struct.Slot*) + br i1 %isSentinel, label %bumpAlloc, label %todoReuse - ; Step 03: endOfChunk = mem + 4294967296 - %endPtr = getelementptr i8, i8* %mem, i64 4294967296 - store i8* %endPtr, i8** @endOfChunk +; 2. Slot Path: Reuse block from To-Do-List. Here, we have to extra call the eraser to ensure that we can reuse it. +todoReuse: + %todoNextPtr = getelementptr inbounds %struct.Slot, %struct.Slot* %todoHead, i32 0, i32 0 + %todoNext = load %struct.Slot*, %struct.Slot** %todoNextPtr, align 8 + store %struct.Slot* %todoNext, %struct.Slot** @todoList, align 8 - ret void + ; Call eraser + ; reusedSlot->eraser(reusedSlot); + %eraserptr = getelementptr inbounds %struct.Slot, %struct.Slot* %todoHead, i32 0, i32 1 + %eraser = load %Eraser, void (%struct.Slot*)** %eraserptr, align 8, !alias.scope !14, !noalias !24 + tail call void %eraser(%struct.Slot* %todoHead) + + ret %struct.Slot* %todoHead + +; 3. Fallback - Bump Path: We have to allocate a new block. +bumpAlloc: + ; Load nextUnusedBlock + %fresh = load ptr, i8** @nextUnusedSlot, align 8 + + ; Move bump pointer forward by object size + %nextBump = getelementptr i8, ptr %fresh, i8 64 + + store ptr %nextBump, i8** @nextUnusedSlot, align 8 + + ret %struct.Slot* %fresh } -define private %Object @myMalloc(i64 %size) { +; Pushes a slot on the top of the free-List. +define private void @pushOntoFreeList(%struct.Slot* %slot) nounwind { entry: - ; Step 01: Check if the free list pointer is not null - %freeList = load %struct.Block*, %struct.Block** @freeList - %isNull = icmp eq %struct.Block* %freeList, null - br i1 %isNull, label %newAllocate, label %reuse + ; oldHead = freeList + %oldHead = load %struct.Slot*, %struct.Slot** @freeList, align 8 -; In case we can recycle a block from the free list, we do so and jump to the reuse label. -reuse: - ; Step 01: block = freeList - %block = load %struct.Block*, %struct.Block** @freeList + ; ptr->next = oldHead + %nextPtr = getelementptr %struct.Slot, %struct.Slot* %slot, i32 0, i32 0 + store %struct.Slot* %oldHead, %struct.Slot** %nextPtr, align 8 - ; Step 02: freeList = freeList.next - %nextPtr = getelementptr %struct.Block, %struct.Block* %block, i32 0, i32 0 - %nextBlock = load %struct.Block*, %struct.Block** %nextPtr - store %struct.Block* %nextBlock, %struct.Block** @freeList + ; freeList = ptr + store %struct.Slot* %slot, %struct.Slot** @freeList, align 8 - ; Step 03: Return - %ret = bitcast %struct.Block* %block to %Object - ret %Object %ret + ret void +} -; In case we do not have a block to reuse -newAllocate: - %nu = load i8*, i8** @nextUnusedBlock - %end = load i8*, i8** @endOfChunk - %blockSize = load i64, i64* @blockSize +; Pushes a slot on the top of the To-Do-List. +define private void @pushOntoTodoList(%struct.Slot* %slot) nounwind { +entry: + ; oldHead = todoList + %oldHead = load %struct.Slot*, %struct.Slot** @todoList, align 8 - ; block = next_unused - %next_plus = getelementptr i8, i8* %nu, i64 %blockSize - store i8* %next_plus, i8** @nextUnusedBlock + ; ptr->next = oldHead + %nextPtr = getelementptr %struct.Slot, %struct.Slot* %slot, i32 0, i32 0 + store %struct.Slot* %oldHead, %struct.Slot** %nextPtr, align 8 - %ret2 = bitcast i8* %nu to %Object - ret %Object %ret2 + ; todoList = ptr + store %struct.Slot* %slot, %struct.Slot** @todoList, align 8 + ret void } -define private void @myFree(%Object %object) { - ; block = (Block*)object - %block = bitcast %Object %object to %struct.Block* - ; block.next = freeList - %nextField = getelementptr %struct.Block, %struct.Block* %block, i32 0, i32 0 - %freeList = load %struct.Block*, %struct.Block** @freeList - store %struct.Block* %freeList, %struct.Block** %nextField - ; freeList = block - store %struct.Block* %block, %struct.Block** @freeList ; <- fails - ret void +; Prompts + +define private %Prompt @currentPrompt(%Stack %stack) { + %prompt_pointer = getelementptr %StackValue, %Stack %stack, i64 0, i32 3 + %prompt = load %Prompt, ptr %prompt_pointer, !alias.scope !11, !noalias !21 + ret %Prompt %prompt +} + +define private %Prompt @freshPrompt() { + %promptSize = ptrtoint ptr getelementptr (%PromptValue, ptr null, i64 1) to i64 + %prompt = call %Prompt @malloc(i64 %promptSize) + store %PromptValue zeroinitializer, %Prompt %prompt, !alias.scope !13, !noalias !23 + ret %Prompt %prompt } define private %Object @newObject(%Eraser %eraser, i64 %environmentSize) alwaysinline { - %headerSize = ptrtoint ptr getelementptr (%Header, ptr null, i64 1) to i64 - %size = add i64 %environmentSize, %headerSize - %object = call ptr @cMalloc(i64 %size) + %object = call ptr @acquire() %objectReferenceCount = getelementptr %Header, ptr %object, i64 0, i32 0 %objectEraser = getelementptr %Header, ptr %object, i64 0, i32 1 store %ReferenceCount 0, ptr %objectReferenceCount, !alias.scope !14, !noalias !24 @@ -274,9 +298,7 @@ define private void @eraseObject(%Object %object) alwaysinline { free: %objectEraser = getelementptr %Header, ptr %object, i64 0, i32 1 %eraser = load %Eraser, ptr %objectEraser, !alias.scope !14, !noalias !24 - %environment = call %Environment @objectEnvironment(%Object %object) - call void %eraser(%Environment %environment) - call void @cFree(%Object %object) + call void %eraser(%Object %object) br label %done done: From 563f3c6721a3c90082e8576b669d8b39d6ef3cd7 Mon Sep 17 00:00:00 2001 From: Flat Date: Fri, 27 Feb 2026 11:15:02 +0100 Subject: [PATCH 06/27] df: sender_receiver and server_client should work now as well. --- libraries/llvm/io.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/libraries/llvm/io.c b/libraries/llvm/io.c index c33984117..44b4f9e51 100644 --- a/libraries/llvm/io.c +++ b/libraries/llvm/io.c @@ -589,11 +589,11 @@ typedef struct { Stack stack; } Signal; -void c_signal_erase(void *envPtr) { - // envPtr points to a Signal _after_ the eraser, so let's adjust it to point to the beginning. - Signal *signal = (Signal*) (envPtr - offsetof(Signal, state)); +void c_signal_erase(void *object) { + Signal *signal = (Signal*) object; erasePositive(signal->value); if (signal->stack != NULL) { eraseStack(signal->stack); } + free(signal); } struct Pos c_signal_make() { From f21ddfd9f8a3aab6907938f5bcee379c47bed5e1 Mon Sep 17 00:00:00 2001 From: Philipp Schuster Date: Tue, 3 Mar 2026 10:07:11 +0100 Subject: [PATCH 07/27] Delete cMalloc --- libraries/llvm/cMalloc.c | 124 --------------------------------------- libraries/llvm/main.c | 1 - libraries/llvm/rts.ll | 8 +-- 3 files changed, 4 insertions(+), 129 deletions(-) delete mode 100644 libraries/llvm/cMalloc.c diff --git a/libraries/llvm/cMalloc.c b/libraries/llvm/cMalloc.c deleted file mode 100644 index f7dd07c87..000000000 --- a/libraries/llvm/cMalloc.c +++ /dev/null @@ -1,124 +0,0 @@ -#include -#include -#include - -// ----------------------------- -// Strukturdefinition -// ----------------------------- - -/** - * @brief Block-Struktur für die Freelist. - * - * Jeder freie Block zeigt auf den nächsten freien Block. - */ -typedef struct Block { - struct Block* next; -} Block; - -// ----------------------------- -// Globale Variablen -// ----------------------------- - -static Block* freeList = NULL; // Kopf der Freelist -static uint8_t* nextUnusedBlock = NULL; // Zeiger auf nächsten unbenutzten Block -static uint8_t* endOfChunk = NULL; // Ende des allokierten Speichers -static const int blockSize = 1024; // Größe jedes Blocks (1KB) - -// ----------------------------- -// Initialisierung -// ----------------------------- - -/** - * @brief Initialisiert den großen Speicherbereich (4GB). - */ -void cInitializeMemory(void) { - size_t chunkSize = (size_t)4294967296ULL; // 4GB - uint8_t* mem = (uint8_t*)malloc(chunkSize); - if (!mem) { - fprintf(stderr, "malloc() failed!\n"); - exit(1); - } - - nextUnusedBlock = mem; - endOfChunk = mem + chunkSize; - printf("[init] Memory initialized: %p - %p\n", (void*)mem, (void*)endOfChunk); -} - -// ----------------------------- -// Allokator -// ----------------------------- - -/** - * @brief Einfacher Speicher-Allocator. - * - * Wenn die Freelist leer ist, nimmt er den nächsten Block im Chunk. - * Wenn die Freelist nicht leer ist, nimmt er den ersten Eintrag daraus. - * - * @param size Ignoriert in diesem simplen Modell (wir geben immer 1KB). - * @return void* Zeiger auf den allokierten Block. - */ -void* cMalloc(uint8_t size) { - // 1. Falls Freelist leer ist → neuer Block - if (freeList == NULL) { - if (nextUnusedBlock + blockSize > endOfChunk) { - fprintf(stderr, "Out of memory!\n"); - return NULL; - } - - void* block = nextUnusedBlock; - nextUnusedBlock += blockSize; - printf("[malloc] New block: %p\n", block); - return block; - } - - - // 2. Falls Freelist nicht leer ist → wiederverwenden - Block* block = freeList; - freeList = block->next; - printf("[malloc] Reusing block: %p\n", (void*)block); - printf("[malloc] freeList: %p\n", (void*)freeList); - return (void*)block; -// return malloc(size); -} - -// ----------------------------- -// Free-Funktion -// ----------------------------- - -/** - * @brief Gibt einen Block zurück in die Freelist. - * - * @param ptr Zeiger auf den Block. - */ -void cFree(void* ptr) { - if (!ptr) return; - - Block* block = (Block*)ptr; - block->next = freeList; - freeList = block; - - printf("[free] Freed block: %p\n", ptr); -// free(ptr); -} - -void* cRealloc(void* ptr, uint8_t size) { - printf("cRealloc: %p, %d\n", ptr, size); - return realloc(ptr,size); -} - -// ----------------------------- -// Test / Demo -// ----------------------------- - -//int main(void) { -// cInitializeMemory(); -// -// void* a = cMalloc(1024); -// void* b = cMalloc(1024); -// cFree(a); -// void* c = cMalloc(1024); // sollte a wiederverwenden -// cFree(b); -// cFree(c); -// -// return 0; -//} diff --git a/libraries/llvm/main.c b/libraries/llvm/main.c index 70d4c5db9..4d01be3c5 100644 --- a/libraries/llvm/main.c +++ b/libraries/llvm/main.c @@ -11,7 +11,6 @@ #include "types.c" #include "bytearray.c" -#include "cMalloc.c" #include "io.c" #include "panic.c" #include "initialize-arena.c" diff --git a/libraries/llvm/rts.ll b/libraries/llvm/rts.ll index bc5ee758e..cc21752a3 100644 --- a/libraries/llvm/rts.ll +++ b/libraries/llvm/rts.ll @@ -93,8 +93,6 @@ %String = type %Pos ; Foreign imports -declare ptr @initializeArena() - declare ptr @malloc(i64) declare void @free(ptr) declare ptr @realloc(ptr, i64) @@ -119,6 +117,7 @@ declare void @print(i64) declare void @exit(i64) declare void @llvm.assume(i1) +declare ptr @initializeArena() ; typedef struct Slot ; { @@ -138,8 +137,9 @@ declare void @llvm.assume(i1) ; Initializes the memory for our effekt-objects that are created by newObject and deleted by eraseObject. define private void @initializeMemory() nounwind { entry: - %startAddress = call noalias ptr @initializeArena() ;How much storage do we allocate at the beginning of a program? =4GB - store i8* %startAddress, i8** @nextUnusedSlot + ; we need this because flags for mmap differ between platforms + %startAddress = call noalias ptr @initializeArena() + store ptr %startAddress, ptr @nextUnusedSlot ret void } From b2bc845766caec7439e6aac8d2904c47f93d0213 Mon Sep 17 00:00:00 2001 From: Philipp Schuster Date: Tue, 3 Mar 2026 10:34:33 +0100 Subject: [PATCH 08/27] Revise acquire --- libraries/llvm/rts.ll | 72 ++++++++++++++++++++++--------------------- 1 file changed, 37 insertions(+), 35 deletions(-) diff --git a/libraries/llvm/rts.ll b/libraries/llvm/rts.ll index cc21752a3..a88087bc0 100644 --- a/libraries/llvm/rts.ll +++ b/libraries/llvm/rts.ll @@ -124,100 +124,102 @@ declare ptr @initializeArena() ; struct Slot* next; ; void (*eraser)(void *object); ; } Slot; -%struct.Slot = type { %struct.Slot*, %Eraser } +%Slot = type { ptr, %Eraser } +; list of immediately available slots +@freeList = private unnamed_addr global ptr null +; list of slots where we still need to erase the children ; initializes the todoList with a sentinel slot. ; Sentinel Slot: Fakes a block with a RC=1. It is used to mark the end of the To-Do-List. ; But it is not a real heap-object, because it is not 8-byte aligned. -@freeList = private unnamed_addr global %struct.Slot* null, align 8 -@todoList = private unnamed_addr global %struct.Slot* inttoptr (i64 1 to %struct.Slot*), align 8 -@nextUnusedSlot = private unnamed_addr global i8* null, align 8 ; Pointer to the next unused Slot - +@todoList = private unnamed_addr global ptr inttoptr (i64 1 to ptr) +; space of unused consecutive slots +@bumpList = private unnamed_addr global ptr null ; Initializes the memory for our effekt-objects that are created by newObject and deleted by eraseObject. define private void @initializeMemory() nounwind { entry: ; we need this because flags for mmap differ between platforms %startAddress = call noalias ptr @initializeArena() - store ptr %startAddress, ptr @nextUnusedSlot + store ptr %startAddress, ptr @bumpList ret void } -define private %struct.Slot* @acquire() nounwind { +define private ptr @acquire() nounwind { entry: - %freeHead = load %struct.Slot*, %struct.Slot** @freeList - %isEmpty = icmp eq %struct.Slot* %freeHead, null + %freeHead = load ptr, ptr @freeList + %isEmpty = icmp eq ptr %freeHead, null br i1 %isEmpty, label %checkTodo, label %freeReuse ; 1. Fast Path: Reuse block from freeList freeReuse: - %freeNextPtr = getelementptr %struct.Slot, %struct.Slot* %freeHead, i32 0, i32 0 - %freeNext = load %struct.Slot*, %struct.Slot** %freeNextPtr, align 8 - store %struct.Slot* %freeNext, %struct.Slot** @freeList, align 8 + %freeNextPtr = getelementptr %Slot, ptr %freeHead, i32 0, i32 0 + %freeNext = load ptr, ptr %freeNextPtr + store ptr %freeNext, ptr @freeList - ret %struct.Slot* %freeHead + ret ptr %freeHead checkTodo: - %todoHead = load %struct.Slot*, %struct.Slot** @todoList - %isSentinel = icmp eq %struct.Slot* %todoHead, inttoptr (i64 1 to %struct.Slot*) + %todoHead = load ptr, ptr @todoList + %isSentinel = icmp eq ptr %todoHead, inttoptr (i64 1 to ptr) br i1 %isSentinel, label %bumpAlloc, label %todoReuse ; 2. Slot Path: Reuse block from To-Do-List. Here, we have to extra call the eraser to ensure that we can reuse it. todoReuse: - %todoNextPtr = getelementptr inbounds %struct.Slot, %struct.Slot* %todoHead, i32 0, i32 0 - %todoNext = load %struct.Slot*, %struct.Slot** %todoNextPtr, align 8 - store %struct.Slot* %todoNext, %struct.Slot** @todoList, align 8 + %todoNextPtr = getelementptr inbounds %Slot, ptr %todoHead, i32 0, i32 0 + %todoNext = load ptr, ptr %todoNextPtr + store ptr %todoNext, ptr @todoList ; Call eraser ; reusedSlot->eraser(reusedSlot); - %eraserptr = getelementptr inbounds %struct.Slot, %struct.Slot* %todoHead, i32 0, i32 1 - %eraser = load %Eraser, void (%struct.Slot*)** %eraserptr, align 8, !alias.scope !14, !noalias !24 - tail call void %eraser(%struct.Slot* %todoHead) + %eraserPtr = getelementptr inbounds %Slot, ptr %todoHead, i32 0, i32 1 + %eraser = load %Eraser, ptr %eraserPtr, !alias.scope !14, !noalias !24 + call void %eraser(ptr %todoHead) - ret %struct.Slot* %todoHead + ret ptr %todoHead ; 3. Fallback - Bump Path: We have to allocate a new block. bumpAlloc: ; Load nextUnusedBlock - %fresh = load ptr, i8** @nextUnusedSlot, align 8 + %fresh = load ptr, ptr @bumpList ; Move bump pointer forward by object size %nextBump = getelementptr i8, ptr %fresh, i8 64 - store ptr %nextBump, i8** @nextUnusedSlot, align 8 + store ptr %nextBump, ptr @bumpList - ret %struct.Slot* %fresh + ret ptr %fresh } ; Pushes a slot on the top of the free-List. -define private void @pushOntoFreeList(%struct.Slot* %slot) nounwind { +define private void @pushOntoFreeList(ptr %slot) nounwind { entry: ; oldHead = freeList - %oldHead = load %struct.Slot*, %struct.Slot** @freeList, align 8 + %oldHead = load ptr, ptr @freeList ; ptr->next = oldHead - %nextPtr = getelementptr %struct.Slot, %struct.Slot* %slot, i32 0, i32 0 - store %struct.Slot* %oldHead, %struct.Slot** %nextPtr, align 8 + %nextPtr = getelementptr %Slot, ptr %slot, i32 0, i32 0 + store ptr %oldHead, ptr %nextPtr ; freeList = ptr - store %struct.Slot* %slot, %struct.Slot** @freeList, align 8 + store ptr %slot, ptr @freeList ret void } ; Pushes a slot on the top of the To-Do-List. -define private void @pushOntoTodoList(%struct.Slot* %slot) nounwind { +define private void @pushOntoTodoList(ptr %slot) nounwind { entry: ; oldHead = todoList - %oldHead = load %struct.Slot*, %struct.Slot** @todoList, align 8 + %oldHead = load ptr, ptr @todoList ; ptr->next = oldHead - %nextPtr = getelementptr %struct.Slot, %struct.Slot* %slot, i32 0, i32 0 - store %struct.Slot* %oldHead, %struct.Slot** %nextPtr, align 8 + %nextPtr = getelementptr %Slot, ptr %slot, i32 0, i32 0 + store ptr %oldHead, ptr %nextPtr ; todoList = ptr - store %struct.Slot* %slot, %struct.Slot** @todoList, align 8 + store ptr %slot, ptr @todoList ret void } From bad6968a1971842d1c8256da144aebb1d9a80822 Mon Sep 17 00:00:00 2001 From: Philipp Schuster Date: Tue, 3 Mar 2026 10:44:29 +0100 Subject: [PATCH 09/27] Remove imports --- .../scala/effekt/generator/llvm/Transformer.scala | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/effekt/shared/src/main/scala/effekt/generator/llvm/Transformer.scala b/effekt/shared/src/main/scala/effekt/generator/llvm/Transformer.scala index 73edb0bdc..cb26f4c0a 100644 --- a/effekt/shared/src/main/scala/effekt/generator/llvm/Transformer.scala +++ b/effekt/shared/src/main/scala/effekt/generator/llvm/Transformer.scala @@ -2,12 +2,8 @@ package effekt package generator package llvm -import effekt.generator.llvm.Type as LLVMType -import effekt.generator.llvm.Instruction.{Call, Load} -import effekt.generator.llvm.Transformer.{ModuleContext, createReleaseFunction, emit, environmentType, freshName, objectEnvironment} import effekt.machine -import effekt.machine.{Environment, Variable} -import effekt.machine.analysis.* +import effekt.machine.analysis.freeVariables import effekt.util.intercalate import effekt.util.messages.ErrorReporter @@ -1060,12 +1056,12 @@ object Transformer { * It might be that an object consists of several slots. * Each slot is pushed onto the free list. */ - private def createReleasePushOntoFreeListBasicBlock(releaseLabel: String, environment: Environment, freeInBody: Set[machine.Variable], `object`: Operand, environmentRef: LocalReference)(using ModuleContext, FunctionContext, BlockContext): Unit = { + private def createReleasePushOntoFreeListBasicBlock(releaseLabel: String, environment: machine.Environment, freeInBody: Set[machine.Variable], `object`: Operand, environmentRef: LocalReference)(using ModuleContext, FunctionContext, BlockContext): Unit = { val allInstructions = mutable.ListBuffer[Instruction](Call("_", Ccc(), VoidType(), ConstantGlobal("pushOntoFreeList"), List(`object`))) var currentEnvironmentPtr = environmentRef val slottedEnvironment = splitEnvironment(environment) - slottedEnvironment.zipWithIndex.foreach { case (slotEnv: Environment, index: Int) => + slottedEnvironment.zipWithIndex.foreach { case (slotEnv: machine.Environment, index: Int) => val isLastSlot = index == slottedEnvironment.length - 1 val slotEnvTypes = if (isLastSlot) environmentType(slotEnv) else StructureType(slotEnv.map { case machine.Variable(_, t) => transform(t) } :+ positiveType) @@ -1167,7 +1163,7 @@ object Transformer { ), RetVoid())) } - private def createAndEmitEraseChildrenBasicBlock(freshEnvironment: Environment, eraseChildrenLabel: String)(using ModuleContext, FunctionContext): Unit = { + private def createAndEmitEraseChildrenBasicBlock(freshEnvironment: machine.Environment, eraseChildrenLabel: String)(using ModuleContext, FunctionContext): Unit = { val environmentRef = LocalReference(environmentType, freshName("environment")) val eraseChildrenInstructions = mutable.ListBuffer[Instruction]() @@ -1208,7 +1204,7 @@ object Transformer { } } - private def emitElementPtrAndLoadOfEnvironmentVariable(environmentRef: LocalReference, eraseChildrenInstructions: ListBuffer[Instruction], envType: LLVMType, tpe: machine.Type, i: Int, fieldPtr: LocalReference, loadedVarName: String, eraserFunction: ConstantGlobal) = { + private def emitElementPtrAndLoadOfEnvironmentVariable(environmentRef: LocalReference, eraseChildrenInstructions: ListBuffer[Instruction], envType: llvm.Type, tpe: machine.Type, i: Int, fieldPtr: LocalReference, loadedVarName: String, eraserFunction: ConstantGlobal) = { eraseChildrenInstructions += GetElementPtr(fieldPtr.name, envType, environmentRef, List(0, i)) eraseChildrenInstructions += Load(loadedVarName, transform(tpe), fieldPtr, Object) eraseChildrenInstructions += Call("_", Ccc(), VoidType(), eraserFunction, List(LocalReference(transform(tpe), loadedVarName))) From c2689fa7f423f150b35466d8d23c6c2ce8520f53 Mon Sep 17 00:00:00 2001 From: Flat Date: Fri, 10 Oct 2025 14:38:03 +0200 Subject: [PATCH 10/27] Fixed the linking of the uv library for Intel Macbooks --- effekt/jvm/src/main/scala/effekt/Runner.scala | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/effekt/jvm/src/main/scala/effekt/Runner.scala b/effekt/jvm/src/main/scala/effekt/Runner.scala index 5c0c3fe9c..a8ab10cf6 100644 --- a/effekt/jvm/src/main/scala/effekt/Runner.scala +++ b/effekt/jvm/src/main/scala/effekt/Runner.scala @@ -306,9 +306,15 @@ object LLVMRunner extends Runner[String] { def libuvArgs(using C: Context): Seq[String] = val OS = System.getProperty("os.name").toLowerCase + + // only relevant for macOS + val arch: String = System.getProperty("os.arch") + assert(!OS.contains("mac") || List("aarch64", "x86_64").contains(arch), "If you have a macbook -> It should have either an aarch64 or x86_64 architecture.") + val libraries = C.config.clangLibraries.toOption.map(file).orElse { OS match { - case os if os.contains("mac") => Some(file("/opt/homebrew/lib")) + case os if os.contains("mac") && arch.equals("aarch64") => Some(file("/opt/homebrew/lib")) + case os if os.contains("mac") => Some(file("/usr/local/lib")) case os if os.contains("win") => None case os if os.contains("linux") => Some(file("/usr/local/lib")) case os => None @@ -316,7 +322,8 @@ object LLVMRunner extends Runner[String] { } val includes = C.config.clangIncludes.toOption.map(file).orElse { OS match { - case os if os.contains("mac") => Some(file("/opt/homebrew/include")) + case os if os.contains("mac") && arch.equals("aarch64") => Some(file("/opt/homebrew/include")) + case os if os.contains("mac") => Some(file("/usr/local/include")) case os if os.contains("win") => None case os if os.contains("linux") => Some(file("/usr/local/include")) case os => None From 82da493880e908d8171f20065168859d6b4a2b23 Mon Sep 17 00:00:00 2001 From: Flat Date: Fri, 24 Oct 2025 18:39:57 +0200 Subject: [PATCH 11/27] df: Added benchmarks --- .../jvm/src/test/scala/effekt/FlatTests.scala | 24 + ...locate_first_then_release_flush_once.check | 65 + ...ocate_first_then_release_flush_once.effekt | 148 ++ ...ocate_first_then_release_flush_twice.check | 0 ...cate_first_then_release_flush_twice.effekt | 282 +++ examples/flat/nooptimized/array_record.check | 1 + examples/flat/nooptimized/array_record.effekt | 10 + .../flat/nooptimized/array_record_match.check | 1 + .../nooptimized/array_record_match.effekt | 21 + .../array_record_match_exhausted.check | 1 + .../array_record_match_exhausted.effekt | 21 + ...different_person_sizes_biggest_first.check | 3 + ...ifferent_person_sizes_biggest_first.effekt | 46 + ...ifferent_person_sizes_smallest_first.check | 3 + ...fferent_person_sizes_smallest_first.effekt | 46 + .../flat/nooptimized/nested_objects.check | 1 + .../flat/nooptimized/nested_objects.effekt | 16 + .../nooptimized/one_big_string_object.check | 1 + .../nooptimized/one_big_string_object.effekt | 9 + examples/flat/nooptimized/one_lg_object.check | 1 + .../flat/nooptimized/one_lg_object.effekt | 18 + examples/flat/nooptimized/one_md_object.check | 1 + .../flat/nooptimized/one_md_object.effekt | 15 + .../one_slot_one_person_list.check | 1 + .../one_slot_one_person_list.effekt | 27 + examples/flat/nooptimized/one_sm_object.check | 1 + .../flat/nooptimized/one_sm_object.effekt | 14 + .../nooptimized/one_small_string_object.check | 1 + .../one_small_string_object.effekt | 8 + examples/flat/nooptimized/one_xl_object.check | 1 + .../flat/nooptimized/one_xl_object.effekt | 19 + examples/flat/nooptimized/one_xs_object.check | 1 + .../flat/nooptimized/one_xs_object.effekt | 11 + .../one_xxl_object_all_fields.check | 100 ++ .../one_xxl_object_all_fields.effekt | 308 ++++ .../flat/nooptimized/one_xxxl_object.check | 1 + .../flat/nooptimized/one_xxxl_object.effekt | 1008 +++++++++++ examples/flat/nooptimized/primitive_ref.check | 1 + .../flat/nooptimized/primitive_ref.effekt | 9 + examples/flat/nooptimized/ref_allocate.check | 1 + examples/flat/nooptimized/ref_allocate.effekt | 19 + examples/flat/nooptimized/simple_list.check | 1 + examples/flat/nooptimized/simple_list.effekt | 15 + examples/flat/nooptimized/simple_ref.check | 1 + examples/flat/nooptimized/simple_ref.effekt | 20 + examples/flat/nooptimized/superperson.check | 2 + examples/flat/nooptimized/superperson.effekt | 33 + .../nooptimized/superperson_with_free.check | 1 + .../nooptimized/superperson_with_free.effekt | 30 + .../nooptimized/three_md_objects_direct.check | 3 + .../three_md_objects_direct.effekt | 20 + .../nooptimized/trigger_child_freeing.check | 0 .../nooptimized/trigger_child_freeing.effekt | 64 + .../flat/nooptimized/trigger_flush_once.check | 0 .../nooptimized/trigger_flush_once.effekt | 17 + .../nooptimized/trigger_flush_twice.check | 0 .../nooptimized/trigger_flush_twice.effekt | 17 + .../trigger_one_child_freeing.check | 0 .../trigger_one_child_freeing.effekt | 26 + .../trigger_two_child_freeing.check | 0 .../trigger_two_child_freeing.effekt | 28 + .../flat/nooptimized/two_lg_objects.check | 2 + .../flat/nooptimized/two_lg_objects.effekt | 20 + .../nooptimized/two_md_mixed_object.check | 2 + .../nooptimized/two_md_mixed_object.effekt | 17 + .../flat/nooptimized/two_md_objects.check | 2 + .../flat/nooptimized/two_md_objects.effekt | 17 + .../two_slot_one_person_list.check | 1 + .../two_slot_one_person_list.effekt | 23 + ...t_one_person_with_free_variable_list.check | 1 + ..._one_person_with_free_variable_list.effekt | 29 + .../two_slot_two_person_list.check | 1 + .../two_slot_two_person_list.effekt | 24 + ...wo_slot_two_person_list_continuation.check | 1 + ...o_slot_two_person_list_continuation.effekt | 27 + ..._person_list_continuation_allocation.check | 2 + ...person_list_continuation_allocation.effekt | 45 + ...o_person_list_continuation_exhausted.check | 1 + ..._person_list_continuation_exhausted.effekt | 27 + .../two_slot_two_person_list_exhausted.check | 1 + .../two_slot_two_person_list_exhausted.effekt | 24 + ...t_two_person_with_free_variable_list.check | 1 + ..._two_person_with_free_variable_list.effekt | 29 + .../nooptimized/two_sm_mixed_object.check | 2 + .../nooptimized/two_sm_mixed_object.effekt | 15 + .../flat/nooptimized/two_sm_objects.check | 2 + .../flat/nooptimized/two_sm_objects.effekt | 16 + .../flat/nooptimized/two_xl_objects.check | 2 + .../flat/nooptimized/two_xl_objects.effekt | 21 + .../flat/nooptimized/two_xs_objects.check | 2 + .../flat/nooptimized/two_xs_objects.effekt | 13 + .../two_xxl_object_all_fields.check | 100 ++ .../two_xxl_object_all_fields.effekt | 308 ++++ .../flat/nooptimized/two_xxl_objects.check | 2 + .../flat/nooptimized/two_xxl_objects.effekt | 312 ++++ .../flat/nooptimized/two_xxxl_objects.check | 2 + .../flat/nooptimized/two_xxxl_objects.effekt | 1512 +++++++++++++++++ 97 files changed, 5149 insertions(+) create mode 100644 effekt/jvm/src/test/scala/effekt/FlatTests.scala create mode 100644 examples/flat/nooptimized/allocate_first_then_release_flush_once.check create mode 100644 examples/flat/nooptimized/allocate_first_then_release_flush_once.effekt create mode 100644 examples/flat/nooptimized/allocate_first_then_release_flush_twice.check create mode 100644 examples/flat/nooptimized/allocate_first_then_release_flush_twice.effekt create mode 100644 examples/flat/nooptimized/array_record.check create mode 100644 examples/flat/nooptimized/array_record.effekt create mode 100644 examples/flat/nooptimized/array_record_match.check create mode 100644 examples/flat/nooptimized/array_record_match.effekt create mode 100644 examples/flat/nooptimized/array_record_match_exhausted.check create mode 100644 examples/flat/nooptimized/array_record_match_exhausted.effekt create mode 100644 examples/flat/nooptimized/different_person_sizes_biggest_first.check create mode 100644 examples/flat/nooptimized/different_person_sizes_biggest_first.effekt create mode 100644 examples/flat/nooptimized/different_person_sizes_smallest_first.check create mode 100644 examples/flat/nooptimized/different_person_sizes_smallest_first.effekt create mode 100644 examples/flat/nooptimized/nested_objects.check create mode 100644 examples/flat/nooptimized/nested_objects.effekt create mode 100644 examples/flat/nooptimized/one_big_string_object.check create mode 100644 examples/flat/nooptimized/one_big_string_object.effekt create mode 100644 examples/flat/nooptimized/one_lg_object.check create mode 100644 examples/flat/nooptimized/one_lg_object.effekt create mode 100644 examples/flat/nooptimized/one_md_object.check create mode 100644 examples/flat/nooptimized/one_md_object.effekt create mode 100644 examples/flat/nooptimized/one_slot_one_person_list.check create mode 100644 examples/flat/nooptimized/one_slot_one_person_list.effekt create mode 100644 examples/flat/nooptimized/one_sm_object.check create mode 100644 examples/flat/nooptimized/one_sm_object.effekt create mode 100644 examples/flat/nooptimized/one_small_string_object.check create mode 100644 examples/flat/nooptimized/one_small_string_object.effekt create mode 100644 examples/flat/nooptimized/one_xl_object.check create mode 100644 examples/flat/nooptimized/one_xl_object.effekt create mode 100644 examples/flat/nooptimized/one_xs_object.check create mode 100644 examples/flat/nooptimized/one_xs_object.effekt create mode 100644 examples/flat/nooptimized/one_xxl_object_all_fields.check create mode 100644 examples/flat/nooptimized/one_xxl_object_all_fields.effekt create mode 100644 examples/flat/nooptimized/one_xxxl_object.check create mode 100644 examples/flat/nooptimized/one_xxxl_object.effekt create mode 100644 examples/flat/nooptimized/primitive_ref.check create mode 100644 examples/flat/nooptimized/primitive_ref.effekt create mode 100644 examples/flat/nooptimized/ref_allocate.check create mode 100644 examples/flat/nooptimized/ref_allocate.effekt create mode 100644 examples/flat/nooptimized/simple_list.check create mode 100644 examples/flat/nooptimized/simple_list.effekt create mode 100644 examples/flat/nooptimized/simple_ref.check create mode 100644 examples/flat/nooptimized/simple_ref.effekt create mode 100644 examples/flat/nooptimized/superperson.check create mode 100644 examples/flat/nooptimized/superperson.effekt create mode 100644 examples/flat/nooptimized/superperson_with_free.check create mode 100644 examples/flat/nooptimized/superperson_with_free.effekt create mode 100644 examples/flat/nooptimized/three_md_objects_direct.check create mode 100644 examples/flat/nooptimized/three_md_objects_direct.effekt create mode 100644 examples/flat/nooptimized/trigger_child_freeing.check create mode 100644 examples/flat/nooptimized/trigger_child_freeing.effekt create mode 100644 examples/flat/nooptimized/trigger_flush_once.check create mode 100644 examples/flat/nooptimized/trigger_flush_once.effekt create mode 100644 examples/flat/nooptimized/trigger_flush_twice.check create mode 100644 examples/flat/nooptimized/trigger_flush_twice.effekt create mode 100644 examples/flat/nooptimized/trigger_one_child_freeing.check create mode 100644 examples/flat/nooptimized/trigger_one_child_freeing.effekt create mode 100644 examples/flat/nooptimized/trigger_two_child_freeing.check create mode 100644 examples/flat/nooptimized/trigger_two_child_freeing.effekt create mode 100644 examples/flat/nooptimized/two_lg_objects.check create mode 100644 examples/flat/nooptimized/two_lg_objects.effekt create mode 100644 examples/flat/nooptimized/two_md_mixed_object.check create mode 100644 examples/flat/nooptimized/two_md_mixed_object.effekt create mode 100644 examples/flat/nooptimized/two_md_objects.check create mode 100644 examples/flat/nooptimized/two_md_objects.effekt create mode 100644 examples/flat/nooptimized/two_slot_one_person_list.check create mode 100644 examples/flat/nooptimized/two_slot_one_person_list.effekt create mode 100644 examples/flat/nooptimized/two_slot_one_person_with_free_variable_list.check create mode 100644 examples/flat/nooptimized/two_slot_one_person_with_free_variable_list.effekt create mode 100644 examples/flat/nooptimized/two_slot_two_person_list.check create mode 100644 examples/flat/nooptimized/two_slot_two_person_list.effekt create mode 100644 examples/flat/nooptimized/two_slot_two_person_list_continuation.check create mode 100644 examples/flat/nooptimized/two_slot_two_person_list_continuation.effekt create mode 100644 examples/flat/nooptimized/two_slot_two_person_list_continuation_allocation.check create mode 100644 examples/flat/nooptimized/two_slot_two_person_list_continuation_allocation.effekt create mode 100644 examples/flat/nooptimized/two_slot_two_person_list_continuation_exhausted.check create mode 100644 examples/flat/nooptimized/two_slot_two_person_list_continuation_exhausted.effekt create mode 100644 examples/flat/nooptimized/two_slot_two_person_list_exhausted.check create mode 100644 examples/flat/nooptimized/two_slot_two_person_list_exhausted.effekt create mode 100644 examples/flat/nooptimized/two_slot_two_person_with_free_variable_list.check create mode 100644 examples/flat/nooptimized/two_slot_two_person_with_free_variable_list.effekt create mode 100644 examples/flat/nooptimized/two_sm_mixed_object.check create mode 100644 examples/flat/nooptimized/two_sm_mixed_object.effekt create mode 100644 examples/flat/nooptimized/two_sm_objects.check create mode 100644 examples/flat/nooptimized/two_sm_objects.effekt create mode 100644 examples/flat/nooptimized/two_xl_objects.check create mode 100644 examples/flat/nooptimized/two_xl_objects.effekt create mode 100644 examples/flat/nooptimized/two_xs_objects.check create mode 100644 examples/flat/nooptimized/two_xs_objects.effekt create mode 100644 examples/flat/nooptimized/two_xxl_object_all_fields.check create mode 100644 examples/flat/nooptimized/two_xxl_object_all_fields.effekt create mode 100644 examples/flat/nooptimized/two_xxl_objects.check create mode 100644 examples/flat/nooptimized/two_xxl_objects.effekt create mode 100644 examples/flat/nooptimized/two_xxxl_objects.check create mode 100644 examples/flat/nooptimized/two_xxxl_objects.effekt diff --git a/effekt/jvm/src/test/scala/effekt/FlatTests.scala b/effekt/jvm/src/test/scala/effekt/FlatTests.scala new file mode 100644 index 000000000..c0c0f6e5c --- /dev/null +++ b/effekt/jvm/src/test/scala/effekt/FlatTests.scala @@ -0,0 +1,24 @@ +package effekt + +import sbt.io.* +import sbt.io.syntax.* + +import java.io.File +import scala.language.implicitConversions +import scala.sys.process.Process + +// df: My own test class to run my requested tests automatically +class FlatTests extends EffektTests { + + def backendName = "llvm" + + override def valgrind = false // works on linux only + + override lazy val positives: Set[File] = Set( + examplesDir / "flat" / "optimized" + ) + + override lazy val withoutOptimizations: Set[File] = Set( + examplesDir / "flat" / "nooptimized", + ) +} diff --git a/examples/flat/nooptimized/allocate_first_then_release_flush_once.check b/examples/flat/nooptimized/allocate_first_then_release_flush_once.check new file mode 100644 index 000000000..90fa4d6e3 --- /dev/null +++ b/examples/flat/nooptimized/allocate_first_then_release_flush_once.check @@ -0,0 +1,65 @@ +1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +11 +12 +13 +14 +15 +16 +17 +18 +19 +20 +21 +22 +23 +24 +25 +26 +27 +28 +29 +30 +31 +32 +33 +34 +35 +36 +37 +38 +39 +40 +41 +42 +43 +44 +45 +46 +47 +48 +49 +50 +51 +52 +53 +54 +55 +56 +57 +58 +59 +60 +61 +62 +63 +64 +65 \ No newline at end of file diff --git a/examples/flat/nooptimized/allocate_first_then_release_flush_once.effekt b/examples/flat/nooptimized/allocate_first_then_release_flush_once.effekt new file mode 100644 index 000000000..4d1f729a1 --- /dev/null +++ b/examples/flat/nooptimized/allocate_first_then_release_flush_once.effekt @@ -0,0 +1,148 @@ + +record OneSlotPerson( + field1: Int, + field2: Int, + field3: Int, + field4: Int, + field5: Int, + field6: Int +) + +def allocate65SlotsAndReleaseThem() = { + var x1 = OneSlotPerson(1, 2, 3, 4, 5, 6) + var x2 = OneSlotPerson(2, 3, 4, 5, 6, 7) + var x3 = OneSlotPerson(3, 4, 5, 6, 7, 8) + var x4 = OneSlotPerson(4, 5, 6, 7, 8, 9) + var x5 = OneSlotPerson(5, 6, 7, 8, 9, 10) + var x6 = OneSlotPerson(6, 7, 8, 9, 10, 11) + var x7 = OneSlotPerson(7, 8, 9, 10, 11, 12) + var x8 = OneSlotPerson(8, 9, 10, 11, 12, 13) + var x9 = OneSlotPerson(9, 10, 11, 12, 13, 14) + var x10 = OneSlotPerson(10, 11, 12, 13, 14, 15) + var x11 = OneSlotPerson(11, 12, 13, 14, 15, 16) + var x12 = OneSlotPerson(12, 13, 14, 15, 16, 17) + var x13 = OneSlotPerson(13, 14, 15, 16, 17, 18) + var x14 = OneSlotPerson(14, 15, 16, 17, 18, 19) + var x15 = OneSlotPerson(15, 16, 17, 18, 19, 20) + var x16 = OneSlotPerson(16, 17, 18, 19, 20, 21) + var x17 = OneSlotPerson(17, 18, 19, 20, 21, 22) + var x18 = OneSlotPerson(18, 19, 20, 21, 22, 23) + var x19 = OneSlotPerson(19, 20, 21, 22, 23, 24) + var x20 = OneSlotPerson(20, 21, 22, 23, 24, 25) + var x21 = OneSlotPerson(21, 22, 23, 24, 25, 26) + var x22 = OneSlotPerson(22, 23, 24, 25, 26, 27) + var x23 = OneSlotPerson(23, 24, 25, 26, 27, 28) + var x24 = OneSlotPerson(24, 25, 26, 27, 28, 29) + var x25 = OneSlotPerson(25, 26, 27, 28, 29, 30) + var x26 = OneSlotPerson(26, 27, 28, 29, 30, 31) + var x27 = OneSlotPerson(27, 28, 29, 30, 31, 32) + var x28 = OneSlotPerson(28, 29, 30, 31, 32, 33) + var x29 = OneSlotPerson(29, 30, 31, 32, 33, 34) + var x30 = OneSlotPerson(30, 31, 32, 33, 34, 35) + var x31 = OneSlotPerson(31, 32, 33, 34, 35, 36) + var x32 = OneSlotPerson(32, 33, 34, 35, 36, 37) + var x33 = OneSlotPerson(33, 34, 35, 36, 37, 38) + var x34 = OneSlotPerson(34, 35, 36, 37, 38, 39) + var x35 = OneSlotPerson(35, 36, 37, 38, 39, 40) + var x36 = OneSlotPerson(36, 37, 38, 39, 40, 41) + var x37 = OneSlotPerson(37, 38, 39, 40, 41, 42) + var x38 = OneSlotPerson(38, 39, 40, 41, 42, 43) + var x39 = OneSlotPerson(39, 40, 41, 42, 43, 44) + var x40 = OneSlotPerson(40, 41, 42, 43, 44, 45) + var x41 = OneSlotPerson(41, 42, 43, 44, 45, 46) + var x42 = OneSlotPerson(42, 43, 44, 45, 46, 47) + var x43 = OneSlotPerson(43, 44, 45, 46, 47, 48) + var x44 = OneSlotPerson(44, 45, 46, 47, 48, 49) + var x45 = OneSlotPerson(45, 46, 47, 48, 49, 50) + var x46 = OneSlotPerson(46, 47, 48, 49, 50, 51) + var x47 = OneSlotPerson(47, 48, 49, 50, 51, 52) + var x48 = OneSlotPerson(48, 49, 50, 51, 52, 53) + var x49 = OneSlotPerson(49, 50, 51, 52, 53, 54) + var x50 = OneSlotPerson(50, 51, 52, 53, 54, 55) + var x51 = OneSlotPerson(51, 52, 53, 54, 55, 56) + var x52 = OneSlotPerson(52, 53, 54, 55, 56, 57) + var x53 = OneSlotPerson(53, 54, 55, 56, 57, 58) + var x54 = OneSlotPerson(54, 55, 56, 57, 58, 59) + var x55 = OneSlotPerson(55, 56, 57, 58, 59, 60) + var x56 = OneSlotPerson(56, 57, 58, 59, 60, 61) + var x57 = OneSlotPerson(57, 58, 59, 60, 61, 62) + var x58 = OneSlotPerson(58, 59, 60, 61, 62, 63) + var x59 = OneSlotPerson(59, 60, 61, 62, 63, 64) + var x60 = OneSlotPerson(60, 61, 62, 63, 64, 65) + var x61 = OneSlotPerson(61, 62, 63, 64, 65, 66) + var x62 = OneSlotPerson(62, 63, 64, 65, 66, 67) + var x63 = OneSlotPerson(63, 64, 65, 66, 67, 68) + var x64 = OneSlotPerson(64, 65, 66, 67, 68, 69) + var x65 = OneSlotPerson(65, 66, 67, 68, 69, 70) + + println(x1.field1) + println(x2.field1) + println(x3.field1) + println(x4.field1) + println(x5.field1) + println(x6.field1) + println(x7.field1) + println(x8.field1) + println(x9.field1) + println(x10.field1) + println(x11.field1) + println(x12.field1) + println(x13.field1) + println(x14.field1) + println(x15.field1) + println(x16.field1) + println(x17.field1) + println(x18.field1) + println(x19.field1) + println(x20.field1) + println(x21.field1) + println(x22.field1) + println(x23.field1) + println(x24.field1) + println(x25.field1) + println(x26.field1) + println(x27.field1) + println(x28.field1) + println(x29.field1) + println(x30.field1) + println(x31.field1) + println(x32.field1) + println(x33.field1) + println(x34.field1) + println(x35.field1) + println(x36.field1) + println(x37.field1) + println(x38.field1) + println(x39.field1) + println(x40.field1) + println(x41.field1) + println(x42.field1) + println(x43.field1) + println(x44.field1) + println(x45.field1) + println(x46.field1) + println(x47.field1) + println(x48.field1) + println(x49.field1) + println(x50.field1) + println(x51.field1) + println(x52.field1) + println(x53.field1) + println(x54.field1) + println(x55.field1) + println(x56.field1) + println(x57.field1) + println(x58.field1) + println(x59.field1) + println(x60.field1) + println(x61.field1) + println(x62.field1) + println(x63.field1) + println(x64.field1) + println(x65.field1) +} + +def main() = { + allocate65SlotsAndReleaseThem(); + var finalObjectThatTriggersFlushingTodoList = OneSlotPerson(1, 2, 3, 4, 5, 6) +} diff --git a/examples/flat/nooptimized/allocate_first_then_release_flush_twice.check b/examples/flat/nooptimized/allocate_first_then_release_flush_twice.check new file mode 100644 index 000000000..e69de29bb diff --git a/examples/flat/nooptimized/allocate_first_then_release_flush_twice.effekt b/examples/flat/nooptimized/allocate_first_then_release_flush_twice.effekt new file mode 100644 index 000000000..d9b4ccbb5 --- /dev/null +++ b/examples/flat/nooptimized/allocate_first_then_release_flush_twice.effekt @@ -0,0 +1,282 @@ + +record OneSlotPerson( + field1: Int, + field2: Int, + field3: Int, + field4: Int, + field5: Int, + field6: Int +) + +// we first allocate 128 slots and then release them all, such that we have exactly 128 slots on the to-do-list +// therefore, we have to flush the to-do list twice to clear it completely +def allocate128SlotsAndReleaseThem() = { + var x1 = OneSlotPerson(1, 2, 3, 4, 5, 6) + var x2 = OneSlotPerson(2, 3, 4, 5, 6, 7) + var x3 = OneSlotPerson(3, 4, 5, 6, 7, 8) + var x4 = OneSlotPerson(4, 5, 6, 7, 8, 9) + var x5 = OneSlotPerson(5, 6, 7, 8, 9, 10) + var x6 = OneSlotPerson(6, 7, 8, 9, 10, 11) + var x7 = OneSlotPerson(7, 8, 9, 10, 11, 12) + var x8 = OneSlotPerson(8, 9, 10, 11, 12, 13) + var x9 = OneSlotPerson(9, 10, 11, 12, 13, 14) + var x10 = OneSlotPerson(10, 11, 12, 13, 14, 15) + var x11 = OneSlotPerson(11, 12, 13, 14, 15, 16) + var x12 = OneSlotPerson(12, 13, 14, 15, 16, 17) + var x13 = OneSlotPerson(13, 14, 15, 16, 17, 18) + var x14 = OneSlotPerson(14, 15, 16, 17, 18, 19) + var x15 = OneSlotPerson(15, 16, 17, 18, 19, 20) + var x16 = OneSlotPerson(16, 17, 18, 19, 20, 21) + var x17 = OneSlotPerson(17, 18, 19, 20, 21, 22) + var x18 = OneSlotPerson(18, 19, 20, 21, 22, 23) + var x19 = OneSlotPerson(19, 20, 21, 22, 23, 24) + var x20 = OneSlotPerson(20, 21, 22, 23, 24, 25) + var x21 = OneSlotPerson(21, 22, 23, 24, 25, 26) + var x22 = OneSlotPerson(22, 23, 24, 25, 26, 27) + var x23 = OneSlotPerson(23, 24, 25, 26, 27, 28) + var x24 = OneSlotPerson(24, 25, 26, 27, 28, 29) + var x25 = OneSlotPerson(25, 26, 27, 28, 29, 30) + var x26 = OneSlotPerson(26, 27, 28, 29, 30, 31) + var x27 = OneSlotPerson(27, 28, 29, 30, 31, 32) + var x28 = OneSlotPerson(28, 29, 30, 31, 32, 33) + var x29 = OneSlotPerson(29, 30, 31, 32, 33, 34) + var x30 = OneSlotPerson(30, 31, 32, 33, 34, 35) + var x31 = OneSlotPerson(31, 32, 33, 34, 35, 36) + var x32 = OneSlotPerson(32, 33, 34, 35, 36, 37) + var x33 = OneSlotPerson(33, 34, 35, 36, 37, 38) + var x34 = OneSlotPerson(34, 35, 36, 37, 38, 39) + var x35 = OneSlotPerson(35, 36, 37, 38, 39, 40) + var x36 = OneSlotPerson(36, 37, 38, 39, 40, 41) + var x37 = OneSlotPerson(37, 38, 39, 40, 41, 42) + var x38 = OneSlotPerson(38, 39, 40, 41, 42, 43) + var x39 = OneSlotPerson(39, 40, 41, 42, 43, 44) + var x40 = OneSlotPerson(40, 41, 42, 43, 44, 45) + var x41 = OneSlotPerson(41, 42, 43, 44, 45, 46) + var x42 = OneSlotPerson(42, 43, 44, 45, 46, 47) + var x43 = OneSlotPerson(43, 44, 45, 46, 47, 48) + var x44 = OneSlotPerson(44, 45, 46, 47, 48, 49) + var x45 = OneSlotPerson(45, 46, 47, 48, 49, 50) + var x46 = OneSlotPerson(46, 47, 48, 49, 50, 51) + var x47 = OneSlotPerson(47, 48, 49, 50, 51, 52) + var x48 = OneSlotPerson(48, 49, 50, 51, 52, 53) + var x49 = OneSlotPerson(49, 50, 51, 52, 53, 54) + var x50 = OneSlotPerson(50, 51, 52, 53, 54, 55) + var x51 = OneSlotPerson(51, 52, 53, 54, 55, 56) + var x52 = OneSlotPerson(52, 53, 54, 55, 56, 57) + var x53 = OneSlotPerson(53, 54, 55, 56, 57, 58) + var x54 = OneSlotPerson(54, 55, 56, 57, 58, 59) + var x55 = OneSlotPerson(55, 56, 57, 58, 59, 60) + var x56 = OneSlotPerson(56, 57, 58, 59, 60, 61) + var x57 = OneSlotPerson(57, 58, 59, 60, 61, 62) + var x58 = OneSlotPerson(58, 59, 60, 61, 62, 63) + var x59 = OneSlotPerson(59, 60, 61, 62, 63, 64) + var x60 = OneSlotPerson(60, 61, 62, 63, 64, 65) + var x61 = OneSlotPerson(61, 62, 63, 64, 65, 66) + var x62 = OneSlotPerson(62, 63, 64, 65, 66, 67) + var x63 = OneSlotPerson(63, 64, 65, 66, 67, 68) + var x64 = OneSlotPerson(64, 65, 66, 67, 68, 69) + var x65 = OneSlotPerson(65, 66, 67, 68, 69, 70) + var x66 = OneSlotPerson(66, 67, 68, 69, 70, 71) + var x67 = OneSlotPerson(67, 68, 69, 70, 71, 72) + var x68 = OneSlotPerson(68, 69, 70, 71, 72, 73) + var x69 = OneSlotPerson(69, 70, 71, 72, 73, 74) + var x70 = OneSlotPerson(70, 71, 72, 73, 74, 75) + var x71 = OneSlotPerson(71, 72, 73, 74, 75, 76) + var x72 = OneSlotPerson(72, 73, 74, 75, 76, 77) + var x73 = OneSlotPerson(73, 74, 75, 76, 77, 78) + var x74 = OneSlotPerson(74, 75, 76, 77, 78, 79) + var x75 = OneSlotPerson(75, 76, 77, 78, 79, 80) + var x76 = OneSlotPerson(76, 77, 78, 79, 80, 81) + var x77 = OneSlotPerson(77, 78, 79, 80, 81, 82) + var x78 = OneSlotPerson(78, 79, 80, 81, 82, 83) + var x79 = OneSlotPerson(79, 80, 81, 82, 83, 84) + var x80 = OneSlotPerson(80, 81, 82, 83, 84, 85) + var x81 = OneSlotPerson(81, 82, 83, 84, 85, 86) + var x82 = OneSlotPerson(82, 83, 84, 85, 86, 87) + var x83 = OneSlotPerson(83, 84, 85, 86, 87, 88) + var x84 = OneSlotPerson(84, 85, 86, 87, 88, 89) + var x85 = OneSlotPerson(85, 86, 87, 88, 89, 90) + var x86 = OneSlotPerson(86, 87, 88, 89, 90, 91) + var x87 = OneSlotPerson(87, 88, 89, 90, 91, 92) + var x88 = OneSlotPerson(88, 89, 90, 91, 92, 93) + var x89 = OneSlotPerson(89, 90, 91, 92, 93, 94) + var x90 = OneSlotPerson(90, 91, 92, 93, 94, 95) + var x91 = OneSlotPerson(91, 92, 93, 94, 95, 96) + var x92 = OneSlotPerson(92, 93, 94, 95, 96, 97) + var x93 = OneSlotPerson(93, 94, 95, 96, 97, 98) + var x94 = OneSlotPerson(94, 95, 96, 97, 98, 99) + var x95 = OneSlotPerson(95, 96, 97, 98, 99, 100) + var x96 = OneSlotPerson(96, 97, 98, 99, 100, 101) + var x97 = OneSlotPerson(97, 98, 99, 100, 101, 102) + var x98 = OneSlotPerson(98, 99, 100, 101, 102, 103) + var x99 = OneSlotPerson(99, 100, 101, 102, 103, 104) + var x100 = OneSlotPerson(100, 101, 102, 103, 104, 105) + var x101 = OneSlotPerson(101, 102, 103, 104, 105, 106) + var x102 = OneSlotPerson(102, 103, 104, 105, 106, 107) + var x103 = OneSlotPerson(103, 104, 105, 106, 107, 108) + var x104 = OneSlotPerson(104, 105, 106, 107, 108, 109) + var x105 = OneSlotPerson(105, 106, 107, 108, 109, 110) + var x106 = OneSlotPerson(106, 107, 108, 109, 110, 111) + var x107 = OneSlotPerson(107, 108, 109, 110, 111, 112) + var x108 = OneSlotPerson(108, 109, 110, 111, 112, 113) + var x109 = OneSlotPerson(109, 110, 111, 112, 113, 114) + var x110 = OneSlotPerson(110, 111, 112, 113, 114, 115) + var x111 = OneSlotPerson(111, 112, 113, 114, 115, 116) + var x112 = OneSlotPerson(112, 113, 114, 115, 116, 117) + var x113 = OneSlotPerson(113, 114, 115, 116, 117, 118) + var x114 = OneSlotPerson(114, 115, 116, 117, 118, 119) + var x115 = OneSlotPerson(115, 116, 117, 118, 119, 120) + var x116 = OneSlotPerson(116, 117, 118, 119, 120, 121) + var x117 = OneSlotPerson(117, 118, 119, 120, 121, 122) + var x118 = OneSlotPerson(118, 119, 120, 121, 122, 123) + var x119 = OneSlotPerson(119, 120, 121, 122, 123, 124) + var x120 = OneSlotPerson(120, 121, 122, 123, 124, 125) + var x121 = OneSlotPerson(121, 122, 123, 124, 125, 126) + var x122 = OneSlotPerson(122, 123, 124, 125, 126, 127) + var x123 = OneSlotPerson(123, 124, 125, 126, 127, 128) + var x124 = OneSlotPerson(124, 125, 126, 127, 128, 129) + var x125 = OneSlotPerson(125, 126, 127, 128, 129, 130) + var x126 = OneSlotPerson(126, 127, 128, 129, 130, 131) + var x127 = OneSlotPerson(127, 128, 129, 130, 131, 132) + var x128 = OneSlotPerson(128, 129, 130, 131, 132, 133) + + println(x1.field1) + println(x2.field1) + println(x3.field1) + println(x4.field1) + println(x5.field1) + println(x6.field1) + println(x7.field1) + println(x8.field1) + println(x9.field1) + println(x10.field1) + println(x11.field1) + println(x12.field1) + println(x13.field1) + println(x14.field1) + println(x15.field1) + println(x16.field1) + println(x17.field1) + println(x18.field1) + println(x19.field1) + println(x20.field1) + println(x21.field1) + println(x22.field1) + println(x23.field1) + println(x24.field1) + println(x25.field1) + println(x26.field1) + println(x27.field1) + println(x28.field1) + println(x29.field1) + println(x30.field1) + println(x31.field1) + println(x32.field1) + println(x33.field1) + println(x34.field1) + println(x35.field1) + println(x36.field1) + println(x37.field1) + println(x38.field1) + println(x39.field1) + println(x40.field1) + println(x41.field1) + println(x42.field1) + println(x43.field1) + println(x44.field1) + println(x45.field1) + println(x46.field1) + println(x47.field1) + println(x48.field1) + println(x49.field1) + println(x50.field1) + println(x51.field1) + println(x52.field1) + println(x53.field1) + println(x54.field1) + println(x55.field1) + println(x56.field1) + println(x57.field1) + println(x58.field1) + println(x59.field1) + println(x60.field1) + println(x61.field1) + println(x62.field1) + println(x63.field1) + println(x64.field1) + println(x65.field1) + println(x66.field1) + println(x67.field1) + println(x68.field1) + println(x69.field1) + println(x70.field1) + println(x71.field1) + println(x72.field1) + println(x73.field1) + println(x74.field1) + println(x75.field1) + println(x76.field1) + println(x77.field1) + println(x78.field1) + println(x79.field1) + println(x80.field1) + println(x81.field1) + println(x82.field1) + println(x83.field1) + println(x84.field1) + println(x85.field1) + println(x86.field1) + println(x87.field1) + println(x88.field1) + println(x89.field1) + println(x90.field1) + println(x91.field1) + println(x92.field1) + println(x93.field1) + println(x94.field1) + println(x95.field1) + println(x96.field1) + println(x97.field1) + println(x98.field1) + println(x99.field1) + println(x100.field1) + println(x101.field1) + println(x102.field1) + println(x103.field1) + println(x104.field1) + println(x105.field1) + println(x106.field1) + println(x107.field1) + println(x108.field1) + println(x109.field1) + println(x110.field1) + println(x111.field1) + println(x112.field1) + println(x113.field1) + println(x114.field1) + println(x115.field1) + println(x116.field1) + println(x117.field1) + println(x118.field1) + println(x119.field1) + println(x120.field1) + println(x121.field1) + println(x122.field1) + println(x123.field1) + println(x124.field1) + println(x125.field1) + println(x126.field1) + println(x127.field1) + println(x128.field1) +} + +def main() = { + //allocate128SlotsAndReleaseThem(); + // allocate & flush to-do list twice + //var flushingTodoListFirstTime = OneSlotPerson(1, 2, 3, 4, 5, 6) + //var flushingTodoListSecondTime = OneSlotPerson(1, 2, 3, 4, 5, 7) + + // deallocate again + //println(flushingTodoListFirstTime.field1) + //println(flushingTodoListSecondTime.field1) +} diff --git a/examples/flat/nooptimized/array_record.check b/examples/flat/nooptimized/array_record.check new file mode 100644 index 000000000..56ea89185 --- /dev/null +++ b/examples/flat/nooptimized/array_record.check @@ -0,0 +1 @@ +Array(1, 2, 3) \ No newline at end of file diff --git a/examples/flat/nooptimized/array_record.effekt b/examples/flat/nooptimized/array_record.effekt new file mode 100644 index 000000000..0580fbeae --- /dev/null +++ b/examples/flat/nooptimized/array_record.effekt @@ -0,0 +1,10 @@ +record Person( + field1: Int, + field2: Array[Int] + ) + +def main() = { + val myArray: Array[Int] = build(3) { i => i + 1 } // Array(1, 2, 3) + val p = Person(1, myArray) + println(myArray) +} \ No newline at end of file diff --git a/examples/flat/nooptimized/array_record_match.check b/examples/flat/nooptimized/array_record_match.check new file mode 100644 index 000000000..56a6051ca --- /dev/null +++ b/examples/flat/nooptimized/array_record_match.check @@ -0,0 +1 @@ +1 \ No newline at end of file diff --git a/examples/flat/nooptimized/array_record_match.effekt b/examples/flat/nooptimized/array_record_match.effekt new file mode 100644 index 000000000..1af090a55 --- /dev/null +++ b/examples/flat/nooptimized/array_record_match.effekt @@ -0,0 +1,21 @@ +record Person( + field1: Int, + field2: Array[Int] + ) + +record OneSlotPerson( + field1: Int, + field2: Int, + field3: Int, + field4: Int, + field5: Int, + field6: Int +) + +def main() = { + val myArray: Array[Int] = array::allocate(1) + val p = Person(1, myArray) + p match { + case Person(f1, _) => println(f1) + } +} \ No newline at end of file diff --git a/examples/flat/nooptimized/array_record_match_exhausted.check b/examples/flat/nooptimized/array_record_match_exhausted.check new file mode 100644 index 000000000..56a6051ca --- /dev/null +++ b/examples/flat/nooptimized/array_record_match_exhausted.check @@ -0,0 +1 @@ +1 \ No newline at end of file diff --git a/examples/flat/nooptimized/array_record_match_exhausted.effekt b/examples/flat/nooptimized/array_record_match_exhausted.effekt new file mode 100644 index 000000000..772e5c8c2 --- /dev/null +++ b/examples/flat/nooptimized/array_record_match_exhausted.effekt @@ -0,0 +1,21 @@ +record Person( + field1: Int, + field2: Array[Int] + ) + +record OneSlotPerson( + field1: Int, + field2: Int, + field3: Int, + field4: Int, + field5: Int, + field6: Int +) + +def main() = { + val myArray: Array[Int] = array::allocate(1) + val p = Person(1, myArray) + p match { + case Person(f1, arr) => println(f1) + } +} \ No newline at end of file diff --git a/examples/flat/nooptimized/different_person_sizes_biggest_first.check b/examples/flat/nooptimized/different_person_sizes_biggest_first.check new file mode 100644 index 000000000..63ea17a09 --- /dev/null +++ b/examples/flat/nooptimized/different_person_sizes_biggest_first.check @@ -0,0 +1,3 @@ +24 +13 +6 \ No newline at end of file diff --git a/examples/flat/nooptimized/different_person_sizes_biggest_first.effekt b/examples/flat/nooptimized/different_person_sizes_biggest_first.effekt new file mode 100644 index 000000000..6a963c745 --- /dev/null +++ b/examples/flat/nooptimized/different_person_sizes_biggest_first.effekt @@ -0,0 +1,46 @@ +// this test is for debugging of the to-do-list approach. Here, we define multiple records that require different +// number of heap-slots (aka. 64 bytes). + +// here we allocate the biggest object at first and go to the smallest. + +record OneSlotPerson( + field1: Int, + field2: Int, + field3: Int, + field4: Int, + field5: Int, + field6: Int + ) + +record TwoSlotPerson( + field1: Int, + field2: Int, + field3: Int, + field4: Int, + field5: Int, + field6: Int, + field7: Int + ) + +record ThreeSlotPerson( + field1: Int, + field2: Int, + field3: Int, + field4: Int, + field5: Int, + field6: Int, + field7: Int, + field8: Int, + field9: Int, + field10: Int, + field11: Int + ) + +def main() = { + val p3 = ThreeSlotPerson(14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24) + println(p3.field11) + val p2 = TwoSlotPerson(7, 8, 9, 10, 11, 12, 13) + println(p2.field7) + val p1 = OneSlotPerson(1, 2, 3, 4, 5, 6) + println(p1.field6) +} \ No newline at end of file diff --git a/examples/flat/nooptimized/different_person_sizes_smallest_first.check b/examples/flat/nooptimized/different_person_sizes_smallest_first.check new file mode 100644 index 000000000..bdfbf007c --- /dev/null +++ b/examples/flat/nooptimized/different_person_sizes_smallest_first.check @@ -0,0 +1,3 @@ +6 +13 +26 \ No newline at end of file diff --git a/examples/flat/nooptimized/different_person_sizes_smallest_first.effekt b/examples/flat/nooptimized/different_person_sizes_smallest_first.effekt new file mode 100644 index 000000000..2a61b272d --- /dev/null +++ b/examples/flat/nooptimized/different_person_sizes_smallest_first.effekt @@ -0,0 +1,46 @@ +// this test is for debugging of the to-do-list approach. Here, we define multiple records that require different +// number of heap-slots (aka. 64 bytes). + +record OneSlotPerson( + field1: Int, + field2: Int, + field3: Int, + field4: Int, + field5: Int, + field6: Int + ) + +record TwoSlotPerson( + field1: Int, + field2: Int, + field3: Int, + field4: Int, + field5: Int, + field6: Int, + field7: Int + ) + +record ThreeSlotPerson( + field1: Int, + field2: Int, + field3: Int, + field4: Int, + field5: Int, + field6: Int, + field7: Int, + field8: Int, + field9: Int, + field10: Int, + field11: Int, + field12: Int, + field13: Int + ) + +def main() = { + val p1 = OneSlotPerson(1, 2, 3, 4, 5, 6) + println(p1.field6) + val p2 = TwoSlotPerson(7, 8, 9, 10, 11, 12, 13) + println(p2.field7) + val p3 = ThreeSlotPerson(14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26) + println(p3.field13) +} \ No newline at end of file diff --git a/examples/flat/nooptimized/nested_objects.check b/examples/flat/nooptimized/nested_objects.check new file mode 100644 index 000000000..e440e5c84 --- /dev/null +++ b/examples/flat/nooptimized/nested_objects.check @@ -0,0 +1 @@ +3 \ No newline at end of file diff --git a/examples/flat/nooptimized/nested_objects.effekt b/examples/flat/nooptimized/nested_objects.effekt new file mode 100644 index 000000000..27a274b5f --- /dev/null +++ b/examples/flat/nooptimized/nested_objects.effekt @@ -0,0 +1,16 @@ +record Person1( + field3: Int, + field4: Int +) + +record Person( + field1: Int, + field2: Int, + person1: Person1 + ) + +def main() = { + val p1 = Person1(3, 4) + val p = Person(1, 2, p1) + println(p.person1.field3) +} \ No newline at end of file diff --git a/examples/flat/nooptimized/one_big_string_object.check b/examples/flat/nooptimized/one_big_string_object.check new file mode 100644 index 000000000..41bfe81b8 --- /dev/null +++ b/examples/flat/nooptimized/one_big_string_object.check @@ -0,0 +1 @@ +Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. \ No newline at end of file diff --git a/examples/flat/nooptimized/one_big_string_object.effekt b/examples/flat/nooptimized/one_big_string_object.effekt new file mode 100644 index 000000000..492ee575c --- /dev/null +++ b/examples/flat/nooptimized/one_big_string_object.effekt @@ -0,0 +1,9 @@ +// contains one big lorem ipsum string with 100 words +record Person( + field1: String + ) + +def main() = { + val p = Person("Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.") + println(p.field1) +} \ No newline at end of file diff --git a/examples/flat/nooptimized/one_lg_object.check b/examples/flat/nooptimized/one_lg_object.check new file mode 100644 index 000000000..9a037142a --- /dev/null +++ b/examples/flat/nooptimized/one_lg_object.check @@ -0,0 +1 @@ +10 \ No newline at end of file diff --git a/examples/flat/nooptimized/one_lg_object.effekt b/examples/flat/nooptimized/one_lg_object.effekt new file mode 100644 index 000000000..18eff9264 --- /dev/null +++ b/examples/flat/nooptimized/one_lg_object.effekt @@ -0,0 +1,18 @@ +// lg = Person fills 2 saving slots completely +record Person( + field1: Int, + field2: Int, + field3: Int, + field4: Int, + field5: Int, + field6: Int, + field7: Int, + field8: Int, + field9: Int, + field10: Int + ) + +def main() = { + val p = Person(1, 2, 3, 4, 5, 6, 7, 8, 9, 10) + println(p.field10) +} \ No newline at end of file diff --git a/examples/flat/nooptimized/one_md_object.check b/examples/flat/nooptimized/one_md_object.check new file mode 100644 index 000000000..c7930257d --- /dev/null +++ b/examples/flat/nooptimized/one_md_object.check @@ -0,0 +1 @@ +7 \ No newline at end of file diff --git a/examples/flat/nooptimized/one_md_object.effekt b/examples/flat/nooptimized/one_md_object.effekt new file mode 100644 index 000000000..d68c5a960 --- /dev/null +++ b/examples/flat/nooptimized/one_md_object.effekt @@ -0,0 +1,15 @@ +// md = Person requires 2 saving slots +record Person( + field1: Int, + field2: Int, + field3: Int, + field4: Int, + field5: Int, + field6: Int, + field7: Int + ) + +def main() = { + val p = Person(1, 2, 3, 4, 5, 6, 7) + println(p.field7) +} \ No newline at end of file diff --git a/examples/flat/nooptimized/one_slot_one_person_list.check b/examples/flat/nooptimized/one_slot_one_person_list.check new file mode 100644 index 000000000..62f945751 --- /dev/null +++ b/examples/flat/nooptimized/one_slot_one_person_list.check @@ -0,0 +1 @@ +6 \ No newline at end of file diff --git a/examples/flat/nooptimized/one_slot_one_person_list.effekt b/examples/flat/nooptimized/one_slot_one_person_list.effekt new file mode 100644 index 000000000..e23065e8e --- /dev/null +++ b/examples/flat/nooptimized/one_slot_one_person_list.effekt @@ -0,0 +1,27 @@ +import list + +record OneSlotPerson( + field1: Int, + field2: Int, + field3: Int, + field4: Int, + field5: Int, + field6: Int +) + +def main() = { + val person1 = OneSlotPerson(1, 2, 3, 4, 5, 6) + var myList = [person1] + //myList = drop(myList, 1) + //val myList = Nil[OneSlotPerson]() + + // prints 6. If -1 is printed, there is a bug + myList match { + case Nil() => println(-1) + case Cons(x, _) => println(x.field6) + //case Cons(x, _) => println(-2) + } + + //myList = drop(myList, 1) + //val person3 = person1 +} diff --git a/examples/flat/nooptimized/one_sm_object.check b/examples/flat/nooptimized/one_sm_object.check new file mode 100644 index 000000000..62f945751 --- /dev/null +++ b/examples/flat/nooptimized/one_sm_object.check @@ -0,0 +1 @@ +6 \ No newline at end of file diff --git a/examples/flat/nooptimized/one_sm_object.effekt b/examples/flat/nooptimized/one_sm_object.effekt new file mode 100644 index 000000000..95ffb2305 --- /dev/null +++ b/examples/flat/nooptimized/one_sm_object.effekt @@ -0,0 +1,14 @@ +// sm = Person fills 1 saving slot completely +record Person( + field1: Int, + field2: Int, + field3: Int, + field4: Int, + field5: Int, + field6: Int + ) + +def main() = { + val p = Person(1, 2, 3, 4, 5, 6) + println(p.field6) +} \ No newline at end of file diff --git a/examples/flat/nooptimized/one_small_string_object.check b/examples/flat/nooptimized/one_small_string_object.check new file mode 100644 index 000000000..30d74d258 --- /dev/null +++ b/examples/flat/nooptimized/one_small_string_object.check @@ -0,0 +1 @@ +test \ No newline at end of file diff --git a/examples/flat/nooptimized/one_small_string_object.effekt b/examples/flat/nooptimized/one_small_string_object.effekt new file mode 100644 index 000000000..efe6e6fef --- /dev/null +++ b/examples/flat/nooptimized/one_small_string_object.effekt @@ -0,0 +1,8 @@ +record Person( + field1: String + ) + +def main() = { + val p = Person("test") + println(p.field1) +} \ No newline at end of file diff --git a/examples/flat/nooptimized/one_xl_object.check b/examples/flat/nooptimized/one_xl_object.check new file mode 100644 index 000000000..9d607966b --- /dev/null +++ b/examples/flat/nooptimized/one_xl_object.check @@ -0,0 +1 @@ +11 \ No newline at end of file diff --git a/examples/flat/nooptimized/one_xl_object.effekt b/examples/flat/nooptimized/one_xl_object.effekt new file mode 100644 index 000000000..bc45859ca --- /dev/null +++ b/examples/flat/nooptimized/one_xl_object.effekt @@ -0,0 +1,19 @@ +// xl = Person needs 3 saving slots +record Person( + field1: Int, + field2: Int, + field3: Int, + field4: Int, + field5: Int, + field6: Int, + field7: Int, + field8: Int, + field9: Int, + field10: Int, + field11: Int + ) + +def main() = { + val p = Person(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11) + println(p.field11) +} \ No newline at end of file diff --git a/examples/flat/nooptimized/one_xs_object.check b/examples/flat/nooptimized/one_xs_object.check new file mode 100644 index 000000000..e440e5c84 --- /dev/null +++ b/examples/flat/nooptimized/one_xs_object.check @@ -0,0 +1 @@ +3 \ No newline at end of file diff --git a/examples/flat/nooptimized/one_xs_object.effekt b/examples/flat/nooptimized/one_xs_object.effekt new file mode 100644 index 000000000..034c32ea5 --- /dev/null +++ b/examples/flat/nooptimized/one_xs_object.effekt @@ -0,0 +1,11 @@ +// xs = Person fits easily in 1 saving slot +record Person( + field1: Int, + field2: Int, + field3: Int + ) + +def main() = { + val p = Person(1, 2, 3) + println(p.field3) +} \ No newline at end of file diff --git a/examples/flat/nooptimized/one_xxl_object_all_fields.check b/examples/flat/nooptimized/one_xxl_object_all_fields.check new file mode 100644 index 000000000..6a0bcb871 --- /dev/null +++ b/examples/flat/nooptimized/one_xxl_object_all_fields.check @@ -0,0 +1,100 @@ +1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +11 +12 +13 +14 +15 +16 +17 +18 +19 +20 +21 +22 +23 +24 +25 +26 +27 +28 +29 +30 +31 +32 +33 +34 +35 +36 +37 +38 +39 +40 +41 +42 +43 +44 +45 +46 +47 +48 +49 +50 +51 +52 +53 +54 +55 +56 +57 +58 +59 +60 +61 +62 +63 +64 +65 +66 +67 +68 +69 +70 +71 +72 +73 +74 +75 +76 +77 +78 +79 +80 +81 +82 +83 +84 +85 +86 +87 +88 +89 +90 +91 +92 +93 +94 +95 +96 +97 +98 +99 +100 \ No newline at end of file diff --git a/examples/flat/nooptimized/one_xxl_object_all_fields.effekt b/examples/flat/nooptimized/one_xxl_object_all_fields.effekt new file mode 100644 index 000000000..824a4b603 --- /dev/null +++ b/examples/flat/nooptimized/one_xxl_object_all_fields.effekt @@ -0,0 +1,308 @@ +// xxl: Person has 100 fields -> need x slots +record Person( + field1: Int, + field2: Int, + field3: Int, + field4: Int, + field5: Int, + field6: Int, + field7: Int, + field8: Int, + field9: Int, + field10: Int, + field11: Int, + field12: Int, + field13: Int, + field14: Int, + field15: Int, + field16: Int, + field17: Int, + field18: Int, + field19: Int, + field20: Int, + field21: Int, + field22: Int, + field23: Int, + field24: Int, + field25: Int, + field26: Int, + field27: Int, + field28: Int, + field29: Int, + field30: Int, + field31: Int, + field32: Int, + field33: Int, + field34: Int, + field35: Int, + field36: Int, + field37: Int, + field38: Int, + field39: Int, + field40: Int, + field41: Int, + field42: Int, + field43: Int, + field44: Int, + field45: Int, + field46: Int, + field47: Int, + field48: Int, + field49: Int, + field50: Int, + field51: Int, + field52: Int, + field53: Int, + field54: Int, + field55: Int, + field56: Int, + field57: Int, + field58: Int, + field59: Int, + field60: Int, + field61: Int, + field62: Int, + field63: Int, + field64: Int, + field65: Int, + field66: Int, + field67: Int, + field68: Int, + field69: Int, + field70: Int, + field71: Int, + field72: Int, + field73: Int, + field74: Int, + field75: Int, + field76: Int, + field77: Int, + field78: Int, + field79: Int, + field80: Int, + field81: Int, + field82: Int, + field83: Int, + field84: Int, + field85: Int, + field86: Int, + field87: Int, + field88: Int, + field89: Int, + field90: Int, + field91: Int, + field92: Int, + field93: Int, + field94: Int, + field95: Int, + field96: Int, + field97: Int, + field98: Int, + field99: Int, + field100: Int +) + +def main() = { + val p1 = Person( + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, + 17, + 18, + 19, + 20, + 21, + 22, + 23, + 24, + 25, + 26, + 27, + 28, + 29, + 30, + 31, + 32, + 33, + 34, + 35, + 36, + 37, + 38, + 39, + 40, + 41, + 42, + 43, + 44, + 45, + 46, + 47, + 48, + 49, + 50, + 51, + 52, + 53, + 54, + 55, + 56, + 57, + 58, + 59, + 60, + 61, + 62, + 63, + 64, + 65, + 66, + 67, + 68, + 69, + 70, + 71, + 72, + 73, + 74, + 75, + 76, + 77, + 78, + 79, + 80, + 81, + 82, + 83, + 84, + 85, + 86, + 87, + 88, + 89, + 90, + 91, + 92, + 93, + 94, + 95, + 96, + 97, + 98, + 99, + 100 +) + println(p1.field1) + println(p1.field2) + println(p1.field3) + println(p1.field4) + println(p1.field5) + println(p1.field6) + println(p1.field7) + println(p1.field8) + println(p1.field9) + println(p1.field10) + println(p1.field11) + println(p1.field12) + println(p1.field13) + println(p1.field14) + println(p1.field15) + println(p1.field16) + println(p1.field17) + println(p1.field18) + println(p1.field19) + println(p1.field20) + println(p1.field21) + println(p1.field22) + println(p1.field23) + println(p1.field24) + println(p1.field25) + println(p1.field26) + println(p1.field27) + println(p1.field28) + println(p1.field29) + println(p1.field30) + println(p1.field31) + println(p1.field32) + println(p1.field33) + println(p1.field34) + println(p1.field35) + println(p1.field36) + println(p1.field37) + println(p1.field38) + println(p1.field39) + println(p1.field40) + println(p1.field41) + println(p1.field42) + println(p1.field43) + println(p1.field44) + println(p1.field45) + println(p1.field46) + println(p1.field47) + println(p1.field48) + println(p1.field49) + println(p1.field50) + println(p1.field51) + println(p1.field52) + println(p1.field53) + println(p1.field54) + println(p1.field55) + println(p1.field56) + println(p1.field57) + println(p1.field58) + println(p1.field59) + println(p1.field60) + println(p1.field61) + println(p1.field62) + println(p1.field63) + println(p1.field64) + println(p1.field65) + println(p1.field66) + println(p1.field67) + println(p1.field68) + println(p1.field69) + println(p1.field70) + println(p1.field71) + println(p1.field72) + println(p1.field73) + println(p1.field74) + println(p1.field75) + println(p1.field76) + println(p1.field77) + println(p1.field78) + println(p1.field79) + println(p1.field80) + println(p1.field81) + println(p1.field82) + println(p1.field83) + println(p1.field84) + println(p1.field85) + println(p1.field86) + println(p1.field87) + println(p1.field88) + println(p1.field89) + println(p1.field90) + println(p1.field91) + println(p1.field92) + println(p1.field93) + println(p1.field94) + println(p1.field95) + println(p1.field96) + println(p1.field97) + println(p1.field98) + println(p1.field99) + println(p1.field100) +} \ No newline at end of file diff --git a/examples/flat/nooptimized/one_xxxl_object.check b/examples/flat/nooptimized/one_xxxl_object.check new file mode 100644 index 000000000..eb1f49486 --- /dev/null +++ b/examples/flat/nooptimized/one_xxxl_object.check @@ -0,0 +1 @@ +500 \ No newline at end of file diff --git a/examples/flat/nooptimized/one_xxxl_object.effekt b/examples/flat/nooptimized/one_xxxl_object.effekt new file mode 100644 index 000000000..74211407a --- /dev/null +++ b/examples/flat/nooptimized/one_xxxl_object.effekt @@ -0,0 +1,1008 @@ +record Person( + field1: Int, + field2: Int, + field3: Int, + field4: Int, + field5: Int, + field6: Int, + field7: Int, + field8: Int, + field9: Int, + field10: Int, + field11: Int, + field12: Int, + field13: Int, + field14: Int, + field15: Int, + field16: Int, + field17: Int, + field18: Int, + field19: Int, + field20: Int, + field21: Int, + field22: Int, + field23: Int, + field24: Int, + field25: Int, + field26: Int, + field27: Int, + field28: Int, + field29: Int, + field30: Int, + field31: Int, + field32: Int, + field33: Int, + field34: Int, + field35: Int, + field36: Int, + field37: Int, + field38: Int, + field39: Int, + field40: Int, + field41: Int, + field42: Int, + field43: Int, + field44: Int, + field45: Int, + field46: Int, + field47: Int, + field48: Int, + field49: Int, + field50: Int, + field51: Int, + field52: Int, + field53: Int, + field54: Int, + field55: Int, + field56: Int, + field57: Int, + field58: Int, + field59: Int, + field60: Int, + field61: Int, + field62: Int, + field63: Int, + field64: Int, + field65: Int, + field66: Int, + field67: Int, + field68: Int, + field69: Int, + field70: Int, + field71: Int, + field72: Int, + field73: Int, + field74: Int, + field75: Int, + field76: Int, + field77: Int, + field78: Int, + field79: Int, + field80: Int, + field81: Int, + field82: Int, + field83: Int, + field84: Int, + field85: Int, + field86: Int, + field87: Int, + field88: Int, + field89: Int, + field90: Int, + field91: Int, + field92: Int, + field93: Int, + field94: Int, + field95: Int, + field96: Int, + field97: Int, + field98: Int, + field99: Int, + field100: Int, + field101: Int, + field102: Int, + field103: Int, + field104: Int, + field105: Int, + field106: Int, + field107: Int, + field108: Int, + field109: Int, + field110: Int, + field111: Int, + field112: Int, + field113: Int, + field114: Int, + field115: Int, + field116: Int, + field117: Int, + field118: Int, + field119: Int, + field120: Int, + field121: Int, + field122: Int, + field123: Int, + field124: Int, + field125: Int, + field126: Int, + field127: Int, + field128: Int, + field129: Int, + field130: Int, + field131: Int, + field132: Int, + field133: Int, + field134: Int, + field135: Int, + field136: Int, + field137: Int, + field138: Int, + field139: Int, + field140: Int, + field141: Int, + field142: Int, + field143: Int, + field144: Int, + field145: Int, + field146: Int, + field147: Int, + field148: Int, + field149: Int, + field150: Int, + field151: Int, + field152: Int, + field153: Int, + field154: Int, + field155: Int, + field156: Int, + field157: Int, + field158: Int, + field159: Int, + field160: Int, + field161: Int, + field162: Int, + field163: Int, + field164: Int, + field165: Int, + field166: Int, + field167: Int, + field168: Int, + field169: Int, + field170: Int, + field171: Int, + field172: Int, + field173: Int, + field174: Int, + field175: Int, + field176: Int, + field177: Int, + field178: Int, + field179: Int, + field180: Int, + field181: Int, + field182: Int, + field183: Int, + field184: Int, + field185: Int, + field186: Int, + field187: Int, + field188: Int, + field189: Int, + field190: Int, + field191: Int, + field192: Int, + field193: Int, + field194: Int, + field195: Int, + field196: Int, + field197: Int, + field198: Int, + field199: Int, + field200: Int, + field201: Int, + field202: Int, + field203: Int, + field204: Int, + field205: Int, + field206: Int, + field207: Int, + field208: Int, + field209: Int, + field210: Int, + field211: Int, + field212: Int, + field213: Int, + field214: Int, + field215: Int, + field216: Int, + field217: Int, + field218: Int, + field219: Int, + field220: Int, + field221: Int, + field222: Int, + field223: Int, + field224: Int, + field225: Int, + field226: Int, + field227: Int, + field228: Int, + field229: Int, + field230: Int, + field231: Int, + field232: Int, + field233: Int, + field234: Int, + field235: Int, + field236: Int, + field237: Int, + field238: Int, + field239: Int, + field240: Int, + field241: Int, + field242: Int, + field243: Int, + field244: Int, + field245: Int, + field246: Int, + field247: Int, + field248: Int, + field249: Int, + field250: Int, + field251: Int, + field252: Int, + field253: Int, + field254: Int, + field255: Int, + field256: Int, + field257: Int, + field258: Int, + field259: Int, + field260: Int, + field261: Int, + field262: Int, + field263: Int, + field264: Int, + field265: Int, + field266: Int, + field267: Int, + field268: Int, + field269: Int, + field270: Int, + field271: Int, + field272: Int, + field273: Int, + field274: Int, + field275: Int, + field276: Int, + field277: Int, + field278: Int, + field279: Int, + field280: Int, + field281: Int, + field282: Int, + field283: Int, + field284: Int, + field285: Int, + field286: Int, + field287: Int, + field288: Int, + field289: Int, + field290: Int, + field291: Int, + field292: Int, + field293: Int, + field294: Int, + field295: Int, + field296: Int, + field297: Int, + field298: Int, + field299: Int, + field300: Int, + field301: Int, + field302: Int, + field303: Int, + field304: Int, + field305: Int, + field306: Int, + field307: Int, + field308: Int, + field309: Int, + field310: Int, + field311: Int, + field312: Int, + field313: Int, + field314: Int, + field315: Int, + field316: Int, + field317: Int, + field318: Int, + field319: Int, + field320: Int, + field321: Int, + field322: Int, + field323: Int, + field324: Int, + field325: Int, + field326: Int, + field327: Int, + field328: Int, + field329: Int, + field330: Int, + field331: Int, + field332: Int, + field333: Int, + field334: Int, + field335: Int, + field336: Int, + field337: Int, + field338: Int, + field339: Int, + field340: Int, + field341: Int, + field342: Int, + field343: Int, + field344: Int, + field345: Int, + field346: Int, + field347: Int, + field348: Int, + field349: Int, + field350: Int, + field351: Int, + field352: Int, + field353: Int, + field354: Int, + field355: Int, + field356: Int, + field357: Int, + field358: Int, + field359: Int, + field360: Int, + field361: Int, + field362: Int, + field363: Int, + field364: Int, + field365: Int, + field366: Int, + field367: Int, + field368: Int, + field369: Int, + field370: Int, + field371: Int, + field372: Int, + field373: Int, + field374: Int, + field375: Int, + field376: Int, + field377: Int, + field378: Int, + field379: Int, + field380: Int, + field381: Int, + field382: Int, + field383: Int, + field384: Int, + field385: Int, + field386: Int, + field387: Int, + field388: Int, + field389: Int, + field390: Int, + field391: Int, + field392: Int, + field393: Int, + field394: Int, + field395: Int, + field396: Int, + field397: Int, + field398: Int, + field399: Int, + field400: Int, + field401: Int, + field402: Int, + field403: Int, + field404: Int, + field405: Int, + field406: Int, + field407: Int, + field408: Int, + field409: Int, + field410: Int, + field411: Int, + field412: Int, + field413: Int, + field414: Int, + field415: Int, + field416: Int, + field417: Int, + field418: Int, + field419: Int, + field420: Int, + field421: Int, + field422: Int, + field423: Int, + field424: Int, + field425: Int, + field426: Int, + field427: Int, + field428: Int, + field429: Int, + field430: Int, + field431: Int, + field432: Int, + field433: Int, + field434: Int, + field435: Int, + field436: Int, + field437: Int, + field438: Int, + field439: Int, + field440: Int, + field441: Int, + field442: Int, + field443: Int, + field444: Int, + field445: Int, + field446: Int, + field447: Int, + field448: Int, + field449: Int, + field450: Int, + field451: Int, + field452: Int, + field453: Int, + field454: Int, + field455: Int, + field456: Int, + field457: Int, + field458: Int, + field459: Int, + field460: Int, + field461: Int, + field462: Int, + field463: Int, + field464: Int, + field465: Int, + field466: Int, + field467: Int, + field468: Int, + field469: Int, + field470: Int, + field471: Int, + field472: Int, + field473: Int, + field474: Int, + field475: Int, + field476: Int, + field477: Int, + field478: Int, + field479: Int, + field480: Int, + field481: Int, + field482: Int, + field483: Int, + field484: Int, + field485: Int, + field486: Int, + field487: Int, + field488: Int, + field489: Int, + field490: Int, + field491: Int, + field492: Int, + field493: Int, + field494: Int, + field495: Int, + field496: Int, + field497: Int, + field498: Int, + field499: Int, + field500: Int +) + +def main() = { + val p1 = Person( + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, + 17, + 18, + 19, + 20, + 21, + 22, + 23, + 24, + 25, + 26, + 27, + 28, + 29, + 30, + 31, + 32, + 33, + 34, + 35, + 36, + 37, + 38, + 39, + 40, + 41, + 42, + 43, + 44, + 45, + 46, + 47, + 48, + 49, + 50, + 51, + 52, + 53, + 54, + 55, + 56, + 57, + 58, + 59, + 60, + 61, + 62, + 63, + 64, + 65, + 66, + 67, + 68, + 69, + 70, + 71, + 72, + 73, + 74, + 75, + 76, + 77, + 78, + 79, + 80, + 81, + 82, + 83, + 84, + 85, + 86, + 87, + 88, + 89, + 90, + 91, + 92, + 93, + 94, + 95, + 96, + 97, + 98, + 99, + 100, + 101, + 102, + 103, + 104, + 105, + 106, + 107, + 108, + 109, + 110, + 111, + 112, + 113, + 114, + 115, + 116, + 117, + 118, + 119, + 120, + 121, + 122, + 123, + 124, + 125, + 126, + 127, + 128, + 129, + 130, + 131, + 132, + 133, + 134, + 135, + 136, + 137, + 138, + 139, + 140, + 141, + 142, + 143, + 144, + 145, + 146, + 147, + 148, + 149, + 150, + 151, + 152, + 153, + 154, + 155, + 156, + 157, + 158, + 159, + 160, + 161, + 162, + 163, + 164, + 165, + 166, + 167, + 168, + 169, + 170, + 171, + 172, + 173, + 174, + 175, + 176, + 177, + 178, + 179, + 180, + 181, + 182, + 183, + 184, + 185, + 186, + 187, + 188, + 189, + 190, + 191, + 192, + 193, + 194, + 195, + 196, + 197, + 198, + 199, + 200, + 201, + 202, + 203, + 204, + 205, + 206, + 207, + 208, + 209, + 210, + 211, + 212, + 213, + 214, + 215, + 216, + 217, + 218, + 219, + 220, + 221, + 222, + 223, + 224, + 225, + 226, + 227, + 228, + 229, + 230, + 231, + 232, + 233, + 234, + 235, + 236, + 237, + 238, + 239, + 240, + 241, + 242, + 243, + 244, + 245, + 246, + 247, + 248, + 249, + 250, + 251, + 252, + 253, + 254, + 255, + 256, + 257, + 258, + 259, + 260, + 261, + 262, + 263, + 264, + 265, + 266, + 267, + 268, + 269, + 270, + 271, + 272, + 273, + 274, + 275, + 276, + 277, + 278, + 279, + 280, + 281, + 282, + 283, + 284, + 285, + 286, + 287, + 288, + 289, + 290, + 291, + 292, + 293, + 294, + 295, + 296, + 297, + 298, + 299, + 300, + 301, + 302, + 303, + 304, + 305, + 306, + 307, + 308, + 309, + 310, + 311, + 312, + 313, + 314, + 315, + 316, + 317, + 318, + 319, + 320, + 321, + 322, + 323, + 324, + 325, + 326, + 327, + 328, + 329, + 330, + 331, + 332, + 333, + 334, + 335, + 336, + 337, + 338, + 339, + 340, + 341, + 342, + 343, + 344, + 345, + 346, + 347, + 348, + 349, + 350, + 351, + 352, + 353, + 354, + 355, + 356, + 357, + 358, + 359, + 360, + 361, + 362, + 363, + 364, + 365, + 366, + 367, + 368, + 369, + 370, + 371, + 372, + 373, + 374, + 375, + 376, + 377, + 378, + 379, + 380, + 381, + 382, + 383, + 384, + 385, + 386, + 387, + 388, + 389, + 390, + 391, + 392, + 393, + 394, + 395, + 396, + 397, + 398, + 399, + 400, + 401, + 402, + 403, + 404, + 405, + 406, + 407, + 408, + 409, + 410, + 411, + 412, + 413, + 414, + 415, + 416, + 417, + 418, + 419, + 420, + 421, + 422, + 423, + 424, + 425, + 426, + 427, + 428, + 429, + 430, + 431, + 432, + 433, + 434, + 435, + 436, + 437, + 438, + 439, + 440, + 441, + 442, + 443, + 444, + 445, + 446, + 447, + 448, + 449, + 450, + 451, + 452, + 453, + 454, + 455, + 456, + 457, + 458, + 459, + 460, + 461, + 462, + 463, + 464, + 465, + 466, + 467, + 468, + 469, + 470, + 471, + 472, + 473, + 474, + 475, + 476, + 477, + 478, + 479, + 480, + 481, + 482, + 483, + 484, + 485, + 486, + 487, + 488, + 489, + 490, + 491, + 492, + 493, + 494, + 495, + 496, + 497, + 498, + 499, + 500 +) + println(p1.field500) +} \ No newline at end of file diff --git a/examples/flat/nooptimized/primitive_ref.check b/examples/flat/nooptimized/primitive_ref.check new file mode 100644 index 000000000..62f945751 --- /dev/null +++ b/examples/flat/nooptimized/primitive_ref.check @@ -0,0 +1 @@ +6 \ No newline at end of file diff --git a/examples/flat/nooptimized/primitive_ref.effekt b/examples/flat/nooptimized/primitive_ref.effekt new file mode 100644 index 000000000..6aa82602e --- /dev/null +++ b/examples/flat/nooptimized/primitive_ref.effekt @@ -0,0 +1,9 @@ +import ref + +def main() = { + val x = 5 + val y = 6 + val z = ref(x) + z.set(y) + println(z.get()) +} diff --git a/examples/flat/nooptimized/ref_allocate.check b/examples/flat/nooptimized/ref_allocate.check new file mode 100644 index 000000000..c7930257d --- /dev/null +++ b/examples/flat/nooptimized/ref_allocate.check @@ -0,0 +1 @@ +7 \ No newline at end of file diff --git a/examples/flat/nooptimized/ref_allocate.effekt b/examples/flat/nooptimized/ref_allocate.effekt new file mode 100644 index 000000000..2b46ceaa7 --- /dev/null +++ b/examples/flat/nooptimized/ref_allocate.effekt @@ -0,0 +1,19 @@ +import ref + +// md = Person requires 2 saving slots +record Person( + field1: Int, + field2: Int, + field3: Int, + field4: Int, + field5: Int, + field6: Int, + field7: Int + ) + +def main() = { + val p1 = ref::allocate() + val p2 = Person(1, 2, 3, 4, 5, 6, 7) + p1.set(p2) + println(p1.get().field7) +} diff --git a/examples/flat/nooptimized/simple_list.check b/examples/flat/nooptimized/simple_list.check new file mode 100644 index 000000000..cabf43b5d --- /dev/null +++ b/examples/flat/nooptimized/simple_list.check @@ -0,0 +1 @@ +24 \ No newline at end of file diff --git a/examples/flat/nooptimized/simple_list.effekt b/examples/flat/nooptimized/simple_list.effekt new file mode 100644 index 000000000..4a3187884 --- /dev/null +++ b/examples/flat/nooptimized/simple_list.effekt @@ -0,0 +1,15 @@ +import list +//import exception + + +def main() = { + // Creates a list with one element + val myList = [24] + + // print 24. If -1 is printed, there is a bug + myList match { + case Nil() => println(-1) + case Cons(x, Nil()) => println(x) + case Cons(x, xs) => println(-1) + } +} diff --git a/examples/flat/nooptimized/simple_ref.check b/examples/flat/nooptimized/simple_ref.check new file mode 100644 index 000000000..f11c82a4c --- /dev/null +++ b/examples/flat/nooptimized/simple_ref.check @@ -0,0 +1 @@ +9 \ No newline at end of file diff --git a/examples/flat/nooptimized/simple_ref.effekt b/examples/flat/nooptimized/simple_ref.effekt new file mode 100644 index 000000000..3549dea0f --- /dev/null +++ b/examples/flat/nooptimized/simple_ref.effekt @@ -0,0 +1,20 @@ +import ref + +// md = Person requires 2 saving slots +record Person( + field1: Int, + field2: Int, + field3: Int, + field4: Int, + field5: Int, + field6: Int, + field7: Int + ) + +def main() = { + val p1 = Person(1, 2, 3, 4, 5, 6, 7) + val p2 = Person(1, 2, 3, 4, 5, 6, 9) + val p3 = ref(p1) + p3.set(p2) + println(p3.get().field7) +} diff --git a/examples/flat/nooptimized/superperson.check b/examples/flat/nooptimized/superperson.check new file mode 100644 index 000000000..968f988c5 --- /dev/null +++ b/examples/flat/nooptimized/superperson.check @@ -0,0 +1,2 @@ +9 +25 \ No newline at end of file diff --git a/examples/flat/nooptimized/superperson.effekt b/examples/flat/nooptimized/superperson.effekt new file mode 100644 index 000000000..d1dbe0b5c --- /dev/null +++ b/examples/flat/nooptimized/superperson.effekt @@ -0,0 +1,33 @@ +import list + +record TwoSlotPerson( + field1: Int, + field2: Int, + field3: Int, + field4: Int, + field5: Int, + field6: Int, + field7: Int + ) + +record SuperPerson( + field1: TwoSlotPerson, + field2: TwoSlotPerson +) + +def main() = { + // Creates a list with one element + val person1 = TwoSlotPerson(1, 2, 3, 4, 5, 6, 7) + val person2 = TwoSlotPerson(8, 9, 10, 11, 12, 13, 14) + val y = TwoSlotPerson(25, 2, 3, 4, 5, 6, 7) + val superPerson = SuperPerson(person1, person2) + + + // prints 9. If -1 is printed, there is a bug + superPerson match { + case SuperPerson(x, z) => println(x.field1 + z.field1) + } + + // prints 25 + println(y.field1) +} diff --git a/examples/flat/nooptimized/superperson_with_free.check b/examples/flat/nooptimized/superperson_with_free.check new file mode 100644 index 000000000..410b14d2c --- /dev/null +++ b/examples/flat/nooptimized/superperson_with_free.check @@ -0,0 +1 @@ +25 \ No newline at end of file diff --git a/examples/flat/nooptimized/superperson_with_free.effekt b/examples/flat/nooptimized/superperson_with_free.effekt new file mode 100644 index 000000000..528fa3fc6 --- /dev/null +++ b/examples/flat/nooptimized/superperson_with_free.effekt @@ -0,0 +1,30 @@ +import list + +record TwoSlotPerson( + field1: Int, + field2: Int, + field3: Int, + field4: Int, + field5: Int, + field6: Int, + field7: Int + ) + +record SuperPerson( + field1: TwoSlotPerson, + field2: TwoSlotPerson +) + +def main() = { + // Creates a list with one element + val person1 = TwoSlotPerson(1, 2, 3, 4, 5, 6, 7) + val person2 = TwoSlotPerson(8, 9, 10, 11, 12, 13, 14) + val y = TwoSlotPerson(25, 2, 3, 4, 5, 6, 7) + val superPerson = SuperPerson(person1, person2) + + + // prints 25. If -1 is printed, there is a bug + superPerson match { + case SuperPerson(x, z) => println(y.field1) + } +} diff --git a/examples/flat/nooptimized/three_md_objects_direct.check b/examples/flat/nooptimized/three_md_objects_direct.check new file mode 100644 index 000000000..8fac22206 --- /dev/null +++ b/examples/flat/nooptimized/three_md_objects_direct.check @@ -0,0 +1,3 @@ +7 +10 +18 \ No newline at end of file diff --git a/examples/flat/nooptimized/three_md_objects_direct.effekt b/examples/flat/nooptimized/three_md_objects_direct.effekt new file mode 100644 index 000000000..ec0561e12 --- /dev/null +++ b/examples/flat/nooptimized/three_md_objects_direct.effekt @@ -0,0 +1,20 @@ +// md = Person requires 2 saving slots +// direct = create person and print field directly +record Person( + field1: Int, + field2: Int, + field3: Int, + field4: Int, + field5: Int, + field6: Int, + field7: Int + ) + +def main() = { + val p1 = Person(1, 2, 3, 4, 5, 6, 7) + println(p1.field7) + val p2 = Person(8, 9, 10, 11, 12, 13, 14) + val p3 = Person(15, 16, 17, 18, 19, 20, 21) + println(p2.field3) + println(p3.field4) +} \ No newline at end of file diff --git a/examples/flat/nooptimized/trigger_child_freeing.check b/examples/flat/nooptimized/trigger_child_freeing.check new file mode 100644 index 000000000..e69de29bb diff --git a/examples/flat/nooptimized/trigger_child_freeing.effekt b/examples/flat/nooptimized/trigger_child_freeing.effekt new file mode 100644 index 000000000..2f96672f0 --- /dev/null +++ b/examples/flat/nooptimized/trigger_child_freeing.effekt @@ -0,0 +1,64 @@ +// a simple program that creates a more complex object +// -> child1 +// parent +// -> child2 -> child3 +// -> child4 -> child5 -> child6 +// -> child7 -> child8 +// where child1 is OneSlotPerson and child2 and child3 are TwoSlotPerson and child4 and child5 and child6 are ThreeSlotPerson, and child7 and child8 are TwoSlotPerson + +record OneSlotPerson( + field1: Int, + field2: Int, + field3: Int, + field4: Int, + field5: Int, + field6: Int +) + +record TwoSlotPerson( + field1: Int, + field2: Int, + field3: Int, + field4: Int, + field5: Int, + field6: Int, + field7: Int +) + +record ThreeSlotPerson( + field1: Int, + field2: Int, + field3: Int, + field4: Int, + field5: Int, + field6: Int, + field7: Int, + field8: Int, + field9: Int, + field10: Int, + field11: Int, + field12: Int, + field13: Int +) + +record Person( + child1: OneSlotPerson, + child2: TwoSlotPerson, + child3: ThreeSlotPerson, + child4: TwoSlotPerson, + child5: OneSlotPerson +) + +def main() = { + var iters = 1 + while(iters <= 66) { + var x = Person( + OneSlotPerson(iters, iters + 1, iters + 2, iters + 3, iters + 4, iters + 5), + TwoSlotPerson(iters, iters + 1, iters + 2, iters + 3, iters + 4, iters + 5, iters + 6), + ThreeSlotPerson(iters, iters + 1, iters + 2, iters + 3, iters + 4, iters + 5, iters + 6, iters + 7, iters + 8, iters + 9, iters + 10, iters + 11, iters + 12), + TwoSlotPerson(iters, iters + 1, iters + 2, iters + 3, iters + 4, iters + 5, iters + 7), + OneSlotPerson(iters, iters + 1, iters + 2, iters + 3, iters + 4, iters + 6) + ) + iters = iters + 1 + } +} diff --git a/examples/flat/nooptimized/trigger_flush_once.check b/examples/flat/nooptimized/trigger_flush_once.check new file mode 100644 index 000000000..e69de29bb diff --git a/examples/flat/nooptimized/trigger_flush_once.effekt b/examples/flat/nooptimized/trigger_flush_once.effekt new file mode 100644 index 000000000..c1306808c --- /dev/null +++ b/examples/flat/nooptimized/trigger_flush_once.effekt @@ -0,0 +1,17 @@ +// a simple program that triggers flush to-do-list once +record OneSlotPerson( + field1: Int, + field2: Int, + field3: Int, + field4: Int, + field5: Int, + field6: Int +) + +def main() = { + var iters = 1 + while(iters <= 65) { + var x = OneSlotPerson(iters, iters + 1, iters + 2, iters + 3, iters + 4, iters + 5) + iters = iters + 1 + } +} diff --git a/examples/flat/nooptimized/trigger_flush_twice.check b/examples/flat/nooptimized/trigger_flush_twice.check new file mode 100644 index 000000000..e69de29bb diff --git a/examples/flat/nooptimized/trigger_flush_twice.effekt b/examples/flat/nooptimized/trigger_flush_twice.effekt new file mode 100644 index 000000000..b364f2fdf --- /dev/null +++ b/examples/flat/nooptimized/trigger_flush_twice.effekt @@ -0,0 +1,17 @@ +// a simple program that triggers flush to-do-list twice +record OneSlotPerson( + field1: Int, + field2: Int, + field3: Int, + field4: Int, + field5: Int, + field6: Int +) + +def main() = { + var iters = 1 + while(iters <= 129) { + var x = OneSlotPerson(iters, iters + 1, iters + 2, iters + 3, iters + 4, iters + 5) + iters = iters + 1 + } +} diff --git a/examples/flat/nooptimized/trigger_one_child_freeing.check b/examples/flat/nooptimized/trigger_one_child_freeing.check new file mode 100644 index 000000000..e69de29bb diff --git a/examples/flat/nooptimized/trigger_one_child_freeing.effekt b/examples/flat/nooptimized/trigger_one_child_freeing.effekt new file mode 100644 index 000000000..a44b4896c --- /dev/null +++ b/examples/flat/nooptimized/trigger_one_child_freeing.effekt @@ -0,0 +1,26 @@ +// a simple program that creates a more complex object +// parent -> child1 +// where child1 is OneSlotPerson + +record OneSlotPerson( + field1: Int, + field2: Int, + field3: Int, + field4: Int, + field5: Int, + field6: Int +) + +record Person( + child1: OneSlotPerson +) + +def main() = { + var iters = 1 + while(iters <= 65) { + var x = Person( + OneSlotPerson(iters, iters + 1, iters + 2, iters + 3, iters + 4, iters + 5) + ) + iters = iters + 1 + } +} diff --git a/examples/flat/nooptimized/trigger_two_child_freeing.check b/examples/flat/nooptimized/trigger_two_child_freeing.check new file mode 100644 index 000000000..e69de29bb diff --git a/examples/flat/nooptimized/trigger_two_child_freeing.effekt b/examples/flat/nooptimized/trigger_two_child_freeing.effekt new file mode 100644 index 000000000..e8eb31933 --- /dev/null +++ b/examples/flat/nooptimized/trigger_two_child_freeing.effekt @@ -0,0 +1,28 @@ +// a simple program that creates a more complex object +// parent -> child1 +// where child1 is OneSlotPerson + +record OneSlotPerson( + field1: Int, + field2: Int, + field3: Int, + field4: Int, + field5: Int, + field6: Int +) + +record Person( + child1: OneSlotPerson, + child2: OneSlotPerson +) + +def main() = { + var iters = 1 + while(iters <= 64) { + var x = Person( + OneSlotPerson(iters, iters + 1, iters + 2, iters + 3, iters + 4, iters + 5), + OneSlotPerson(iters + 6, iters + 7, iters + 8, iters + 9, iters + 10, iters + 11) + ) + iters = iters + 1 + } +} diff --git a/examples/flat/nooptimized/two_lg_objects.check b/examples/flat/nooptimized/two_lg_objects.check new file mode 100644 index 000000000..8f59f50a4 --- /dev/null +++ b/examples/flat/nooptimized/two_lg_objects.check @@ -0,0 +1,2 @@ +10 +16 \ No newline at end of file diff --git a/examples/flat/nooptimized/two_lg_objects.effekt b/examples/flat/nooptimized/two_lg_objects.effekt new file mode 100644 index 000000000..6393bd171 --- /dev/null +++ b/examples/flat/nooptimized/two_lg_objects.effekt @@ -0,0 +1,20 @@ +// lg = Person fills 2 saving slots completely +record Person( + field1: Int, + field2: Int, + field3: Int, + field4: Int, + field5: Int, + field6: Int, + field7: Int, + field8: Int, + field9: Int, + field10: Int + ) + +def main() = { + val p1 = Person(1, 2, 3, 4, 5, 6, 7, 8, 9, 10) + val p2 = Person(11, 12, 13, 14, 15, 16, 17, 18, 19, 20) + println(p1.field10) + println(p2.field6) +} \ No newline at end of file diff --git a/examples/flat/nooptimized/two_md_mixed_object.check b/examples/flat/nooptimized/two_md_mixed_object.check new file mode 100644 index 000000000..f21c60d7e --- /dev/null +++ b/examples/flat/nooptimized/two_md_mixed_object.check @@ -0,0 +1,2 @@ +P1Field2 +10 \ No newline at end of file diff --git a/examples/flat/nooptimized/two_md_mixed_object.effekt b/examples/flat/nooptimized/two_md_mixed_object.effekt new file mode 100644 index 000000000..4d67068e4 --- /dev/null +++ b/examples/flat/nooptimized/two_md_mixed_object.effekt @@ -0,0 +1,17 @@ +// md = Person needs 2 slots +// contains strings and integers. +// First slot contains field1, second slot contains field2, field3, field4, field5. +record Person( + field1: Int, + field2: String, + field3: String, + field4: String, + field5: Int + ) + +def main() = { + val p1 = Person(1, "P1Field2", "P1Field3", "P1Field4", 5) + val p2 = Person(6, "P2Field2", "P2Field3", "P2Field4", 10) + println(p1.field2) + println(p2.field5) +} \ No newline at end of file diff --git a/examples/flat/nooptimized/two_md_objects.check b/examples/flat/nooptimized/two_md_objects.check new file mode 100644 index 000000000..78bd7702c --- /dev/null +++ b/examples/flat/nooptimized/two_md_objects.check @@ -0,0 +1,2 @@ +7 +9 \ No newline at end of file diff --git a/examples/flat/nooptimized/two_md_objects.effekt b/examples/flat/nooptimized/two_md_objects.effekt new file mode 100644 index 000000000..d3bdb013f --- /dev/null +++ b/examples/flat/nooptimized/two_md_objects.effekt @@ -0,0 +1,17 @@ +// md = Person requires 2 saving slots +record Person( + field1: Int, + field2: Int, + field3: Int, + field4: Int, + field5: Int, + field6: Int, + field7: Int + ) + +def main() = { + val p1 = Person(1, 2, 3, 4, 5, 6, 7) + val p2 = Person(8, 9, 10, 11, 12, 13, 14) + println(p1.field7) + println(p2.field2) +} \ No newline at end of file diff --git a/examples/flat/nooptimized/two_slot_one_person_list.check b/examples/flat/nooptimized/two_slot_one_person_list.check new file mode 100644 index 000000000..c7930257d --- /dev/null +++ b/examples/flat/nooptimized/two_slot_one_person_list.check @@ -0,0 +1 @@ +7 \ No newline at end of file diff --git a/examples/flat/nooptimized/two_slot_one_person_list.effekt b/examples/flat/nooptimized/two_slot_one_person_list.effekt new file mode 100644 index 000000000..e15b30ef1 --- /dev/null +++ b/examples/flat/nooptimized/two_slot_one_person_list.effekt @@ -0,0 +1,23 @@ +import list + +record TwoSlotPerson( + field1: Int, + field2: Int, + field3: Int, + field4: Int, + field5: Int, + field6: Int, + field7: Int + ) + +def main() = { + // Creates a list with one element + val person1 = TwoSlotPerson(1, 2, 3, 4, 5, 6, 7) + var myList = [person1] + + // prints 7. If -1 is printed, there is a bug + myList match { + case Nil() => println(-1) + case Cons(x, _) => println(x.field7) + } +} diff --git a/examples/flat/nooptimized/two_slot_one_person_with_free_variable_list.check b/examples/flat/nooptimized/two_slot_one_person_with_free_variable_list.check new file mode 100644 index 000000000..410b14d2c --- /dev/null +++ b/examples/flat/nooptimized/two_slot_one_person_with_free_variable_list.check @@ -0,0 +1 @@ +25 \ No newline at end of file diff --git a/examples/flat/nooptimized/two_slot_one_person_with_free_variable_list.effekt b/examples/flat/nooptimized/two_slot_one_person_with_free_variable_list.effekt new file mode 100644 index 000000000..25bf64831 --- /dev/null +++ b/examples/flat/nooptimized/two_slot_one_person_with_free_variable_list.effekt @@ -0,0 +1,29 @@ +import list + +record TwoSlotPerson( + field1: Int, + field2: Int, + field3: Int, + field4: Int, + field5: Int, + field6: Int, + field7: Int + ) + +def main() = { + // Creates a list with one element + val person1 = TwoSlotPerson(1, 2, 3, 4, 5, 6, 7) + val y = TwoSlotPerson(25, 2, 3, 4, 5, 6, 7) + var myList = [person1] + + // prints 25. If -1 is printed, there is a bug + myList match { + case Nil() => println(-1) + //case Cons(x, _) => println(-2) + case Cons(x, _) => println(y.field1) + //case Cons(x, _) => println(person.field1) + } + + //myList = drop(myList, 1) + //val person3 = person1 +} diff --git a/examples/flat/nooptimized/two_slot_two_person_list.check b/examples/flat/nooptimized/two_slot_two_person_list.check new file mode 100644 index 000000000..bf0d87ab1 --- /dev/null +++ b/examples/flat/nooptimized/two_slot_two_person_list.check @@ -0,0 +1 @@ +4 \ No newline at end of file diff --git a/examples/flat/nooptimized/two_slot_two_person_list.effekt b/examples/flat/nooptimized/two_slot_two_person_list.effekt new file mode 100644 index 000000000..6946a2895 --- /dev/null +++ b/examples/flat/nooptimized/two_slot_two_person_list.effekt @@ -0,0 +1,24 @@ +import list + +record TwoSlotPerson( + field1: Int, + field2: Int, + field3: Int, + field4: Int, + field5: Int, + field6: Int, + field7: Int + ) + +def main() = { + // Creates a list with one element + val person1 = TwoSlotPerson(1, 2, 3, 4, 5, 6, 7) + val person2 = TwoSlotPerson(8, 9, 10, 11, 12, 13, 14) + val myList = [person1, person2] + + // print 4. If -1 is printed, there is a bug + myList match { + case Nil() => println(-1) + case Cons(p1, _) => println(p1.field4) + } +} diff --git a/examples/flat/nooptimized/two_slot_two_person_list_continuation.check b/examples/flat/nooptimized/two_slot_two_person_list_continuation.check new file mode 100644 index 000000000..bf0d87ab1 --- /dev/null +++ b/examples/flat/nooptimized/two_slot_two_person_list_continuation.check @@ -0,0 +1 @@ +4 \ No newline at end of file diff --git a/examples/flat/nooptimized/two_slot_two_person_list_continuation.effekt b/examples/flat/nooptimized/two_slot_two_person_list_continuation.effekt new file mode 100644 index 000000000..0e29c515c --- /dev/null +++ b/examples/flat/nooptimized/two_slot_two_person_list_continuation.effekt @@ -0,0 +1,27 @@ +import list + +record TwoSlotPerson( + field1: Int, + field2: Int, + field3: Int, + field4: Int, + field5: Int, + field6: Int, + field7: Int + ) + +def main() = { + // Creates a list with one element + val person1 = TwoSlotPerson(1, 2, 3, 4, 5, 6, 7) + val person2 = TwoSlotPerson(8, 9, 10, 11, 12, 13, 14) + val myList = [person1, person2] + + // print 4. If -1 is printed, there is a bug + myList match { + case Nil() => println(-1) + case Cons(p1, _) => println(p1.field4) // here, we shorten it to _ + } + + // we continue the program here, so the compiler does not erase myList immediately after the Switch statement + val isEmpty = isEmpty(myList) +} \ No newline at end of file diff --git a/examples/flat/nooptimized/two_slot_two_person_list_continuation_allocation.check b/examples/flat/nooptimized/two_slot_two_person_list_continuation_allocation.check new file mode 100644 index 000000000..a246a2d52 --- /dev/null +++ b/examples/flat/nooptimized/two_slot_two_person_list_continuation_allocation.check @@ -0,0 +1,2 @@ +4 +24 \ No newline at end of file diff --git a/examples/flat/nooptimized/two_slot_two_person_list_continuation_allocation.effekt b/examples/flat/nooptimized/two_slot_two_person_list_continuation_allocation.effekt new file mode 100644 index 000000000..03036c9c5 --- /dev/null +++ b/examples/flat/nooptimized/two_slot_two_person_list_continuation_allocation.effekt @@ -0,0 +1,45 @@ +import list + +record TwoSlotPerson( + field1: Int, + field2: Int, + field3: Int, + field4: Int, + field5: Int, + field6: Int, + field7: Int + ) + +record ThreeSlotPerson( + field1: Int, + field2: Int, + field3: Int, + field4: Int, + field5: Int, + field6: Int, + field7: Int, + field8: Int, + field9: Int, + field10: Int, + field11: Int + ) + +def main() = { + // Creates a list with one element + val person1 = TwoSlotPerson(1, 2, 3, 4, 5, 6, 7) + val person2 = TwoSlotPerson(8, 9, 10, 11, 12, 13, 14) + val myList = [person1, person2] + + // print 4. If -1 is printed, there is a bug + myList match { + case Nil() => println(-1) + case Cons(p1, _) => println(p1.field4) // here, we shorten it to _ + } + + // we continue the program here, so the compiler does not erase myList immediately after the Switch statement + val isEmpty = isEmpty(myList) + + // reuse the freed slots again to look how the storage looks like + val p3 = ThreeSlotPerson(14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24) + println(p3.field11) +} \ No newline at end of file diff --git a/examples/flat/nooptimized/two_slot_two_person_list_continuation_exhausted.check b/examples/flat/nooptimized/two_slot_two_person_list_continuation_exhausted.check new file mode 100644 index 000000000..bf0d87ab1 --- /dev/null +++ b/examples/flat/nooptimized/two_slot_two_person_list_continuation_exhausted.check @@ -0,0 +1 @@ +4 \ No newline at end of file diff --git a/examples/flat/nooptimized/two_slot_two_person_list_continuation_exhausted.effekt b/examples/flat/nooptimized/two_slot_two_person_list_continuation_exhausted.effekt new file mode 100644 index 000000000..d064888aa --- /dev/null +++ b/examples/flat/nooptimized/two_slot_two_person_list_continuation_exhausted.effekt @@ -0,0 +1,27 @@ +import list + +record TwoSlotPerson( + field1: Int, + field2: Int, + field3: Int, + field4: Int, + field5: Int, + field6: Int, + field7: Int + ) + +def main() = { + // Creates a list with one element + val person1 = TwoSlotPerson(1, 2, 3, 4, 5, 6, 7) + val person2 = TwoSlotPerson(8, 9, 10, 11, 12, 13, 14) + val myList = [person1, person2] + + // print 4. If -1 is printed, there is a bug + myList match { + case Nil() => println(-1) + case Cons(p1, cont) => println(p1.field4) // here, we declare cont. It makes a difference for the release function + } + + // we continue the program here, so the compiler does not erase myList immediately after the Switch statement + val isEmpty = isEmpty(myList) +} \ No newline at end of file diff --git a/examples/flat/nooptimized/two_slot_two_person_list_exhausted.check b/examples/flat/nooptimized/two_slot_two_person_list_exhausted.check new file mode 100644 index 000000000..bf0d87ab1 --- /dev/null +++ b/examples/flat/nooptimized/two_slot_two_person_list_exhausted.check @@ -0,0 +1 @@ +4 \ No newline at end of file diff --git a/examples/flat/nooptimized/two_slot_two_person_list_exhausted.effekt b/examples/flat/nooptimized/two_slot_two_person_list_exhausted.effekt new file mode 100644 index 000000000..66ee8acbe --- /dev/null +++ b/examples/flat/nooptimized/two_slot_two_person_list_exhausted.effekt @@ -0,0 +1,24 @@ +import list + +record TwoSlotPerson( + field1: Int, + field2: Int, + field3: Int, + field4: Int, + field5: Int, + field6: Int, + field7: Int + ) + +def main() = { + // Creates a list with one element + val person1 = TwoSlotPerson(1, 2, 3, 4, 5, 6, 7) + val person2 = TwoSlotPerson(8, 9, 10, 11, 12, 13, 14) + val myList = [person1, person2] + + // print 4. If -1 is printed, there is a bug + myList match { + case Nil() => println(-1) + case Cons(p1, cont) => println(p1.field4) + } +} diff --git a/examples/flat/nooptimized/two_slot_two_person_with_free_variable_list.check b/examples/flat/nooptimized/two_slot_two_person_with_free_variable_list.check new file mode 100644 index 000000000..410b14d2c --- /dev/null +++ b/examples/flat/nooptimized/two_slot_two_person_with_free_variable_list.check @@ -0,0 +1 @@ +25 \ No newline at end of file diff --git a/examples/flat/nooptimized/two_slot_two_person_with_free_variable_list.effekt b/examples/flat/nooptimized/two_slot_two_person_with_free_variable_list.effekt new file mode 100644 index 000000000..4e0df6426 --- /dev/null +++ b/examples/flat/nooptimized/two_slot_two_person_with_free_variable_list.effekt @@ -0,0 +1,29 @@ +import list + +record TwoSlotPerson( + field1: Int, + field2: Int, + field3: Int, + field4: Int, + field5: Int, + field6: Int, + field7: Int + ) + +def main() = { + // Creates a list with one element + val person1 = TwoSlotPerson(1, 2, 3, 4, 5, 6, 7) + val person2 = TwoSlotPerson(8, 9, 10, 11, 12, 13, 14) + val y = TwoSlotPerson(25, 2, 3, 4, 5, 6, 7) + var myList = [person1, person2] + + + // prints 25. If -1 is printed, there is a bug + myList match { + case Nil() => println(-1) + case Cons(x, xs) => xs match { + case Nil() => println(y.field2) + case Cons(z, _) => println(y.field1) + } + } +} diff --git a/examples/flat/nooptimized/two_sm_mixed_object.check b/examples/flat/nooptimized/two_sm_mixed_object.check new file mode 100644 index 000000000..ca3d17d48 --- /dev/null +++ b/examples/flat/nooptimized/two_sm_mixed_object.check @@ -0,0 +1,2 @@ +P1Field1 +8 \ No newline at end of file diff --git a/examples/flat/nooptimized/two_sm_mixed_object.effekt b/examples/flat/nooptimized/two_sm_mixed_object.effekt new file mode 100644 index 000000000..c07c2af92 --- /dev/null +++ b/examples/flat/nooptimized/two_sm_mixed_object.effekt @@ -0,0 +1,15 @@ +// sm = Person fills 1 saving slot completely +// contains strings and integers +record Person( + field1: String, + field2: Int, + field3: String, + field4: Int + ) + +def main() = { + val p1 = Person("P1Field1", 2, "P1Field3", 4) + val p2 = Person("P2Field1", 6, "P2Field3", 8) + println(p1.field1) + println(p2.field4) +} \ No newline at end of file diff --git a/examples/flat/nooptimized/two_sm_objects.check b/examples/flat/nooptimized/two_sm_objects.check new file mode 100644 index 000000000..b8a0ddcef --- /dev/null +++ b/examples/flat/nooptimized/two_sm_objects.check @@ -0,0 +1,2 @@ +6 +8 \ No newline at end of file diff --git a/examples/flat/nooptimized/two_sm_objects.effekt b/examples/flat/nooptimized/two_sm_objects.effekt new file mode 100644 index 000000000..a1d1d206c --- /dev/null +++ b/examples/flat/nooptimized/two_sm_objects.effekt @@ -0,0 +1,16 @@ +// sm = Person fills 1 saving slot completely +record Person( + field1: Int, + field2: Int, + field3: Int, + field4: Int, + field5: Int, + field6: Int + ) + +def main() = { + val p1 = Person(1, 2, 3, 4, 5, 6) + val p2 = Person(7, 8, 9, 10, 11, 12) + println(p1.field6) + println(p2.field2) +} \ No newline at end of file diff --git a/examples/flat/nooptimized/two_xl_objects.check b/examples/flat/nooptimized/two_xl_objects.check new file mode 100644 index 000000000..10afbfb7e --- /dev/null +++ b/examples/flat/nooptimized/two_xl_objects.check @@ -0,0 +1,2 @@ +11 +18 \ No newline at end of file diff --git a/examples/flat/nooptimized/two_xl_objects.effekt b/examples/flat/nooptimized/two_xl_objects.effekt new file mode 100644 index 000000000..e5628b0b7 --- /dev/null +++ b/examples/flat/nooptimized/two_xl_objects.effekt @@ -0,0 +1,21 @@ +// xl = Person needs 3 saving slots +record Person( + field1: Int, + field2: Int, + field3: Int, + field4: Int, + field5: Int, + field6: Int, + field7: Int, + field8: Int, + field9: Int, + field10: Int, + field11: Int + ) + +def main() = { + val p1 = Person(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11) + val p2 = Person(12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22) + println(p1.field11) + println(p2.field7) +} \ No newline at end of file diff --git a/examples/flat/nooptimized/two_xs_objects.check b/examples/flat/nooptimized/two_xs_objects.check new file mode 100644 index 000000000..69cc3abe5 --- /dev/null +++ b/examples/flat/nooptimized/two_xs_objects.check @@ -0,0 +1,2 @@ +3 +5 \ No newline at end of file diff --git a/examples/flat/nooptimized/two_xs_objects.effekt b/examples/flat/nooptimized/two_xs_objects.effekt new file mode 100644 index 000000000..02f18b3a9 --- /dev/null +++ b/examples/flat/nooptimized/two_xs_objects.effekt @@ -0,0 +1,13 @@ +// xs = Person fits easily in 1 saving slot +record Person( + field1: Int, + field2: Int, + field3: Int + ) + +def main() = { + val p1 = Person(1, 2, 3) + val p2 = Person(4, 5, 6) + println(p1.field3) + println(p2.field2) +} \ No newline at end of file diff --git a/examples/flat/nooptimized/two_xxl_object_all_fields.check b/examples/flat/nooptimized/two_xxl_object_all_fields.check new file mode 100644 index 000000000..6a0bcb871 --- /dev/null +++ b/examples/flat/nooptimized/two_xxl_object_all_fields.check @@ -0,0 +1,100 @@ +1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +11 +12 +13 +14 +15 +16 +17 +18 +19 +20 +21 +22 +23 +24 +25 +26 +27 +28 +29 +30 +31 +32 +33 +34 +35 +36 +37 +38 +39 +40 +41 +42 +43 +44 +45 +46 +47 +48 +49 +50 +51 +52 +53 +54 +55 +56 +57 +58 +59 +60 +61 +62 +63 +64 +65 +66 +67 +68 +69 +70 +71 +72 +73 +74 +75 +76 +77 +78 +79 +80 +81 +82 +83 +84 +85 +86 +87 +88 +89 +90 +91 +92 +93 +94 +95 +96 +97 +98 +99 +100 \ No newline at end of file diff --git a/examples/flat/nooptimized/two_xxl_object_all_fields.effekt b/examples/flat/nooptimized/two_xxl_object_all_fields.effekt new file mode 100644 index 000000000..824a4b603 --- /dev/null +++ b/examples/flat/nooptimized/two_xxl_object_all_fields.effekt @@ -0,0 +1,308 @@ +// xxl: Person has 100 fields -> need x slots +record Person( + field1: Int, + field2: Int, + field3: Int, + field4: Int, + field5: Int, + field6: Int, + field7: Int, + field8: Int, + field9: Int, + field10: Int, + field11: Int, + field12: Int, + field13: Int, + field14: Int, + field15: Int, + field16: Int, + field17: Int, + field18: Int, + field19: Int, + field20: Int, + field21: Int, + field22: Int, + field23: Int, + field24: Int, + field25: Int, + field26: Int, + field27: Int, + field28: Int, + field29: Int, + field30: Int, + field31: Int, + field32: Int, + field33: Int, + field34: Int, + field35: Int, + field36: Int, + field37: Int, + field38: Int, + field39: Int, + field40: Int, + field41: Int, + field42: Int, + field43: Int, + field44: Int, + field45: Int, + field46: Int, + field47: Int, + field48: Int, + field49: Int, + field50: Int, + field51: Int, + field52: Int, + field53: Int, + field54: Int, + field55: Int, + field56: Int, + field57: Int, + field58: Int, + field59: Int, + field60: Int, + field61: Int, + field62: Int, + field63: Int, + field64: Int, + field65: Int, + field66: Int, + field67: Int, + field68: Int, + field69: Int, + field70: Int, + field71: Int, + field72: Int, + field73: Int, + field74: Int, + field75: Int, + field76: Int, + field77: Int, + field78: Int, + field79: Int, + field80: Int, + field81: Int, + field82: Int, + field83: Int, + field84: Int, + field85: Int, + field86: Int, + field87: Int, + field88: Int, + field89: Int, + field90: Int, + field91: Int, + field92: Int, + field93: Int, + field94: Int, + field95: Int, + field96: Int, + field97: Int, + field98: Int, + field99: Int, + field100: Int +) + +def main() = { + val p1 = Person( + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, + 17, + 18, + 19, + 20, + 21, + 22, + 23, + 24, + 25, + 26, + 27, + 28, + 29, + 30, + 31, + 32, + 33, + 34, + 35, + 36, + 37, + 38, + 39, + 40, + 41, + 42, + 43, + 44, + 45, + 46, + 47, + 48, + 49, + 50, + 51, + 52, + 53, + 54, + 55, + 56, + 57, + 58, + 59, + 60, + 61, + 62, + 63, + 64, + 65, + 66, + 67, + 68, + 69, + 70, + 71, + 72, + 73, + 74, + 75, + 76, + 77, + 78, + 79, + 80, + 81, + 82, + 83, + 84, + 85, + 86, + 87, + 88, + 89, + 90, + 91, + 92, + 93, + 94, + 95, + 96, + 97, + 98, + 99, + 100 +) + println(p1.field1) + println(p1.field2) + println(p1.field3) + println(p1.field4) + println(p1.field5) + println(p1.field6) + println(p1.field7) + println(p1.field8) + println(p1.field9) + println(p1.field10) + println(p1.field11) + println(p1.field12) + println(p1.field13) + println(p1.field14) + println(p1.field15) + println(p1.field16) + println(p1.field17) + println(p1.field18) + println(p1.field19) + println(p1.field20) + println(p1.field21) + println(p1.field22) + println(p1.field23) + println(p1.field24) + println(p1.field25) + println(p1.field26) + println(p1.field27) + println(p1.field28) + println(p1.field29) + println(p1.field30) + println(p1.field31) + println(p1.field32) + println(p1.field33) + println(p1.field34) + println(p1.field35) + println(p1.field36) + println(p1.field37) + println(p1.field38) + println(p1.field39) + println(p1.field40) + println(p1.field41) + println(p1.field42) + println(p1.field43) + println(p1.field44) + println(p1.field45) + println(p1.field46) + println(p1.field47) + println(p1.field48) + println(p1.field49) + println(p1.field50) + println(p1.field51) + println(p1.field52) + println(p1.field53) + println(p1.field54) + println(p1.field55) + println(p1.field56) + println(p1.field57) + println(p1.field58) + println(p1.field59) + println(p1.field60) + println(p1.field61) + println(p1.field62) + println(p1.field63) + println(p1.field64) + println(p1.field65) + println(p1.field66) + println(p1.field67) + println(p1.field68) + println(p1.field69) + println(p1.field70) + println(p1.field71) + println(p1.field72) + println(p1.field73) + println(p1.field74) + println(p1.field75) + println(p1.field76) + println(p1.field77) + println(p1.field78) + println(p1.field79) + println(p1.field80) + println(p1.field81) + println(p1.field82) + println(p1.field83) + println(p1.field84) + println(p1.field85) + println(p1.field86) + println(p1.field87) + println(p1.field88) + println(p1.field89) + println(p1.field90) + println(p1.field91) + println(p1.field92) + println(p1.field93) + println(p1.field94) + println(p1.field95) + println(p1.field96) + println(p1.field97) + println(p1.field98) + println(p1.field99) + println(p1.field100) +} \ No newline at end of file diff --git a/examples/flat/nooptimized/two_xxl_objects.check b/examples/flat/nooptimized/two_xxl_objects.check new file mode 100644 index 000000000..2a817d143 --- /dev/null +++ b/examples/flat/nooptimized/two_xxl_objects.check @@ -0,0 +1,2 @@ +100 +151 \ No newline at end of file diff --git a/examples/flat/nooptimized/two_xxl_objects.effekt b/examples/flat/nooptimized/two_xxl_objects.effekt new file mode 100644 index 000000000..7258d179a --- /dev/null +++ b/examples/flat/nooptimized/two_xxl_objects.effekt @@ -0,0 +1,312 @@ +// xxl: Person has 100 fields -> need x slots +record Person( + field1: Int, + field2: Int, + field3: Int, + field4: Int, + field5: Int, + field6: Int, + field7: Int, + field8: Int, + field9: Int, + field10: Int, + field11: Int, + field12: Int, + field13: Int, + field14: Int, + field15: Int, + field16: Int, + field17: Int, + field18: Int, + field19: Int, + field20: Int, + field21: Int, + field22: Int, + field23: Int, + field24: Int, + field25: Int, + field26: Int, + field27: Int, + field28: Int, + field29: Int, + field30: Int, + field31: Int, + field32: Int, + field33: Int, + field34: Int, + field35: Int, + field36: Int, + field37: Int, + field38: Int, + field39: Int, + field40: Int, + field41: Int, + field42: Int, + field43: Int, + field44: Int, + field45: Int, + field46: Int, + field47: Int, + field48: Int, + field49: Int, + field50: Int, + field51: Int, + field52: Int, + field53: Int, + field54: Int, + field55: Int, + field56: Int, + field57: Int, + field58: Int, + field59: Int, + field60: Int, + field61: Int, + field62: Int, + field63: Int, + field64: Int, + field65: Int, + field66: Int, + field67: Int, + field68: Int, + field69: Int, + field70: Int, + field71: Int, + field72: Int, + field73: Int, + field74: Int, + field75: Int, + field76: Int, + field77: Int, + field78: Int, + field79: Int, + field80: Int, + field81: Int, + field82: Int, + field83: Int, + field84: Int, + field85: Int, + field86: Int, + field87: Int, + field88: Int, + field89: Int, + field90: Int, + field91: Int, + field92: Int, + field93: Int, + field94: Int, + field95: Int, + field96: Int, + field97: Int, + field98: Int, + field99: Int, + field100: Int +) + +def main() = { + val p1 = Person( + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, + 17, + 18, + 19, + 20, + 21, + 22, + 23, + 24, + 25, + 26, + 27, + 28, + 29, + 30, + 31, + 32, + 33, + 34, + 35, + 36, + 37, + 38, + 39, + 40, + 41, + 42, + 43, + 44, + 45, + 46, + 47, + 48, + 49, + 50, + 51, + 52, + 53, + 54, + 55, + 56, + 57, + 58, + 59, + 60, + 61, + 62, + 63, + 64, + 65, + 66, + 67, + 68, + 69, + 70, + 71, + 72, + 73, + 74, + 75, + 76, + 77, + 78, + 79, + 80, + 81, + 82, + 83, + 84, + 85, + 86, + 87, + 88, + 89, + 90, + 91, + 92, + 93, + 94, + 95, + 96, + 97, + 98, + 99, + 100 +) + val p2 = Person( + 101, + 102, + 103, + 104, + 105, + 106, + 107, + 108, + 109, + 110, + 111, + 112, + 113, + 114, + 115, + 116, + 117, + 118, + 119, + 120, + 121, + 122, + 123, + 124, + 125, + 126, + 127, + 128, + 129, + 130, + 131, + 132, + 133, + 134, + 135, + 136, + 137, + 138, + 139, + 140, + 141, + 142, + 143, + 144, + 145, + 146, + 147, + 148, + 149, + 150, + 151, + 152, + 153, + 154, + 155, + 156, + 157, + 158, + 159, + 160, + 161, + 162, + 163, + 164, + 165, + 166, + 167, + 168, + 169, + 170, + 171, + 172, + 173, + 174, + 175, + 176, + 177, + 178, + 179, + 180, + 181, + 182, + 183, + 184, + 185, + 186, + 187, + 188, + 189, + 190, + 191, + 192, + 193, + 194, + 195, + 196, + 197, + 198, + 199, + 200 +) + println(p1.field100) + println(p2.field51) +} \ No newline at end of file diff --git a/examples/flat/nooptimized/two_xxxl_objects.check b/examples/flat/nooptimized/two_xxxl_objects.check new file mode 100644 index 000000000..f10f03bb2 --- /dev/null +++ b/examples/flat/nooptimized/two_xxxl_objects.check @@ -0,0 +1,2 @@ +500 +999 \ No newline at end of file diff --git a/examples/flat/nooptimized/two_xxxl_objects.effekt b/examples/flat/nooptimized/two_xxxl_objects.effekt new file mode 100644 index 000000000..0e3ee0511 --- /dev/null +++ b/examples/flat/nooptimized/two_xxxl_objects.effekt @@ -0,0 +1,1512 @@ +// xxxl: Person has 500 fields -> need x slots +record Person( + field1: Int, + field2: Int, + field3: Int, + field4: Int, + field5: Int, + field6: Int, + field7: Int, + field8: Int, + field9: Int, + field10: Int, + field11: Int, + field12: Int, + field13: Int, + field14: Int, + field15: Int, + field16: Int, + field17: Int, + field18: Int, + field19: Int, + field20: Int, + field21: Int, + field22: Int, + field23: Int, + field24: Int, + field25: Int, + field26: Int, + field27: Int, + field28: Int, + field29: Int, + field30: Int, + field31: Int, + field32: Int, + field33: Int, + field34: Int, + field35: Int, + field36: Int, + field37: Int, + field38: Int, + field39: Int, + field40: Int, + field41: Int, + field42: Int, + field43: Int, + field44: Int, + field45: Int, + field46: Int, + field47: Int, + field48: Int, + field49: Int, + field50: Int, + field51: Int, + field52: Int, + field53: Int, + field54: Int, + field55: Int, + field56: Int, + field57: Int, + field58: Int, + field59: Int, + field60: Int, + field61: Int, + field62: Int, + field63: Int, + field64: Int, + field65: Int, + field66: Int, + field67: Int, + field68: Int, + field69: Int, + field70: Int, + field71: Int, + field72: Int, + field73: Int, + field74: Int, + field75: Int, + field76: Int, + field77: Int, + field78: Int, + field79: Int, + field80: Int, + field81: Int, + field82: Int, + field83: Int, + field84: Int, + field85: Int, + field86: Int, + field87: Int, + field88: Int, + field89: Int, + field90: Int, + field91: Int, + field92: Int, + field93: Int, + field94: Int, + field95: Int, + field96: Int, + field97: Int, + field98: Int, + field99: Int, + field100: Int, + field101: Int, + field102: Int, + field103: Int, + field104: Int, + field105: Int, + field106: Int, + field107: Int, + field108: Int, + field109: Int, + field110: Int, + field111: Int, + field112: Int, + field113: Int, + field114: Int, + field115: Int, + field116: Int, + field117: Int, + field118: Int, + field119: Int, + field120: Int, + field121: Int, + field122: Int, + field123: Int, + field124: Int, + field125: Int, + field126: Int, + field127: Int, + field128: Int, + field129: Int, + field130: Int, + field131: Int, + field132: Int, + field133: Int, + field134: Int, + field135: Int, + field136: Int, + field137: Int, + field138: Int, + field139: Int, + field140: Int, + field141: Int, + field142: Int, + field143: Int, + field144: Int, + field145: Int, + field146: Int, + field147: Int, + field148: Int, + field149: Int, + field150: Int, + field151: Int, + field152: Int, + field153: Int, + field154: Int, + field155: Int, + field156: Int, + field157: Int, + field158: Int, + field159: Int, + field160: Int, + field161: Int, + field162: Int, + field163: Int, + field164: Int, + field165: Int, + field166: Int, + field167: Int, + field168: Int, + field169: Int, + field170: Int, + field171: Int, + field172: Int, + field173: Int, + field174: Int, + field175: Int, + field176: Int, + field177: Int, + field178: Int, + field179: Int, + field180: Int, + field181: Int, + field182: Int, + field183: Int, + field184: Int, + field185: Int, + field186: Int, + field187: Int, + field188: Int, + field189: Int, + field190: Int, + field191: Int, + field192: Int, + field193: Int, + field194: Int, + field195: Int, + field196: Int, + field197: Int, + field198: Int, + field199: Int, + field200: Int, + field201: Int, + field202: Int, + field203: Int, + field204: Int, + field205: Int, + field206: Int, + field207: Int, + field208: Int, + field209: Int, + field210: Int, + field211: Int, + field212: Int, + field213: Int, + field214: Int, + field215: Int, + field216: Int, + field217: Int, + field218: Int, + field219: Int, + field220: Int, + field221: Int, + field222: Int, + field223: Int, + field224: Int, + field225: Int, + field226: Int, + field227: Int, + field228: Int, + field229: Int, + field230: Int, + field231: Int, + field232: Int, + field233: Int, + field234: Int, + field235: Int, + field236: Int, + field237: Int, + field238: Int, + field239: Int, + field240: Int, + field241: Int, + field242: Int, + field243: Int, + field244: Int, + field245: Int, + field246: Int, + field247: Int, + field248: Int, + field249: Int, + field250: Int, + field251: Int, + field252: Int, + field253: Int, + field254: Int, + field255: Int, + field256: Int, + field257: Int, + field258: Int, + field259: Int, + field260: Int, + field261: Int, + field262: Int, + field263: Int, + field264: Int, + field265: Int, + field266: Int, + field267: Int, + field268: Int, + field269: Int, + field270: Int, + field271: Int, + field272: Int, + field273: Int, + field274: Int, + field275: Int, + field276: Int, + field277: Int, + field278: Int, + field279: Int, + field280: Int, + field281: Int, + field282: Int, + field283: Int, + field284: Int, + field285: Int, + field286: Int, + field287: Int, + field288: Int, + field289: Int, + field290: Int, + field291: Int, + field292: Int, + field293: Int, + field294: Int, + field295: Int, + field296: Int, + field297: Int, + field298: Int, + field299: Int, + field300: Int, + field301: Int, + field302: Int, + field303: Int, + field304: Int, + field305: Int, + field306: Int, + field307: Int, + field308: Int, + field309: Int, + field310: Int, + field311: Int, + field312: Int, + field313: Int, + field314: Int, + field315: Int, + field316: Int, + field317: Int, + field318: Int, + field319: Int, + field320: Int, + field321: Int, + field322: Int, + field323: Int, + field324: Int, + field325: Int, + field326: Int, + field327: Int, + field328: Int, + field329: Int, + field330: Int, + field331: Int, + field332: Int, + field333: Int, + field334: Int, + field335: Int, + field336: Int, + field337: Int, + field338: Int, + field339: Int, + field340: Int, + field341: Int, + field342: Int, + field343: Int, + field344: Int, + field345: Int, + field346: Int, + field347: Int, + field348: Int, + field349: Int, + field350: Int, + field351: Int, + field352: Int, + field353: Int, + field354: Int, + field355: Int, + field356: Int, + field357: Int, + field358: Int, + field359: Int, + field360: Int, + field361: Int, + field362: Int, + field363: Int, + field364: Int, + field365: Int, + field366: Int, + field367: Int, + field368: Int, + field369: Int, + field370: Int, + field371: Int, + field372: Int, + field373: Int, + field374: Int, + field375: Int, + field376: Int, + field377: Int, + field378: Int, + field379: Int, + field380: Int, + field381: Int, + field382: Int, + field383: Int, + field384: Int, + field385: Int, + field386: Int, + field387: Int, + field388: Int, + field389: Int, + field390: Int, + field391: Int, + field392: Int, + field393: Int, + field394: Int, + field395: Int, + field396: Int, + field397: Int, + field398: Int, + field399: Int, + field400: Int, + field401: Int, + field402: Int, + field403: Int, + field404: Int, + field405: Int, + field406: Int, + field407: Int, + field408: Int, + field409: Int, + field410: Int, + field411: Int, + field412: Int, + field413: Int, + field414: Int, + field415: Int, + field416: Int, + field417: Int, + field418: Int, + field419: Int, + field420: Int, + field421: Int, + field422: Int, + field423: Int, + field424: Int, + field425: Int, + field426: Int, + field427: Int, + field428: Int, + field429: Int, + field430: Int, + field431: Int, + field432: Int, + field433: Int, + field434: Int, + field435: Int, + field436: Int, + field437: Int, + field438: Int, + field439: Int, + field440: Int, + field441: Int, + field442: Int, + field443: Int, + field444: Int, + field445: Int, + field446: Int, + field447: Int, + field448: Int, + field449: Int, + field450: Int, + field451: Int, + field452: Int, + field453: Int, + field454: Int, + field455: Int, + field456: Int, + field457: Int, + field458: Int, + field459: Int, + field460: Int, + field461: Int, + field462: Int, + field463: Int, + field464: Int, + field465: Int, + field466: Int, + field467: Int, + field468: Int, + field469: Int, + field470: Int, + field471: Int, + field472: Int, + field473: Int, + field474: Int, + field475: Int, + field476: Int, + field477: Int, + field478: Int, + field479: Int, + field480: Int, + field481: Int, + field482: Int, + field483: Int, + field484: Int, + field485: Int, + field486: Int, + field487: Int, + field488: Int, + field489: Int, + field490: Int, + field491: Int, + field492: Int, + field493: Int, + field494: Int, + field495: Int, + field496: Int, + field497: Int, + field498: Int, + field499: Int, + field500: Int +) + +def main() = { + val p1 = Person( + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, + 17, + 18, + 19, + 20, + 21, + 22, + 23, + 24, + 25, + 26, + 27, + 28, + 29, + 30, + 31, + 32, + 33, + 34, + 35, + 36, + 37, + 38, + 39, + 40, + 41, + 42, + 43, + 44, + 45, + 46, + 47, + 48, + 49, + 50, + 51, + 52, + 53, + 54, + 55, + 56, + 57, + 58, + 59, + 60, + 61, + 62, + 63, + 64, + 65, + 66, + 67, + 68, + 69, + 70, + 71, + 72, + 73, + 74, + 75, + 76, + 77, + 78, + 79, + 80, + 81, + 82, + 83, + 84, + 85, + 86, + 87, + 88, + 89, + 90, + 91, + 92, + 93, + 94, + 95, + 96, + 97, + 98, + 99, + 100, + 101, + 102, + 103, + 104, + 105, + 106, + 107, + 108, + 109, + 110, + 111, + 112, + 113, + 114, + 115, + 116, + 117, + 118, + 119, + 120, + 121, + 122, + 123, + 124, + 125, + 126, + 127, + 128, + 129, + 130, + 131, + 132, + 133, + 134, + 135, + 136, + 137, + 138, + 139, + 140, + 141, + 142, + 143, + 144, + 145, + 146, + 147, + 148, + 149, + 150, + 151, + 152, + 153, + 154, + 155, + 156, + 157, + 158, + 159, + 160, + 161, + 162, + 163, + 164, + 165, + 166, + 167, + 168, + 169, + 170, + 171, + 172, + 173, + 174, + 175, + 176, + 177, + 178, + 179, + 180, + 181, + 182, + 183, + 184, + 185, + 186, + 187, + 188, + 189, + 190, + 191, + 192, + 193, + 194, + 195, + 196, + 197, + 198, + 199, + 200, + 201, + 202, + 203, + 204, + 205, + 206, + 207, + 208, + 209, + 210, + 211, + 212, + 213, + 214, + 215, + 216, + 217, + 218, + 219, + 220, + 221, + 222, + 223, + 224, + 225, + 226, + 227, + 228, + 229, + 230, + 231, + 232, + 233, + 234, + 235, + 236, + 237, + 238, + 239, + 240, + 241, + 242, + 243, + 244, + 245, + 246, + 247, + 248, + 249, + 250, + 251, + 252, + 253, + 254, + 255, + 256, + 257, + 258, + 259, + 260, + 261, + 262, + 263, + 264, + 265, + 266, + 267, + 268, + 269, + 270, + 271, + 272, + 273, + 274, + 275, + 276, + 277, + 278, + 279, + 280, + 281, + 282, + 283, + 284, + 285, + 286, + 287, + 288, + 289, + 290, + 291, + 292, + 293, + 294, + 295, + 296, + 297, + 298, + 299, + 300, + 301, + 302, + 303, + 304, + 305, + 306, + 307, + 308, + 309, + 310, + 311, + 312, + 313, + 314, + 315, + 316, + 317, + 318, + 319, + 320, + 321, + 322, + 323, + 324, + 325, + 326, + 327, + 328, + 329, + 330, + 331, + 332, + 333, + 334, + 335, + 336, + 337, + 338, + 339, + 340, + 341, + 342, + 343, + 344, + 345, + 346, + 347, + 348, + 349, + 350, + 351, + 352, + 353, + 354, + 355, + 356, + 357, + 358, + 359, + 360, + 361, + 362, + 363, + 364, + 365, + 366, + 367, + 368, + 369, + 370, + 371, + 372, + 373, + 374, + 375, + 376, + 377, + 378, + 379, + 380, + 381, + 382, + 383, + 384, + 385, + 386, + 387, + 388, + 389, + 390, + 391, + 392, + 393, + 394, + 395, + 396, + 397, + 398, + 399, + 400, + 401, + 402, + 403, + 404, + 405, + 406, + 407, + 408, + 409, + 410, + 411, + 412, + 413, + 414, + 415, + 416, + 417, + 418, + 419, + 420, + 421, + 422, + 423, + 424, + 425, + 426, + 427, + 428, + 429, + 430, + 431, + 432, + 433, + 434, + 435, + 436, + 437, + 438, + 439, + 440, + 441, + 442, + 443, + 444, + 445, + 446, + 447, + 448, + 449, + 450, + 451, + 452, + 453, + 454, + 455, + 456, + 457, + 458, + 459, + 460, + 461, + 462, + 463, + 464, + 465, + 466, + 467, + 468, + 469, + 470, + 471, + 472, + 473, + 474, + 475, + 476, + 477, + 478, + 479, + 480, + 481, + 482, + 483, + 484, + 485, + 486, + 487, + 488, + 489, + 490, + 491, + 492, + 493, + 494, + 495, + 496, + 497, + 498, + 499, + 500 +) + val p2 = Person( + 501, + 502, + 503, + 504, + 505, + 506, + 507, + 508, + 509, + 510, + 511, + 512, + 513, + 514, + 515, + 516, + 517, + 518, + 519, + 520, + 521, + 522, + 523, + 524, + 525, + 526, + 527, + 528, + 529, + 530, + 531, + 532, + 533, + 534, + 535, + 536, + 537, + 538, + 539, + 540, + 541, + 542, + 543, + 544, + 545, + 546, + 547, + 548, + 549, + 550, + 551, + 552, + 553, + 554, + 555, + 556, + 557, + 558, + 559, + 560, + 561, + 562, + 563, + 564, + 565, + 566, + 567, + 568, + 569, + 570, + 571, + 572, + 573, + 574, + 575, + 576, + 577, + 578, + 579, + 580, + 581, + 582, + 583, + 584, + 585, + 586, + 587, + 588, + 589, + 590, + 591, + 592, + 593, + 594, + 595, + 596, + 597, + 598, + 599, + 600, + 601, + 602, + 603, + 604, + 605, + 606, + 607, + 608, + 609, + 610, + 611, + 612, + 613, + 614, + 615, + 616, + 617, + 618, + 619, + 620, + 621, + 622, + 623, + 624, + 625, + 626, + 627, + 628, + 629, + 630, + 631, + 632, + 633, + 634, + 635, + 636, + 637, + 638, + 639, + 640, + 641, + 642, + 643, + 644, + 645, + 646, + 647, + 648, + 649, + 650, + 651, + 652, + 653, + 654, + 655, + 656, + 657, + 658, + 659, + 660, + 661, + 662, + 663, + 664, + 665, + 666, + 667, + 668, + 669, + 670, + 671, + 672, + 673, + 674, + 675, + 676, + 677, + 678, + 679, + 680, + 681, + 682, + 683, + 684, + 685, + 686, + 687, + 688, + 689, + 690, + 691, + 692, + 693, + 694, + 695, + 696, + 697, + 698, + 699, + 700, + 701, + 702, + 703, + 704, + 705, + 706, + 707, + 708, + 709, + 710, + 711, + 712, + 713, + 714, + 715, + 716, + 717, + 718, + 719, + 720, + 721, + 722, + 723, + 724, + 725, + 726, + 727, + 728, + 729, + 730, + 731, + 732, + 733, + 734, + 735, + 736, + 737, + 738, + 739, + 740, + 741, + 742, + 743, + 744, + 745, + 746, + 747, + 748, + 749, + 750, + 751, + 752, + 753, + 754, + 755, + 756, + 757, + 758, + 759, + 760, + 761, + 762, + 763, + 764, + 765, + 766, + 767, + 768, + 769, + 770, + 771, + 772, + 773, + 774, + 775, + 776, + 777, + 778, + 779, + 780, + 781, + 782, + 783, + 784, + 785, + 786, + 787, + 788, + 789, + 790, + 791, + 792, + 793, + 794, + 795, + 796, + 797, + 798, + 799, + 800, + 801, + 802, + 803, + 804, + 805, + 806, + 807, + 808, + 809, + 810, + 811, + 812, + 813, + 814, + 815, + 816, + 817, + 818, + 819, + 820, + 821, + 822, + 823, + 824, + 825, + 826, + 827, + 828, + 829, + 830, + 831, + 832, + 833, + 834, + 835, + 836, + 837, + 838, + 839, + 840, + 841, + 842, + 843, + 844, + 845, + 846, + 847, + 848, + 849, + 850, + 851, + 852, + 853, + 854, + 855, + 856, + 857, + 858, + 859, + 860, + 861, + 862, + 863, + 864, + 865, + 866, + 867, + 868, + 869, + 870, + 871, + 872, + 873, + 874, + 875, + 876, + 877, + 878, + 879, + 880, + 881, + 882, + 883, + 884, + 885, + 886, + 887, + 888, + 889, + 890, + 891, + 892, + 893, + 894, + 895, + 896, + 897, + 898, + 899, + 900, + 901, + 902, + 903, + 904, + 905, + 906, + 907, + 908, + 909, + 910, + 911, + 912, + 913, + 914, + 915, + 916, + 917, + 918, + 919, + 920, + 921, + 922, + 923, + 924, + 925, + 926, + 927, + 928, + 929, + 930, + 931, + 932, + 933, + 934, + 935, + 936, + 937, + 938, + 939, + 940, + 941, + 942, + 943, + 944, + 945, + 946, + 947, + 948, + 949, + 950, + 951, + 952, + 953, + 954, + 955, + 956, + 957, + 958, + 959, + 960, + 961, + 962, + 963, + 964, + 965, + 966, + 967, + 968, + 969, + 970, + 971, + 972, + 973, + 974, + 975, + 976, + 977, + 978, + 979, + 980, + 981, + 982, + 983, + 984, + 985, + 986, + 987, + 988, + 989, + 990, + 991, + 992, + 993, + 994, + 995, + 996, + 997, + 998, + 999, + 1000 +) + println(p1.field500) + println(p2.field499) +} \ No newline at end of file From c699d9c97912fda22f7efec3e937e7139c4f22c9 Mon Sep 17 00:00:00 2001 From: Flat Date: Wed, 24 Sep 2025 15:12:29 +0200 Subject: [PATCH 12/27] Basic Bumb allocation --- .../effekt/generator/llvm/Transformer.scala | 2 ++ libraries/llvm/rts.ll | 24 +++++++++++++++++-- 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/effekt/shared/src/main/scala/effekt/generator/llvm/Transformer.scala b/effekt/shared/src/main/scala/effekt/generator/llvm/Transformer.scala index b7a572519..50a4d77fa 100644 --- a/effekt/shared/src/main/scala/effekt/generator/llvm/Transformer.scala +++ b/effekt/shared/src/main/scala/effekt/generator/llvm/Transformer.scala @@ -24,6 +24,7 @@ object Transformer { val entryInstructions = List( Call("stack", Ccc(), stackType, withEmptyStack, List()), + Call("", Ccc(), VoidType(), initializeMemory, List()), Call("_", Tailcc(false), VoidType(), transform(entry), List(LocalReference(stackType, "stack")))) val entryBlock = BasicBlock("entry", entryInstructions, RetVoid()) val entryFunction = Function(External(), Ccc(), VoidType(), "effektMain", List(), List(entryBlock)) @@ -715,6 +716,7 @@ object Transformer { emit(Load(returnAddressName, returnAddressType, returnAddressPointer, StackPointer)); } + val initializeMemory = ConstantGlobal("initializeMemory"); val newObject = ConstantGlobal("newObject"); val objectEnvironment = ConstantGlobal("objectEnvironment"); diff --git a/libraries/llvm/rts.ll b/libraries/llvm/rts.ll index a2bc718c5..2675e8680 100644 --- a/libraries/llvm/rts.ll +++ b/libraries/llvm/rts.ll @@ -136,10 +136,30 @@ define private %Prompt @freshPrompt() { ; Garbage collection + +@freeList = global ptr null + +define private %Object @myMalloc(i64 %size) { + %freeList = load ptr, ptr @freeList + %nextFree = getelementptr i8, ptr %freeList, i64 %size + store ptr %nextFree, ptr @freeList + ret ptr %freeList +} + +define private void @myFree(ptr %object) { + ret void +} + +define private void @initializeMemory() { + %freeList = call ptr @malloc(i64 4294967296) + store ptr %freeList, ptr @freeList + ret void +} + define private %Object @newObject(%Eraser %eraser, i64 %environmentSize) alwaysinline { %headerSize = ptrtoint ptr getelementptr (%Header, ptr null, i64 1) to i64 %size = add i64 %environmentSize, %headerSize - %object = call ptr @malloc(i64 %size) + %object = call ptr @myMalloc(i64 %size) %objectReferenceCount = getelementptr %Header, ptr %object, i64 0, i32 0 %objectEraser = getelementptr %Header, ptr %object, i64 0, i32 1 store %ReferenceCount 0, ptr %objectReferenceCount, !alias.scope !14, !noalias !24 @@ -199,7 +219,7 @@ define private void @eraseObject(%Object %object) alwaysinline { %eraser = load %Eraser, ptr %objectEraser, !alias.scope !14, !noalias !24 %environment = call %Environment @objectEnvironment(%Object %object) call void %eraser(%Environment %environment) - call void @free(%Object %object) + call void @myFree(%Object %object) br label %done done: From 4402387b9801188d82e995291574c246b434aadb Mon Sep 17 00:00:00 2001 From: Flat Date: Mon, 6 Oct 2025 11:30:14 +0200 Subject: [PATCH 13/27] First approach of a 2nd step of memory-management, but first done in C instead of LLVM because of better debug possibilities --- .../effekt/generator/llvm/Transformer.scala | 2 +- libraries/llvm/bytearray.c | 6 +- libraries/llvm/cMalloc.c | 124 ++++++++++++++++++ libraries/llvm/main.c | 1 + libraries/llvm/rts.ll | 83 ++++++++++-- 5 files changed, 201 insertions(+), 15 deletions(-) create mode 100644 libraries/llvm/cMalloc.c diff --git a/effekt/shared/src/main/scala/effekt/generator/llvm/Transformer.scala b/effekt/shared/src/main/scala/effekt/generator/llvm/Transformer.scala index 50a4d77fa..a3b5eb108 100644 --- a/effekt/shared/src/main/scala/effekt/generator/llvm/Transformer.scala +++ b/effekt/shared/src/main/scala/effekt/generator/llvm/Transformer.scala @@ -716,7 +716,7 @@ object Transformer { emit(Load(returnAddressName, returnAddressType, returnAddressPointer, StackPointer)); } - val initializeMemory = ConstantGlobal("initializeMemory"); + val initializeMemory = ConstantGlobal("cInitializeMemory"); val newObject = ConstantGlobal("newObject"); val objectEnvironment = ConstantGlobal("objectEnvironment"); diff --git a/libraries/llvm/bytearray.c b/libraries/llvm/bytearray.c index 4fef7999b..9aa8d9082 100644 --- a/libraries/llvm/bytearray.c +++ b/libraries/llvm/bytearray.c @@ -5,6 +5,9 @@ #include #include +extern void* cMalloc(uint8_t size); + + /** We represent bytearrays like positive types. * * - The field `tag` contains the size @@ -21,7 +24,8 @@ void c_bytearray_erase_noop(void *envPtr) { (void)envPtr; } struct Pos c_bytearray_new(const Int size) { - void *objPtr = malloc(sizeof(struct Header) + size); + int object_size = sizeof(struct Header) + size; + void *objPtr = cMalloc(object_size); struct Header *headerPtr = objPtr; *headerPtr = (struct Header) { .rc = 0, .eraser = c_bytearray_erase_noop, }; return (struct Pos) { diff --git a/libraries/llvm/cMalloc.c b/libraries/llvm/cMalloc.c new file mode 100644 index 000000000..f7dd07c87 --- /dev/null +++ b/libraries/llvm/cMalloc.c @@ -0,0 +1,124 @@ +#include +#include +#include + +// ----------------------------- +// Strukturdefinition +// ----------------------------- + +/** + * @brief Block-Struktur für die Freelist. + * + * Jeder freie Block zeigt auf den nächsten freien Block. + */ +typedef struct Block { + struct Block* next; +} Block; + +// ----------------------------- +// Globale Variablen +// ----------------------------- + +static Block* freeList = NULL; // Kopf der Freelist +static uint8_t* nextUnusedBlock = NULL; // Zeiger auf nächsten unbenutzten Block +static uint8_t* endOfChunk = NULL; // Ende des allokierten Speichers +static const int blockSize = 1024; // Größe jedes Blocks (1KB) + +// ----------------------------- +// Initialisierung +// ----------------------------- + +/** + * @brief Initialisiert den großen Speicherbereich (4GB). + */ +void cInitializeMemory(void) { + size_t chunkSize = (size_t)4294967296ULL; // 4GB + uint8_t* mem = (uint8_t*)malloc(chunkSize); + if (!mem) { + fprintf(stderr, "malloc() failed!\n"); + exit(1); + } + + nextUnusedBlock = mem; + endOfChunk = mem + chunkSize; + printf("[init] Memory initialized: %p - %p\n", (void*)mem, (void*)endOfChunk); +} + +// ----------------------------- +// Allokator +// ----------------------------- + +/** + * @brief Einfacher Speicher-Allocator. + * + * Wenn die Freelist leer ist, nimmt er den nächsten Block im Chunk. + * Wenn die Freelist nicht leer ist, nimmt er den ersten Eintrag daraus. + * + * @param size Ignoriert in diesem simplen Modell (wir geben immer 1KB). + * @return void* Zeiger auf den allokierten Block. + */ +void* cMalloc(uint8_t size) { + // 1. Falls Freelist leer ist → neuer Block + if (freeList == NULL) { + if (nextUnusedBlock + blockSize > endOfChunk) { + fprintf(stderr, "Out of memory!\n"); + return NULL; + } + + void* block = nextUnusedBlock; + nextUnusedBlock += blockSize; + printf("[malloc] New block: %p\n", block); + return block; + } + + + // 2. Falls Freelist nicht leer ist → wiederverwenden + Block* block = freeList; + freeList = block->next; + printf("[malloc] Reusing block: %p\n", (void*)block); + printf("[malloc] freeList: %p\n", (void*)freeList); + return (void*)block; +// return malloc(size); +} + +// ----------------------------- +// Free-Funktion +// ----------------------------- + +/** + * @brief Gibt einen Block zurück in die Freelist. + * + * @param ptr Zeiger auf den Block. + */ +void cFree(void* ptr) { + if (!ptr) return; + + Block* block = (Block*)ptr; + block->next = freeList; + freeList = block; + + printf("[free] Freed block: %p\n", ptr); +// free(ptr); +} + +void* cRealloc(void* ptr, uint8_t size) { + printf("cRealloc: %p, %d\n", ptr, size); + return realloc(ptr,size); +} + +// ----------------------------- +// Test / Demo +// ----------------------------- + +//int main(void) { +// cInitializeMemory(); +// +// void* a = cMalloc(1024); +// void* b = cMalloc(1024); +// cFree(a); +// void* c = cMalloc(1024); // sollte a wiederverwenden +// cFree(b); +// cFree(c); +// +// return 0; +//} diff --git a/libraries/llvm/main.c b/libraries/llvm/main.c index 0ea587ab3..89e94309d 100644 --- a/libraries/llvm/main.c +++ b/libraries/llvm/main.c @@ -11,6 +11,7 @@ #include "types.c" #include "bytearray.c" +#include "cMalloc.c" #include "io.c" #include "panic.c" diff --git a/libraries/llvm/rts.ll b/libraries/llvm/rts.ll index 2675e8680..a2750eed8 100644 --- a/libraries/llvm/rts.ll +++ b/libraries/llvm/rts.ll @@ -94,6 +94,11 @@ ; Foreign imports +declare void @cInitializeMemory() +declare ptr @cMalloc(i64) +declare void @cFree(ptr) +declare ptr @cRealloc(ptr, i64) + declare ptr @malloc(i64) declare void @free(ptr) declare ptr @realloc(ptr, i64) @@ -136,30 +141,82 @@ define private %Prompt @freshPrompt() { ; Garbage collection +; A type for the free list +%struct.Block = type { %struct.Block* } -@freeList = global ptr null +@freeList = global %struct.Block* null +@nextUnusedBlock = global i8* null +@endOfChunk = global i8* null +@blockSize = global i64 1024 ; each Block is 1KB -define private %Object @myMalloc(i64 %size) { - %freeList = load ptr, ptr @freeList - %nextFree = getelementptr i8, ptr %freeList, i64 %size - store ptr %nextFree, ptr @freeList - ret ptr %freeList -} +define private void @initializeMemory() { + ; Step 01: mem = malloc(4294967296) + %mem = call i8* @malloc(i64 4294967296) + + ; Step 02: nextUnusedBlock = mem + store i8* %mem, i8** @nextUnusedBlock + + ; Step 03: endOfChunk = mem + 4294967296 + %endPtr = getelementptr i8, i8* %mem, i64 4294967296 + store i8* %endPtr, i8** @endOfChunk -define private void @myFree(ptr %object) { ret void } -define private void @initializeMemory() { - %freeList = call ptr @malloc(i64 4294967296) - store ptr %freeList, ptr @freeList +define private %Object @myMalloc(i64 %size) { +entry: + ; Step 01: Check if the free list pointer is not null + %freeList = load %struct.Block*, %struct.Block** @freeList + %isNull = icmp eq %struct.Block* %freeList, null + br i1 %isNull, label %newAllocate, label %reuse + +; In case we can recycle a block from the free list, we do so and jump to the reuse label. +reuse: + ; Step 01: block = freeList + %block = load %struct.Block*, %struct.Block** @freeList + + ; Step 02: freeList = freeList.next + %nextPtr = getelementptr %struct.Block, %struct.Block* %block, i32 0, i32 0 + %nextBlock = load %struct.Block*, %struct.Block** %nextPtr + store %struct.Block* %nextBlock, %struct.Block** @freeList + + ; Step 03: Return + %ret = bitcast %struct.Block* %block to %Object + ret %Object %ret + +; In case we do not have a block to reuse +newAllocate: + %nu = load i8*, i8** @nextUnusedBlock + %end = load i8*, i8** @endOfChunk + %blockSize = load i64, i64* @blockSize + + ; block = next_unused + %next_plus = getelementptr i8, i8* %nu, i64 %blockSize + store i8* %next_plus, i8** @nextUnusedBlock + + %ret2 = bitcast i8* %nu to %Object + ret %Object %ret2 + +} + +define private void @myFree(%Object %object) { + ; block = (Block*)object + %block = bitcast %Object %object to %struct.Block* + + ; block.next = freeList + %nextField = getelementptr %struct.Block, %struct.Block* %block, i32 0, i32 0 + %freeList = load %struct.Block*, %struct.Block** @freeList + store %struct.Block* %freeList, %struct.Block** %nextField + + ; freeList = block + store %struct.Block* %block, %struct.Block** @freeList ; <- fails ret void } define private %Object @newObject(%Eraser %eraser, i64 %environmentSize) alwaysinline { %headerSize = ptrtoint ptr getelementptr (%Header, ptr null, i64 1) to i64 %size = add i64 %environmentSize, %headerSize - %object = call ptr @myMalloc(i64 %size) + %object = call ptr @cMalloc(i64 %size) %objectReferenceCount = getelementptr %Header, ptr %object, i64 0, i32 0 %objectEraser = getelementptr %Header, ptr %object, i64 0, i32 1 store %ReferenceCount 0, ptr %objectReferenceCount, !alias.scope !14, !noalias !24 @@ -219,7 +276,7 @@ define private void @eraseObject(%Object %object) alwaysinline { %eraser = load %Eraser, ptr %objectEraser, !alias.scope !14, !noalias !24 %environment = call %Environment @objectEnvironment(%Object %object) call void %eraser(%Environment %environment) - call void @myFree(%Object %object) + call void @cFree(%Object %object) br label %done done: From ea2fcf4075adab0349dc7cbe4d12e5acd20fd0d8 Mon Sep 17 00:00:00 2001 From: Flat Date: Fri, 27 Feb 2026 10:38:01 +0100 Subject: [PATCH 14/27] df: Added ctrc for effekt (except for sender_receiver and server_client) --- .../{FlatTests.scala => CTRCTests.scala} | 7 +- .../effekt/generator/llvm/Transformer.scala | 535 ++++++++++++++++-- ...locate_first_then_release_flush_once.check | 0 ...ocate_first_then_release_flush_once.effekt | 0 ...ocate_first_then_release_flush_twice.check | 0 ...cate_first_then_release_flush_twice.effekt | 0 .../nooptimized/array_record.check | 0 .../nooptimized/array_record.effekt | 0 .../nooptimized/array_record_match.check | 0 .../nooptimized/array_record_match.effekt | 2 +- .../array_record_match_exhausted.check | 0 .../array_record_match_exhausted.effekt | 2 +- ...different_person_sizes_biggest_first.check | 0 ...ifferent_person_sizes_biggest_first.effekt | 0 ...ifferent_person_sizes_smallest_first.check | 0 ...fferent_person_sizes_smallest_first.effekt | 0 .../nooptimized/nested_objects.check | 0 .../nooptimized/nested_objects.effekt | 0 .../nooptimized/one_big_string_object.check | 0 .../nooptimized/one_big_string_object.effekt | 0 .../nooptimized/one_lg_object.check | 0 .../nooptimized/one_lg_object.effekt | 0 .../nooptimized/one_md_object.check | 0 .../nooptimized/one_md_object.effekt | 0 .../one_slot_one_person_list.check | 0 .../one_slot_one_person_list.effekt | 0 .../nooptimized/one_sm_object.check | 0 .../nooptimized/one_sm_object.effekt | 0 .../nooptimized/one_small_string_object.check | 0 .../one_small_string_object.effekt | 0 .../nooptimized/one_xl_object.check | 0 .../nooptimized/one_xl_object.effekt | 0 .../nooptimized/one_xs_object.check | 0 .../nooptimized/one_xs_object.effekt | 0 .../one_xxl_object_all_fields.check | 0 .../one_xxl_object_all_fields.effekt | 0 .../nooptimized/one_xxxl_object.check | 0 .../nooptimized/one_xxxl_object.effekt | 0 .../nooptimized/primitive_ref.check | 0 .../nooptimized/primitive_ref.effekt | 0 .../nooptimized/ref_allocate.check | 0 .../nooptimized/ref_allocate.effekt | 2 +- .../nooptimized/simple_list.check | 0 .../nooptimized/simple_list.effekt | 0 .../nooptimized/simple_ref.check | 0 .../nooptimized/simple_ref.effekt | 0 .../nooptimized/superperson.check | 0 .../nooptimized/superperson.effekt | 0 .../nooptimized/superperson_with_free.check | 0 .../nooptimized/superperson_with_free.effekt | 0 .../nooptimized/three_md_objects_direct.check | 0 .../three_md_objects_direct.effekt | 0 .../nooptimized/trigger_child_freeing.check | 0 .../nooptimized/trigger_child_freeing.effekt | 0 .../nooptimized/trigger_flush_once.check | 0 .../nooptimized/trigger_flush_once.effekt | 0 .../nooptimized/trigger_flush_twice.check | 0 .../nooptimized/trigger_flush_twice.effekt | 0 .../trigger_one_child_freeing.check | 0 .../trigger_one_child_freeing.effekt | 0 .../trigger_two_child_freeing.check | 0 .../trigger_two_child_freeing.effekt | 0 .../nooptimized/two_lg_objects.check | 0 .../nooptimized/two_lg_objects.effekt | 0 .../nooptimized/two_md_mixed_object.check | 0 .../nooptimized/two_md_mixed_object.effekt | 0 .../nooptimized/two_md_objects.check | 0 .../nooptimized/two_md_objects.effekt | 0 .../two_slot_one_person_list.check | 0 .../two_slot_one_person_list.effekt | 0 ...t_one_person_with_free_variable_list.check | 0 ..._one_person_with_free_variable_list.effekt | 0 .../two_slot_two_person_list.check | 0 .../two_slot_two_person_list.effekt | 0 ...wo_slot_two_person_list_continuation.check | 0 ...o_slot_two_person_list_continuation.effekt | 0 ..._person_list_continuation_allocation.check | 0 ...person_list_continuation_allocation.effekt | 0 ...o_person_list_continuation_exhausted.check | 0 ..._person_list_continuation_exhausted.effekt | 0 .../two_slot_two_person_list_exhausted.check | 0 .../two_slot_two_person_list_exhausted.effekt | 0 ...t_two_person_with_free_variable_list.check | 0 ..._two_person_with_free_variable_list.effekt | 0 .../nooptimized/two_sm_mixed_object.check | 0 .../nooptimized/two_sm_mixed_object.effekt | 0 .../nooptimized/two_sm_objects.check | 0 .../nooptimized/two_sm_objects.effekt | 0 .../nooptimized/two_xl_objects.check | 0 .../nooptimized/two_xl_objects.effekt | 0 .../nooptimized/two_xs_objects.check | 0 .../nooptimized/two_xs_objects.effekt | 0 .../two_xxl_object_all_fields.check | 0 .../two_xxl_object_all_fields.effekt | 0 .../nooptimized/two_xxl_objects.check | 0 .../nooptimized/two_xxl_objects.effekt | 0 .../nooptimized/two_xxxl_objects.check | 0 .../nooptimized/two_xxxl_objects.effekt | 0 libraries/common/array.effekt | 17 +- libraries/common/ref.effekt | 15 +- libraries/llvm/bytearray.c | 12 +- libraries/llvm/initialize-arena.c | 14 + libraries/llvm/main.c | 1 + libraries/llvm/rts.ll | 170 +++--- 104 files changed, 625 insertions(+), 152 deletions(-) rename effekt/jvm/src/test/scala/effekt/{FlatTests.scala => CTRCTests.scala} (66%) rename examples/{flat => ctrc}/nooptimized/allocate_first_then_release_flush_once.check (100%) rename examples/{flat => ctrc}/nooptimized/allocate_first_then_release_flush_once.effekt (100%) rename examples/{flat => ctrc}/nooptimized/allocate_first_then_release_flush_twice.check (100%) rename examples/{flat => ctrc}/nooptimized/allocate_first_then_release_flush_twice.effekt (100%) rename examples/{flat => ctrc}/nooptimized/array_record.check (100%) rename examples/{flat => ctrc}/nooptimized/array_record.effekt (100%) rename examples/{flat => ctrc}/nooptimized/array_record_match.check (100%) rename examples/{flat => ctrc}/nooptimized/array_record_match.effekt (83%) rename examples/{flat => ctrc}/nooptimized/array_record_match_exhausted.check (100%) rename examples/{flat => ctrc}/nooptimized/array_record_match_exhausted.effekt (83%) rename examples/{flat => ctrc}/nooptimized/different_person_sizes_biggest_first.check (100%) rename examples/{flat => ctrc}/nooptimized/different_person_sizes_biggest_first.effekt (100%) rename examples/{flat => ctrc}/nooptimized/different_person_sizes_smallest_first.check (100%) rename examples/{flat => ctrc}/nooptimized/different_person_sizes_smallest_first.effekt (100%) rename examples/{flat => ctrc}/nooptimized/nested_objects.check (100%) rename examples/{flat => ctrc}/nooptimized/nested_objects.effekt (100%) rename examples/{flat => ctrc}/nooptimized/one_big_string_object.check (100%) rename examples/{flat => ctrc}/nooptimized/one_big_string_object.effekt (100%) rename examples/{flat => ctrc}/nooptimized/one_lg_object.check (100%) rename examples/{flat => ctrc}/nooptimized/one_lg_object.effekt (100%) rename examples/{flat => ctrc}/nooptimized/one_md_object.check (100%) rename examples/{flat => ctrc}/nooptimized/one_md_object.effekt (100%) rename examples/{flat => ctrc}/nooptimized/one_slot_one_person_list.check (100%) rename examples/{flat => ctrc}/nooptimized/one_slot_one_person_list.effekt (100%) rename examples/{flat => ctrc}/nooptimized/one_sm_object.check (100%) rename examples/{flat => ctrc}/nooptimized/one_sm_object.effekt (100%) rename examples/{flat => ctrc}/nooptimized/one_small_string_object.check (100%) rename examples/{flat => ctrc}/nooptimized/one_small_string_object.effekt (100%) rename examples/{flat => ctrc}/nooptimized/one_xl_object.check (100%) rename examples/{flat => ctrc}/nooptimized/one_xl_object.effekt (100%) rename examples/{flat => ctrc}/nooptimized/one_xs_object.check (100%) rename examples/{flat => ctrc}/nooptimized/one_xs_object.effekt (100%) rename examples/{flat => ctrc}/nooptimized/one_xxl_object_all_fields.check (100%) rename examples/{flat => ctrc}/nooptimized/one_xxl_object_all_fields.effekt (100%) rename examples/{flat => ctrc}/nooptimized/one_xxxl_object.check (100%) rename examples/{flat => ctrc}/nooptimized/one_xxxl_object.effekt (100%) rename examples/{flat => ctrc}/nooptimized/primitive_ref.check (100%) rename examples/{flat => ctrc}/nooptimized/primitive_ref.effekt (100%) rename examples/{flat => ctrc}/nooptimized/ref_allocate.check (100%) rename examples/{flat => ctrc}/nooptimized/ref_allocate.effekt (89%) rename examples/{flat => ctrc}/nooptimized/simple_list.check (100%) rename examples/{flat => ctrc}/nooptimized/simple_list.effekt (100%) rename examples/{flat => ctrc}/nooptimized/simple_ref.check (100%) rename examples/{flat => ctrc}/nooptimized/simple_ref.effekt (100%) rename examples/{flat => ctrc}/nooptimized/superperson.check (100%) rename examples/{flat => ctrc}/nooptimized/superperson.effekt (100%) rename examples/{flat => ctrc}/nooptimized/superperson_with_free.check (100%) rename examples/{flat => ctrc}/nooptimized/superperson_with_free.effekt (100%) rename examples/{flat => ctrc}/nooptimized/three_md_objects_direct.check (100%) rename examples/{flat => ctrc}/nooptimized/three_md_objects_direct.effekt (100%) rename examples/{flat => ctrc}/nooptimized/trigger_child_freeing.check (100%) rename examples/{flat => ctrc}/nooptimized/trigger_child_freeing.effekt (100%) rename examples/{flat => ctrc}/nooptimized/trigger_flush_once.check (100%) rename examples/{flat => ctrc}/nooptimized/trigger_flush_once.effekt (100%) rename examples/{flat => ctrc}/nooptimized/trigger_flush_twice.check (100%) rename examples/{flat => ctrc}/nooptimized/trigger_flush_twice.effekt (100%) rename examples/{flat => ctrc}/nooptimized/trigger_one_child_freeing.check (100%) rename examples/{flat => ctrc}/nooptimized/trigger_one_child_freeing.effekt (100%) rename examples/{flat => ctrc}/nooptimized/trigger_two_child_freeing.check (100%) rename examples/{flat => ctrc}/nooptimized/trigger_two_child_freeing.effekt (100%) rename examples/{flat => ctrc}/nooptimized/two_lg_objects.check (100%) rename examples/{flat => ctrc}/nooptimized/two_lg_objects.effekt (100%) rename examples/{flat => ctrc}/nooptimized/two_md_mixed_object.check (100%) rename examples/{flat => ctrc}/nooptimized/two_md_mixed_object.effekt (100%) rename examples/{flat => ctrc}/nooptimized/two_md_objects.check (100%) rename examples/{flat => ctrc}/nooptimized/two_md_objects.effekt (100%) rename examples/{flat => ctrc}/nooptimized/two_slot_one_person_list.check (100%) rename examples/{flat => ctrc}/nooptimized/two_slot_one_person_list.effekt (100%) rename examples/{flat => ctrc}/nooptimized/two_slot_one_person_with_free_variable_list.check (100%) rename examples/{flat => ctrc}/nooptimized/two_slot_one_person_with_free_variable_list.effekt (100%) rename examples/{flat => ctrc}/nooptimized/two_slot_two_person_list.check (100%) rename examples/{flat => ctrc}/nooptimized/two_slot_two_person_list.effekt (100%) rename examples/{flat => ctrc}/nooptimized/two_slot_two_person_list_continuation.check (100%) rename examples/{flat => ctrc}/nooptimized/two_slot_two_person_list_continuation.effekt (100%) rename examples/{flat => ctrc}/nooptimized/two_slot_two_person_list_continuation_allocation.check (100%) rename examples/{flat => ctrc}/nooptimized/two_slot_two_person_list_continuation_allocation.effekt (100%) rename examples/{flat => ctrc}/nooptimized/two_slot_two_person_list_continuation_exhausted.check (100%) rename examples/{flat => ctrc}/nooptimized/two_slot_two_person_list_continuation_exhausted.effekt (100%) rename examples/{flat => ctrc}/nooptimized/two_slot_two_person_list_exhausted.check (100%) rename examples/{flat => ctrc}/nooptimized/two_slot_two_person_list_exhausted.effekt (100%) rename examples/{flat => ctrc}/nooptimized/two_slot_two_person_with_free_variable_list.check (100%) rename examples/{flat => ctrc}/nooptimized/two_slot_two_person_with_free_variable_list.effekt (100%) rename examples/{flat => ctrc}/nooptimized/two_sm_mixed_object.check (100%) rename examples/{flat => ctrc}/nooptimized/two_sm_mixed_object.effekt (100%) rename examples/{flat => ctrc}/nooptimized/two_sm_objects.check (100%) rename examples/{flat => ctrc}/nooptimized/two_sm_objects.effekt (100%) rename examples/{flat => ctrc}/nooptimized/two_xl_objects.check (100%) rename examples/{flat => ctrc}/nooptimized/two_xl_objects.effekt (100%) rename examples/{flat => ctrc}/nooptimized/two_xs_objects.check (100%) rename examples/{flat => ctrc}/nooptimized/two_xs_objects.effekt (100%) rename examples/{flat => ctrc}/nooptimized/two_xxl_object_all_fields.check (100%) rename examples/{flat => ctrc}/nooptimized/two_xxl_object_all_fields.effekt (100%) rename examples/{flat => ctrc}/nooptimized/two_xxl_objects.check (100%) rename examples/{flat => ctrc}/nooptimized/two_xxl_objects.effekt (100%) rename examples/{flat => ctrc}/nooptimized/two_xxxl_objects.check (100%) rename examples/{flat => ctrc}/nooptimized/two_xxxl_objects.effekt (100%) create mode 100644 libraries/llvm/initialize-arena.c diff --git a/effekt/jvm/src/test/scala/effekt/FlatTests.scala b/effekt/jvm/src/test/scala/effekt/CTRCTests.scala similarity index 66% rename from effekt/jvm/src/test/scala/effekt/FlatTests.scala rename to effekt/jvm/src/test/scala/effekt/CTRCTests.scala index c0c0f6e5c..76d65570b 100644 --- a/effekt/jvm/src/test/scala/effekt/FlatTests.scala +++ b/effekt/jvm/src/test/scala/effekt/CTRCTests.scala @@ -7,18 +7,17 @@ import java.io.File import scala.language.implicitConversions import scala.sys.process.Process -// df: My own test class to run my requested tests automatically -class FlatTests extends EffektTests { +class CTRCTests extends EffektTests { def backendName = "llvm" override def valgrind = false // works on linux only override lazy val positives: Set[File] = Set( - examplesDir / "flat" / "optimized" + examplesDir / "ctrc" / "optimized" ) override lazy val withoutOptimizations: Set[File] = Set( - examplesDir / "flat" / "nooptimized", + examplesDir / "ctrc" / "nooptimized", ) } diff --git a/effekt/shared/src/main/scala/effekt/generator/llvm/Transformer.scala b/effekt/shared/src/main/scala/effekt/generator/llvm/Transformer.scala index a3b5eb108..73edb0bdc 100644 --- a/effekt/shared/src/main/scala/effekt/generator/llvm/Transformer.scala +++ b/effekt/shared/src/main/scala/effekt/generator/llvm/Transformer.scala @@ -2,17 +2,23 @@ package effekt package generator package llvm +import effekt.generator.llvm.Type as LLVMType +import effekt.generator.llvm.Instruction.{Call, Load} +import effekt.generator.llvm.Transformer.{ModuleContext, createReleaseFunction, emit, environmentType, freshName, objectEnvironment} import effekt.machine +import effekt.machine.{Environment, Variable} +import effekt.machine.analysis.* import effekt.util.intercalate import effekt.util.messages.ErrorReporter -import effekt.machine.analysis.* import scala.annotation.tailrec import scala.collection.mutable +import scala.collection.mutable.ListBuffer object Transformer { val llvmFeatureFlags: List[String] = List("llvm") + val slotSize: Int = 64 // the size of a heap slot in bytes def transform(program: machine.Program)(using ErrorReporter): List[Definition] = program match { case machine.Program(declarations, definitions, entry) => @@ -24,8 +30,9 @@ object Transformer { val entryInstructions = List( Call("stack", Ccc(), stackType, withEmptyStack, List()), - Call("", Ccc(), VoidType(), initializeMemory, List()), - Call("_", Tailcc(false), VoidType(), transform(entry), List(LocalReference(stackType, "stack")))) + Call("", Ccc(), VoidType(), initializeMemory, List()), + Call("_", Tailcc(false), VoidType(), transform(entry), List(LocalReference(stackType, "stack"))), + ) val entryBlock = BasicBlock("entry", entryInstructions, RetVoid()) val entryFunction = Function(External(), Ccc(), VoidType(), "effektMain", List(), List(entryBlock)) @@ -58,26 +65,26 @@ object Transformer { """call void @hole() |unreachable |""".stripMargin - } + } def transform(template: Template[machine.Variable]): String = "; variable\n " ++ intercalate(template.strings, template.args.map { case machine.Variable(name, tpe) => PrettyPrinter.localName(name) }).mkString def transform(definition: machine.Definition)(using ModuleContext): Unit = definition match { - case machine.Definition(machine.Label(name, environment), body) => - val parameters = environment.map { case machine.Variable(name, tpe) => Parameter(transform(tpe), name) } - defineLabel(name, parameters) { - emit(Comment(s"definition $name, environment length ${environment.length}")) - eraseValues(environment, freeVariables(body)) - transform(body) - } + case machine.Definition(machine.Label(name, environment), body) => + val parameters = environment.map { case machine.Variable(name, tpe) => Parameter(transform(tpe), name) } + defineLabel(name, parameters) { + emit(Comment(s"definition $name, environment length ${environment.length}")) + eraseValues(environment, freeVariables(body)) + transform(body) + } } def transform(statement: machine.Statement)(using ModuleContext, FunctionContext, BlockContext): Terminator = statement match { - case machine.Jump(label, arguments) => + case machine.Jump(label, arguments) => emit(Comment(s"jump ${label.name}")) shareValues(arguments, Set()) emit(callLabel(transform(label), arguments.map(transform))) @@ -426,6 +433,8 @@ object Transformer { val resumptionType = NamedType("Resumption"); val promptType = NamedType("Prompt"); val referenceType = NamedType("Reference"); + val headerType = NamedType("Header"); + val referenceCountType = NamedType("ReferenceCount"); def transform(tpe: machine.Type): Type = tpe match { case machine.Positive() => positiveType @@ -516,16 +525,7 @@ object Transformer { C.erasers.getOrElseUpdate((types, kind), { kind match { case ObjectEraser => - val eraser = ConstantGlobal(freshName("eraser")); - defineFunction(eraser.name, List(Parameter(environmentType, "environment"))) { - emit(Comment(s"${kind} eraser, ${freshEnvironment.length} free variables")) - - // TODO avoid unnecessary loads - loadEnvironmentAt(LocalReference(environmentType, "environment"), freshEnvironment, Object); - eraseValues(freshEnvironment, Set()); - RetVoid() - }; - eraser + createEraserForNormalObjects(freshEnvironment) case StackEraser | StackFrameEraser => val eraser = ConstantGlobal(freshName("eraser")); defineFunction(eraser.name, List(Parameter(stackPointerType, "stackPointer"))) { @@ -570,32 +570,39 @@ object Transformer { }) } + /** + * Produces an Object. It is always ${slotSize} bytes long + */ def produceObject(role: String, environment: machine.Environment, freeInBody: Set[machine.Variable])(using ModuleContext, FunctionContext, BlockContext): Operand = { if (environment.isEmpty) { ConstantNull(objectType) + } else if (fitsInOneSavingSlot(environment)) { + produceSingleObject(role, environment, freeInBody) } else { - val objectReference = LocalReference(objectType, freshName(role)); - val environmentReference = LocalReference(environmentType, freshName("environment")); - val size = ConstantInt(environmentSize(environment)); - val eraser = getEraser(environment, ObjectEraser) - - emit(Call(objectReference.name, Ccc(), objectType, newObject, List(eraser, size))); - emit(Call(environmentReference.name, Ccc(), environmentType, objectEnvironment, List(objectReference))); - shareValues(environment, freeInBody); - storeEnvironment(environmentReference, environment, Object); - objectReference + produceShardedObject(role, environment, freeInBody) } } - def consumeObject(`object`: Operand, environment: machine.Environment, freeInBody: Set[machine.Variable])(using ModuleContext, FunctionContext, BlockContext): Unit = { + def consumeObject(`object`: LocalReference, environment: machine.Environment, freeInBody: Set[machine.Variable])(using ModuleContext, FunctionContext, BlockContext): Unit = { if (environment.isEmpty) { () } else { + // Step 01: We load the variables of the environment such that the continuation can continue val environmentReference = LocalReference(environmentType, freshName("environment")); emit(Call(environmentReference.name, Ccc(), environmentType, objectEnvironment, List(`object`))); - loadEnvironment(environmentReference, environment, Object); - shareValues(environment, freeInBody); - emit(Call("_", Ccc(), VoidType(), eraseObject, List(`object`))); + loadEnvironment(environmentReference, environment, Object) + + // Step 02: we create the release function for this object + val release = ConstantGlobal(freshName("release")); + defineFunction(release.name, List(Parameter(objectType, "object"))) { + createReleaseFunction(release.name, environment, freeInBody) + } + + // Step 03: we call the release function + emit(Call("_", Ccc(), VoidType(), release, List(`object`))); + +// shareValues(environment, freeInBody); +// emit(Call("_", Ccc(), VoidType(), eraseObject, List(`object`))); } } @@ -652,13 +659,88 @@ object Transformer { } } - def loadEnvironmentAt(pointer: Operand, environment: machine.Environment, alias: AliasInfo)(using ModuleContext, FunctionContext, BlockContext): Unit = { - val `type` = environmentType(environment) - environment.zipWithIndex.foreach { - case (machine.Variable(name, tpe), i) => - val field = LocalReference(PointerType(), freshName(name + "_pointer")); - emit(GetElementPtr(field.name, `type`, pointer, List(0, i))); - emit(Load(name, transform(tpe), field, alias)) + def loadEnvironmentAt(elementPointer: Operand, environment: machine.Environment, alias: AliasInfo)(using ModuleContext, FunctionContext, BlockContext): Unit = { + alias match { + // if we have a sharded object + case Object if !fitsInOneSavingSlot(environment) => + // Follow chained ${slotSize}-byte blocks created in produceObject + val chunkedEnvironments = splitEnvironment(environment) + var currentEnvironmentPtr: Operand = elementPointer + + // here we loop over all environments *in* order + chunkedEnvironments.zipWithIndex.foreach { case (chunk, idx) => + val isLast = idx == chunkedEnvironments.length - 1 + if (isLast) { + val tpe = environmentType(chunk) + loadAllVariables(currentEnvironmentPtr, chunk, alias, tpe) + } else { + // Here we do the same as for the normal slot plus some extra stuff + + // For non-last chunkedEnvironments, layout is chunk ++ [Pos link] + val tpe = StructureType(chunk.map { case machine.Variable(_, t) => transform(t) } :+ positiveType) // the same as for the normal case + positive Type for the link + loadAllVariables(currentEnvironmentPtr, chunk, alias, tpe) + + // Follow link to next block. The Link pointer is the last element of the chunk + val linkPtr = LocalReference(PointerType(), freshName("link_pointer")) + emit(GetElementPtr(linkPtr.name, tpe, currentEnvironmentPtr, List(0, chunk.length))) + + val linkVal = LocalReference(positiveType, freshName("link")) + emit(Load(linkVal.name, positiveType, linkPtr, alias)) + + val nextObj = LocalReference(objectType, freshName("next_object")) + emit(ExtractValue(nextObj.name, linkVal, 1)) + + val nextEnv = LocalReference(environmentType, freshName("environment")) + emit(Call(nextEnv.name, Ccc(), environmentType, objectEnvironment, List(nextObj))) + currentEnvironmentPtr = nextEnv + } + } + case _: AliasInfo => + val tpe = environmentType(environment) + loadAllVariables(elementPointer, environment, alias, tpe) + } + } + + def loadEnvironmentAtDirectly(elementPointer: Operand, environment: machine.Environment, alias: AliasInfo, allInstructions: mutable.ListBuffer[Instruction])(using ModuleContext, FunctionContext, BlockContext): Unit = { + alias match { + // if we have a sharded object + case Object if !fitsInOneSavingSlot(environment) => + // Follow chained ${slotSize}-byte blocks created in produceObject + val chunkedEnvironments = splitEnvironment(environment) + var currentEnvironmentPtr: Operand = elementPointer + + // here we loop over all environments *in* order + chunkedEnvironments.zipWithIndex.foreach { case (chunk, idx) => + val isLast = idx == chunkedEnvironments.length - 1 + if (isLast) { + val tpe = environmentType(chunk) + loadAllVariablesDirectly(currentEnvironmentPtr, chunk, alias, tpe, allInstructions) + } else { + // Here we do the same as for the normal slot plus some extra stuff + + // For non-last chunkedEnvironments, layout is chunk ++ [Pos link] + val tpe = StructureType(chunk.map { case machine.Variable(_, t) => transform(t) } :+ positiveType) // the same as for the normal case + positive Type for the link + loadAllVariablesDirectly(currentEnvironmentPtr, chunk, alias, tpe, allInstructions) + + // Follow link to next block. The Link pointer is the last element of the chunk + val linkPtr = LocalReference(PointerType(), freshName("link_pointer")) + allInstructions += GetElementPtr(linkPtr.name, tpe, currentEnvironmentPtr, List(0, chunk.length)) + + val linkVal = LocalReference(positiveType, freshName("link")) + allInstructions += Load(linkVal.name, positiveType, linkPtr, alias) + + val nextObj = LocalReference(objectType, freshName("next_object")) + allInstructions += ExtractValue(nextObj.name, linkVal, 1) + + val nextEnv = LocalReference(environmentType, freshName("environment")) + allInstructions += Call(nextEnv.name, Ccc(), environmentType, objectEnvironment, List(nextObj)) + currentEnvironmentPtr = nextEnv + } + } + case _: AliasInfo => + val tpe = environmentType(environment) + loadAllVariablesDirectly(elementPointer, environment, alias, tpe, allInstructions) + } } @@ -668,15 +750,38 @@ object Transformer { values match { case Nil => () case value :: values => - if values.contains(value) then { - shareValue(value); - loop(values) - } else if freeInBody.contains(value) then { - shareValue(value); - loop(values) - } else { - loop(values) - } + if values.contains(value) then { + shareValue(value); + loop(values) + } else if freeInBody.contains(value) then { + shareValue(value); + loop(values) + } else { + loop(values) + } + } + }; + loop(values) + } + + /* + * Adds all sharing functions to the allInstructions list + */ + def shareValuesDirectly(values: machine.Environment, freeInBody: Set[machine.Variable], allInstructions: ListBuffer[Instruction])(using FunctionContext, BlockContext): Unit = { + @tailrec + def loop(values: machine.Environment): Unit = { + values match { + case Nil => () + case value :: values => + if values.contains(value) then { + shareValueDirectly(value, allInstructions); + loop(values) + } else if freeInBody.contains(value) then { + shareValueDirectly(value, allInstructions); + loop(values) + } else { + loop(values) + } } }; loop(values) @@ -695,6 +800,17 @@ object Transformer { }.map(emit) } + /** + * adds the sharing Functions to the allInstructions list. + */ + def shareValueDirectly(value: machine.Variable, allInstructions: ListBuffer[Instruction])(using FunctionContext, BlockContext): Unit = { + Option(value.tpe).collect { + case machine.Positive() => allInstructions += (Call("_", Ccc(), VoidType(), sharePositive, List(transform(value)))) + case machine.Negative() => allInstructions += Call("_", Ccc(), VoidType(), shareNegative, List(transform(value))) + case machine.Type.Stack() => allInstructions += Call("_", Ccc(), VoidType(), shareResumption, List(transform(value))) + } + } + def eraseValue(value: machine.Variable)(using FunctionContext, BlockContext): Unit = { Option(value.tpe).collect { case machine.Positive() => Call("_", Ccc(), VoidType(), erasePositive, List(transform(value))) @@ -716,7 +832,7 @@ object Transformer { emit(Load(returnAddressName, returnAddressType, returnAddressPointer, StackPointer)); } - val initializeMemory = ConstantGlobal("cInitializeMemory"); + val initializeMemory = ConstantGlobal("initializeMemory"); val newObject = ConstantGlobal("newObject"); val objectEnvironment = ConstantGlobal("objectEnvironment"); @@ -794,4 +910,317 @@ object Transformer { case None => acc += c } }.toString() + + /** + * if we can fit our object in one single saving block -> Easiest case + * Else we have to split our environment into multiple saving slots and reference in a linked list fashion + */ + private def fitsInOneSavingSlot(environment: machine.Environment): Boolean = { + environmentSize(environment) > 0 && environmentSize(environment) <= 48 + } + + /** + * Splits the environment into multiple environment such that you can store one object in multiple saving slots. + * Is required to do fixed-sized-allocation. + */ + private def splitEnvironment(environment: machine.Environment): List[machine.Environment] = { + val headerSize = 16 // we use 16 byte for the last saving block only, the others are 32 bytes + val linkSize = 16 // how much bytes we need to store the link to the next block (%Pos object) + + // How much bytes do we need to reserve to save a slot? + // The last block only needs 16 bytes, because here we only need to store the header. + // For all other blocks we need 32 bytes, because we need to store the header and the link to the next block. + var reservedSpaceForSlot = headerSize + + var currentEnvironment = List[machine.Variable]() + var result = List[machine.Environment]() + var isLast = true + for (variable <- environment.reverse) { + val variableSize = typeSize(variable.tpe) + + if (reservedSpaceForSlot + (environmentSize(currentEnvironment) + variableSize) <= slotSize) { + currentEnvironment = currentEnvironment :+ variable + } + else { + if (isLast) { + reservedSpaceForSlot = headerSize + linkSize // normal header size + size of the positive type which is the reference to the next object + isLast = false + } + result = result :+ currentEnvironment.reverse + currentEnvironment = List(variable) + } + } + result = result :+ currentEnvironment.reverse + + result.reverse + } + + /** + * When you have a big object to produce, you shard it into multiple slots instead of one single big slot. + * The end of each slot references to the next one. + * Each slot is 64 byte long + */ + private def produceShardedObject(role: String, environment: machine.Environment, freeInBody: Set[machine.Variable])(using ModuleContext, FunctionContext, BlockContext): Operand = { + // Split into multiple 64-byte blocks and chain them via a boxed link (%Pos with tag 0 pointing to next %Object) + val shardedEnvironments = splitEnvironment(environment) + + // Allocate the last block first. + val lastEnvironment = shardedEnvironments.last + val lastObjectReference = LocalReference(objectType, freshName(role)) + val lastEnvPtr = LocalReference(environmentType, freshName("environment")) + val lastSize = ConstantInt(environmentSize(lastEnvironment)) + val lastEraser = getEraser(lastEnvironment, ObjectEraser) + + emit(Call(lastObjectReference.name, Ccc(), objectType, newObject, List(lastEraser, lastSize))) + emit(Call(lastEnvPtr.name, Ccc(), environmentType, objectEnvironment, List(lastObjectReference))) + shareValues(lastEnvironment, freeInBody) + storeEnvironment(lastEnvPtr, lastEnvironment, Object) + + // Chain preceding blocks, each storing a boxed link to the next object + var headObject: LocalReference = lastObjectReference + + // loop through all shardedEnvironments except the last one in reversed order + shardedEnvironments.init.reverse.foreach { envChunk => + val temporaryName = freshName("link_temporary") + val linkValName = freshName("link") + + // we create a new Positive Object with tag 0... + emit(InsertValue(temporaryName, ConstantAggregateZero(positiveType), ConstantInt(0), 0)) // we create a fake Link Tag 0 that we just use for store a tag in the Pos + emit(InsertValue(linkValName, LocalReference(positiveType, temporaryName), headObject, 1)) + + // ... and inject it into our environment... + val extendedEnv = envChunk :+ machine.Variable(linkValName, machine.Positive()) + + // ...finally, we do the usual behavior when we produce an object + headObject = produceSingleObject(role, extendedEnv, freeInBody) + } + headObject + } + + /** + * Creates a new object and stores its environment in it + */ + private def produceSingleObject(role: String, environment: machine.Environment, freeInBody: Set[machine.Variable])(using ModuleContext, FunctionContext, BlockContext): LocalReference = { + val objectReference = LocalReference(objectType, freshName(role)) + val environmentReference = LocalReference(environmentType, freshName("environment")) + val size = ConstantInt(environmentSize(environment)) + val eraser = getEraser(environment, ObjectEraser) + + emit(Call(objectReference.name, Ccc(), objectType, newObject, List(eraser, size))); + emit(Call(environmentReference.name, Ccc(), environmentType, objectEnvironment, List(objectReference))); + shareValues(environment, freeInBody); + storeEnvironment(environmentReference, environment, Object); + objectReference + } + + private def loadAllVariables(pointer: Operand, environment: machine.Environment, alias: AliasInfo, typ: Type)(using ModuleContext, FunctionContext, BlockContext): Unit = { + environment.zipWithIndex.foreach { + case (machine.Variable(name, tpe), i) => + val field = LocalReference(PointerType(), freshName(name + "_pointer")) + emit(GetElementPtr(field.name, typ, pointer, List(0, i))) + emit(Load(name, transform(tpe), field, alias)) + } + } + + private def loadAllVariablesDirectly(pointer: Operand, environment: machine.Environment, alias: AliasInfo, typ: Type, allInstructions: mutable.ListBuffer[Instruction])(using ModuleContext, FunctionContext, BlockContext): Unit = { + environment.zipWithIndex.foreach { + case (machine.Variable(name, tpe), i) => + val field = LocalReference(PointerType(), freshName(name + "_pointer")) + allInstructions += GetElementPtr(field.name, typ, pointer, List(0, i)) + allInstructions += Load(name, transform(tpe), field, alias) + } + } + + private def createReleaseFunction(releaseLabel: String, environment: machine.Environment, freeInBody: Set[machine.Variable])(using ModuleContext, FunctionContext, BlockContext): Terminator = { + val pushOntoFreeListLabel = freshName("pushOntoFreeList") + val shareChildrenAndEraseLabel = freshName("shareChildrenAndErase") + val objectReference = LocalReference(objectType, "object") + val environmentRef = LocalReference(environmentType, freshName("environment")) + + val referenceCountPtr = LocalReference(PointerType(), freshName("referenceCount_pointer")) + val referenceCount: LocalReference = LocalReference(referenceCountType, freshName("referenceCount")) + + // Step 01: Load the environment + emit(Call(environmentRef.name, Ccc(), environmentType, ConstantGlobal("objectEnvironment"), List(objectReference))) + + // Step 02: Load the reference count + emit(GetElementPtr(referenceCountPtr.name, headerType, LocalReference(objectType, "object"), List(0, 0))) + emit(Load(referenceCount.name, referenceCountType, referenceCountPtr, Object)) + + // Step 03: Create the branches for dealing with the given reference count + createReleasePushOntoFreeListBasicBlock(pushOntoFreeListLabel, environment, freeInBody, objectReference, environmentRef) + createReleaseShareChildrenAndEraseBasicBlock(shareChildrenAndEraseLabel, environment, freeInBody, objectReference, environmentRef) + + // Step 04: Check the reference count + Switch(referenceCount, shareChildrenAndEraseLabel, List((0, pushOntoFreeListLabel))) + } + + /** + * In this branch of the release function, we know that we can safely erase the object. + * It might be that an object consists of several slots. + * Each slot is pushed onto the free list. + */ + private def createReleasePushOntoFreeListBasicBlock(releaseLabel: String, environment: Environment, freeInBody: Set[machine.Variable], `object`: Operand, environmentRef: LocalReference)(using ModuleContext, FunctionContext, BlockContext): Unit = { + val allInstructions = mutable.ListBuffer[Instruction](Call("_", Ccc(), VoidType(), ConstantGlobal("pushOntoFreeList"), List(`object`))) + var currentEnvironmentPtr = environmentRef + val slottedEnvironment = splitEnvironment(environment) + + slottedEnvironment.zipWithIndex.foreach { case (slotEnv: Environment, index: Int) => + val isLastSlot = index == slottedEnvironment.length - 1 + val slotEnvTypes = if (isLastSlot) environmentType(slotEnv) else StructureType(slotEnv.map { case machine.Variable(_, t) => transform(t) } :+ positiveType) + + slotEnv.zipWithIndex.foreach { case (variable@machine.Variable(varName, tpe), i) => + val isHeapType = tpe match { + case machine.Positive() | machine.Negative() | machine.Type.Stack() => true + case _ => false + } + + if (isHeapType) { + val variableType = transform(tpe) + val fieldPtr = LocalReference(PointerType(), freshName(varName + "_pointer")) + val loadedVar = LocalReference(variableType, freshName(varName)) + + // Load the variable + allInstructions += GetElementPtr(fieldPtr.name, slotEnvTypes, currentEnvironmentPtr, List(0, i)) + allInstructions += Load(loadedVar.name, variableType, fieldPtr, Object) + + val isVariableFreeInBody = freeInBody.contains(variable) + + if (!isVariableFreeInBody) { + // Variable is used in the scope -> erase it + val erasingFunction = getErasingFunctionForType(variableType) + allInstructions += Call("_", Ccc(), VoidType(), erasingFunction, List(loadedVar)) + } + } + } + + if (!isLastSlot) { + // erase the link slot + val linkIndexOfSlot = slotEnv.length + val linkPtr = LocalReference(PointerType(), freshName("link_pointer")) + val linkVal = LocalReference(positiveType, freshName("link")) + val nextObj = LocalReference(objectType, freshName("next_object")) + val nextEnv = LocalReference(environmentType, freshName("environment")) + + // add all instructions + allInstructions += GetElementPtr(linkPtr.name, slotEnvTypes, currentEnvironmentPtr, List(0, linkIndexOfSlot)) + allInstructions += Load(linkVal.name, positiveType, linkPtr, Object) + allInstructions += ExtractValue(nextObj.name, linkVal, 1) + allInstructions += Call("_", Ccc(), VoidType(), ConstantGlobal("pushOntoFreeList"), List(nextObj)) + allInstructions += Call(nextEnv.name, Ccc(), environmentType, objectEnvironment, List(nextObj)) + + // now we have to follow the link to the next environment + currentEnvironmentPtr = nextEnv + } + } + + emit(BasicBlock(releaseLabel, allInstructions.toList, RetVoid())) + } + + private def createReleaseShareChildrenAndEraseBasicBlock(shareChildrenLabel: String, environment: machine.Environment, freeInBody: Set[machine.Variable], `object`: Operand, environmentRef: LocalReference)(using ModuleContext, FunctionContext, BlockContext): Unit = { + val allInstructions = mutable.ListBuffer[Instruction]() + // Step 02: Load all variables + loadEnvironmentAtDirectly(environmentRef, environment, Object, allInstructions) + shareValuesDirectly(environment, freeInBody, allInstructions) + allInstructions += (Call("_", Ccc(), VoidType(), eraseObject, List(`object`))) + emit(BasicBlock(shareChildrenLabel, allInstructions.toList, RetVoid())) + } + + /** + * Creates an eraser for normal objects (e.g. Pos and Neg). + * When @eraseObject is called, we also call the eraser. And for Pos and Neg objects, that is the eraser. + * The object is called 2 times. + * 1. Phase: When call @eraseObject -> We call release to prepend the object to our to-do-list. + * 2. Phase: When call acquire -> We call %erase on each child, so the object can be reused again. + * + * @param freshEnvironment the variables of the object + * @return the eraser + */ + private def createEraserForNormalObjects(freshEnvironment: machine.Environment)(using C: ModuleContext): Operand = { + val eraser = ConstantGlobal(freshName("eraser")) + defineFunction(eraser.name, List(Parameter(objectType, "object"))) { + val objectRefCountPtr = LocalReference(PointerType(), freshName("objectReferenceCount")) + val referenceCount = LocalReference(referenceCountType, freshName("referenceCount")) + val pushOntoTodoListLabel = freshName("pushOntoTodoList") + val eraseChildrenLabel = freshName("eraseChildren") + + // Entry block: Check reference count to determine phase + // Switch: if refCount == 0, go to "pushOntoTodoList" (first phase), else "eraseChildren" (second phase) + // Note: When refCount == 0, this is the first call from eraseObject -> just push onto to-do list + // When refCount != 0, this is the second call from acquire -> erase children + emit(GetElementPtr(objectRefCountPtr.name, headerType, LocalReference(objectType, "object"), List(0, 0))) + emit(Load(referenceCount.name, referenceCountType, objectRefCountPtr, Object)) + + createAndEmitPushOntoTodoBasicBasicBlock(pushOntoTodoListLabel) + createAndEmitEraseChildrenBasicBlock(freshEnvironment, eraseChildrenLabel) + + // Return switch terminator from entry block + Switch(referenceCount, eraseChildrenLabel, List((0, pushOntoTodoListLabel))) + } + + eraser + } + + private def createAndEmitPushOntoTodoBasicBasicBlock(releaseLabel: String)(using ModuleContext, FunctionContext): Unit = { + emit(BasicBlock(releaseLabel, List( + Call("", Ccc(), VoidType(), ConstantGlobal("pushOntoTodoList"), List(LocalReference(objectType, "object"))) + ), RetVoid())) + } + + private def createAndEmitEraseChildrenBasicBlock(freshEnvironment: Environment, eraseChildrenLabel: String)(using ModuleContext, FunctionContext): Unit = { + val environmentRef = LocalReference(environmentType, freshName("environment")) + val eraseChildrenInstructions = mutable.ListBuffer[Instruction]() + + // Load environment variables and erase them + val envType = environmentType(freshEnvironment) + + val isAtLeastOneObjectToRelease: Boolean = + freshEnvironment.exists { + case machine.Variable(_, tpe) => + tpe match { + case machine.Positive() | machine.Negative() | machine.Type.Stack() => true + case _ => false + } + } + + if (isAtLeastOneObjectToRelease) { + // Get environment pointer + eraseChildrenInstructions += Call(environmentRef.name, Ccc(), environmentType, ConstantGlobal("objectEnvironment"), List(LocalReference(objectType, "object"))) + + freshEnvironment.zipWithIndex.foreach { case (machine.Variable(varName, tpe), i) => + val fieldPtr = LocalReference(PointerType(), freshName(varName + "_pointer")) + val loadedVarName = freshName(varName) + // Erase the value based on its type + tpe match { + case machine.Positive() => + emitElementPtrAndLoadOfEnvironmentVariable(environmentRef, eraseChildrenInstructions, envType, tpe, i, fieldPtr, loadedVarName, erasePositive) + case machine.Negative() => + emitElementPtrAndLoadOfEnvironmentVariable(environmentRef, eraseChildrenInstructions, envType, tpe, i, fieldPtr, loadedVarName, eraseNegative) + case machine.Type.Stack() => + emitElementPtrAndLoadOfEnvironmentVariable(environmentRef, eraseChildrenInstructions, envType, tpe, i, fieldPtr, loadedVarName, eraseResumption) + case _ => // Int, Byte, Double, Reference, etc. don't need erasing + } + } + emit(BasicBlock(eraseChildrenLabel, eraseChildrenInstructions.toList, RetVoid())) + } else { + // If not: we can return immediately, since we don't need to erase anything + emit(BasicBlock(eraseChildrenLabel, eraseChildrenInstructions.toList, RetVoid())) + } + } + + private def emitElementPtrAndLoadOfEnvironmentVariable(environmentRef: LocalReference, eraseChildrenInstructions: ListBuffer[Instruction], envType: LLVMType, tpe: machine.Type, i: Int, fieldPtr: LocalReference, loadedVarName: String, eraserFunction: ConstantGlobal) = { + eraseChildrenInstructions += GetElementPtr(fieldPtr.name, envType, environmentRef, List(0, i)) + eraseChildrenInstructions += Load(loadedVarName, transform(tpe), fieldPtr, Object) + eraseChildrenInstructions += Call("_", Ccc(), VoidType(), eraserFunction, List(LocalReference(transform(tpe), loadedVarName))) + } + + /** + * Loads the right erasing function for the given type + */ + private def getErasingFunctionForType(tpe: Type) = tpe match { + case NamedType("Pos") => erasePositive + case NamedType("Neg") => eraseNegative + case NamedType("Stack") => eraseResumption + case _ => ??? + } } diff --git a/examples/flat/nooptimized/allocate_first_then_release_flush_once.check b/examples/ctrc/nooptimized/allocate_first_then_release_flush_once.check similarity index 100% rename from examples/flat/nooptimized/allocate_first_then_release_flush_once.check rename to examples/ctrc/nooptimized/allocate_first_then_release_flush_once.check diff --git a/examples/flat/nooptimized/allocate_first_then_release_flush_once.effekt b/examples/ctrc/nooptimized/allocate_first_then_release_flush_once.effekt similarity index 100% rename from examples/flat/nooptimized/allocate_first_then_release_flush_once.effekt rename to examples/ctrc/nooptimized/allocate_first_then_release_flush_once.effekt diff --git a/examples/flat/nooptimized/allocate_first_then_release_flush_twice.check b/examples/ctrc/nooptimized/allocate_first_then_release_flush_twice.check similarity index 100% rename from examples/flat/nooptimized/allocate_first_then_release_flush_twice.check rename to examples/ctrc/nooptimized/allocate_first_then_release_flush_twice.check diff --git a/examples/flat/nooptimized/allocate_first_then_release_flush_twice.effekt b/examples/ctrc/nooptimized/allocate_first_then_release_flush_twice.effekt similarity index 100% rename from examples/flat/nooptimized/allocate_first_then_release_flush_twice.effekt rename to examples/ctrc/nooptimized/allocate_first_then_release_flush_twice.effekt diff --git a/examples/flat/nooptimized/array_record.check b/examples/ctrc/nooptimized/array_record.check similarity index 100% rename from examples/flat/nooptimized/array_record.check rename to examples/ctrc/nooptimized/array_record.check diff --git a/examples/flat/nooptimized/array_record.effekt b/examples/ctrc/nooptimized/array_record.effekt similarity index 100% rename from examples/flat/nooptimized/array_record.effekt rename to examples/ctrc/nooptimized/array_record.effekt diff --git a/examples/flat/nooptimized/array_record_match.check b/examples/ctrc/nooptimized/array_record_match.check similarity index 100% rename from examples/flat/nooptimized/array_record_match.check rename to examples/ctrc/nooptimized/array_record_match.check diff --git a/examples/flat/nooptimized/array_record_match.effekt b/examples/ctrc/nooptimized/array_record_match.effekt similarity index 83% rename from examples/flat/nooptimized/array_record_match.effekt rename to examples/ctrc/nooptimized/array_record_match.effekt index 1af090a55..e6856cf32 100644 --- a/examples/flat/nooptimized/array_record_match.effekt +++ b/examples/ctrc/nooptimized/array_record_match.effekt @@ -13,7 +13,7 @@ record OneSlotPerson( ) def main() = { - val myArray: Array[Int] = array::allocate(1) + val myArray: Array[Int] = array::unsafeAllocate(1) val p = Person(1, myArray) p match { case Person(f1, _) => println(f1) diff --git a/examples/flat/nooptimized/array_record_match_exhausted.check b/examples/ctrc/nooptimized/array_record_match_exhausted.check similarity index 100% rename from examples/flat/nooptimized/array_record_match_exhausted.check rename to examples/ctrc/nooptimized/array_record_match_exhausted.check diff --git a/examples/flat/nooptimized/array_record_match_exhausted.effekt b/examples/ctrc/nooptimized/array_record_match_exhausted.effekt similarity index 83% rename from examples/flat/nooptimized/array_record_match_exhausted.effekt rename to examples/ctrc/nooptimized/array_record_match_exhausted.effekt index 772e5c8c2..66ebfc8e3 100644 --- a/examples/flat/nooptimized/array_record_match_exhausted.effekt +++ b/examples/ctrc/nooptimized/array_record_match_exhausted.effekt @@ -13,7 +13,7 @@ record OneSlotPerson( ) def main() = { - val myArray: Array[Int] = array::allocate(1) + val myArray: Array[Int] = array::unsafeAllocate(1) val p = Person(1, myArray) p match { case Person(f1, arr) => println(f1) diff --git a/examples/flat/nooptimized/different_person_sizes_biggest_first.check b/examples/ctrc/nooptimized/different_person_sizes_biggest_first.check similarity index 100% rename from examples/flat/nooptimized/different_person_sizes_biggest_first.check rename to examples/ctrc/nooptimized/different_person_sizes_biggest_first.check diff --git a/examples/flat/nooptimized/different_person_sizes_biggest_first.effekt b/examples/ctrc/nooptimized/different_person_sizes_biggest_first.effekt similarity index 100% rename from examples/flat/nooptimized/different_person_sizes_biggest_first.effekt rename to examples/ctrc/nooptimized/different_person_sizes_biggest_first.effekt diff --git a/examples/flat/nooptimized/different_person_sizes_smallest_first.check b/examples/ctrc/nooptimized/different_person_sizes_smallest_first.check similarity index 100% rename from examples/flat/nooptimized/different_person_sizes_smallest_first.check rename to examples/ctrc/nooptimized/different_person_sizes_smallest_first.check diff --git a/examples/flat/nooptimized/different_person_sizes_smallest_first.effekt b/examples/ctrc/nooptimized/different_person_sizes_smallest_first.effekt similarity index 100% rename from examples/flat/nooptimized/different_person_sizes_smallest_first.effekt rename to examples/ctrc/nooptimized/different_person_sizes_smallest_first.effekt diff --git a/examples/flat/nooptimized/nested_objects.check b/examples/ctrc/nooptimized/nested_objects.check similarity index 100% rename from examples/flat/nooptimized/nested_objects.check rename to examples/ctrc/nooptimized/nested_objects.check diff --git a/examples/flat/nooptimized/nested_objects.effekt b/examples/ctrc/nooptimized/nested_objects.effekt similarity index 100% rename from examples/flat/nooptimized/nested_objects.effekt rename to examples/ctrc/nooptimized/nested_objects.effekt diff --git a/examples/flat/nooptimized/one_big_string_object.check b/examples/ctrc/nooptimized/one_big_string_object.check similarity index 100% rename from examples/flat/nooptimized/one_big_string_object.check rename to examples/ctrc/nooptimized/one_big_string_object.check diff --git a/examples/flat/nooptimized/one_big_string_object.effekt b/examples/ctrc/nooptimized/one_big_string_object.effekt similarity index 100% rename from examples/flat/nooptimized/one_big_string_object.effekt rename to examples/ctrc/nooptimized/one_big_string_object.effekt diff --git a/examples/flat/nooptimized/one_lg_object.check b/examples/ctrc/nooptimized/one_lg_object.check similarity index 100% rename from examples/flat/nooptimized/one_lg_object.check rename to examples/ctrc/nooptimized/one_lg_object.check diff --git a/examples/flat/nooptimized/one_lg_object.effekt b/examples/ctrc/nooptimized/one_lg_object.effekt similarity index 100% rename from examples/flat/nooptimized/one_lg_object.effekt rename to examples/ctrc/nooptimized/one_lg_object.effekt diff --git a/examples/flat/nooptimized/one_md_object.check b/examples/ctrc/nooptimized/one_md_object.check similarity index 100% rename from examples/flat/nooptimized/one_md_object.check rename to examples/ctrc/nooptimized/one_md_object.check diff --git a/examples/flat/nooptimized/one_md_object.effekt b/examples/ctrc/nooptimized/one_md_object.effekt similarity index 100% rename from examples/flat/nooptimized/one_md_object.effekt rename to examples/ctrc/nooptimized/one_md_object.effekt diff --git a/examples/flat/nooptimized/one_slot_one_person_list.check b/examples/ctrc/nooptimized/one_slot_one_person_list.check similarity index 100% rename from examples/flat/nooptimized/one_slot_one_person_list.check rename to examples/ctrc/nooptimized/one_slot_one_person_list.check diff --git a/examples/flat/nooptimized/one_slot_one_person_list.effekt b/examples/ctrc/nooptimized/one_slot_one_person_list.effekt similarity index 100% rename from examples/flat/nooptimized/one_slot_one_person_list.effekt rename to examples/ctrc/nooptimized/one_slot_one_person_list.effekt diff --git a/examples/flat/nooptimized/one_sm_object.check b/examples/ctrc/nooptimized/one_sm_object.check similarity index 100% rename from examples/flat/nooptimized/one_sm_object.check rename to examples/ctrc/nooptimized/one_sm_object.check diff --git a/examples/flat/nooptimized/one_sm_object.effekt b/examples/ctrc/nooptimized/one_sm_object.effekt similarity index 100% rename from examples/flat/nooptimized/one_sm_object.effekt rename to examples/ctrc/nooptimized/one_sm_object.effekt diff --git a/examples/flat/nooptimized/one_small_string_object.check b/examples/ctrc/nooptimized/one_small_string_object.check similarity index 100% rename from examples/flat/nooptimized/one_small_string_object.check rename to examples/ctrc/nooptimized/one_small_string_object.check diff --git a/examples/flat/nooptimized/one_small_string_object.effekt b/examples/ctrc/nooptimized/one_small_string_object.effekt similarity index 100% rename from examples/flat/nooptimized/one_small_string_object.effekt rename to examples/ctrc/nooptimized/one_small_string_object.effekt diff --git a/examples/flat/nooptimized/one_xl_object.check b/examples/ctrc/nooptimized/one_xl_object.check similarity index 100% rename from examples/flat/nooptimized/one_xl_object.check rename to examples/ctrc/nooptimized/one_xl_object.check diff --git a/examples/flat/nooptimized/one_xl_object.effekt b/examples/ctrc/nooptimized/one_xl_object.effekt similarity index 100% rename from examples/flat/nooptimized/one_xl_object.effekt rename to examples/ctrc/nooptimized/one_xl_object.effekt diff --git a/examples/flat/nooptimized/one_xs_object.check b/examples/ctrc/nooptimized/one_xs_object.check similarity index 100% rename from examples/flat/nooptimized/one_xs_object.check rename to examples/ctrc/nooptimized/one_xs_object.check diff --git a/examples/flat/nooptimized/one_xs_object.effekt b/examples/ctrc/nooptimized/one_xs_object.effekt similarity index 100% rename from examples/flat/nooptimized/one_xs_object.effekt rename to examples/ctrc/nooptimized/one_xs_object.effekt diff --git a/examples/flat/nooptimized/one_xxl_object_all_fields.check b/examples/ctrc/nooptimized/one_xxl_object_all_fields.check similarity index 100% rename from examples/flat/nooptimized/one_xxl_object_all_fields.check rename to examples/ctrc/nooptimized/one_xxl_object_all_fields.check diff --git a/examples/flat/nooptimized/one_xxl_object_all_fields.effekt b/examples/ctrc/nooptimized/one_xxl_object_all_fields.effekt similarity index 100% rename from examples/flat/nooptimized/one_xxl_object_all_fields.effekt rename to examples/ctrc/nooptimized/one_xxl_object_all_fields.effekt diff --git a/examples/flat/nooptimized/one_xxxl_object.check b/examples/ctrc/nooptimized/one_xxxl_object.check similarity index 100% rename from examples/flat/nooptimized/one_xxxl_object.check rename to examples/ctrc/nooptimized/one_xxxl_object.check diff --git a/examples/flat/nooptimized/one_xxxl_object.effekt b/examples/ctrc/nooptimized/one_xxxl_object.effekt similarity index 100% rename from examples/flat/nooptimized/one_xxxl_object.effekt rename to examples/ctrc/nooptimized/one_xxxl_object.effekt diff --git a/examples/flat/nooptimized/primitive_ref.check b/examples/ctrc/nooptimized/primitive_ref.check similarity index 100% rename from examples/flat/nooptimized/primitive_ref.check rename to examples/ctrc/nooptimized/primitive_ref.check diff --git a/examples/flat/nooptimized/primitive_ref.effekt b/examples/ctrc/nooptimized/primitive_ref.effekt similarity index 100% rename from examples/flat/nooptimized/primitive_ref.effekt rename to examples/ctrc/nooptimized/primitive_ref.effekt diff --git a/examples/flat/nooptimized/ref_allocate.check b/examples/ctrc/nooptimized/ref_allocate.check similarity index 100% rename from examples/flat/nooptimized/ref_allocate.check rename to examples/ctrc/nooptimized/ref_allocate.check diff --git a/examples/flat/nooptimized/ref_allocate.effekt b/examples/ctrc/nooptimized/ref_allocate.effekt similarity index 89% rename from examples/flat/nooptimized/ref_allocate.effekt rename to examples/ctrc/nooptimized/ref_allocate.effekt index 2b46ceaa7..011684f47 100644 --- a/examples/flat/nooptimized/ref_allocate.effekt +++ b/examples/ctrc/nooptimized/ref_allocate.effekt @@ -12,7 +12,7 @@ record Person( ) def main() = { - val p1 = ref::allocate() + val p1 = ref::unsafeAllocate() val p2 = Person(1, 2, 3, 4, 5, 6, 7) p1.set(p2) println(p1.get().field7) diff --git a/examples/flat/nooptimized/simple_list.check b/examples/ctrc/nooptimized/simple_list.check similarity index 100% rename from examples/flat/nooptimized/simple_list.check rename to examples/ctrc/nooptimized/simple_list.check diff --git a/examples/flat/nooptimized/simple_list.effekt b/examples/ctrc/nooptimized/simple_list.effekt similarity index 100% rename from examples/flat/nooptimized/simple_list.effekt rename to examples/ctrc/nooptimized/simple_list.effekt diff --git a/examples/flat/nooptimized/simple_ref.check b/examples/ctrc/nooptimized/simple_ref.check similarity index 100% rename from examples/flat/nooptimized/simple_ref.check rename to examples/ctrc/nooptimized/simple_ref.check diff --git a/examples/flat/nooptimized/simple_ref.effekt b/examples/ctrc/nooptimized/simple_ref.effekt similarity index 100% rename from examples/flat/nooptimized/simple_ref.effekt rename to examples/ctrc/nooptimized/simple_ref.effekt diff --git a/examples/flat/nooptimized/superperson.check b/examples/ctrc/nooptimized/superperson.check similarity index 100% rename from examples/flat/nooptimized/superperson.check rename to examples/ctrc/nooptimized/superperson.check diff --git a/examples/flat/nooptimized/superperson.effekt b/examples/ctrc/nooptimized/superperson.effekt similarity index 100% rename from examples/flat/nooptimized/superperson.effekt rename to examples/ctrc/nooptimized/superperson.effekt diff --git a/examples/flat/nooptimized/superperson_with_free.check b/examples/ctrc/nooptimized/superperson_with_free.check similarity index 100% rename from examples/flat/nooptimized/superperson_with_free.check rename to examples/ctrc/nooptimized/superperson_with_free.check diff --git a/examples/flat/nooptimized/superperson_with_free.effekt b/examples/ctrc/nooptimized/superperson_with_free.effekt similarity index 100% rename from examples/flat/nooptimized/superperson_with_free.effekt rename to examples/ctrc/nooptimized/superperson_with_free.effekt diff --git a/examples/flat/nooptimized/three_md_objects_direct.check b/examples/ctrc/nooptimized/three_md_objects_direct.check similarity index 100% rename from examples/flat/nooptimized/three_md_objects_direct.check rename to examples/ctrc/nooptimized/three_md_objects_direct.check diff --git a/examples/flat/nooptimized/three_md_objects_direct.effekt b/examples/ctrc/nooptimized/three_md_objects_direct.effekt similarity index 100% rename from examples/flat/nooptimized/three_md_objects_direct.effekt rename to examples/ctrc/nooptimized/three_md_objects_direct.effekt diff --git a/examples/flat/nooptimized/trigger_child_freeing.check b/examples/ctrc/nooptimized/trigger_child_freeing.check similarity index 100% rename from examples/flat/nooptimized/trigger_child_freeing.check rename to examples/ctrc/nooptimized/trigger_child_freeing.check diff --git a/examples/flat/nooptimized/trigger_child_freeing.effekt b/examples/ctrc/nooptimized/trigger_child_freeing.effekt similarity index 100% rename from examples/flat/nooptimized/trigger_child_freeing.effekt rename to examples/ctrc/nooptimized/trigger_child_freeing.effekt diff --git a/examples/flat/nooptimized/trigger_flush_once.check b/examples/ctrc/nooptimized/trigger_flush_once.check similarity index 100% rename from examples/flat/nooptimized/trigger_flush_once.check rename to examples/ctrc/nooptimized/trigger_flush_once.check diff --git a/examples/flat/nooptimized/trigger_flush_once.effekt b/examples/ctrc/nooptimized/trigger_flush_once.effekt similarity index 100% rename from examples/flat/nooptimized/trigger_flush_once.effekt rename to examples/ctrc/nooptimized/trigger_flush_once.effekt diff --git a/examples/flat/nooptimized/trigger_flush_twice.check b/examples/ctrc/nooptimized/trigger_flush_twice.check similarity index 100% rename from examples/flat/nooptimized/trigger_flush_twice.check rename to examples/ctrc/nooptimized/trigger_flush_twice.check diff --git a/examples/flat/nooptimized/trigger_flush_twice.effekt b/examples/ctrc/nooptimized/trigger_flush_twice.effekt similarity index 100% rename from examples/flat/nooptimized/trigger_flush_twice.effekt rename to examples/ctrc/nooptimized/trigger_flush_twice.effekt diff --git a/examples/flat/nooptimized/trigger_one_child_freeing.check b/examples/ctrc/nooptimized/trigger_one_child_freeing.check similarity index 100% rename from examples/flat/nooptimized/trigger_one_child_freeing.check rename to examples/ctrc/nooptimized/trigger_one_child_freeing.check diff --git a/examples/flat/nooptimized/trigger_one_child_freeing.effekt b/examples/ctrc/nooptimized/trigger_one_child_freeing.effekt similarity index 100% rename from examples/flat/nooptimized/trigger_one_child_freeing.effekt rename to examples/ctrc/nooptimized/trigger_one_child_freeing.effekt diff --git a/examples/flat/nooptimized/trigger_two_child_freeing.check b/examples/ctrc/nooptimized/trigger_two_child_freeing.check similarity index 100% rename from examples/flat/nooptimized/trigger_two_child_freeing.check rename to examples/ctrc/nooptimized/trigger_two_child_freeing.check diff --git a/examples/flat/nooptimized/trigger_two_child_freeing.effekt b/examples/ctrc/nooptimized/trigger_two_child_freeing.effekt similarity index 100% rename from examples/flat/nooptimized/trigger_two_child_freeing.effekt rename to examples/ctrc/nooptimized/trigger_two_child_freeing.effekt diff --git a/examples/flat/nooptimized/two_lg_objects.check b/examples/ctrc/nooptimized/two_lg_objects.check similarity index 100% rename from examples/flat/nooptimized/two_lg_objects.check rename to examples/ctrc/nooptimized/two_lg_objects.check diff --git a/examples/flat/nooptimized/two_lg_objects.effekt b/examples/ctrc/nooptimized/two_lg_objects.effekt similarity index 100% rename from examples/flat/nooptimized/two_lg_objects.effekt rename to examples/ctrc/nooptimized/two_lg_objects.effekt diff --git a/examples/flat/nooptimized/two_md_mixed_object.check b/examples/ctrc/nooptimized/two_md_mixed_object.check similarity index 100% rename from examples/flat/nooptimized/two_md_mixed_object.check rename to examples/ctrc/nooptimized/two_md_mixed_object.check diff --git a/examples/flat/nooptimized/two_md_mixed_object.effekt b/examples/ctrc/nooptimized/two_md_mixed_object.effekt similarity index 100% rename from examples/flat/nooptimized/two_md_mixed_object.effekt rename to examples/ctrc/nooptimized/two_md_mixed_object.effekt diff --git a/examples/flat/nooptimized/two_md_objects.check b/examples/ctrc/nooptimized/two_md_objects.check similarity index 100% rename from examples/flat/nooptimized/two_md_objects.check rename to examples/ctrc/nooptimized/two_md_objects.check diff --git a/examples/flat/nooptimized/two_md_objects.effekt b/examples/ctrc/nooptimized/two_md_objects.effekt similarity index 100% rename from examples/flat/nooptimized/two_md_objects.effekt rename to examples/ctrc/nooptimized/two_md_objects.effekt diff --git a/examples/flat/nooptimized/two_slot_one_person_list.check b/examples/ctrc/nooptimized/two_slot_one_person_list.check similarity index 100% rename from examples/flat/nooptimized/two_slot_one_person_list.check rename to examples/ctrc/nooptimized/two_slot_one_person_list.check diff --git a/examples/flat/nooptimized/two_slot_one_person_list.effekt b/examples/ctrc/nooptimized/two_slot_one_person_list.effekt similarity index 100% rename from examples/flat/nooptimized/two_slot_one_person_list.effekt rename to examples/ctrc/nooptimized/two_slot_one_person_list.effekt diff --git a/examples/flat/nooptimized/two_slot_one_person_with_free_variable_list.check b/examples/ctrc/nooptimized/two_slot_one_person_with_free_variable_list.check similarity index 100% rename from examples/flat/nooptimized/two_slot_one_person_with_free_variable_list.check rename to examples/ctrc/nooptimized/two_slot_one_person_with_free_variable_list.check diff --git a/examples/flat/nooptimized/two_slot_one_person_with_free_variable_list.effekt b/examples/ctrc/nooptimized/two_slot_one_person_with_free_variable_list.effekt similarity index 100% rename from examples/flat/nooptimized/two_slot_one_person_with_free_variable_list.effekt rename to examples/ctrc/nooptimized/two_slot_one_person_with_free_variable_list.effekt diff --git a/examples/flat/nooptimized/two_slot_two_person_list.check b/examples/ctrc/nooptimized/two_slot_two_person_list.check similarity index 100% rename from examples/flat/nooptimized/two_slot_two_person_list.check rename to examples/ctrc/nooptimized/two_slot_two_person_list.check diff --git a/examples/flat/nooptimized/two_slot_two_person_list.effekt b/examples/ctrc/nooptimized/two_slot_two_person_list.effekt similarity index 100% rename from examples/flat/nooptimized/two_slot_two_person_list.effekt rename to examples/ctrc/nooptimized/two_slot_two_person_list.effekt diff --git a/examples/flat/nooptimized/two_slot_two_person_list_continuation.check b/examples/ctrc/nooptimized/two_slot_two_person_list_continuation.check similarity index 100% rename from examples/flat/nooptimized/two_slot_two_person_list_continuation.check rename to examples/ctrc/nooptimized/two_slot_two_person_list_continuation.check diff --git a/examples/flat/nooptimized/two_slot_two_person_list_continuation.effekt b/examples/ctrc/nooptimized/two_slot_two_person_list_continuation.effekt similarity index 100% rename from examples/flat/nooptimized/two_slot_two_person_list_continuation.effekt rename to examples/ctrc/nooptimized/two_slot_two_person_list_continuation.effekt diff --git a/examples/flat/nooptimized/two_slot_two_person_list_continuation_allocation.check b/examples/ctrc/nooptimized/two_slot_two_person_list_continuation_allocation.check similarity index 100% rename from examples/flat/nooptimized/two_slot_two_person_list_continuation_allocation.check rename to examples/ctrc/nooptimized/two_slot_two_person_list_continuation_allocation.check diff --git a/examples/flat/nooptimized/two_slot_two_person_list_continuation_allocation.effekt b/examples/ctrc/nooptimized/two_slot_two_person_list_continuation_allocation.effekt similarity index 100% rename from examples/flat/nooptimized/two_slot_two_person_list_continuation_allocation.effekt rename to examples/ctrc/nooptimized/two_slot_two_person_list_continuation_allocation.effekt diff --git a/examples/flat/nooptimized/two_slot_two_person_list_continuation_exhausted.check b/examples/ctrc/nooptimized/two_slot_two_person_list_continuation_exhausted.check similarity index 100% rename from examples/flat/nooptimized/two_slot_two_person_list_continuation_exhausted.check rename to examples/ctrc/nooptimized/two_slot_two_person_list_continuation_exhausted.check diff --git a/examples/flat/nooptimized/two_slot_two_person_list_continuation_exhausted.effekt b/examples/ctrc/nooptimized/two_slot_two_person_list_continuation_exhausted.effekt similarity index 100% rename from examples/flat/nooptimized/two_slot_two_person_list_continuation_exhausted.effekt rename to examples/ctrc/nooptimized/two_slot_two_person_list_continuation_exhausted.effekt diff --git a/examples/flat/nooptimized/two_slot_two_person_list_exhausted.check b/examples/ctrc/nooptimized/two_slot_two_person_list_exhausted.check similarity index 100% rename from examples/flat/nooptimized/two_slot_two_person_list_exhausted.check rename to examples/ctrc/nooptimized/two_slot_two_person_list_exhausted.check diff --git a/examples/flat/nooptimized/two_slot_two_person_list_exhausted.effekt b/examples/ctrc/nooptimized/two_slot_two_person_list_exhausted.effekt similarity index 100% rename from examples/flat/nooptimized/two_slot_two_person_list_exhausted.effekt rename to examples/ctrc/nooptimized/two_slot_two_person_list_exhausted.effekt diff --git a/examples/flat/nooptimized/two_slot_two_person_with_free_variable_list.check b/examples/ctrc/nooptimized/two_slot_two_person_with_free_variable_list.check similarity index 100% rename from examples/flat/nooptimized/two_slot_two_person_with_free_variable_list.check rename to examples/ctrc/nooptimized/two_slot_two_person_with_free_variable_list.check diff --git a/examples/flat/nooptimized/two_slot_two_person_with_free_variable_list.effekt b/examples/ctrc/nooptimized/two_slot_two_person_with_free_variable_list.effekt similarity index 100% rename from examples/flat/nooptimized/two_slot_two_person_with_free_variable_list.effekt rename to examples/ctrc/nooptimized/two_slot_two_person_with_free_variable_list.effekt diff --git a/examples/flat/nooptimized/two_sm_mixed_object.check b/examples/ctrc/nooptimized/two_sm_mixed_object.check similarity index 100% rename from examples/flat/nooptimized/two_sm_mixed_object.check rename to examples/ctrc/nooptimized/two_sm_mixed_object.check diff --git a/examples/flat/nooptimized/two_sm_mixed_object.effekt b/examples/ctrc/nooptimized/two_sm_mixed_object.effekt similarity index 100% rename from examples/flat/nooptimized/two_sm_mixed_object.effekt rename to examples/ctrc/nooptimized/two_sm_mixed_object.effekt diff --git a/examples/flat/nooptimized/two_sm_objects.check b/examples/ctrc/nooptimized/two_sm_objects.check similarity index 100% rename from examples/flat/nooptimized/two_sm_objects.check rename to examples/ctrc/nooptimized/two_sm_objects.check diff --git a/examples/flat/nooptimized/two_sm_objects.effekt b/examples/ctrc/nooptimized/two_sm_objects.effekt similarity index 100% rename from examples/flat/nooptimized/two_sm_objects.effekt rename to examples/ctrc/nooptimized/two_sm_objects.effekt diff --git a/examples/flat/nooptimized/two_xl_objects.check b/examples/ctrc/nooptimized/two_xl_objects.check similarity index 100% rename from examples/flat/nooptimized/two_xl_objects.check rename to examples/ctrc/nooptimized/two_xl_objects.check diff --git a/examples/flat/nooptimized/two_xl_objects.effekt b/examples/ctrc/nooptimized/two_xl_objects.effekt similarity index 100% rename from examples/flat/nooptimized/two_xl_objects.effekt rename to examples/ctrc/nooptimized/two_xl_objects.effekt diff --git a/examples/flat/nooptimized/two_xs_objects.check b/examples/ctrc/nooptimized/two_xs_objects.check similarity index 100% rename from examples/flat/nooptimized/two_xs_objects.check rename to examples/ctrc/nooptimized/two_xs_objects.check diff --git a/examples/flat/nooptimized/two_xs_objects.effekt b/examples/ctrc/nooptimized/two_xs_objects.effekt similarity index 100% rename from examples/flat/nooptimized/two_xs_objects.effekt rename to examples/ctrc/nooptimized/two_xs_objects.effekt diff --git a/examples/flat/nooptimized/two_xxl_object_all_fields.check b/examples/ctrc/nooptimized/two_xxl_object_all_fields.check similarity index 100% rename from examples/flat/nooptimized/two_xxl_object_all_fields.check rename to examples/ctrc/nooptimized/two_xxl_object_all_fields.check diff --git a/examples/flat/nooptimized/two_xxl_object_all_fields.effekt b/examples/ctrc/nooptimized/two_xxl_object_all_fields.effekt similarity index 100% rename from examples/flat/nooptimized/two_xxl_object_all_fields.effekt rename to examples/ctrc/nooptimized/two_xxl_object_all_fields.effekt diff --git a/examples/flat/nooptimized/two_xxl_objects.check b/examples/ctrc/nooptimized/two_xxl_objects.check similarity index 100% rename from examples/flat/nooptimized/two_xxl_objects.check rename to examples/ctrc/nooptimized/two_xxl_objects.check diff --git a/examples/flat/nooptimized/two_xxl_objects.effekt b/examples/ctrc/nooptimized/two_xxl_objects.effekt similarity index 100% rename from examples/flat/nooptimized/two_xxl_objects.effekt rename to examples/ctrc/nooptimized/two_xxl_objects.effekt diff --git a/examples/flat/nooptimized/two_xxxl_objects.check b/examples/ctrc/nooptimized/two_xxxl_objects.check similarity index 100% rename from examples/flat/nooptimized/two_xxxl_objects.check rename to examples/ctrc/nooptimized/two_xxxl_objects.check diff --git a/examples/flat/nooptimized/two_xxxl_objects.effekt b/examples/ctrc/nooptimized/two_xxxl_objects.effekt similarity index 100% rename from examples/flat/nooptimized/two_xxxl_objects.effekt rename to examples/ctrc/nooptimized/two_xxxl_objects.effekt diff --git a/libraries/common/array.effekt b/libraries/common/array.effekt index a2c345c1f..758e7a717 100644 --- a/libraries/common/array.effekt +++ b/libraries/common/array.effekt @@ -19,10 +19,15 @@ extern type Array[T] */ extern llvm """ -define void @array_erase_fields(ptr %array_pointer) { +define void @array_erase(%Object %object) { entry: - %data_pointer = getelementptr inbounds i64, ptr %array_pointer, i64 1 - %size = load i64, ptr %array_pointer, align 8 + ; header of arrays looks like that: rc (0), eraser (1), size (2), data (3) + %size_pointer = getelementptr inbounds i64, ptr %object, i64 2 + %size = load i64, ptr %size_pointer, align 8 + + ; data starts after 3 entries in our object + %data_pointer = getelementptr inbounds ptr, ptr %object, i64 3 + %size_eq_0 = icmp eq i64 %size, 0 br i1 %size_eq_0, label %exit, label %loop loop: @@ -31,11 +36,13 @@ loop: %element_pointer = getelementptr inbounds %Pos, ptr %data_pointer, i64 %loop_phi %element = load %Pos, ptr %element_pointer - call void @erasePositive(%Pos %element) + call void @erasePositive(%Pos %element) ; we erase each child of the array + %inc = add nuw i64 %loop_phi, 1 %cmp = icmp ult i64 %inc, %size br i1 %cmp, label %loop, label %exit exit: + call void @free(%Object %object) ; we delete the array ret void } """ @@ -52,7 +59,7 @@ extern def unsafeAllocate[T](size: Int) at global: Array[T] = %eraser_pointer = getelementptr ptr, ptr %calloc, i64 1 %size_pointer = getelementptr ptr, ptr %calloc, i64 2 store i64 0, ptr %calloc - store ptr @array_erase_fields, ptr %eraser_pointer + store ptr @array_erase, ptr %eraser_pointer store i64 ${size}, ptr %size_pointer %ret_pos = insertvalue %Pos { i64 0, ptr poison }, ptr %calloc, 1 ret %Pos %ret_pos diff --git a/libraries/common/ref.effekt b/libraries/common/ref.effekt index 5d6de8e09..f24e01bbb 100644 --- a/libraries/common/ref.effekt +++ b/libraries/common/ref.effekt @@ -10,9 +10,12 @@ extern js """ """ extern llvm """ -define void @c_ref_erase_field(ptr %0) { - %field = load %Pos, ptr %0, align 8 - tail call void @erasePositive(%Pos %field) +define void @c_ref_erase(%Object %object) { + %headerSize = ptrtoint ptr getelementptr (%Header, ptr null, i64 1) to i64 + %environment = getelementptr i8, ptr %object, i64 %headerSize + %field = load %Pos, ptr %environment, align 8 + call void @free(%Object %object) + call void @erasePositive(%Pos %field) ret void } """ @@ -41,9 +44,9 @@ extern def unsafeAllocate[T]() at global: Ref[T] = %fieldData_pointer = getelementptr ptr, ptr %ref, i64 3 store i64 0, ptr %ref, align 8 - store ptr @c_ref_erase_field, ptr %refEraser, align 8 + store ptr @c_ref_erase, ptr %refEraser, align 8 store i64 0, ptr %fieldTag, align 8 - store ptr null, ptr %fieldData_pointer, align 8 + store ptr null, ptr %fieldData_pointer, align 8 %refWrap = insertvalue %Pos { i64 0, ptr poison }, ptr %ref, 1 ret %Pos %refWrap @@ -62,7 +65,7 @@ extern def ref[T](init: T) at global: Ref[T] = %refField = getelementptr ptr, ptr %ref, i64 2 store i64 0, ptr %ref, align 8 - store ptr @c_ref_erase_field, ptr %refEraser, align 8 + store ptr @c_ref_erase, ptr %refEraser, align 8 store %Pos ${init}, ptr %refField, align 8 %refWrap = insertvalue %Pos { i64 0, ptr poison }, ptr %ref, 1 diff --git a/libraries/llvm/bytearray.c b/libraries/llvm/bytearray.c index 9aa8d9082..e3a1fc766 100644 --- a/libraries/llvm/bytearray.c +++ b/libraries/llvm/bytearray.c @@ -2,11 +2,7 @@ #define EFFEKT_BYTEARRAY_C #include // For memcopy -#include -#include - -extern void* cMalloc(uint8_t size); - +#include /** We represent bytearrays like positive types. * @@ -21,11 +17,13 @@ extern void* cMalloc(uint8_t size); */ -void c_bytearray_erase_noop(void *envPtr) { (void)envPtr; } +void c_bytearray_erase_noop(void* object) { + free(object); +} struct Pos c_bytearray_new(const Int size) { int object_size = sizeof(struct Header) + size; - void *objPtr = cMalloc(object_size); + void *objPtr = malloc(object_size); struct Header *headerPtr = objPtr; *headerPtr = (struct Header) { .rc = 0, .eraser = c_bytearray_erase_noop, }; return (struct Pos) { diff --git a/libraries/llvm/initialize-arena.c b/libraries/llvm/initialize-arena.c new file mode 100644 index 000000000..df635bdce --- /dev/null +++ b/libraries/llvm/initialize-arena.c @@ -0,0 +1,14 @@ +#include + +// Initialize a 4 GiB arena via mmap. +// Does not work in LLVM properly, therefore it is done in C. +void* initializeArena(void) { + return mmap( + NULL, // no specific start adress + 4294967296ULL, // 4 GiB + PROT_READ | PROT_WRITE, // Can read and write + MAP_PRIVATE | MAP_ANONYMOUS, // isolated, clean arena + -1, // No file descriptor + 0 // Offset + ); +} \ No newline at end of file diff --git a/libraries/llvm/main.c b/libraries/llvm/main.c index 89e94309d..70d4c5db9 100644 --- a/libraries/llvm/main.c +++ b/libraries/llvm/main.c @@ -14,6 +14,7 @@ #include "cMalloc.c" #include "io.c" #include "panic.c" +#include "initialize-arena.c" extern void effektMain(); diff --git a/libraries/llvm/rts.ll b/libraries/llvm/rts.ll index a2750eed8..bc5ee758e 100644 --- a/libraries/llvm/rts.ll +++ b/libraries/llvm/rts.ll @@ -93,11 +93,7 @@ %String = type %Pos ; Foreign imports - -declare void @cInitializeMemory() -declare ptr @cMalloc(i64) -declare void @cFree(ptr) -declare ptr @cRealloc(ptr, i64) +declare ptr @initializeArena() declare ptr @malloc(i64) declare void @free(ptr) @@ -124,99 +120,127 @@ declare void @exit(i64) declare void @llvm.assume(i1) -; Prompts +; typedef struct Slot +; { +; struct Slot* next; +; void (*eraser)(void *object); +; } Slot; +%struct.Slot = type { %struct.Slot*, %Eraser } -define private %Prompt @currentPrompt(%Stack %stack) { - %prompt_pointer = getelementptr %StackValue, %Stack %stack, i64 0, i32 3 - %prompt = load %Prompt, ptr %prompt_pointer, !alias.scope !11, !noalias !21 - ret %Prompt %prompt -} +; initializes the todoList with a sentinel slot. +; Sentinel Slot: Fakes a block with a RC=1. It is used to mark the end of the To-Do-List. +; But it is not a real heap-object, because it is not 8-byte aligned. +@freeList = private unnamed_addr global %struct.Slot* null, align 8 +@todoList = private unnamed_addr global %struct.Slot* inttoptr (i64 1 to %struct.Slot*), align 8 +@nextUnusedSlot = private unnamed_addr global i8* null, align 8 ; Pointer to the next unused Slot -define private %Prompt @freshPrompt() { - %promptSize = ptrtoint ptr getelementptr (%PromptValue, ptr null, i64 1) to i64 - %prompt = call %Prompt @malloc(i64 %promptSize) - store %PromptValue zeroinitializer, %Prompt %prompt, !alias.scope !13, !noalias !23 - ret %Prompt %prompt + +; Initializes the memory for our effekt-objects that are created by newObject and deleted by eraseObject. +define private void @initializeMemory() nounwind { +entry: + %startAddress = call noalias ptr @initializeArena() ;How much storage do we allocate at the beginning of a program? =4GB + store i8* %startAddress, i8** @nextUnusedSlot + ret void } -; Garbage collection -; A type for the free list -%struct.Block = type { %struct.Block* } +define private %struct.Slot* @acquire() nounwind { +entry: + %freeHead = load %struct.Slot*, %struct.Slot** @freeList + %isEmpty = icmp eq %struct.Slot* %freeHead, null + br i1 %isEmpty, label %checkTodo, label %freeReuse -@freeList = global %struct.Block* null -@nextUnusedBlock = global i8* null -@endOfChunk = global i8* null -@blockSize = global i64 1024 ; each Block is 1KB +; 1. Fast Path: Reuse block from freeList +freeReuse: + %freeNextPtr = getelementptr %struct.Slot, %struct.Slot* %freeHead, i32 0, i32 0 + %freeNext = load %struct.Slot*, %struct.Slot** %freeNextPtr, align 8 + store %struct.Slot* %freeNext, %struct.Slot** @freeList, align 8 -define private void @initializeMemory() { - ; Step 01: mem = malloc(4294967296) - %mem = call i8* @malloc(i64 4294967296) + ret %struct.Slot* %freeHead - ; Step 02: nextUnusedBlock = mem - store i8* %mem, i8** @nextUnusedBlock +checkTodo: + %todoHead = load %struct.Slot*, %struct.Slot** @todoList + %isSentinel = icmp eq %struct.Slot* %todoHead, inttoptr (i64 1 to %struct.Slot*) + br i1 %isSentinel, label %bumpAlloc, label %todoReuse - ; Step 03: endOfChunk = mem + 4294967296 - %endPtr = getelementptr i8, i8* %mem, i64 4294967296 - store i8* %endPtr, i8** @endOfChunk +; 2. Slot Path: Reuse block from To-Do-List. Here, we have to extra call the eraser to ensure that we can reuse it. +todoReuse: + %todoNextPtr = getelementptr inbounds %struct.Slot, %struct.Slot* %todoHead, i32 0, i32 0 + %todoNext = load %struct.Slot*, %struct.Slot** %todoNextPtr, align 8 + store %struct.Slot* %todoNext, %struct.Slot** @todoList, align 8 - ret void + ; Call eraser + ; reusedSlot->eraser(reusedSlot); + %eraserptr = getelementptr inbounds %struct.Slot, %struct.Slot* %todoHead, i32 0, i32 1 + %eraser = load %Eraser, void (%struct.Slot*)** %eraserptr, align 8, !alias.scope !14, !noalias !24 + tail call void %eraser(%struct.Slot* %todoHead) + + ret %struct.Slot* %todoHead + +; 3. Fallback - Bump Path: We have to allocate a new block. +bumpAlloc: + ; Load nextUnusedBlock + %fresh = load ptr, i8** @nextUnusedSlot, align 8 + + ; Move bump pointer forward by object size + %nextBump = getelementptr i8, ptr %fresh, i8 64 + + store ptr %nextBump, i8** @nextUnusedSlot, align 8 + + ret %struct.Slot* %fresh } -define private %Object @myMalloc(i64 %size) { +; Pushes a slot on the top of the free-List. +define private void @pushOntoFreeList(%struct.Slot* %slot) nounwind { entry: - ; Step 01: Check if the free list pointer is not null - %freeList = load %struct.Block*, %struct.Block** @freeList - %isNull = icmp eq %struct.Block* %freeList, null - br i1 %isNull, label %newAllocate, label %reuse + ; oldHead = freeList + %oldHead = load %struct.Slot*, %struct.Slot** @freeList, align 8 -; In case we can recycle a block from the free list, we do so and jump to the reuse label. -reuse: - ; Step 01: block = freeList - %block = load %struct.Block*, %struct.Block** @freeList + ; ptr->next = oldHead + %nextPtr = getelementptr %struct.Slot, %struct.Slot* %slot, i32 0, i32 0 + store %struct.Slot* %oldHead, %struct.Slot** %nextPtr, align 8 - ; Step 02: freeList = freeList.next - %nextPtr = getelementptr %struct.Block, %struct.Block* %block, i32 0, i32 0 - %nextBlock = load %struct.Block*, %struct.Block** %nextPtr - store %struct.Block* %nextBlock, %struct.Block** @freeList + ; freeList = ptr + store %struct.Slot* %slot, %struct.Slot** @freeList, align 8 - ; Step 03: Return - %ret = bitcast %struct.Block* %block to %Object - ret %Object %ret + ret void +} -; In case we do not have a block to reuse -newAllocate: - %nu = load i8*, i8** @nextUnusedBlock - %end = load i8*, i8** @endOfChunk - %blockSize = load i64, i64* @blockSize +; Pushes a slot on the top of the To-Do-List. +define private void @pushOntoTodoList(%struct.Slot* %slot) nounwind { +entry: + ; oldHead = todoList + %oldHead = load %struct.Slot*, %struct.Slot** @todoList, align 8 - ; block = next_unused - %next_plus = getelementptr i8, i8* %nu, i64 %blockSize - store i8* %next_plus, i8** @nextUnusedBlock + ; ptr->next = oldHead + %nextPtr = getelementptr %struct.Slot, %struct.Slot* %slot, i32 0, i32 0 + store %struct.Slot* %oldHead, %struct.Slot** %nextPtr, align 8 - %ret2 = bitcast i8* %nu to %Object - ret %Object %ret2 + ; todoList = ptr + store %struct.Slot* %slot, %struct.Slot** @todoList, align 8 + ret void } -define private void @myFree(%Object %object) { - ; block = (Block*)object - %block = bitcast %Object %object to %struct.Block* - ; block.next = freeList - %nextField = getelementptr %struct.Block, %struct.Block* %block, i32 0, i32 0 - %freeList = load %struct.Block*, %struct.Block** @freeList - store %struct.Block* %freeList, %struct.Block** %nextField - ; freeList = block - store %struct.Block* %block, %struct.Block** @freeList ; <- fails - ret void +; Prompts + +define private %Prompt @currentPrompt(%Stack %stack) { + %prompt_pointer = getelementptr %StackValue, %Stack %stack, i64 0, i32 3 + %prompt = load %Prompt, ptr %prompt_pointer, !alias.scope !11, !noalias !21 + ret %Prompt %prompt +} + +define private %Prompt @freshPrompt() { + %promptSize = ptrtoint ptr getelementptr (%PromptValue, ptr null, i64 1) to i64 + %prompt = call %Prompt @malloc(i64 %promptSize) + store %PromptValue zeroinitializer, %Prompt %prompt, !alias.scope !13, !noalias !23 + ret %Prompt %prompt } define private %Object @newObject(%Eraser %eraser, i64 %environmentSize) alwaysinline { - %headerSize = ptrtoint ptr getelementptr (%Header, ptr null, i64 1) to i64 - %size = add i64 %environmentSize, %headerSize - %object = call ptr @cMalloc(i64 %size) + %object = call ptr @acquire() %objectReferenceCount = getelementptr %Header, ptr %object, i64 0, i32 0 %objectEraser = getelementptr %Header, ptr %object, i64 0, i32 1 store %ReferenceCount 0, ptr %objectReferenceCount, !alias.scope !14, !noalias !24 @@ -274,9 +298,7 @@ define private void @eraseObject(%Object %object) alwaysinline { free: %objectEraser = getelementptr %Header, ptr %object, i64 0, i32 1 %eraser = load %Eraser, ptr %objectEraser, !alias.scope !14, !noalias !24 - %environment = call %Environment @objectEnvironment(%Object %object) - call void %eraser(%Environment %environment) - call void @cFree(%Object %object) + call void %eraser(%Object %object) br label %done done: From 3801f88c3df1034ff9afb9fa82308f84bff613ca Mon Sep 17 00:00:00 2001 From: Flat Date: Fri, 27 Feb 2026 11:15:02 +0100 Subject: [PATCH 15/27] df: sender_receiver and server_client should work now as well. --- libraries/llvm/io.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/libraries/llvm/io.c b/libraries/llvm/io.c index c33984117..44b4f9e51 100644 --- a/libraries/llvm/io.c +++ b/libraries/llvm/io.c @@ -589,11 +589,11 @@ typedef struct { Stack stack; } Signal; -void c_signal_erase(void *envPtr) { - // envPtr points to a Signal _after_ the eraser, so let's adjust it to point to the beginning. - Signal *signal = (Signal*) (envPtr - offsetof(Signal, state)); +void c_signal_erase(void *object) { + Signal *signal = (Signal*) object; erasePositive(signal->value); if (signal->stack != NULL) { eraseStack(signal->stack); } + free(signal); } struct Pos c_signal_make() { From 2e8cfcc9c49c1194d1e9af64772e0ec36e3f749f Mon Sep 17 00:00:00 2001 From: Philipp Schuster Date: Tue, 3 Mar 2026 10:07:11 +0100 Subject: [PATCH 16/27] Delete cMalloc --- libraries/llvm/cMalloc.c | 124 --------------------------------------- libraries/llvm/main.c | 1 - libraries/llvm/rts.ll | 8 +-- 3 files changed, 4 insertions(+), 129 deletions(-) delete mode 100644 libraries/llvm/cMalloc.c diff --git a/libraries/llvm/cMalloc.c b/libraries/llvm/cMalloc.c deleted file mode 100644 index f7dd07c87..000000000 --- a/libraries/llvm/cMalloc.c +++ /dev/null @@ -1,124 +0,0 @@ -#include -#include -#include - -// ----------------------------- -// Strukturdefinition -// ----------------------------- - -/** - * @brief Block-Struktur für die Freelist. - * - * Jeder freie Block zeigt auf den nächsten freien Block. - */ -typedef struct Block { - struct Block* next; -} Block; - -// ----------------------------- -// Globale Variablen -// ----------------------------- - -static Block* freeList = NULL; // Kopf der Freelist -static uint8_t* nextUnusedBlock = NULL; // Zeiger auf nächsten unbenutzten Block -static uint8_t* endOfChunk = NULL; // Ende des allokierten Speichers -static const int blockSize = 1024; // Größe jedes Blocks (1KB) - -// ----------------------------- -// Initialisierung -// ----------------------------- - -/** - * @brief Initialisiert den großen Speicherbereich (4GB). - */ -void cInitializeMemory(void) { - size_t chunkSize = (size_t)4294967296ULL; // 4GB - uint8_t* mem = (uint8_t*)malloc(chunkSize); - if (!mem) { - fprintf(stderr, "malloc() failed!\n"); - exit(1); - } - - nextUnusedBlock = mem; - endOfChunk = mem + chunkSize; - printf("[init] Memory initialized: %p - %p\n", (void*)mem, (void*)endOfChunk); -} - -// ----------------------------- -// Allokator -// ----------------------------- - -/** - * @brief Einfacher Speicher-Allocator. - * - * Wenn die Freelist leer ist, nimmt er den nächsten Block im Chunk. - * Wenn die Freelist nicht leer ist, nimmt er den ersten Eintrag daraus. - * - * @param size Ignoriert in diesem simplen Modell (wir geben immer 1KB). - * @return void* Zeiger auf den allokierten Block. - */ -void* cMalloc(uint8_t size) { - // 1. Falls Freelist leer ist → neuer Block - if (freeList == NULL) { - if (nextUnusedBlock + blockSize > endOfChunk) { - fprintf(stderr, "Out of memory!\n"); - return NULL; - } - - void* block = nextUnusedBlock; - nextUnusedBlock += blockSize; - printf("[malloc] New block: %p\n", block); - return block; - } - - - // 2. Falls Freelist nicht leer ist → wiederverwenden - Block* block = freeList; - freeList = block->next; - printf("[malloc] Reusing block: %p\n", (void*)block); - printf("[malloc] freeList: %p\n", (void*)freeList); - return (void*)block; -// return malloc(size); -} - -// ----------------------------- -// Free-Funktion -// ----------------------------- - -/** - * @brief Gibt einen Block zurück in die Freelist. - * - * @param ptr Zeiger auf den Block. - */ -void cFree(void* ptr) { - if (!ptr) return; - - Block* block = (Block*)ptr; - block->next = freeList; - freeList = block; - - printf("[free] Freed block: %p\n", ptr); -// free(ptr); -} - -void* cRealloc(void* ptr, uint8_t size) { - printf("cRealloc: %p, %d\n", ptr, size); - return realloc(ptr,size); -} - -// ----------------------------- -// Test / Demo -// ----------------------------- - -//int main(void) { -// cInitializeMemory(); -// -// void* a = cMalloc(1024); -// void* b = cMalloc(1024); -// cFree(a); -// void* c = cMalloc(1024); // sollte a wiederverwenden -// cFree(b); -// cFree(c); -// -// return 0; -//} diff --git a/libraries/llvm/main.c b/libraries/llvm/main.c index 70d4c5db9..4d01be3c5 100644 --- a/libraries/llvm/main.c +++ b/libraries/llvm/main.c @@ -11,7 +11,6 @@ #include "types.c" #include "bytearray.c" -#include "cMalloc.c" #include "io.c" #include "panic.c" #include "initialize-arena.c" diff --git a/libraries/llvm/rts.ll b/libraries/llvm/rts.ll index bc5ee758e..cc21752a3 100644 --- a/libraries/llvm/rts.ll +++ b/libraries/llvm/rts.ll @@ -93,8 +93,6 @@ %String = type %Pos ; Foreign imports -declare ptr @initializeArena() - declare ptr @malloc(i64) declare void @free(ptr) declare ptr @realloc(ptr, i64) @@ -119,6 +117,7 @@ declare void @print(i64) declare void @exit(i64) declare void @llvm.assume(i1) +declare ptr @initializeArena() ; typedef struct Slot ; { @@ -138,8 +137,9 @@ declare void @llvm.assume(i1) ; Initializes the memory for our effekt-objects that are created by newObject and deleted by eraseObject. define private void @initializeMemory() nounwind { entry: - %startAddress = call noalias ptr @initializeArena() ;How much storage do we allocate at the beginning of a program? =4GB - store i8* %startAddress, i8** @nextUnusedSlot + ; we need this because flags for mmap differ between platforms + %startAddress = call noalias ptr @initializeArena() + store ptr %startAddress, ptr @nextUnusedSlot ret void } From e8601f887dca6c6217d7a19d8bceea90b815717e Mon Sep 17 00:00:00 2001 From: Philipp Schuster Date: Tue, 3 Mar 2026 10:34:33 +0100 Subject: [PATCH 17/27] Revise acquire --- libraries/llvm/rts.ll | 72 ++++++++++++++++++++++--------------------- 1 file changed, 37 insertions(+), 35 deletions(-) diff --git a/libraries/llvm/rts.ll b/libraries/llvm/rts.ll index cc21752a3..a88087bc0 100644 --- a/libraries/llvm/rts.ll +++ b/libraries/llvm/rts.ll @@ -124,100 +124,102 @@ declare ptr @initializeArena() ; struct Slot* next; ; void (*eraser)(void *object); ; } Slot; -%struct.Slot = type { %struct.Slot*, %Eraser } +%Slot = type { ptr, %Eraser } +; list of immediately available slots +@freeList = private unnamed_addr global ptr null +; list of slots where we still need to erase the children ; initializes the todoList with a sentinel slot. ; Sentinel Slot: Fakes a block with a RC=1. It is used to mark the end of the To-Do-List. ; But it is not a real heap-object, because it is not 8-byte aligned. -@freeList = private unnamed_addr global %struct.Slot* null, align 8 -@todoList = private unnamed_addr global %struct.Slot* inttoptr (i64 1 to %struct.Slot*), align 8 -@nextUnusedSlot = private unnamed_addr global i8* null, align 8 ; Pointer to the next unused Slot - +@todoList = private unnamed_addr global ptr inttoptr (i64 1 to ptr) +; space of unused consecutive slots +@bumpList = private unnamed_addr global ptr null ; Initializes the memory for our effekt-objects that are created by newObject and deleted by eraseObject. define private void @initializeMemory() nounwind { entry: ; we need this because flags for mmap differ between platforms %startAddress = call noalias ptr @initializeArena() - store ptr %startAddress, ptr @nextUnusedSlot + store ptr %startAddress, ptr @bumpList ret void } -define private %struct.Slot* @acquire() nounwind { +define private ptr @acquire() nounwind { entry: - %freeHead = load %struct.Slot*, %struct.Slot** @freeList - %isEmpty = icmp eq %struct.Slot* %freeHead, null + %freeHead = load ptr, ptr @freeList + %isEmpty = icmp eq ptr %freeHead, null br i1 %isEmpty, label %checkTodo, label %freeReuse ; 1. Fast Path: Reuse block from freeList freeReuse: - %freeNextPtr = getelementptr %struct.Slot, %struct.Slot* %freeHead, i32 0, i32 0 - %freeNext = load %struct.Slot*, %struct.Slot** %freeNextPtr, align 8 - store %struct.Slot* %freeNext, %struct.Slot** @freeList, align 8 + %freeNextPtr = getelementptr %Slot, ptr %freeHead, i32 0, i32 0 + %freeNext = load ptr, ptr %freeNextPtr + store ptr %freeNext, ptr @freeList - ret %struct.Slot* %freeHead + ret ptr %freeHead checkTodo: - %todoHead = load %struct.Slot*, %struct.Slot** @todoList - %isSentinel = icmp eq %struct.Slot* %todoHead, inttoptr (i64 1 to %struct.Slot*) + %todoHead = load ptr, ptr @todoList + %isSentinel = icmp eq ptr %todoHead, inttoptr (i64 1 to ptr) br i1 %isSentinel, label %bumpAlloc, label %todoReuse ; 2. Slot Path: Reuse block from To-Do-List. Here, we have to extra call the eraser to ensure that we can reuse it. todoReuse: - %todoNextPtr = getelementptr inbounds %struct.Slot, %struct.Slot* %todoHead, i32 0, i32 0 - %todoNext = load %struct.Slot*, %struct.Slot** %todoNextPtr, align 8 - store %struct.Slot* %todoNext, %struct.Slot** @todoList, align 8 + %todoNextPtr = getelementptr inbounds %Slot, ptr %todoHead, i32 0, i32 0 + %todoNext = load ptr, ptr %todoNextPtr + store ptr %todoNext, ptr @todoList ; Call eraser ; reusedSlot->eraser(reusedSlot); - %eraserptr = getelementptr inbounds %struct.Slot, %struct.Slot* %todoHead, i32 0, i32 1 - %eraser = load %Eraser, void (%struct.Slot*)** %eraserptr, align 8, !alias.scope !14, !noalias !24 - tail call void %eraser(%struct.Slot* %todoHead) + %eraserPtr = getelementptr inbounds %Slot, ptr %todoHead, i32 0, i32 1 + %eraser = load %Eraser, ptr %eraserPtr, !alias.scope !14, !noalias !24 + call void %eraser(ptr %todoHead) - ret %struct.Slot* %todoHead + ret ptr %todoHead ; 3. Fallback - Bump Path: We have to allocate a new block. bumpAlloc: ; Load nextUnusedBlock - %fresh = load ptr, i8** @nextUnusedSlot, align 8 + %fresh = load ptr, ptr @bumpList ; Move bump pointer forward by object size %nextBump = getelementptr i8, ptr %fresh, i8 64 - store ptr %nextBump, i8** @nextUnusedSlot, align 8 + store ptr %nextBump, ptr @bumpList - ret %struct.Slot* %fresh + ret ptr %fresh } ; Pushes a slot on the top of the free-List. -define private void @pushOntoFreeList(%struct.Slot* %slot) nounwind { +define private void @pushOntoFreeList(ptr %slot) nounwind { entry: ; oldHead = freeList - %oldHead = load %struct.Slot*, %struct.Slot** @freeList, align 8 + %oldHead = load ptr, ptr @freeList ; ptr->next = oldHead - %nextPtr = getelementptr %struct.Slot, %struct.Slot* %slot, i32 0, i32 0 - store %struct.Slot* %oldHead, %struct.Slot** %nextPtr, align 8 + %nextPtr = getelementptr %Slot, ptr %slot, i32 0, i32 0 + store ptr %oldHead, ptr %nextPtr ; freeList = ptr - store %struct.Slot* %slot, %struct.Slot** @freeList, align 8 + store ptr %slot, ptr @freeList ret void } ; Pushes a slot on the top of the To-Do-List. -define private void @pushOntoTodoList(%struct.Slot* %slot) nounwind { +define private void @pushOntoTodoList(ptr %slot) nounwind { entry: ; oldHead = todoList - %oldHead = load %struct.Slot*, %struct.Slot** @todoList, align 8 + %oldHead = load ptr, ptr @todoList ; ptr->next = oldHead - %nextPtr = getelementptr %struct.Slot, %struct.Slot* %slot, i32 0, i32 0 - store %struct.Slot* %oldHead, %struct.Slot** %nextPtr, align 8 + %nextPtr = getelementptr %Slot, ptr %slot, i32 0, i32 0 + store ptr %oldHead, ptr %nextPtr ; todoList = ptr - store %struct.Slot* %slot, %struct.Slot** @todoList, align 8 + store ptr %slot, ptr @todoList ret void } From bc0560193d173587976f9d3a0604846b57171913 Mon Sep 17 00:00:00 2001 From: Philipp Schuster Date: Tue, 3 Mar 2026 10:44:29 +0100 Subject: [PATCH 18/27] Remove imports --- .../scala/effekt/generator/llvm/Transformer.scala | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/effekt/shared/src/main/scala/effekt/generator/llvm/Transformer.scala b/effekt/shared/src/main/scala/effekt/generator/llvm/Transformer.scala index 73edb0bdc..cb26f4c0a 100644 --- a/effekt/shared/src/main/scala/effekt/generator/llvm/Transformer.scala +++ b/effekt/shared/src/main/scala/effekt/generator/llvm/Transformer.scala @@ -2,12 +2,8 @@ package effekt package generator package llvm -import effekt.generator.llvm.Type as LLVMType -import effekt.generator.llvm.Instruction.{Call, Load} -import effekt.generator.llvm.Transformer.{ModuleContext, createReleaseFunction, emit, environmentType, freshName, objectEnvironment} import effekt.machine -import effekt.machine.{Environment, Variable} -import effekt.machine.analysis.* +import effekt.machine.analysis.freeVariables import effekt.util.intercalate import effekt.util.messages.ErrorReporter @@ -1060,12 +1056,12 @@ object Transformer { * It might be that an object consists of several slots. * Each slot is pushed onto the free list. */ - private def createReleasePushOntoFreeListBasicBlock(releaseLabel: String, environment: Environment, freeInBody: Set[machine.Variable], `object`: Operand, environmentRef: LocalReference)(using ModuleContext, FunctionContext, BlockContext): Unit = { + private def createReleasePushOntoFreeListBasicBlock(releaseLabel: String, environment: machine.Environment, freeInBody: Set[machine.Variable], `object`: Operand, environmentRef: LocalReference)(using ModuleContext, FunctionContext, BlockContext): Unit = { val allInstructions = mutable.ListBuffer[Instruction](Call("_", Ccc(), VoidType(), ConstantGlobal("pushOntoFreeList"), List(`object`))) var currentEnvironmentPtr = environmentRef val slottedEnvironment = splitEnvironment(environment) - slottedEnvironment.zipWithIndex.foreach { case (slotEnv: Environment, index: Int) => + slottedEnvironment.zipWithIndex.foreach { case (slotEnv: machine.Environment, index: Int) => val isLastSlot = index == slottedEnvironment.length - 1 val slotEnvTypes = if (isLastSlot) environmentType(slotEnv) else StructureType(slotEnv.map { case machine.Variable(_, t) => transform(t) } :+ positiveType) @@ -1167,7 +1163,7 @@ object Transformer { ), RetVoid())) } - private def createAndEmitEraseChildrenBasicBlock(freshEnvironment: Environment, eraseChildrenLabel: String)(using ModuleContext, FunctionContext): Unit = { + private def createAndEmitEraseChildrenBasicBlock(freshEnvironment: machine.Environment, eraseChildrenLabel: String)(using ModuleContext, FunctionContext): Unit = { val environmentRef = LocalReference(environmentType, freshName("environment")) val eraseChildrenInstructions = mutable.ListBuffer[Instruction]() @@ -1208,7 +1204,7 @@ object Transformer { } } - private def emitElementPtrAndLoadOfEnvironmentVariable(environmentRef: LocalReference, eraseChildrenInstructions: ListBuffer[Instruction], envType: LLVMType, tpe: machine.Type, i: Int, fieldPtr: LocalReference, loadedVarName: String, eraserFunction: ConstantGlobal) = { + private def emitElementPtrAndLoadOfEnvironmentVariable(environmentRef: LocalReference, eraseChildrenInstructions: ListBuffer[Instruction], envType: llvm.Type, tpe: machine.Type, i: Int, fieldPtr: LocalReference, loadedVarName: String, eraserFunction: ConstantGlobal) = { eraseChildrenInstructions += GetElementPtr(fieldPtr.name, envType, environmentRef, List(0, i)) eraseChildrenInstructions += Load(loadedVarName, transform(tpe), fieldPtr, Object) eraseChildrenInstructions += Call("_", Ccc(), VoidType(), eraserFunction, List(LocalReference(transform(tpe), loadedVarName))) From a1985c82a7988cd939e8f394a20207c0e782eafd Mon Sep 17 00:00:00 2001 From: Philipp Schuster Date: Tue, 3 Mar 2026 11:38:43 +0100 Subject: [PATCH 19/27] Insert other free call --- libraries/common/bytearray.effekt | 5 +++-- libraries/llvm/bytearray.c | 4 ++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/libraries/common/bytearray.effekt b/libraries/common/bytearray.effekt index 3bcceaf37..d7c606ec8 100644 --- a/libraries/common/bytearray.effekt +++ b/libraries/common/bytearray.effekt @@ -31,7 +31,7 @@ extern def allocate(size: Int) at global: ByteArray = %object_alloc = tail call noalias ptr @calloc(i64 %object_size, i64 1) store i64 0, ptr %object_alloc, align 8 %object_data_ptr = getelementptr inbounds i8, ptr %object_alloc, i64 8 - store ptr @bytearray_erase_noop, ptr %object_data_ptr, align 8 + store ptr @bytearray_erase, ptr %object_data_ptr, align 8 %ret_object1 = insertvalue %Pos poison, i64 ${size}, 0 %ret_object2 = insertvalue %Pos %ret_object1, ptr %object_alloc, 1 ret %Pos %ret_object2 @@ -180,7 +180,8 @@ extern js """ """ extern llvm """ -define void @bytearray_erase_noop(ptr readnone %0) { +define void @bytearray_erase(ptr readnone %0) { + tail call void @free(ptr %0) ret void } """ diff --git a/libraries/llvm/bytearray.c b/libraries/llvm/bytearray.c index e3a1fc766..15ab96486 100644 --- a/libraries/llvm/bytearray.c +++ b/libraries/llvm/bytearray.c @@ -17,7 +17,7 @@ */ -void c_bytearray_erase_noop(void* object) { +void c_bytearray_erase(void* object) { free(object); } @@ -25,7 +25,7 @@ struct Pos c_bytearray_new(const Int size) { int object_size = sizeof(struct Header) + size; void *objPtr = malloc(object_size); struct Header *headerPtr = objPtr; - *headerPtr = (struct Header) { .rc = 0, .eraser = c_bytearray_erase_noop, }; + *headerPtr = (struct Header) { .rc = 0, .eraser = c_bytearray_erase, }; return (struct Pos) { .tag = size, .obj = objPtr, From d0cc38ef11fb25fe410c71214f80e46b9ce6b189 Mon Sep 17 00:00:00 2001 From: Philipp Schuster Date: Tue, 3 Mar 2026 17:00:51 +0100 Subject: [PATCH 20/27] Delete tests for now --- .../jvm/src/test/scala/effekt/CTRCTests.scala | 23 - ...locate_first_then_release_flush_once.check | 65 - ...ocate_first_then_release_flush_once.effekt | 148 -- ...ocate_first_then_release_flush_twice.check | 0 ...cate_first_then_release_flush_twice.effekt | 282 --- examples/ctrc/nooptimized/array_record.check | 1 - examples/ctrc/nooptimized/array_record.effekt | 10 - .../ctrc/nooptimized/array_record_match.check | 1 - .../nooptimized/array_record_match.effekt | 21 - .../array_record_match_exhausted.check | 1 - .../array_record_match_exhausted.effekt | 21 - ...different_person_sizes_biggest_first.check | 3 - ...ifferent_person_sizes_biggest_first.effekt | 46 - ...ifferent_person_sizes_smallest_first.check | 3 - ...fferent_person_sizes_smallest_first.effekt | 46 - .../ctrc/nooptimized/nested_objects.check | 1 - .../ctrc/nooptimized/nested_objects.effekt | 16 - .../nooptimized/one_big_string_object.check | 1 - .../nooptimized/one_big_string_object.effekt | 9 - examples/ctrc/nooptimized/one_lg_object.check | 1 - .../ctrc/nooptimized/one_lg_object.effekt | 18 - examples/ctrc/nooptimized/one_md_object.check | 1 - .../ctrc/nooptimized/one_md_object.effekt | 15 - .../one_slot_one_person_list.check | 1 - .../one_slot_one_person_list.effekt | 27 - examples/ctrc/nooptimized/one_sm_object.check | 1 - .../ctrc/nooptimized/one_sm_object.effekt | 14 - .../nooptimized/one_small_string_object.check | 1 - .../one_small_string_object.effekt | 8 - examples/ctrc/nooptimized/one_xl_object.check | 1 - .../ctrc/nooptimized/one_xl_object.effekt | 19 - examples/ctrc/nooptimized/one_xs_object.check | 1 - .../ctrc/nooptimized/one_xs_object.effekt | 11 - .../one_xxl_object_all_fields.check | 100 -- .../one_xxl_object_all_fields.effekt | 308 ---- .../ctrc/nooptimized/one_xxxl_object.check | 1 - .../ctrc/nooptimized/one_xxxl_object.effekt | 1008 ----------- examples/ctrc/nooptimized/primitive_ref.check | 1 - .../ctrc/nooptimized/primitive_ref.effekt | 9 - examples/ctrc/nooptimized/ref_allocate.check | 1 - examples/ctrc/nooptimized/ref_allocate.effekt | 19 - examples/ctrc/nooptimized/simple_list.check | 1 - examples/ctrc/nooptimized/simple_list.effekt | 15 - examples/ctrc/nooptimized/simple_ref.check | 1 - examples/ctrc/nooptimized/simple_ref.effekt | 20 - examples/ctrc/nooptimized/superperson.check | 2 - examples/ctrc/nooptimized/superperson.effekt | 33 - .../nooptimized/superperson_with_free.check | 1 - .../nooptimized/superperson_with_free.effekt | 30 - .../nooptimized/three_md_objects_direct.check | 3 - .../three_md_objects_direct.effekt | 20 - .../nooptimized/trigger_child_freeing.check | 0 .../nooptimized/trigger_child_freeing.effekt | 64 - .../ctrc/nooptimized/trigger_flush_once.check | 0 .../nooptimized/trigger_flush_once.effekt | 17 - .../nooptimized/trigger_flush_twice.check | 0 .../nooptimized/trigger_flush_twice.effekt | 17 - .../trigger_one_child_freeing.check | 0 .../trigger_one_child_freeing.effekt | 26 - .../trigger_two_child_freeing.check | 0 .../trigger_two_child_freeing.effekt | 28 - .../ctrc/nooptimized/two_lg_objects.check | 2 - .../ctrc/nooptimized/two_lg_objects.effekt | 20 - .../nooptimized/two_md_mixed_object.check | 2 - .../nooptimized/two_md_mixed_object.effekt | 17 - .../ctrc/nooptimized/two_md_objects.check | 2 - .../ctrc/nooptimized/two_md_objects.effekt | 17 - .../two_slot_one_person_list.check | 1 - .../two_slot_one_person_list.effekt | 23 - ...t_one_person_with_free_variable_list.check | 1 - ..._one_person_with_free_variable_list.effekt | 29 - .../two_slot_two_person_list.check | 1 - .../two_slot_two_person_list.effekt | 24 - ...wo_slot_two_person_list_continuation.check | 1 - ...o_slot_two_person_list_continuation.effekt | 27 - ..._person_list_continuation_allocation.check | 2 - ...person_list_continuation_allocation.effekt | 45 - ...o_person_list_continuation_exhausted.check | 1 - ..._person_list_continuation_exhausted.effekt | 27 - .../two_slot_two_person_list_exhausted.check | 1 - .../two_slot_two_person_list_exhausted.effekt | 24 - ...t_two_person_with_free_variable_list.check | 1 - ..._two_person_with_free_variable_list.effekt | 29 - .../nooptimized/two_sm_mixed_object.check | 2 - .../nooptimized/two_sm_mixed_object.effekt | 15 - .../ctrc/nooptimized/two_sm_objects.check | 2 - .../ctrc/nooptimized/two_sm_objects.effekt | 16 - .../ctrc/nooptimized/two_xl_objects.check | 2 - .../ctrc/nooptimized/two_xl_objects.effekt | 21 - .../ctrc/nooptimized/two_xs_objects.check | 2 - .../ctrc/nooptimized/two_xs_objects.effekt | 13 - .../two_xxl_object_all_fields.check | 100 -- .../two_xxl_object_all_fields.effekt | 308 ---- .../ctrc/nooptimized/two_xxl_objects.check | 2 - .../ctrc/nooptimized/two_xxl_objects.effekt | 312 ---- .../ctrc/nooptimized/two_xxxl_objects.check | 2 - .../ctrc/nooptimized/two_xxxl_objects.effekt | 1512 ----------------- 97 files changed, 5148 deletions(-) delete mode 100644 effekt/jvm/src/test/scala/effekt/CTRCTests.scala delete mode 100644 examples/ctrc/nooptimized/allocate_first_then_release_flush_once.check delete mode 100644 examples/ctrc/nooptimized/allocate_first_then_release_flush_once.effekt delete mode 100644 examples/ctrc/nooptimized/allocate_first_then_release_flush_twice.check delete mode 100644 examples/ctrc/nooptimized/allocate_first_then_release_flush_twice.effekt delete mode 100644 examples/ctrc/nooptimized/array_record.check delete mode 100644 examples/ctrc/nooptimized/array_record.effekt delete mode 100644 examples/ctrc/nooptimized/array_record_match.check delete mode 100644 examples/ctrc/nooptimized/array_record_match.effekt delete mode 100644 examples/ctrc/nooptimized/array_record_match_exhausted.check delete mode 100644 examples/ctrc/nooptimized/array_record_match_exhausted.effekt delete mode 100644 examples/ctrc/nooptimized/different_person_sizes_biggest_first.check delete mode 100644 examples/ctrc/nooptimized/different_person_sizes_biggest_first.effekt delete mode 100644 examples/ctrc/nooptimized/different_person_sizes_smallest_first.check delete mode 100644 examples/ctrc/nooptimized/different_person_sizes_smallest_first.effekt delete mode 100644 examples/ctrc/nooptimized/nested_objects.check delete mode 100644 examples/ctrc/nooptimized/nested_objects.effekt delete mode 100644 examples/ctrc/nooptimized/one_big_string_object.check delete mode 100644 examples/ctrc/nooptimized/one_big_string_object.effekt delete mode 100644 examples/ctrc/nooptimized/one_lg_object.check delete mode 100644 examples/ctrc/nooptimized/one_lg_object.effekt delete mode 100644 examples/ctrc/nooptimized/one_md_object.check delete mode 100644 examples/ctrc/nooptimized/one_md_object.effekt delete mode 100644 examples/ctrc/nooptimized/one_slot_one_person_list.check delete mode 100644 examples/ctrc/nooptimized/one_slot_one_person_list.effekt delete mode 100644 examples/ctrc/nooptimized/one_sm_object.check delete mode 100644 examples/ctrc/nooptimized/one_sm_object.effekt delete mode 100644 examples/ctrc/nooptimized/one_small_string_object.check delete mode 100644 examples/ctrc/nooptimized/one_small_string_object.effekt delete mode 100644 examples/ctrc/nooptimized/one_xl_object.check delete mode 100644 examples/ctrc/nooptimized/one_xl_object.effekt delete mode 100644 examples/ctrc/nooptimized/one_xs_object.check delete mode 100644 examples/ctrc/nooptimized/one_xs_object.effekt delete mode 100644 examples/ctrc/nooptimized/one_xxl_object_all_fields.check delete mode 100644 examples/ctrc/nooptimized/one_xxl_object_all_fields.effekt delete mode 100644 examples/ctrc/nooptimized/one_xxxl_object.check delete mode 100644 examples/ctrc/nooptimized/one_xxxl_object.effekt delete mode 100644 examples/ctrc/nooptimized/primitive_ref.check delete mode 100644 examples/ctrc/nooptimized/primitive_ref.effekt delete mode 100644 examples/ctrc/nooptimized/ref_allocate.check delete mode 100644 examples/ctrc/nooptimized/ref_allocate.effekt delete mode 100644 examples/ctrc/nooptimized/simple_list.check delete mode 100644 examples/ctrc/nooptimized/simple_list.effekt delete mode 100644 examples/ctrc/nooptimized/simple_ref.check delete mode 100644 examples/ctrc/nooptimized/simple_ref.effekt delete mode 100644 examples/ctrc/nooptimized/superperson.check delete mode 100644 examples/ctrc/nooptimized/superperson.effekt delete mode 100644 examples/ctrc/nooptimized/superperson_with_free.check delete mode 100644 examples/ctrc/nooptimized/superperson_with_free.effekt delete mode 100644 examples/ctrc/nooptimized/three_md_objects_direct.check delete mode 100644 examples/ctrc/nooptimized/three_md_objects_direct.effekt delete mode 100644 examples/ctrc/nooptimized/trigger_child_freeing.check delete mode 100644 examples/ctrc/nooptimized/trigger_child_freeing.effekt delete mode 100644 examples/ctrc/nooptimized/trigger_flush_once.check delete mode 100644 examples/ctrc/nooptimized/trigger_flush_once.effekt delete mode 100644 examples/ctrc/nooptimized/trigger_flush_twice.check delete mode 100644 examples/ctrc/nooptimized/trigger_flush_twice.effekt delete mode 100644 examples/ctrc/nooptimized/trigger_one_child_freeing.check delete mode 100644 examples/ctrc/nooptimized/trigger_one_child_freeing.effekt delete mode 100644 examples/ctrc/nooptimized/trigger_two_child_freeing.check delete mode 100644 examples/ctrc/nooptimized/trigger_two_child_freeing.effekt delete mode 100644 examples/ctrc/nooptimized/two_lg_objects.check delete mode 100644 examples/ctrc/nooptimized/two_lg_objects.effekt delete mode 100644 examples/ctrc/nooptimized/two_md_mixed_object.check delete mode 100644 examples/ctrc/nooptimized/two_md_mixed_object.effekt delete mode 100644 examples/ctrc/nooptimized/two_md_objects.check delete mode 100644 examples/ctrc/nooptimized/two_md_objects.effekt delete mode 100644 examples/ctrc/nooptimized/two_slot_one_person_list.check delete mode 100644 examples/ctrc/nooptimized/two_slot_one_person_list.effekt delete mode 100644 examples/ctrc/nooptimized/two_slot_one_person_with_free_variable_list.check delete mode 100644 examples/ctrc/nooptimized/two_slot_one_person_with_free_variable_list.effekt delete mode 100644 examples/ctrc/nooptimized/two_slot_two_person_list.check delete mode 100644 examples/ctrc/nooptimized/two_slot_two_person_list.effekt delete mode 100644 examples/ctrc/nooptimized/two_slot_two_person_list_continuation.check delete mode 100644 examples/ctrc/nooptimized/two_slot_two_person_list_continuation.effekt delete mode 100644 examples/ctrc/nooptimized/two_slot_two_person_list_continuation_allocation.check delete mode 100644 examples/ctrc/nooptimized/two_slot_two_person_list_continuation_allocation.effekt delete mode 100644 examples/ctrc/nooptimized/two_slot_two_person_list_continuation_exhausted.check delete mode 100644 examples/ctrc/nooptimized/two_slot_two_person_list_continuation_exhausted.effekt delete mode 100644 examples/ctrc/nooptimized/two_slot_two_person_list_exhausted.check delete mode 100644 examples/ctrc/nooptimized/two_slot_two_person_list_exhausted.effekt delete mode 100644 examples/ctrc/nooptimized/two_slot_two_person_with_free_variable_list.check delete mode 100644 examples/ctrc/nooptimized/two_slot_two_person_with_free_variable_list.effekt delete mode 100644 examples/ctrc/nooptimized/two_sm_mixed_object.check delete mode 100644 examples/ctrc/nooptimized/two_sm_mixed_object.effekt delete mode 100644 examples/ctrc/nooptimized/two_sm_objects.check delete mode 100644 examples/ctrc/nooptimized/two_sm_objects.effekt delete mode 100644 examples/ctrc/nooptimized/two_xl_objects.check delete mode 100644 examples/ctrc/nooptimized/two_xl_objects.effekt delete mode 100644 examples/ctrc/nooptimized/two_xs_objects.check delete mode 100644 examples/ctrc/nooptimized/two_xs_objects.effekt delete mode 100644 examples/ctrc/nooptimized/two_xxl_object_all_fields.check delete mode 100644 examples/ctrc/nooptimized/two_xxl_object_all_fields.effekt delete mode 100644 examples/ctrc/nooptimized/two_xxl_objects.check delete mode 100644 examples/ctrc/nooptimized/two_xxl_objects.effekt delete mode 100644 examples/ctrc/nooptimized/two_xxxl_objects.check delete mode 100644 examples/ctrc/nooptimized/two_xxxl_objects.effekt diff --git a/effekt/jvm/src/test/scala/effekt/CTRCTests.scala b/effekt/jvm/src/test/scala/effekt/CTRCTests.scala deleted file mode 100644 index 76d65570b..000000000 --- a/effekt/jvm/src/test/scala/effekt/CTRCTests.scala +++ /dev/null @@ -1,23 +0,0 @@ -package effekt - -import sbt.io.* -import sbt.io.syntax.* - -import java.io.File -import scala.language.implicitConversions -import scala.sys.process.Process - -class CTRCTests extends EffektTests { - - def backendName = "llvm" - - override def valgrind = false // works on linux only - - override lazy val positives: Set[File] = Set( - examplesDir / "ctrc" / "optimized" - ) - - override lazy val withoutOptimizations: Set[File] = Set( - examplesDir / "ctrc" / "nooptimized", - ) -} diff --git a/examples/ctrc/nooptimized/allocate_first_then_release_flush_once.check b/examples/ctrc/nooptimized/allocate_first_then_release_flush_once.check deleted file mode 100644 index 90fa4d6e3..000000000 --- a/examples/ctrc/nooptimized/allocate_first_then_release_flush_once.check +++ /dev/null @@ -1,65 +0,0 @@ -1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 \ No newline at end of file diff --git a/examples/ctrc/nooptimized/allocate_first_then_release_flush_once.effekt b/examples/ctrc/nooptimized/allocate_first_then_release_flush_once.effekt deleted file mode 100644 index 4d1f729a1..000000000 --- a/examples/ctrc/nooptimized/allocate_first_then_release_flush_once.effekt +++ /dev/null @@ -1,148 +0,0 @@ - -record OneSlotPerson( - field1: Int, - field2: Int, - field3: Int, - field4: Int, - field5: Int, - field6: Int -) - -def allocate65SlotsAndReleaseThem() = { - var x1 = OneSlotPerson(1, 2, 3, 4, 5, 6) - var x2 = OneSlotPerson(2, 3, 4, 5, 6, 7) - var x3 = OneSlotPerson(3, 4, 5, 6, 7, 8) - var x4 = OneSlotPerson(4, 5, 6, 7, 8, 9) - var x5 = OneSlotPerson(5, 6, 7, 8, 9, 10) - var x6 = OneSlotPerson(6, 7, 8, 9, 10, 11) - var x7 = OneSlotPerson(7, 8, 9, 10, 11, 12) - var x8 = OneSlotPerson(8, 9, 10, 11, 12, 13) - var x9 = OneSlotPerson(9, 10, 11, 12, 13, 14) - var x10 = OneSlotPerson(10, 11, 12, 13, 14, 15) - var x11 = OneSlotPerson(11, 12, 13, 14, 15, 16) - var x12 = OneSlotPerson(12, 13, 14, 15, 16, 17) - var x13 = OneSlotPerson(13, 14, 15, 16, 17, 18) - var x14 = OneSlotPerson(14, 15, 16, 17, 18, 19) - var x15 = OneSlotPerson(15, 16, 17, 18, 19, 20) - var x16 = OneSlotPerson(16, 17, 18, 19, 20, 21) - var x17 = OneSlotPerson(17, 18, 19, 20, 21, 22) - var x18 = OneSlotPerson(18, 19, 20, 21, 22, 23) - var x19 = OneSlotPerson(19, 20, 21, 22, 23, 24) - var x20 = OneSlotPerson(20, 21, 22, 23, 24, 25) - var x21 = OneSlotPerson(21, 22, 23, 24, 25, 26) - var x22 = OneSlotPerson(22, 23, 24, 25, 26, 27) - var x23 = OneSlotPerson(23, 24, 25, 26, 27, 28) - var x24 = OneSlotPerson(24, 25, 26, 27, 28, 29) - var x25 = OneSlotPerson(25, 26, 27, 28, 29, 30) - var x26 = OneSlotPerson(26, 27, 28, 29, 30, 31) - var x27 = OneSlotPerson(27, 28, 29, 30, 31, 32) - var x28 = OneSlotPerson(28, 29, 30, 31, 32, 33) - var x29 = OneSlotPerson(29, 30, 31, 32, 33, 34) - var x30 = OneSlotPerson(30, 31, 32, 33, 34, 35) - var x31 = OneSlotPerson(31, 32, 33, 34, 35, 36) - var x32 = OneSlotPerson(32, 33, 34, 35, 36, 37) - var x33 = OneSlotPerson(33, 34, 35, 36, 37, 38) - var x34 = OneSlotPerson(34, 35, 36, 37, 38, 39) - var x35 = OneSlotPerson(35, 36, 37, 38, 39, 40) - var x36 = OneSlotPerson(36, 37, 38, 39, 40, 41) - var x37 = OneSlotPerson(37, 38, 39, 40, 41, 42) - var x38 = OneSlotPerson(38, 39, 40, 41, 42, 43) - var x39 = OneSlotPerson(39, 40, 41, 42, 43, 44) - var x40 = OneSlotPerson(40, 41, 42, 43, 44, 45) - var x41 = OneSlotPerson(41, 42, 43, 44, 45, 46) - var x42 = OneSlotPerson(42, 43, 44, 45, 46, 47) - var x43 = OneSlotPerson(43, 44, 45, 46, 47, 48) - var x44 = OneSlotPerson(44, 45, 46, 47, 48, 49) - var x45 = OneSlotPerson(45, 46, 47, 48, 49, 50) - var x46 = OneSlotPerson(46, 47, 48, 49, 50, 51) - var x47 = OneSlotPerson(47, 48, 49, 50, 51, 52) - var x48 = OneSlotPerson(48, 49, 50, 51, 52, 53) - var x49 = OneSlotPerson(49, 50, 51, 52, 53, 54) - var x50 = OneSlotPerson(50, 51, 52, 53, 54, 55) - var x51 = OneSlotPerson(51, 52, 53, 54, 55, 56) - var x52 = OneSlotPerson(52, 53, 54, 55, 56, 57) - var x53 = OneSlotPerson(53, 54, 55, 56, 57, 58) - var x54 = OneSlotPerson(54, 55, 56, 57, 58, 59) - var x55 = OneSlotPerson(55, 56, 57, 58, 59, 60) - var x56 = OneSlotPerson(56, 57, 58, 59, 60, 61) - var x57 = OneSlotPerson(57, 58, 59, 60, 61, 62) - var x58 = OneSlotPerson(58, 59, 60, 61, 62, 63) - var x59 = OneSlotPerson(59, 60, 61, 62, 63, 64) - var x60 = OneSlotPerson(60, 61, 62, 63, 64, 65) - var x61 = OneSlotPerson(61, 62, 63, 64, 65, 66) - var x62 = OneSlotPerson(62, 63, 64, 65, 66, 67) - var x63 = OneSlotPerson(63, 64, 65, 66, 67, 68) - var x64 = OneSlotPerson(64, 65, 66, 67, 68, 69) - var x65 = OneSlotPerson(65, 66, 67, 68, 69, 70) - - println(x1.field1) - println(x2.field1) - println(x3.field1) - println(x4.field1) - println(x5.field1) - println(x6.field1) - println(x7.field1) - println(x8.field1) - println(x9.field1) - println(x10.field1) - println(x11.field1) - println(x12.field1) - println(x13.field1) - println(x14.field1) - println(x15.field1) - println(x16.field1) - println(x17.field1) - println(x18.field1) - println(x19.field1) - println(x20.field1) - println(x21.field1) - println(x22.field1) - println(x23.field1) - println(x24.field1) - println(x25.field1) - println(x26.field1) - println(x27.field1) - println(x28.field1) - println(x29.field1) - println(x30.field1) - println(x31.field1) - println(x32.field1) - println(x33.field1) - println(x34.field1) - println(x35.field1) - println(x36.field1) - println(x37.field1) - println(x38.field1) - println(x39.field1) - println(x40.field1) - println(x41.field1) - println(x42.field1) - println(x43.field1) - println(x44.field1) - println(x45.field1) - println(x46.field1) - println(x47.field1) - println(x48.field1) - println(x49.field1) - println(x50.field1) - println(x51.field1) - println(x52.field1) - println(x53.field1) - println(x54.field1) - println(x55.field1) - println(x56.field1) - println(x57.field1) - println(x58.field1) - println(x59.field1) - println(x60.field1) - println(x61.field1) - println(x62.field1) - println(x63.field1) - println(x64.field1) - println(x65.field1) -} - -def main() = { - allocate65SlotsAndReleaseThem(); - var finalObjectThatTriggersFlushingTodoList = OneSlotPerson(1, 2, 3, 4, 5, 6) -} diff --git a/examples/ctrc/nooptimized/allocate_first_then_release_flush_twice.check b/examples/ctrc/nooptimized/allocate_first_then_release_flush_twice.check deleted file mode 100644 index e69de29bb..000000000 diff --git a/examples/ctrc/nooptimized/allocate_first_then_release_flush_twice.effekt b/examples/ctrc/nooptimized/allocate_first_then_release_flush_twice.effekt deleted file mode 100644 index d9b4ccbb5..000000000 --- a/examples/ctrc/nooptimized/allocate_first_then_release_flush_twice.effekt +++ /dev/null @@ -1,282 +0,0 @@ - -record OneSlotPerson( - field1: Int, - field2: Int, - field3: Int, - field4: Int, - field5: Int, - field6: Int -) - -// we first allocate 128 slots and then release them all, such that we have exactly 128 slots on the to-do-list -// therefore, we have to flush the to-do list twice to clear it completely -def allocate128SlotsAndReleaseThem() = { - var x1 = OneSlotPerson(1, 2, 3, 4, 5, 6) - var x2 = OneSlotPerson(2, 3, 4, 5, 6, 7) - var x3 = OneSlotPerson(3, 4, 5, 6, 7, 8) - var x4 = OneSlotPerson(4, 5, 6, 7, 8, 9) - var x5 = OneSlotPerson(5, 6, 7, 8, 9, 10) - var x6 = OneSlotPerson(6, 7, 8, 9, 10, 11) - var x7 = OneSlotPerson(7, 8, 9, 10, 11, 12) - var x8 = OneSlotPerson(8, 9, 10, 11, 12, 13) - var x9 = OneSlotPerson(9, 10, 11, 12, 13, 14) - var x10 = OneSlotPerson(10, 11, 12, 13, 14, 15) - var x11 = OneSlotPerson(11, 12, 13, 14, 15, 16) - var x12 = OneSlotPerson(12, 13, 14, 15, 16, 17) - var x13 = OneSlotPerson(13, 14, 15, 16, 17, 18) - var x14 = OneSlotPerson(14, 15, 16, 17, 18, 19) - var x15 = OneSlotPerson(15, 16, 17, 18, 19, 20) - var x16 = OneSlotPerson(16, 17, 18, 19, 20, 21) - var x17 = OneSlotPerson(17, 18, 19, 20, 21, 22) - var x18 = OneSlotPerson(18, 19, 20, 21, 22, 23) - var x19 = OneSlotPerson(19, 20, 21, 22, 23, 24) - var x20 = OneSlotPerson(20, 21, 22, 23, 24, 25) - var x21 = OneSlotPerson(21, 22, 23, 24, 25, 26) - var x22 = OneSlotPerson(22, 23, 24, 25, 26, 27) - var x23 = OneSlotPerson(23, 24, 25, 26, 27, 28) - var x24 = OneSlotPerson(24, 25, 26, 27, 28, 29) - var x25 = OneSlotPerson(25, 26, 27, 28, 29, 30) - var x26 = OneSlotPerson(26, 27, 28, 29, 30, 31) - var x27 = OneSlotPerson(27, 28, 29, 30, 31, 32) - var x28 = OneSlotPerson(28, 29, 30, 31, 32, 33) - var x29 = OneSlotPerson(29, 30, 31, 32, 33, 34) - var x30 = OneSlotPerson(30, 31, 32, 33, 34, 35) - var x31 = OneSlotPerson(31, 32, 33, 34, 35, 36) - var x32 = OneSlotPerson(32, 33, 34, 35, 36, 37) - var x33 = OneSlotPerson(33, 34, 35, 36, 37, 38) - var x34 = OneSlotPerson(34, 35, 36, 37, 38, 39) - var x35 = OneSlotPerson(35, 36, 37, 38, 39, 40) - var x36 = OneSlotPerson(36, 37, 38, 39, 40, 41) - var x37 = OneSlotPerson(37, 38, 39, 40, 41, 42) - var x38 = OneSlotPerson(38, 39, 40, 41, 42, 43) - var x39 = OneSlotPerson(39, 40, 41, 42, 43, 44) - var x40 = OneSlotPerson(40, 41, 42, 43, 44, 45) - var x41 = OneSlotPerson(41, 42, 43, 44, 45, 46) - var x42 = OneSlotPerson(42, 43, 44, 45, 46, 47) - var x43 = OneSlotPerson(43, 44, 45, 46, 47, 48) - var x44 = OneSlotPerson(44, 45, 46, 47, 48, 49) - var x45 = OneSlotPerson(45, 46, 47, 48, 49, 50) - var x46 = OneSlotPerson(46, 47, 48, 49, 50, 51) - var x47 = OneSlotPerson(47, 48, 49, 50, 51, 52) - var x48 = OneSlotPerson(48, 49, 50, 51, 52, 53) - var x49 = OneSlotPerson(49, 50, 51, 52, 53, 54) - var x50 = OneSlotPerson(50, 51, 52, 53, 54, 55) - var x51 = OneSlotPerson(51, 52, 53, 54, 55, 56) - var x52 = OneSlotPerson(52, 53, 54, 55, 56, 57) - var x53 = OneSlotPerson(53, 54, 55, 56, 57, 58) - var x54 = OneSlotPerson(54, 55, 56, 57, 58, 59) - var x55 = OneSlotPerson(55, 56, 57, 58, 59, 60) - var x56 = OneSlotPerson(56, 57, 58, 59, 60, 61) - var x57 = OneSlotPerson(57, 58, 59, 60, 61, 62) - var x58 = OneSlotPerson(58, 59, 60, 61, 62, 63) - var x59 = OneSlotPerson(59, 60, 61, 62, 63, 64) - var x60 = OneSlotPerson(60, 61, 62, 63, 64, 65) - var x61 = OneSlotPerson(61, 62, 63, 64, 65, 66) - var x62 = OneSlotPerson(62, 63, 64, 65, 66, 67) - var x63 = OneSlotPerson(63, 64, 65, 66, 67, 68) - var x64 = OneSlotPerson(64, 65, 66, 67, 68, 69) - var x65 = OneSlotPerson(65, 66, 67, 68, 69, 70) - var x66 = OneSlotPerson(66, 67, 68, 69, 70, 71) - var x67 = OneSlotPerson(67, 68, 69, 70, 71, 72) - var x68 = OneSlotPerson(68, 69, 70, 71, 72, 73) - var x69 = OneSlotPerson(69, 70, 71, 72, 73, 74) - var x70 = OneSlotPerson(70, 71, 72, 73, 74, 75) - var x71 = OneSlotPerson(71, 72, 73, 74, 75, 76) - var x72 = OneSlotPerson(72, 73, 74, 75, 76, 77) - var x73 = OneSlotPerson(73, 74, 75, 76, 77, 78) - var x74 = OneSlotPerson(74, 75, 76, 77, 78, 79) - var x75 = OneSlotPerson(75, 76, 77, 78, 79, 80) - var x76 = OneSlotPerson(76, 77, 78, 79, 80, 81) - var x77 = OneSlotPerson(77, 78, 79, 80, 81, 82) - var x78 = OneSlotPerson(78, 79, 80, 81, 82, 83) - var x79 = OneSlotPerson(79, 80, 81, 82, 83, 84) - var x80 = OneSlotPerson(80, 81, 82, 83, 84, 85) - var x81 = OneSlotPerson(81, 82, 83, 84, 85, 86) - var x82 = OneSlotPerson(82, 83, 84, 85, 86, 87) - var x83 = OneSlotPerson(83, 84, 85, 86, 87, 88) - var x84 = OneSlotPerson(84, 85, 86, 87, 88, 89) - var x85 = OneSlotPerson(85, 86, 87, 88, 89, 90) - var x86 = OneSlotPerson(86, 87, 88, 89, 90, 91) - var x87 = OneSlotPerson(87, 88, 89, 90, 91, 92) - var x88 = OneSlotPerson(88, 89, 90, 91, 92, 93) - var x89 = OneSlotPerson(89, 90, 91, 92, 93, 94) - var x90 = OneSlotPerson(90, 91, 92, 93, 94, 95) - var x91 = OneSlotPerson(91, 92, 93, 94, 95, 96) - var x92 = OneSlotPerson(92, 93, 94, 95, 96, 97) - var x93 = OneSlotPerson(93, 94, 95, 96, 97, 98) - var x94 = OneSlotPerson(94, 95, 96, 97, 98, 99) - var x95 = OneSlotPerson(95, 96, 97, 98, 99, 100) - var x96 = OneSlotPerson(96, 97, 98, 99, 100, 101) - var x97 = OneSlotPerson(97, 98, 99, 100, 101, 102) - var x98 = OneSlotPerson(98, 99, 100, 101, 102, 103) - var x99 = OneSlotPerson(99, 100, 101, 102, 103, 104) - var x100 = OneSlotPerson(100, 101, 102, 103, 104, 105) - var x101 = OneSlotPerson(101, 102, 103, 104, 105, 106) - var x102 = OneSlotPerson(102, 103, 104, 105, 106, 107) - var x103 = OneSlotPerson(103, 104, 105, 106, 107, 108) - var x104 = OneSlotPerson(104, 105, 106, 107, 108, 109) - var x105 = OneSlotPerson(105, 106, 107, 108, 109, 110) - var x106 = OneSlotPerson(106, 107, 108, 109, 110, 111) - var x107 = OneSlotPerson(107, 108, 109, 110, 111, 112) - var x108 = OneSlotPerson(108, 109, 110, 111, 112, 113) - var x109 = OneSlotPerson(109, 110, 111, 112, 113, 114) - var x110 = OneSlotPerson(110, 111, 112, 113, 114, 115) - var x111 = OneSlotPerson(111, 112, 113, 114, 115, 116) - var x112 = OneSlotPerson(112, 113, 114, 115, 116, 117) - var x113 = OneSlotPerson(113, 114, 115, 116, 117, 118) - var x114 = OneSlotPerson(114, 115, 116, 117, 118, 119) - var x115 = OneSlotPerson(115, 116, 117, 118, 119, 120) - var x116 = OneSlotPerson(116, 117, 118, 119, 120, 121) - var x117 = OneSlotPerson(117, 118, 119, 120, 121, 122) - var x118 = OneSlotPerson(118, 119, 120, 121, 122, 123) - var x119 = OneSlotPerson(119, 120, 121, 122, 123, 124) - var x120 = OneSlotPerson(120, 121, 122, 123, 124, 125) - var x121 = OneSlotPerson(121, 122, 123, 124, 125, 126) - var x122 = OneSlotPerson(122, 123, 124, 125, 126, 127) - var x123 = OneSlotPerson(123, 124, 125, 126, 127, 128) - var x124 = OneSlotPerson(124, 125, 126, 127, 128, 129) - var x125 = OneSlotPerson(125, 126, 127, 128, 129, 130) - var x126 = OneSlotPerson(126, 127, 128, 129, 130, 131) - var x127 = OneSlotPerson(127, 128, 129, 130, 131, 132) - var x128 = OneSlotPerson(128, 129, 130, 131, 132, 133) - - println(x1.field1) - println(x2.field1) - println(x3.field1) - println(x4.field1) - println(x5.field1) - println(x6.field1) - println(x7.field1) - println(x8.field1) - println(x9.field1) - println(x10.field1) - println(x11.field1) - println(x12.field1) - println(x13.field1) - println(x14.field1) - println(x15.field1) - println(x16.field1) - println(x17.field1) - println(x18.field1) - println(x19.field1) - println(x20.field1) - println(x21.field1) - println(x22.field1) - println(x23.field1) - println(x24.field1) - println(x25.field1) - println(x26.field1) - println(x27.field1) - println(x28.field1) - println(x29.field1) - println(x30.field1) - println(x31.field1) - println(x32.field1) - println(x33.field1) - println(x34.field1) - println(x35.field1) - println(x36.field1) - println(x37.field1) - println(x38.field1) - println(x39.field1) - println(x40.field1) - println(x41.field1) - println(x42.field1) - println(x43.field1) - println(x44.field1) - println(x45.field1) - println(x46.field1) - println(x47.field1) - println(x48.field1) - println(x49.field1) - println(x50.field1) - println(x51.field1) - println(x52.field1) - println(x53.field1) - println(x54.field1) - println(x55.field1) - println(x56.field1) - println(x57.field1) - println(x58.field1) - println(x59.field1) - println(x60.field1) - println(x61.field1) - println(x62.field1) - println(x63.field1) - println(x64.field1) - println(x65.field1) - println(x66.field1) - println(x67.field1) - println(x68.field1) - println(x69.field1) - println(x70.field1) - println(x71.field1) - println(x72.field1) - println(x73.field1) - println(x74.field1) - println(x75.field1) - println(x76.field1) - println(x77.field1) - println(x78.field1) - println(x79.field1) - println(x80.field1) - println(x81.field1) - println(x82.field1) - println(x83.field1) - println(x84.field1) - println(x85.field1) - println(x86.field1) - println(x87.field1) - println(x88.field1) - println(x89.field1) - println(x90.field1) - println(x91.field1) - println(x92.field1) - println(x93.field1) - println(x94.field1) - println(x95.field1) - println(x96.field1) - println(x97.field1) - println(x98.field1) - println(x99.field1) - println(x100.field1) - println(x101.field1) - println(x102.field1) - println(x103.field1) - println(x104.field1) - println(x105.field1) - println(x106.field1) - println(x107.field1) - println(x108.field1) - println(x109.field1) - println(x110.field1) - println(x111.field1) - println(x112.field1) - println(x113.field1) - println(x114.field1) - println(x115.field1) - println(x116.field1) - println(x117.field1) - println(x118.field1) - println(x119.field1) - println(x120.field1) - println(x121.field1) - println(x122.field1) - println(x123.field1) - println(x124.field1) - println(x125.field1) - println(x126.field1) - println(x127.field1) - println(x128.field1) -} - -def main() = { - //allocate128SlotsAndReleaseThem(); - // allocate & flush to-do list twice - //var flushingTodoListFirstTime = OneSlotPerson(1, 2, 3, 4, 5, 6) - //var flushingTodoListSecondTime = OneSlotPerson(1, 2, 3, 4, 5, 7) - - // deallocate again - //println(flushingTodoListFirstTime.field1) - //println(flushingTodoListSecondTime.field1) -} diff --git a/examples/ctrc/nooptimized/array_record.check b/examples/ctrc/nooptimized/array_record.check deleted file mode 100644 index 56ea89185..000000000 --- a/examples/ctrc/nooptimized/array_record.check +++ /dev/null @@ -1 +0,0 @@ -Array(1, 2, 3) \ No newline at end of file diff --git a/examples/ctrc/nooptimized/array_record.effekt b/examples/ctrc/nooptimized/array_record.effekt deleted file mode 100644 index 0580fbeae..000000000 --- a/examples/ctrc/nooptimized/array_record.effekt +++ /dev/null @@ -1,10 +0,0 @@ -record Person( - field1: Int, - field2: Array[Int] - ) - -def main() = { - val myArray: Array[Int] = build(3) { i => i + 1 } // Array(1, 2, 3) - val p = Person(1, myArray) - println(myArray) -} \ No newline at end of file diff --git a/examples/ctrc/nooptimized/array_record_match.check b/examples/ctrc/nooptimized/array_record_match.check deleted file mode 100644 index 56a6051ca..000000000 --- a/examples/ctrc/nooptimized/array_record_match.check +++ /dev/null @@ -1 +0,0 @@ -1 \ No newline at end of file diff --git a/examples/ctrc/nooptimized/array_record_match.effekt b/examples/ctrc/nooptimized/array_record_match.effekt deleted file mode 100644 index e6856cf32..000000000 --- a/examples/ctrc/nooptimized/array_record_match.effekt +++ /dev/null @@ -1,21 +0,0 @@ -record Person( - field1: Int, - field2: Array[Int] - ) - -record OneSlotPerson( - field1: Int, - field2: Int, - field3: Int, - field4: Int, - field5: Int, - field6: Int -) - -def main() = { - val myArray: Array[Int] = array::unsafeAllocate(1) - val p = Person(1, myArray) - p match { - case Person(f1, _) => println(f1) - } -} \ No newline at end of file diff --git a/examples/ctrc/nooptimized/array_record_match_exhausted.check b/examples/ctrc/nooptimized/array_record_match_exhausted.check deleted file mode 100644 index 56a6051ca..000000000 --- a/examples/ctrc/nooptimized/array_record_match_exhausted.check +++ /dev/null @@ -1 +0,0 @@ -1 \ No newline at end of file diff --git a/examples/ctrc/nooptimized/array_record_match_exhausted.effekt b/examples/ctrc/nooptimized/array_record_match_exhausted.effekt deleted file mode 100644 index 66ebfc8e3..000000000 --- a/examples/ctrc/nooptimized/array_record_match_exhausted.effekt +++ /dev/null @@ -1,21 +0,0 @@ -record Person( - field1: Int, - field2: Array[Int] - ) - -record OneSlotPerson( - field1: Int, - field2: Int, - field3: Int, - field4: Int, - field5: Int, - field6: Int -) - -def main() = { - val myArray: Array[Int] = array::unsafeAllocate(1) - val p = Person(1, myArray) - p match { - case Person(f1, arr) => println(f1) - } -} \ No newline at end of file diff --git a/examples/ctrc/nooptimized/different_person_sizes_biggest_first.check b/examples/ctrc/nooptimized/different_person_sizes_biggest_first.check deleted file mode 100644 index 63ea17a09..000000000 --- a/examples/ctrc/nooptimized/different_person_sizes_biggest_first.check +++ /dev/null @@ -1,3 +0,0 @@ -24 -13 -6 \ No newline at end of file diff --git a/examples/ctrc/nooptimized/different_person_sizes_biggest_first.effekt b/examples/ctrc/nooptimized/different_person_sizes_biggest_first.effekt deleted file mode 100644 index 6a963c745..000000000 --- a/examples/ctrc/nooptimized/different_person_sizes_biggest_first.effekt +++ /dev/null @@ -1,46 +0,0 @@ -// this test is for debugging of the to-do-list approach. Here, we define multiple records that require different -// number of heap-slots (aka. 64 bytes). - -// here we allocate the biggest object at first and go to the smallest. - -record OneSlotPerson( - field1: Int, - field2: Int, - field3: Int, - field4: Int, - field5: Int, - field6: Int - ) - -record TwoSlotPerson( - field1: Int, - field2: Int, - field3: Int, - field4: Int, - field5: Int, - field6: Int, - field7: Int - ) - -record ThreeSlotPerson( - field1: Int, - field2: Int, - field3: Int, - field4: Int, - field5: Int, - field6: Int, - field7: Int, - field8: Int, - field9: Int, - field10: Int, - field11: Int - ) - -def main() = { - val p3 = ThreeSlotPerson(14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24) - println(p3.field11) - val p2 = TwoSlotPerson(7, 8, 9, 10, 11, 12, 13) - println(p2.field7) - val p1 = OneSlotPerson(1, 2, 3, 4, 5, 6) - println(p1.field6) -} \ No newline at end of file diff --git a/examples/ctrc/nooptimized/different_person_sizes_smallest_first.check b/examples/ctrc/nooptimized/different_person_sizes_smallest_first.check deleted file mode 100644 index bdfbf007c..000000000 --- a/examples/ctrc/nooptimized/different_person_sizes_smallest_first.check +++ /dev/null @@ -1,3 +0,0 @@ -6 -13 -26 \ No newline at end of file diff --git a/examples/ctrc/nooptimized/different_person_sizes_smallest_first.effekt b/examples/ctrc/nooptimized/different_person_sizes_smallest_first.effekt deleted file mode 100644 index 2a61b272d..000000000 --- a/examples/ctrc/nooptimized/different_person_sizes_smallest_first.effekt +++ /dev/null @@ -1,46 +0,0 @@ -// this test is for debugging of the to-do-list approach. Here, we define multiple records that require different -// number of heap-slots (aka. 64 bytes). - -record OneSlotPerson( - field1: Int, - field2: Int, - field3: Int, - field4: Int, - field5: Int, - field6: Int - ) - -record TwoSlotPerson( - field1: Int, - field2: Int, - field3: Int, - field4: Int, - field5: Int, - field6: Int, - field7: Int - ) - -record ThreeSlotPerson( - field1: Int, - field2: Int, - field3: Int, - field4: Int, - field5: Int, - field6: Int, - field7: Int, - field8: Int, - field9: Int, - field10: Int, - field11: Int, - field12: Int, - field13: Int - ) - -def main() = { - val p1 = OneSlotPerson(1, 2, 3, 4, 5, 6) - println(p1.field6) - val p2 = TwoSlotPerson(7, 8, 9, 10, 11, 12, 13) - println(p2.field7) - val p3 = ThreeSlotPerson(14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26) - println(p3.field13) -} \ No newline at end of file diff --git a/examples/ctrc/nooptimized/nested_objects.check b/examples/ctrc/nooptimized/nested_objects.check deleted file mode 100644 index e440e5c84..000000000 --- a/examples/ctrc/nooptimized/nested_objects.check +++ /dev/null @@ -1 +0,0 @@ -3 \ No newline at end of file diff --git a/examples/ctrc/nooptimized/nested_objects.effekt b/examples/ctrc/nooptimized/nested_objects.effekt deleted file mode 100644 index 27a274b5f..000000000 --- a/examples/ctrc/nooptimized/nested_objects.effekt +++ /dev/null @@ -1,16 +0,0 @@ -record Person1( - field3: Int, - field4: Int -) - -record Person( - field1: Int, - field2: Int, - person1: Person1 - ) - -def main() = { - val p1 = Person1(3, 4) - val p = Person(1, 2, p1) - println(p.person1.field3) -} \ No newline at end of file diff --git a/examples/ctrc/nooptimized/one_big_string_object.check b/examples/ctrc/nooptimized/one_big_string_object.check deleted file mode 100644 index 41bfe81b8..000000000 --- a/examples/ctrc/nooptimized/one_big_string_object.check +++ /dev/null @@ -1 +0,0 @@ -Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. \ No newline at end of file diff --git a/examples/ctrc/nooptimized/one_big_string_object.effekt b/examples/ctrc/nooptimized/one_big_string_object.effekt deleted file mode 100644 index 492ee575c..000000000 --- a/examples/ctrc/nooptimized/one_big_string_object.effekt +++ /dev/null @@ -1,9 +0,0 @@ -// contains one big lorem ipsum string with 100 words -record Person( - field1: String - ) - -def main() = { - val p = Person("Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.") - println(p.field1) -} \ No newline at end of file diff --git a/examples/ctrc/nooptimized/one_lg_object.check b/examples/ctrc/nooptimized/one_lg_object.check deleted file mode 100644 index 9a037142a..000000000 --- a/examples/ctrc/nooptimized/one_lg_object.check +++ /dev/null @@ -1 +0,0 @@ -10 \ No newline at end of file diff --git a/examples/ctrc/nooptimized/one_lg_object.effekt b/examples/ctrc/nooptimized/one_lg_object.effekt deleted file mode 100644 index 18eff9264..000000000 --- a/examples/ctrc/nooptimized/one_lg_object.effekt +++ /dev/null @@ -1,18 +0,0 @@ -// lg = Person fills 2 saving slots completely -record Person( - field1: Int, - field2: Int, - field3: Int, - field4: Int, - field5: Int, - field6: Int, - field7: Int, - field8: Int, - field9: Int, - field10: Int - ) - -def main() = { - val p = Person(1, 2, 3, 4, 5, 6, 7, 8, 9, 10) - println(p.field10) -} \ No newline at end of file diff --git a/examples/ctrc/nooptimized/one_md_object.check b/examples/ctrc/nooptimized/one_md_object.check deleted file mode 100644 index c7930257d..000000000 --- a/examples/ctrc/nooptimized/one_md_object.check +++ /dev/null @@ -1 +0,0 @@ -7 \ No newline at end of file diff --git a/examples/ctrc/nooptimized/one_md_object.effekt b/examples/ctrc/nooptimized/one_md_object.effekt deleted file mode 100644 index d68c5a960..000000000 --- a/examples/ctrc/nooptimized/one_md_object.effekt +++ /dev/null @@ -1,15 +0,0 @@ -// md = Person requires 2 saving slots -record Person( - field1: Int, - field2: Int, - field3: Int, - field4: Int, - field5: Int, - field6: Int, - field7: Int - ) - -def main() = { - val p = Person(1, 2, 3, 4, 5, 6, 7) - println(p.field7) -} \ No newline at end of file diff --git a/examples/ctrc/nooptimized/one_slot_one_person_list.check b/examples/ctrc/nooptimized/one_slot_one_person_list.check deleted file mode 100644 index 62f945751..000000000 --- a/examples/ctrc/nooptimized/one_slot_one_person_list.check +++ /dev/null @@ -1 +0,0 @@ -6 \ No newline at end of file diff --git a/examples/ctrc/nooptimized/one_slot_one_person_list.effekt b/examples/ctrc/nooptimized/one_slot_one_person_list.effekt deleted file mode 100644 index e23065e8e..000000000 --- a/examples/ctrc/nooptimized/one_slot_one_person_list.effekt +++ /dev/null @@ -1,27 +0,0 @@ -import list - -record OneSlotPerson( - field1: Int, - field2: Int, - field3: Int, - field4: Int, - field5: Int, - field6: Int -) - -def main() = { - val person1 = OneSlotPerson(1, 2, 3, 4, 5, 6) - var myList = [person1] - //myList = drop(myList, 1) - //val myList = Nil[OneSlotPerson]() - - // prints 6. If -1 is printed, there is a bug - myList match { - case Nil() => println(-1) - case Cons(x, _) => println(x.field6) - //case Cons(x, _) => println(-2) - } - - //myList = drop(myList, 1) - //val person3 = person1 -} diff --git a/examples/ctrc/nooptimized/one_sm_object.check b/examples/ctrc/nooptimized/one_sm_object.check deleted file mode 100644 index 62f945751..000000000 --- a/examples/ctrc/nooptimized/one_sm_object.check +++ /dev/null @@ -1 +0,0 @@ -6 \ No newline at end of file diff --git a/examples/ctrc/nooptimized/one_sm_object.effekt b/examples/ctrc/nooptimized/one_sm_object.effekt deleted file mode 100644 index 95ffb2305..000000000 --- a/examples/ctrc/nooptimized/one_sm_object.effekt +++ /dev/null @@ -1,14 +0,0 @@ -// sm = Person fills 1 saving slot completely -record Person( - field1: Int, - field2: Int, - field3: Int, - field4: Int, - field5: Int, - field6: Int - ) - -def main() = { - val p = Person(1, 2, 3, 4, 5, 6) - println(p.field6) -} \ No newline at end of file diff --git a/examples/ctrc/nooptimized/one_small_string_object.check b/examples/ctrc/nooptimized/one_small_string_object.check deleted file mode 100644 index 30d74d258..000000000 --- a/examples/ctrc/nooptimized/one_small_string_object.check +++ /dev/null @@ -1 +0,0 @@ -test \ No newline at end of file diff --git a/examples/ctrc/nooptimized/one_small_string_object.effekt b/examples/ctrc/nooptimized/one_small_string_object.effekt deleted file mode 100644 index efe6e6fef..000000000 --- a/examples/ctrc/nooptimized/one_small_string_object.effekt +++ /dev/null @@ -1,8 +0,0 @@ -record Person( - field1: String - ) - -def main() = { - val p = Person("test") - println(p.field1) -} \ No newline at end of file diff --git a/examples/ctrc/nooptimized/one_xl_object.check b/examples/ctrc/nooptimized/one_xl_object.check deleted file mode 100644 index 9d607966b..000000000 --- a/examples/ctrc/nooptimized/one_xl_object.check +++ /dev/null @@ -1 +0,0 @@ -11 \ No newline at end of file diff --git a/examples/ctrc/nooptimized/one_xl_object.effekt b/examples/ctrc/nooptimized/one_xl_object.effekt deleted file mode 100644 index bc45859ca..000000000 --- a/examples/ctrc/nooptimized/one_xl_object.effekt +++ /dev/null @@ -1,19 +0,0 @@ -// xl = Person needs 3 saving slots -record Person( - field1: Int, - field2: Int, - field3: Int, - field4: Int, - field5: Int, - field6: Int, - field7: Int, - field8: Int, - field9: Int, - field10: Int, - field11: Int - ) - -def main() = { - val p = Person(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11) - println(p.field11) -} \ No newline at end of file diff --git a/examples/ctrc/nooptimized/one_xs_object.check b/examples/ctrc/nooptimized/one_xs_object.check deleted file mode 100644 index e440e5c84..000000000 --- a/examples/ctrc/nooptimized/one_xs_object.check +++ /dev/null @@ -1 +0,0 @@ -3 \ No newline at end of file diff --git a/examples/ctrc/nooptimized/one_xs_object.effekt b/examples/ctrc/nooptimized/one_xs_object.effekt deleted file mode 100644 index 034c32ea5..000000000 --- a/examples/ctrc/nooptimized/one_xs_object.effekt +++ /dev/null @@ -1,11 +0,0 @@ -// xs = Person fits easily in 1 saving slot -record Person( - field1: Int, - field2: Int, - field3: Int - ) - -def main() = { - val p = Person(1, 2, 3) - println(p.field3) -} \ No newline at end of file diff --git a/examples/ctrc/nooptimized/one_xxl_object_all_fields.check b/examples/ctrc/nooptimized/one_xxl_object_all_fields.check deleted file mode 100644 index 6a0bcb871..000000000 --- a/examples/ctrc/nooptimized/one_xxl_object_all_fields.check +++ /dev/null @@ -1,100 +0,0 @@ -1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71 -72 -73 -74 -75 -76 -77 -78 -79 -80 -81 -82 -83 -84 -85 -86 -87 -88 -89 -90 -91 -92 -93 -94 -95 -96 -97 -98 -99 -100 \ No newline at end of file diff --git a/examples/ctrc/nooptimized/one_xxl_object_all_fields.effekt b/examples/ctrc/nooptimized/one_xxl_object_all_fields.effekt deleted file mode 100644 index 824a4b603..000000000 --- a/examples/ctrc/nooptimized/one_xxl_object_all_fields.effekt +++ /dev/null @@ -1,308 +0,0 @@ -// xxl: Person has 100 fields -> need x slots -record Person( - field1: Int, - field2: Int, - field3: Int, - field4: Int, - field5: Int, - field6: Int, - field7: Int, - field8: Int, - field9: Int, - field10: Int, - field11: Int, - field12: Int, - field13: Int, - field14: Int, - field15: Int, - field16: Int, - field17: Int, - field18: Int, - field19: Int, - field20: Int, - field21: Int, - field22: Int, - field23: Int, - field24: Int, - field25: Int, - field26: Int, - field27: Int, - field28: Int, - field29: Int, - field30: Int, - field31: Int, - field32: Int, - field33: Int, - field34: Int, - field35: Int, - field36: Int, - field37: Int, - field38: Int, - field39: Int, - field40: Int, - field41: Int, - field42: Int, - field43: Int, - field44: Int, - field45: Int, - field46: Int, - field47: Int, - field48: Int, - field49: Int, - field50: Int, - field51: Int, - field52: Int, - field53: Int, - field54: Int, - field55: Int, - field56: Int, - field57: Int, - field58: Int, - field59: Int, - field60: Int, - field61: Int, - field62: Int, - field63: Int, - field64: Int, - field65: Int, - field66: Int, - field67: Int, - field68: Int, - field69: Int, - field70: Int, - field71: Int, - field72: Int, - field73: Int, - field74: Int, - field75: Int, - field76: Int, - field77: Int, - field78: Int, - field79: Int, - field80: Int, - field81: Int, - field82: Int, - field83: Int, - field84: Int, - field85: Int, - field86: Int, - field87: Int, - field88: Int, - field89: Int, - field90: Int, - field91: Int, - field92: Int, - field93: Int, - field94: Int, - field95: Int, - field96: Int, - field97: Int, - field98: Int, - field99: Int, - field100: Int -) - -def main() = { - val p1 = Person( - 1, - 2, - 3, - 4, - 5, - 6, - 7, - 8, - 9, - 10, - 11, - 12, - 13, - 14, - 15, - 16, - 17, - 18, - 19, - 20, - 21, - 22, - 23, - 24, - 25, - 26, - 27, - 28, - 29, - 30, - 31, - 32, - 33, - 34, - 35, - 36, - 37, - 38, - 39, - 40, - 41, - 42, - 43, - 44, - 45, - 46, - 47, - 48, - 49, - 50, - 51, - 52, - 53, - 54, - 55, - 56, - 57, - 58, - 59, - 60, - 61, - 62, - 63, - 64, - 65, - 66, - 67, - 68, - 69, - 70, - 71, - 72, - 73, - 74, - 75, - 76, - 77, - 78, - 79, - 80, - 81, - 82, - 83, - 84, - 85, - 86, - 87, - 88, - 89, - 90, - 91, - 92, - 93, - 94, - 95, - 96, - 97, - 98, - 99, - 100 -) - println(p1.field1) - println(p1.field2) - println(p1.field3) - println(p1.field4) - println(p1.field5) - println(p1.field6) - println(p1.field7) - println(p1.field8) - println(p1.field9) - println(p1.field10) - println(p1.field11) - println(p1.field12) - println(p1.field13) - println(p1.field14) - println(p1.field15) - println(p1.field16) - println(p1.field17) - println(p1.field18) - println(p1.field19) - println(p1.field20) - println(p1.field21) - println(p1.field22) - println(p1.field23) - println(p1.field24) - println(p1.field25) - println(p1.field26) - println(p1.field27) - println(p1.field28) - println(p1.field29) - println(p1.field30) - println(p1.field31) - println(p1.field32) - println(p1.field33) - println(p1.field34) - println(p1.field35) - println(p1.field36) - println(p1.field37) - println(p1.field38) - println(p1.field39) - println(p1.field40) - println(p1.field41) - println(p1.field42) - println(p1.field43) - println(p1.field44) - println(p1.field45) - println(p1.field46) - println(p1.field47) - println(p1.field48) - println(p1.field49) - println(p1.field50) - println(p1.field51) - println(p1.field52) - println(p1.field53) - println(p1.field54) - println(p1.field55) - println(p1.field56) - println(p1.field57) - println(p1.field58) - println(p1.field59) - println(p1.field60) - println(p1.field61) - println(p1.field62) - println(p1.field63) - println(p1.field64) - println(p1.field65) - println(p1.field66) - println(p1.field67) - println(p1.field68) - println(p1.field69) - println(p1.field70) - println(p1.field71) - println(p1.field72) - println(p1.field73) - println(p1.field74) - println(p1.field75) - println(p1.field76) - println(p1.field77) - println(p1.field78) - println(p1.field79) - println(p1.field80) - println(p1.field81) - println(p1.field82) - println(p1.field83) - println(p1.field84) - println(p1.field85) - println(p1.field86) - println(p1.field87) - println(p1.field88) - println(p1.field89) - println(p1.field90) - println(p1.field91) - println(p1.field92) - println(p1.field93) - println(p1.field94) - println(p1.field95) - println(p1.field96) - println(p1.field97) - println(p1.field98) - println(p1.field99) - println(p1.field100) -} \ No newline at end of file diff --git a/examples/ctrc/nooptimized/one_xxxl_object.check b/examples/ctrc/nooptimized/one_xxxl_object.check deleted file mode 100644 index eb1f49486..000000000 --- a/examples/ctrc/nooptimized/one_xxxl_object.check +++ /dev/null @@ -1 +0,0 @@ -500 \ No newline at end of file diff --git a/examples/ctrc/nooptimized/one_xxxl_object.effekt b/examples/ctrc/nooptimized/one_xxxl_object.effekt deleted file mode 100644 index 74211407a..000000000 --- a/examples/ctrc/nooptimized/one_xxxl_object.effekt +++ /dev/null @@ -1,1008 +0,0 @@ -record Person( - field1: Int, - field2: Int, - field3: Int, - field4: Int, - field5: Int, - field6: Int, - field7: Int, - field8: Int, - field9: Int, - field10: Int, - field11: Int, - field12: Int, - field13: Int, - field14: Int, - field15: Int, - field16: Int, - field17: Int, - field18: Int, - field19: Int, - field20: Int, - field21: Int, - field22: Int, - field23: Int, - field24: Int, - field25: Int, - field26: Int, - field27: Int, - field28: Int, - field29: Int, - field30: Int, - field31: Int, - field32: Int, - field33: Int, - field34: Int, - field35: Int, - field36: Int, - field37: Int, - field38: Int, - field39: Int, - field40: Int, - field41: Int, - field42: Int, - field43: Int, - field44: Int, - field45: Int, - field46: Int, - field47: Int, - field48: Int, - field49: Int, - field50: Int, - field51: Int, - field52: Int, - field53: Int, - field54: Int, - field55: Int, - field56: Int, - field57: Int, - field58: Int, - field59: Int, - field60: Int, - field61: Int, - field62: Int, - field63: Int, - field64: Int, - field65: Int, - field66: Int, - field67: Int, - field68: Int, - field69: Int, - field70: Int, - field71: Int, - field72: Int, - field73: Int, - field74: Int, - field75: Int, - field76: Int, - field77: Int, - field78: Int, - field79: Int, - field80: Int, - field81: Int, - field82: Int, - field83: Int, - field84: Int, - field85: Int, - field86: Int, - field87: Int, - field88: Int, - field89: Int, - field90: Int, - field91: Int, - field92: Int, - field93: Int, - field94: Int, - field95: Int, - field96: Int, - field97: Int, - field98: Int, - field99: Int, - field100: Int, - field101: Int, - field102: Int, - field103: Int, - field104: Int, - field105: Int, - field106: Int, - field107: Int, - field108: Int, - field109: Int, - field110: Int, - field111: Int, - field112: Int, - field113: Int, - field114: Int, - field115: Int, - field116: Int, - field117: Int, - field118: Int, - field119: Int, - field120: Int, - field121: Int, - field122: Int, - field123: Int, - field124: Int, - field125: Int, - field126: Int, - field127: Int, - field128: Int, - field129: Int, - field130: Int, - field131: Int, - field132: Int, - field133: Int, - field134: Int, - field135: Int, - field136: Int, - field137: Int, - field138: Int, - field139: Int, - field140: Int, - field141: Int, - field142: Int, - field143: Int, - field144: Int, - field145: Int, - field146: Int, - field147: Int, - field148: Int, - field149: Int, - field150: Int, - field151: Int, - field152: Int, - field153: Int, - field154: Int, - field155: Int, - field156: Int, - field157: Int, - field158: Int, - field159: Int, - field160: Int, - field161: Int, - field162: Int, - field163: Int, - field164: Int, - field165: Int, - field166: Int, - field167: Int, - field168: Int, - field169: Int, - field170: Int, - field171: Int, - field172: Int, - field173: Int, - field174: Int, - field175: Int, - field176: Int, - field177: Int, - field178: Int, - field179: Int, - field180: Int, - field181: Int, - field182: Int, - field183: Int, - field184: Int, - field185: Int, - field186: Int, - field187: Int, - field188: Int, - field189: Int, - field190: Int, - field191: Int, - field192: Int, - field193: Int, - field194: Int, - field195: Int, - field196: Int, - field197: Int, - field198: Int, - field199: Int, - field200: Int, - field201: Int, - field202: Int, - field203: Int, - field204: Int, - field205: Int, - field206: Int, - field207: Int, - field208: Int, - field209: Int, - field210: Int, - field211: Int, - field212: Int, - field213: Int, - field214: Int, - field215: Int, - field216: Int, - field217: Int, - field218: Int, - field219: Int, - field220: Int, - field221: Int, - field222: Int, - field223: Int, - field224: Int, - field225: Int, - field226: Int, - field227: Int, - field228: Int, - field229: Int, - field230: Int, - field231: Int, - field232: Int, - field233: Int, - field234: Int, - field235: Int, - field236: Int, - field237: Int, - field238: Int, - field239: Int, - field240: Int, - field241: Int, - field242: Int, - field243: Int, - field244: Int, - field245: Int, - field246: Int, - field247: Int, - field248: Int, - field249: Int, - field250: Int, - field251: Int, - field252: Int, - field253: Int, - field254: Int, - field255: Int, - field256: Int, - field257: Int, - field258: Int, - field259: Int, - field260: Int, - field261: Int, - field262: Int, - field263: Int, - field264: Int, - field265: Int, - field266: Int, - field267: Int, - field268: Int, - field269: Int, - field270: Int, - field271: Int, - field272: Int, - field273: Int, - field274: Int, - field275: Int, - field276: Int, - field277: Int, - field278: Int, - field279: Int, - field280: Int, - field281: Int, - field282: Int, - field283: Int, - field284: Int, - field285: Int, - field286: Int, - field287: Int, - field288: Int, - field289: Int, - field290: Int, - field291: Int, - field292: Int, - field293: Int, - field294: Int, - field295: Int, - field296: Int, - field297: Int, - field298: Int, - field299: Int, - field300: Int, - field301: Int, - field302: Int, - field303: Int, - field304: Int, - field305: Int, - field306: Int, - field307: Int, - field308: Int, - field309: Int, - field310: Int, - field311: Int, - field312: Int, - field313: Int, - field314: Int, - field315: Int, - field316: Int, - field317: Int, - field318: Int, - field319: Int, - field320: Int, - field321: Int, - field322: Int, - field323: Int, - field324: Int, - field325: Int, - field326: Int, - field327: Int, - field328: Int, - field329: Int, - field330: Int, - field331: Int, - field332: Int, - field333: Int, - field334: Int, - field335: Int, - field336: Int, - field337: Int, - field338: Int, - field339: Int, - field340: Int, - field341: Int, - field342: Int, - field343: Int, - field344: Int, - field345: Int, - field346: Int, - field347: Int, - field348: Int, - field349: Int, - field350: Int, - field351: Int, - field352: Int, - field353: Int, - field354: Int, - field355: Int, - field356: Int, - field357: Int, - field358: Int, - field359: Int, - field360: Int, - field361: Int, - field362: Int, - field363: Int, - field364: Int, - field365: Int, - field366: Int, - field367: Int, - field368: Int, - field369: Int, - field370: Int, - field371: Int, - field372: Int, - field373: Int, - field374: Int, - field375: Int, - field376: Int, - field377: Int, - field378: Int, - field379: Int, - field380: Int, - field381: Int, - field382: Int, - field383: Int, - field384: Int, - field385: Int, - field386: Int, - field387: Int, - field388: Int, - field389: Int, - field390: Int, - field391: Int, - field392: Int, - field393: Int, - field394: Int, - field395: Int, - field396: Int, - field397: Int, - field398: Int, - field399: Int, - field400: Int, - field401: Int, - field402: Int, - field403: Int, - field404: Int, - field405: Int, - field406: Int, - field407: Int, - field408: Int, - field409: Int, - field410: Int, - field411: Int, - field412: Int, - field413: Int, - field414: Int, - field415: Int, - field416: Int, - field417: Int, - field418: Int, - field419: Int, - field420: Int, - field421: Int, - field422: Int, - field423: Int, - field424: Int, - field425: Int, - field426: Int, - field427: Int, - field428: Int, - field429: Int, - field430: Int, - field431: Int, - field432: Int, - field433: Int, - field434: Int, - field435: Int, - field436: Int, - field437: Int, - field438: Int, - field439: Int, - field440: Int, - field441: Int, - field442: Int, - field443: Int, - field444: Int, - field445: Int, - field446: Int, - field447: Int, - field448: Int, - field449: Int, - field450: Int, - field451: Int, - field452: Int, - field453: Int, - field454: Int, - field455: Int, - field456: Int, - field457: Int, - field458: Int, - field459: Int, - field460: Int, - field461: Int, - field462: Int, - field463: Int, - field464: Int, - field465: Int, - field466: Int, - field467: Int, - field468: Int, - field469: Int, - field470: Int, - field471: Int, - field472: Int, - field473: Int, - field474: Int, - field475: Int, - field476: Int, - field477: Int, - field478: Int, - field479: Int, - field480: Int, - field481: Int, - field482: Int, - field483: Int, - field484: Int, - field485: Int, - field486: Int, - field487: Int, - field488: Int, - field489: Int, - field490: Int, - field491: Int, - field492: Int, - field493: Int, - field494: Int, - field495: Int, - field496: Int, - field497: Int, - field498: Int, - field499: Int, - field500: Int -) - -def main() = { - val p1 = Person( - 1, - 2, - 3, - 4, - 5, - 6, - 7, - 8, - 9, - 10, - 11, - 12, - 13, - 14, - 15, - 16, - 17, - 18, - 19, - 20, - 21, - 22, - 23, - 24, - 25, - 26, - 27, - 28, - 29, - 30, - 31, - 32, - 33, - 34, - 35, - 36, - 37, - 38, - 39, - 40, - 41, - 42, - 43, - 44, - 45, - 46, - 47, - 48, - 49, - 50, - 51, - 52, - 53, - 54, - 55, - 56, - 57, - 58, - 59, - 60, - 61, - 62, - 63, - 64, - 65, - 66, - 67, - 68, - 69, - 70, - 71, - 72, - 73, - 74, - 75, - 76, - 77, - 78, - 79, - 80, - 81, - 82, - 83, - 84, - 85, - 86, - 87, - 88, - 89, - 90, - 91, - 92, - 93, - 94, - 95, - 96, - 97, - 98, - 99, - 100, - 101, - 102, - 103, - 104, - 105, - 106, - 107, - 108, - 109, - 110, - 111, - 112, - 113, - 114, - 115, - 116, - 117, - 118, - 119, - 120, - 121, - 122, - 123, - 124, - 125, - 126, - 127, - 128, - 129, - 130, - 131, - 132, - 133, - 134, - 135, - 136, - 137, - 138, - 139, - 140, - 141, - 142, - 143, - 144, - 145, - 146, - 147, - 148, - 149, - 150, - 151, - 152, - 153, - 154, - 155, - 156, - 157, - 158, - 159, - 160, - 161, - 162, - 163, - 164, - 165, - 166, - 167, - 168, - 169, - 170, - 171, - 172, - 173, - 174, - 175, - 176, - 177, - 178, - 179, - 180, - 181, - 182, - 183, - 184, - 185, - 186, - 187, - 188, - 189, - 190, - 191, - 192, - 193, - 194, - 195, - 196, - 197, - 198, - 199, - 200, - 201, - 202, - 203, - 204, - 205, - 206, - 207, - 208, - 209, - 210, - 211, - 212, - 213, - 214, - 215, - 216, - 217, - 218, - 219, - 220, - 221, - 222, - 223, - 224, - 225, - 226, - 227, - 228, - 229, - 230, - 231, - 232, - 233, - 234, - 235, - 236, - 237, - 238, - 239, - 240, - 241, - 242, - 243, - 244, - 245, - 246, - 247, - 248, - 249, - 250, - 251, - 252, - 253, - 254, - 255, - 256, - 257, - 258, - 259, - 260, - 261, - 262, - 263, - 264, - 265, - 266, - 267, - 268, - 269, - 270, - 271, - 272, - 273, - 274, - 275, - 276, - 277, - 278, - 279, - 280, - 281, - 282, - 283, - 284, - 285, - 286, - 287, - 288, - 289, - 290, - 291, - 292, - 293, - 294, - 295, - 296, - 297, - 298, - 299, - 300, - 301, - 302, - 303, - 304, - 305, - 306, - 307, - 308, - 309, - 310, - 311, - 312, - 313, - 314, - 315, - 316, - 317, - 318, - 319, - 320, - 321, - 322, - 323, - 324, - 325, - 326, - 327, - 328, - 329, - 330, - 331, - 332, - 333, - 334, - 335, - 336, - 337, - 338, - 339, - 340, - 341, - 342, - 343, - 344, - 345, - 346, - 347, - 348, - 349, - 350, - 351, - 352, - 353, - 354, - 355, - 356, - 357, - 358, - 359, - 360, - 361, - 362, - 363, - 364, - 365, - 366, - 367, - 368, - 369, - 370, - 371, - 372, - 373, - 374, - 375, - 376, - 377, - 378, - 379, - 380, - 381, - 382, - 383, - 384, - 385, - 386, - 387, - 388, - 389, - 390, - 391, - 392, - 393, - 394, - 395, - 396, - 397, - 398, - 399, - 400, - 401, - 402, - 403, - 404, - 405, - 406, - 407, - 408, - 409, - 410, - 411, - 412, - 413, - 414, - 415, - 416, - 417, - 418, - 419, - 420, - 421, - 422, - 423, - 424, - 425, - 426, - 427, - 428, - 429, - 430, - 431, - 432, - 433, - 434, - 435, - 436, - 437, - 438, - 439, - 440, - 441, - 442, - 443, - 444, - 445, - 446, - 447, - 448, - 449, - 450, - 451, - 452, - 453, - 454, - 455, - 456, - 457, - 458, - 459, - 460, - 461, - 462, - 463, - 464, - 465, - 466, - 467, - 468, - 469, - 470, - 471, - 472, - 473, - 474, - 475, - 476, - 477, - 478, - 479, - 480, - 481, - 482, - 483, - 484, - 485, - 486, - 487, - 488, - 489, - 490, - 491, - 492, - 493, - 494, - 495, - 496, - 497, - 498, - 499, - 500 -) - println(p1.field500) -} \ No newline at end of file diff --git a/examples/ctrc/nooptimized/primitive_ref.check b/examples/ctrc/nooptimized/primitive_ref.check deleted file mode 100644 index 62f945751..000000000 --- a/examples/ctrc/nooptimized/primitive_ref.check +++ /dev/null @@ -1 +0,0 @@ -6 \ No newline at end of file diff --git a/examples/ctrc/nooptimized/primitive_ref.effekt b/examples/ctrc/nooptimized/primitive_ref.effekt deleted file mode 100644 index 6aa82602e..000000000 --- a/examples/ctrc/nooptimized/primitive_ref.effekt +++ /dev/null @@ -1,9 +0,0 @@ -import ref - -def main() = { - val x = 5 - val y = 6 - val z = ref(x) - z.set(y) - println(z.get()) -} diff --git a/examples/ctrc/nooptimized/ref_allocate.check b/examples/ctrc/nooptimized/ref_allocate.check deleted file mode 100644 index c7930257d..000000000 --- a/examples/ctrc/nooptimized/ref_allocate.check +++ /dev/null @@ -1 +0,0 @@ -7 \ No newline at end of file diff --git a/examples/ctrc/nooptimized/ref_allocate.effekt b/examples/ctrc/nooptimized/ref_allocate.effekt deleted file mode 100644 index 011684f47..000000000 --- a/examples/ctrc/nooptimized/ref_allocate.effekt +++ /dev/null @@ -1,19 +0,0 @@ -import ref - -// md = Person requires 2 saving slots -record Person( - field1: Int, - field2: Int, - field3: Int, - field4: Int, - field5: Int, - field6: Int, - field7: Int - ) - -def main() = { - val p1 = ref::unsafeAllocate() - val p2 = Person(1, 2, 3, 4, 5, 6, 7) - p1.set(p2) - println(p1.get().field7) -} diff --git a/examples/ctrc/nooptimized/simple_list.check b/examples/ctrc/nooptimized/simple_list.check deleted file mode 100644 index cabf43b5d..000000000 --- a/examples/ctrc/nooptimized/simple_list.check +++ /dev/null @@ -1 +0,0 @@ -24 \ No newline at end of file diff --git a/examples/ctrc/nooptimized/simple_list.effekt b/examples/ctrc/nooptimized/simple_list.effekt deleted file mode 100644 index 4a3187884..000000000 --- a/examples/ctrc/nooptimized/simple_list.effekt +++ /dev/null @@ -1,15 +0,0 @@ -import list -//import exception - - -def main() = { - // Creates a list with one element - val myList = [24] - - // print 24. If -1 is printed, there is a bug - myList match { - case Nil() => println(-1) - case Cons(x, Nil()) => println(x) - case Cons(x, xs) => println(-1) - } -} diff --git a/examples/ctrc/nooptimized/simple_ref.check b/examples/ctrc/nooptimized/simple_ref.check deleted file mode 100644 index f11c82a4c..000000000 --- a/examples/ctrc/nooptimized/simple_ref.check +++ /dev/null @@ -1 +0,0 @@ -9 \ No newline at end of file diff --git a/examples/ctrc/nooptimized/simple_ref.effekt b/examples/ctrc/nooptimized/simple_ref.effekt deleted file mode 100644 index 3549dea0f..000000000 --- a/examples/ctrc/nooptimized/simple_ref.effekt +++ /dev/null @@ -1,20 +0,0 @@ -import ref - -// md = Person requires 2 saving slots -record Person( - field1: Int, - field2: Int, - field3: Int, - field4: Int, - field5: Int, - field6: Int, - field7: Int - ) - -def main() = { - val p1 = Person(1, 2, 3, 4, 5, 6, 7) - val p2 = Person(1, 2, 3, 4, 5, 6, 9) - val p3 = ref(p1) - p3.set(p2) - println(p3.get().field7) -} diff --git a/examples/ctrc/nooptimized/superperson.check b/examples/ctrc/nooptimized/superperson.check deleted file mode 100644 index 968f988c5..000000000 --- a/examples/ctrc/nooptimized/superperson.check +++ /dev/null @@ -1,2 +0,0 @@ -9 -25 \ No newline at end of file diff --git a/examples/ctrc/nooptimized/superperson.effekt b/examples/ctrc/nooptimized/superperson.effekt deleted file mode 100644 index d1dbe0b5c..000000000 --- a/examples/ctrc/nooptimized/superperson.effekt +++ /dev/null @@ -1,33 +0,0 @@ -import list - -record TwoSlotPerson( - field1: Int, - field2: Int, - field3: Int, - field4: Int, - field5: Int, - field6: Int, - field7: Int - ) - -record SuperPerson( - field1: TwoSlotPerson, - field2: TwoSlotPerson -) - -def main() = { - // Creates a list with one element - val person1 = TwoSlotPerson(1, 2, 3, 4, 5, 6, 7) - val person2 = TwoSlotPerson(8, 9, 10, 11, 12, 13, 14) - val y = TwoSlotPerson(25, 2, 3, 4, 5, 6, 7) - val superPerson = SuperPerson(person1, person2) - - - // prints 9. If -1 is printed, there is a bug - superPerson match { - case SuperPerson(x, z) => println(x.field1 + z.field1) - } - - // prints 25 - println(y.field1) -} diff --git a/examples/ctrc/nooptimized/superperson_with_free.check b/examples/ctrc/nooptimized/superperson_with_free.check deleted file mode 100644 index 410b14d2c..000000000 --- a/examples/ctrc/nooptimized/superperson_with_free.check +++ /dev/null @@ -1 +0,0 @@ -25 \ No newline at end of file diff --git a/examples/ctrc/nooptimized/superperson_with_free.effekt b/examples/ctrc/nooptimized/superperson_with_free.effekt deleted file mode 100644 index 528fa3fc6..000000000 --- a/examples/ctrc/nooptimized/superperson_with_free.effekt +++ /dev/null @@ -1,30 +0,0 @@ -import list - -record TwoSlotPerson( - field1: Int, - field2: Int, - field3: Int, - field4: Int, - field5: Int, - field6: Int, - field7: Int - ) - -record SuperPerson( - field1: TwoSlotPerson, - field2: TwoSlotPerson -) - -def main() = { - // Creates a list with one element - val person1 = TwoSlotPerson(1, 2, 3, 4, 5, 6, 7) - val person2 = TwoSlotPerson(8, 9, 10, 11, 12, 13, 14) - val y = TwoSlotPerson(25, 2, 3, 4, 5, 6, 7) - val superPerson = SuperPerson(person1, person2) - - - // prints 25. If -1 is printed, there is a bug - superPerson match { - case SuperPerson(x, z) => println(y.field1) - } -} diff --git a/examples/ctrc/nooptimized/three_md_objects_direct.check b/examples/ctrc/nooptimized/three_md_objects_direct.check deleted file mode 100644 index 8fac22206..000000000 --- a/examples/ctrc/nooptimized/three_md_objects_direct.check +++ /dev/null @@ -1,3 +0,0 @@ -7 -10 -18 \ No newline at end of file diff --git a/examples/ctrc/nooptimized/three_md_objects_direct.effekt b/examples/ctrc/nooptimized/three_md_objects_direct.effekt deleted file mode 100644 index ec0561e12..000000000 --- a/examples/ctrc/nooptimized/three_md_objects_direct.effekt +++ /dev/null @@ -1,20 +0,0 @@ -// md = Person requires 2 saving slots -// direct = create person and print field directly -record Person( - field1: Int, - field2: Int, - field3: Int, - field4: Int, - field5: Int, - field6: Int, - field7: Int - ) - -def main() = { - val p1 = Person(1, 2, 3, 4, 5, 6, 7) - println(p1.field7) - val p2 = Person(8, 9, 10, 11, 12, 13, 14) - val p3 = Person(15, 16, 17, 18, 19, 20, 21) - println(p2.field3) - println(p3.field4) -} \ No newline at end of file diff --git a/examples/ctrc/nooptimized/trigger_child_freeing.check b/examples/ctrc/nooptimized/trigger_child_freeing.check deleted file mode 100644 index e69de29bb..000000000 diff --git a/examples/ctrc/nooptimized/trigger_child_freeing.effekt b/examples/ctrc/nooptimized/trigger_child_freeing.effekt deleted file mode 100644 index 2f96672f0..000000000 --- a/examples/ctrc/nooptimized/trigger_child_freeing.effekt +++ /dev/null @@ -1,64 +0,0 @@ -// a simple program that creates a more complex object -// -> child1 -// parent -// -> child2 -> child3 -// -> child4 -> child5 -> child6 -// -> child7 -> child8 -// where child1 is OneSlotPerson and child2 and child3 are TwoSlotPerson and child4 and child5 and child6 are ThreeSlotPerson, and child7 and child8 are TwoSlotPerson - -record OneSlotPerson( - field1: Int, - field2: Int, - field3: Int, - field4: Int, - field5: Int, - field6: Int -) - -record TwoSlotPerson( - field1: Int, - field2: Int, - field3: Int, - field4: Int, - field5: Int, - field6: Int, - field7: Int -) - -record ThreeSlotPerson( - field1: Int, - field2: Int, - field3: Int, - field4: Int, - field5: Int, - field6: Int, - field7: Int, - field8: Int, - field9: Int, - field10: Int, - field11: Int, - field12: Int, - field13: Int -) - -record Person( - child1: OneSlotPerson, - child2: TwoSlotPerson, - child3: ThreeSlotPerson, - child4: TwoSlotPerson, - child5: OneSlotPerson -) - -def main() = { - var iters = 1 - while(iters <= 66) { - var x = Person( - OneSlotPerson(iters, iters + 1, iters + 2, iters + 3, iters + 4, iters + 5), - TwoSlotPerson(iters, iters + 1, iters + 2, iters + 3, iters + 4, iters + 5, iters + 6), - ThreeSlotPerson(iters, iters + 1, iters + 2, iters + 3, iters + 4, iters + 5, iters + 6, iters + 7, iters + 8, iters + 9, iters + 10, iters + 11, iters + 12), - TwoSlotPerson(iters, iters + 1, iters + 2, iters + 3, iters + 4, iters + 5, iters + 7), - OneSlotPerson(iters, iters + 1, iters + 2, iters + 3, iters + 4, iters + 6) - ) - iters = iters + 1 - } -} diff --git a/examples/ctrc/nooptimized/trigger_flush_once.check b/examples/ctrc/nooptimized/trigger_flush_once.check deleted file mode 100644 index e69de29bb..000000000 diff --git a/examples/ctrc/nooptimized/trigger_flush_once.effekt b/examples/ctrc/nooptimized/trigger_flush_once.effekt deleted file mode 100644 index c1306808c..000000000 --- a/examples/ctrc/nooptimized/trigger_flush_once.effekt +++ /dev/null @@ -1,17 +0,0 @@ -// a simple program that triggers flush to-do-list once -record OneSlotPerson( - field1: Int, - field2: Int, - field3: Int, - field4: Int, - field5: Int, - field6: Int -) - -def main() = { - var iters = 1 - while(iters <= 65) { - var x = OneSlotPerson(iters, iters + 1, iters + 2, iters + 3, iters + 4, iters + 5) - iters = iters + 1 - } -} diff --git a/examples/ctrc/nooptimized/trigger_flush_twice.check b/examples/ctrc/nooptimized/trigger_flush_twice.check deleted file mode 100644 index e69de29bb..000000000 diff --git a/examples/ctrc/nooptimized/trigger_flush_twice.effekt b/examples/ctrc/nooptimized/trigger_flush_twice.effekt deleted file mode 100644 index b364f2fdf..000000000 --- a/examples/ctrc/nooptimized/trigger_flush_twice.effekt +++ /dev/null @@ -1,17 +0,0 @@ -// a simple program that triggers flush to-do-list twice -record OneSlotPerson( - field1: Int, - field2: Int, - field3: Int, - field4: Int, - field5: Int, - field6: Int -) - -def main() = { - var iters = 1 - while(iters <= 129) { - var x = OneSlotPerson(iters, iters + 1, iters + 2, iters + 3, iters + 4, iters + 5) - iters = iters + 1 - } -} diff --git a/examples/ctrc/nooptimized/trigger_one_child_freeing.check b/examples/ctrc/nooptimized/trigger_one_child_freeing.check deleted file mode 100644 index e69de29bb..000000000 diff --git a/examples/ctrc/nooptimized/trigger_one_child_freeing.effekt b/examples/ctrc/nooptimized/trigger_one_child_freeing.effekt deleted file mode 100644 index a44b4896c..000000000 --- a/examples/ctrc/nooptimized/trigger_one_child_freeing.effekt +++ /dev/null @@ -1,26 +0,0 @@ -// a simple program that creates a more complex object -// parent -> child1 -// where child1 is OneSlotPerson - -record OneSlotPerson( - field1: Int, - field2: Int, - field3: Int, - field4: Int, - field5: Int, - field6: Int -) - -record Person( - child1: OneSlotPerson -) - -def main() = { - var iters = 1 - while(iters <= 65) { - var x = Person( - OneSlotPerson(iters, iters + 1, iters + 2, iters + 3, iters + 4, iters + 5) - ) - iters = iters + 1 - } -} diff --git a/examples/ctrc/nooptimized/trigger_two_child_freeing.check b/examples/ctrc/nooptimized/trigger_two_child_freeing.check deleted file mode 100644 index e69de29bb..000000000 diff --git a/examples/ctrc/nooptimized/trigger_two_child_freeing.effekt b/examples/ctrc/nooptimized/trigger_two_child_freeing.effekt deleted file mode 100644 index e8eb31933..000000000 --- a/examples/ctrc/nooptimized/trigger_two_child_freeing.effekt +++ /dev/null @@ -1,28 +0,0 @@ -// a simple program that creates a more complex object -// parent -> child1 -// where child1 is OneSlotPerson - -record OneSlotPerson( - field1: Int, - field2: Int, - field3: Int, - field4: Int, - field5: Int, - field6: Int -) - -record Person( - child1: OneSlotPerson, - child2: OneSlotPerson -) - -def main() = { - var iters = 1 - while(iters <= 64) { - var x = Person( - OneSlotPerson(iters, iters + 1, iters + 2, iters + 3, iters + 4, iters + 5), - OneSlotPerson(iters + 6, iters + 7, iters + 8, iters + 9, iters + 10, iters + 11) - ) - iters = iters + 1 - } -} diff --git a/examples/ctrc/nooptimized/two_lg_objects.check b/examples/ctrc/nooptimized/two_lg_objects.check deleted file mode 100644 index 8f59f50a4..000000000 --- a/examples/ctrc/nooptimized/two_lg_objects.check +++ /dev/null @@ -1,2 +0,0 @@ -10 -16 \ No newline at end of file diff --git a/examples/ctrc/nooptimized/two_lg_objects.effekt b/examples/ctrc/nooptimized/two_lg_objects.effekt deleted file mode 100644 index 6393bd171..000000000 --- a/examples/ctrc/nooptimized/two_lg_objects.effekt +++ /dev/null @@ -1,20 +0,0 @@ -// lg = Person fills 2 saving slots completely -record Person( - field1: Int, - field2: Int, - field3: Int, - field4: Int, - field5: Int, - field6: Int, - field7: Int, - field8: Int, - field9: Int, - field10: Int - ) - -def main() = { - val p1 = Person(1, 2, 3, 4, 5, 6, 7, 8, 9, 10) - val p2 = Person(11, 12, 13, 14, 15, 16, 17, 18, 19, 20) - println(p1.field10) - println(p2.field6) -} \ No newline at end of file diff --git a/examples/ctrc/nooptimized/two_md_mixed_object.check b/examples/ctrc/nooptimized/two_md_mixed_object.check deleted file mode 100644 index f21c60d7e..000000000 --- a/examples/ctrc/nooptimized/two_md_mixed_object.check +++ /dev/null @@ -1,2 +0,0 @@ -P1Field2 -10 \ No newline at end of file diff --git a/examples/ctrc/nooptimized/two_md_mixed_object.effekt b/examples/ctrc/nooptimized/two_md_mixed_object.effekt deleted file mode 100644 index 4d67068e4..000000000 --- a/examples/ctrc/nooptimized/two_md_mixed_object.effekt +++ /dev/null @@ -1,17 +0,0 @@ -// md = Person needs 2 slots -// contains strings and integers. -// First slot contains field1, second slot contains field2, field3, field4, field5. -record Person( - field1: Int, - field2: String, - field3: String, - field4: String, - field5: Int - ) - -def main() = { - val p1 = Person(1, "P1Field2", "P1Field3", "P1Field4", 5) - val p2 = Person(6, "P2Field2", "P2Field3", "P2Field4", 10) - println(p1.field2) - println(p2.field5) -} \ No newline at end of file diff --git a/examples/ctrc/nooptimized/two_md_objects.check b/examples/ctrc/nooptimized/two_md_objects.check deleted file mode 100644 index 78bd7702c..000000000 --- a/examples/ctrc/nooptimized/two_md_objects.check +++ /dev/null @@ -1,2 +0,0 @@ -7 -9 \ No newline at end of file diff --git a/examples/ctrc/nooptimized/two_md_objects.effekt b/examples/ctrc/nooptimized/two_md_objects.effekt deleted file mode 100644 index d3bdb013f..000000000 --- a/examples/ctrc/nooptimized/two_md_objects.effekt +++ /dev/null @@ -1,17 +0,0 @@ -// md = Person requires 2 saving slots -record Person( - field1: Int, - field2: Int, - field3: Int, - field4: Int, - field5: Int, - field6: Int, - field7: Int - ) - -def main() = { - val p1 = Person(1, 2, 3, 4, 5, 6, 7) - val p2 = Person(8, 9, 10, 11, 12, 13, 14) - println(p1.field7) - println(p2.field2) -} \ No newline at end of file diff --git a/examples/ctrc/nooptimized/two_slot_one_person_list.check b/examples/ctrc/nooptimized/two_slot_one_person_list.check deleted file mode 100644 index c7930257d..000000000 --- a/examples/ctrc/nooptimized/two_slot_one_person_list.check +++ /dev/null @@ -1 +0,0 @@ -7 \ No newline at end of file diff --git a/examples/ctrc/nooptimized/two_slot_one_person_list.effekt b/examples/ctrc/nooptimized/two_slot_one_person_list.effekt deleted file mode 100644 index e15b30ef1..000000000 --- a/examples/ctrc/nooptimized/two_slot_one_person_list.effekt +++ /dev/null @@ -1,23 +0,0 @@ -import list - -record TwoSlotPerson( - field1: Int, - field2: Int, - field3: Int, - field4: Int, - field5: Int, - field6: Int, - field7: Int - ) - -def main() = { - // Creates a list with one element - val person1 = TwoSlotPerson(1, 2, 3, 4, 5, 6, 7) - var myList = [person1] - - // prints 7. If -1 is printed, there is a bug - myList match { - case Nil() => println(-1) - case Cons(x, _) => println(x.field7) - } -} diff --git a/examples/ctrc/nooptimized/two_slot_one_person_with_free_variable_list.check b/examples/ctrc/nooptimized/two_slot_one_person_with_free_variable_list.check deleted file mode 100644 index 410b14d2c..000000000 --- a/examples/ctrc/nooptimized/two_slot_one_person_with_free_variable_list.check +++ /dev/null @@ -1 +0,0 @@ -25 \ No newline at end of file diff --git a/examples/ctrc/nooptimized/two_slot_one_person_with_free_variable_list.effekt b/examples/ctrc/nooptimized/two_slot_one_person_with_free_variable_list.effekt deleted file mode 100644 index 25bf64831..000000000 --- a/examples/ctrc/nooptimized/two_slot_one_person_with_free_variable_list.effekt +++ /dev/null @@ -1,29 +0,0 @@ -import list - -record TwoSlotPerson( - field1: Int, - field2: Int, - field3: Int, - field4: Int, - field5: Int, - field6: Int, - field7: Int - ) - -def main() = { - // Creates a list with one element - val person1 = TwoSlotPerson(1, 2, 3, 4, 5, 6, 7) - val y = TwoSlotPerson(25, 2, 3, 4, 5, 6, 7) - var myList = [person1] - - // prints 25. If -1 is printed, there is a bug - myList match { - case Nil() => println(-1) - //case Cons(x, _) => println(-2) - case Cons(x, _) => println(y.field1) - //case Cons(x, _) => println(person.field1) - } - - //myList = drop(myList, 1) - //val person3 = person1 -} diff --git a/examples/ctrc/nooptimized/two_slot_two_person_list.check b/examples/ctrc/nooptimized/two_slot_two_person_list.check deleted file mode 100644 index bf0d87ab1..000000000 --- a/examples/ctrc/nooptimized/two_slot_two_person_list.check +++ /dev/null @@ -1 +0,0 @@ -4 \ No newline at end of file diff --git a/examples/ctrc/nooptimized/two_slot_two_person_list.effekt b/examples/ctrc/nooptimized/two_slot_two_person_list.effekt deleted file mode 100644 index 6946a2895..000000000 --- a/examples/ctrc/nooptimized/two_slot_two_person_list.effekt +++ /dev/null @@ -1,24 +0,0 @@ -import list - -record TwoSlotPerson( - field1: Int, - field2: Int, - field3: Int, - field4: Int, - field5: Int, - field6: Int, - field7: Int - ) - -def main() = { - // Creates a list with one element - val person1 = TwoSlotPerson(1, 2, 3, 4, 5, 6, 7) - val person2 = TwoSlotPerson(8, 9, 10, 11, 12, 13, 14) - val myList = [person1, person2] - - // print 4. If -1 is printed, there is a bug - myList match { - case Nil() => println(-1) - case Cons(p1, _) => println(p1.field4) - } -} diff --git a/examples/ctrc/nooptimized/two_slot_two_person_list_continuation.check b/examples/ctrc/nooptimized/two_slot_two_person_list_continuation.check deleted file mode 100644 index bf0d87ab1..000000000 --- a/examples/ctrc/nooptimized/two_slot_two_person_list_continuation.check +++ /dev/null @@ -1 +0,0 @@ -4 \ No newline at end of file diff --git a/examples/ctrc/nooptimized/two_slot_two_person_list_continuation.effekt b/examples/ctrc/nooptimized/two_slot_two_person_list_continuation.effekt deleted file mode 100644 index 0e29c515c..000000000 --- a/examples/ctrc/nooptimized/two_slot_two_person_list_continuation.effekt +++ /dev/null @@ -1,27 +0,0 @@ -import list - -record TwoSlotPerson( - field1: Int, - field2: Int, - field3: Int, - field4: Int, - field5: Int, - field6: Int, - field7: Int - ) - -def main() = { - // Creates a list with one element - val person1 = TwoSlotPerson(1, 2, 3, 4, 5, 6, 7) - val person2 = TwoSlotPerson(8, 9, 10, 11, 12, 13, 14) - val myList = [person1, person2] - - // print 4. If -1 is printed, there is a bug - myList match { - case Nil() => println(-1) - case Cons(p1, _) => println(p1.field4) // here, we shorten it to _ - } - - // we continue the program here, so the compiler does not erase myList immediately after the Switch statement - val isEmpty = isEmpty(myList) -} \ No newline at end of file diff --git a/examples/ctrc/nooptimized/two_slot_two_person_list_continuation_allocation.check b/examples/ctrc/nooptimized/two_slot_two_person_list_continuation_allocation.check deleted file mode 100644 index a246a2d52..000000000 --- a/examples/ctrc/nooptimized/two_slot_two_person_list_continuation_allocation.check +++ /dev/null @@ -1,2 +0,0 @@ -4 -24 \ No newline at end of file diff --git a/examples/ctrc/nooptimized/two_slot_two_person_list_continuation_allocation.effekt b/examples/ctrc/nooptimized/two_slot_two_person_list_continuation_allocation.effekt deleted file mode 100644 index 03036c9c5..000000000 --- a/examples/ctrc/nooptimized/two_slot_two_person_list_continuation_allocation.effekt +++ /dev/null @@ -1,45 +0,0 @@ -import list - -record TwoSlotPerson( - field1: Int, - field2: Int, - field3: Int, - field4: Int, - field5: Int, - field6: Int, - field7: Int - ) - -record ThreeSlotPerson( - field1: Int, - field2: Int, - field3: Int, - field4: Int, - field5: Int, - field6: Int, - field7: Int, - field8: Int, - field9: Int, - field10: Int, - field11: Int - ) - -def main() = { - // Creates a list with one element - val person1 = TwoSlotPerson(1, 2, 3, 4, 5, 6, 7) - val person2 = TwoSlotPerson(8, 9, 10, 11, 12, 13, 14) - val myList = [person1, person2] - - // print 4. If -1 is printed, there is a bug - myList match { - case Nil() => println(-1) - case Cons(p1, _) => println(p1.field4) // here, we shorten it to _ - } - - // we continue the program here, so the compiler does not erase myList immediately after the Switch statement - val isEmpty = isEmpty(myList) - - // reuse the freed slots again to look how the storage looks like - val p3 = ThreeSlotPerson(14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24) - println(p3.field11) -} \ No newline at end of file diff --git a/examples/ctrc/nooptimized/two_slot_two_person_list_continuation_exhausted.check b/examples/ctrc/nooptimized/two_slot_two_person_list_continuation_exhausted.check deleted file mode 100644 index bf0d87ab1..000000000 --- a/examples/ctrc/nooptimized/two_slot_two_person_list_continuation_exhausted.check +++ /dev/null @@ -1 +0,0 @@ -4 \ No newline at end of file diff --git a/examples/ctrc/nooptimized/two_slot_two_person_list_continuation_exhausted.effekt b/examples/ctrc/nooptimized/two_slot_two_person_list_continuation_exhausted.effekt deleted file mode 100644 index d064888aa..000000000 --- a/examples/ctrc/nooptimized/two_slot_two_person_list_continuation_exhausted.effekt +++ /dev/null @@ -1,27 +0,0 @@ -import list - -record TwoSlotPerson( - field1: Int, - field2: Int, - field3: Int, - field4: Int, - field5: Int, - field6: Int, - field7: Int - ) - -def main() = { - // Creates a list with one element - val person1 = TwoSlotPerson(1, 2, 3, 4, 5, 6, 7) - val person2 = TwoSlotPerson(8, 9, 10, 11, 12, 13, 14) - val myList = [person1, person2] - - // print 4. If -1 is printed, there is a bug - myList match { - case Nil() => println(-1) - case Cons(p1, cont) => println(p1.field4) // here, we declare cont. It makes a difference for the release function - } - - // we continue the program here, so the compiler does not erase myList immediately after the Switch statement - val isEmpty = isEmpty(myList) -} \ No newline at end of file diff --git a/examples/ctrc/nooptimized/two_slot_two_person_list_exhausted.check b/examples/ctrc/nooptimized/two_slot_two_person_list_exhausted.check deleted file mode 100644 index bf0d87ab1..000000000 --- a/examples/ctrc/nooptimized/two_slot_two_person_list_exhausted.check +++ /dev/null @@ -1 +0,0 @@ -4 \ No newline at end of file diff --git a/examples/ctrc/nooptimized/two_slot_two_person_list_exhausted.effekt b/examples/ctrc/nooptimized/two_slot_two_person_list_exhausted.effekt deleted file mode 100644 index 66ee8acbe..000000000 --- a/examples/ctrc/nooptimized/two_slot_two_person_list_exhausted.effekt +++ /dev/null @@ -1,24 +0,0 @@ -import list - -record TwoSlotPerson( - field1: Int, - field2: Int, - field3: Int, - field4: Int, - field5: Int, - field6: Int, - field7: Int - ) - -def main() = { - // Creates a list with one element - val person1 = TwoSlotPerson(1, 2, 3, 4, 5, 6, 7) - val person2 = TwoSlotPerson(8, 9, 10, 11, 12, 13, 14) - val myList = [person1, person2] - - // print 4. If -1 is printed, there is a bug - myList match { - case Nil() => println(-1) - case Cons(p1, cont) => println(p1.field4) - } -} diff --git a/examples/ctrc/nooptimized/two_slot_two_person_with_free_variable_list.check b/examples/ctrc/nooptimized/two_slot_two_person_with_free_variable_list.check deleted file mode 100644 index 410b14d2c..000000000 --- a/examples/ctrc/nooptimized/two_slot_two_person_with_free_variable_list.check +++ /dev/null @@ -1 +0,0 @@ -25 \ No newline at end of file diff --git a/examples/ctrc/nooptimized/two_slot_two_person_with_free_variable_list.effekt b/examples/ctrc/nooptimized/two_slot_two_person_with_free_variable_list.effekt deleted file mode 100644 index 4e0df6426..000000000 --- a/examples/ctrc/nooptimized/two_slot_two_person_with_free_variable_list.effekt +++ /dev/null @@ -1,29 +0,0 @@ -import list - -record TwoSlotPerson( - field1: Int, - field2: Int, - field3: Int, - field4: Int, - field5: Int, - field6: Int, - field7: Int - ) - -def main() = { - // Creates a list with one element - val person1 = TwoSlotPerson(1, 2, 3, 4, 5, 6, 7) - val person2 = TwoSlotPerson(8, 9, 10, 11, 12, 13, 14) - val y = TwoSlotPerson(25, 2, 3, 4, 5, 6, 7) - var myList = [person1, person2] - - - // prints 25. If -1 is printed, there is a bug - myList match { - case Nil() => println(-1) - case Cons(x, xs) => xs match { - case Nil() => println(y.field2) - case Cons(z, _) => println(y.field1) - } - } -} diff --git a/examples/ctrc/nooptimized/two_sm_mixed_object.check b/examples/ctrc/nooptimized/two_sm_mixed_object.check deleted file mode 100644 index ca3d17d48..000000000 --- a/examples/ctrc/nooptimized/two_sm_mixed_object.check +++ /dev/null @@ -1,2 +0,0 @@ -P1Field1 -8 \ No newline at end of file diff --git a/examples/ctrc/nooptimized/two_sm_mixed_object.effekt b/examples/ctrc/nooptimized/two_sm_mixed_object.effekt deleted file mode 100644 index c07c2af92..000000000 --- a/examples/ctrc/nooptimized/two_sm_mixed_object.effekt +++ /dev/null @@ -1,15 +0,0 @@ -// sm = Person fills 1 saving slot completely -// contains strings and integers -record Person( - field1: String, - field2: Int, - field3: String, - field4: Int - ) - -def main() = { - val p1 = Person("P1Field1", 2, "P1Field3", 4) - val p2 = Person("P2Field1", 6, "P2Field3", 8) - println(p1.field1) - println(p2.field4) -} \ No newline at end of file diff --git a/examples/ctrc/nooptimized/two_sm_objects.check b/examples/ctrc/nooptimized/two_sm_objects.check deleted file mode 100644 index b8a0ddcef..000000000 --- a/examples/ctrc/nooptimized/two_sm_objects.check +++ /dev/null @@ -1,2 +0,0 @@ -6 -8 \ No newline at end of file diff --git a/examples/ctrc/nooptimized/two_sm_objects.effekt b/examples/ctrc/nooptimized/two_sm_objects.effekt deleted file mode 100644 index a1d1d206c..000000000 --- a/examples/ctrc/nooptimized/two_sm_objects.effekt +++ /dev/null @@ -1,16 +0,0 @@ -// sm = Person fills 1 saving slot completely -record Person( - field1: Int, - field2: Int, - field3: Int, - field4: Int, - field5: Int, - field6: Int - ) - -def main() = { - val p1 = Person(1, 2, 3, 4, 5, 6) - val p2 = Person(7, 8, 9, 10, 11, 12) - println(p1.field6) - println(p2.field2) -} \ No newline at end of file diff --git a/examples/ctrc/nooptimized/two_xl_objects.check b/examples/ctrc/nooptimized/two_xl_objects.check deleted file mode 100644 index 10afbfb7e..000000000 --- a/examples/ctrc/nooptimized/two_xl_objects.check +++ /dev/null @@ -1,2 +0,0 @@ -11 -18 \ No newline at end of file diff --git a/examples/ctrc/nooptimized/two_xl_objects.effekt b/examples/ctrc/nooptimized/two_xl_objects.effekt deleted file mode 100644 index e5628b0b7..000000000 --- a/examples/ctrc/nooptimized/two_xl_objects.effekt +++ /dev/null @@ -1,21 +0,0 @@ -// xl = Person needs 3 saving slots -record Person( - field1: Int, - field2: Int, - field3: Int, - field4: Int, - field5: Int, - field6: Int, - field7: Int, - field8: Int, - field9: Int, - field10: Int, - field11: Int - ) - -def main() = { - val p1 = Person(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11) - val p2 = Person(12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22) - println(p1.field11) - println(p2.field7) -} \ No newline at end of file diff --git a/examples/ctrc/nooptimized/two_xs_objects.check b/examples/ctrc/nooptimized/two_xs_objects.check deleted file mode 100644 index 69cc3abe5..000000000 --- a/examples/ctrc/nooptimized/two_xs_objects.check +++ /dev/null @@ -1,2 +0,0 @@ -3 -5 \ No newline at end of file diff --git a/examples/ctrc/nooptimized/two_xs_objects.effekt b/examples/ctrc/nooptimized/two_xs_objects.effekt deleted file mode 100644 index 02f18b3a9..000000000 --- a/examples/ctrc/nooptimized/two_xs_objects.effekt +++ /dev/null @@ -1,13 +0,0 @@ -// xs = Person fits easily in 1 saving slot -record Person( - field1: Int, - field2: Int, - field3: Int - ) - -def main() = { - val p1 = Person(1, 2, 3) - val p2 = Person(4, 5, 6) - println(p1.field3) - println(p2.field2) -} \ No newline at end of file diff --git a/examples/ctrc/nooptimized/two_xxl_object_all_fields.check b/examples/ctrc/nooptimized/two_xxl_object_all_fields.check deleted file mode 100644 index 6a0bcb871..000000000 --- a/examples/ctrc/nooptimized/two_xxl_object_all_fields.check +++ /dev/null @@ -1,100 +0,0 @@ -1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71 -72 -73 -74 -75 -76 -77 -78 -79 -80 -81 -82 -83 -84 -85 -86 -87 -88 -89 -90 -91 -92 -93 -94 -95 -96 -97 -98 -99 -100 \ No newline at end of file diff --git a/examples/ctrc/nooptimized/two_xxl_object_all_fields.effekt b/examples/ctrc/nooptimized/two_xxl_object_all_fields.effekt deleted file mode 100644 index 824a4b603..000000000 --- a/examples/ctrc/nooptimized/two_xxl_object_all_fields.effekt +++ /dev/null @@ -1,308 +0,0 @@ -// xxl: Person has 100 fields -> need x slots -record Person( - field1: Int, - field2: Int, - field3: Int, - field4: Int, - field5: Int, - field6: Int, - field7: Int, - field8: Int, - field9: Int, - field10: Int, - field11: Int, - field12: Int, - field13: Int, - field14: Int, - field15: Int, - field16: Int, - field17: Int, - field18: Int, - field19: Int, - field20: Int, - field21: Int, - field22: Int, - field23: Int, - field24: Int, - field25: Int, - field26: Int, - field27: Int, - field28: Int, - field29: Int, - field30: Int, - field31: Int, - field32: Int, - field33: Int, - field34: Int, - field35: Int, - field36: Int, - field37: Int, - field38: Int, - field39: Int, - field40: Int, - field41: Int, - field42: Int, - field43: Int, - field44: Int, - field45: Int, - field46: Int, - field47: Int, - field48: Int, - field49: Int, - field50: Int, - field51: Int, - field52: Int, - field53: Int, - field54: Int, - field55: Int, - field56: Int, - field57: Int, - field58: Int, - field59: Int, - field60: Int, - field61: Int, - field62: Int, - field63: Int, - field64: Int, - field65: Int, - field66: Int, - field67: Int, - field68: Int, - field69: Int, - field70: Int, - field71: Int, - field72: Int, - field73: Int, - field74: Int, - field75: Int, - field76: Int, - field77: Int, - field78: Int, - field79: Int, - field80: Int, - field81: Int, - field82: Int, - field83: Int, - field84: Int, - field85: Int, - field86: Int, - field87: Int, - field88: Int, - field89: Int, - field90: Int, - field91: Int, - field92: Int, - field93: Int, - field94: Int, - field95: Int, - field96: Int, - field97: Int, - field98: Int, - field99: Int, - field100: Int -) - -def main() = { - val p1 = Person( - 1, - 2, - 3, - 4, - 5, - 6, - 7, - 8, - 9, - 10, - 11, - 12, - 13, - 14, - 15, - 16, - 17, - 18, - 19, - 20, - 21, - 22, - 23, - 24, - 25, - 26, - 27, - 28, - 29, - 30, - 31, - 32, - 33, - 34, - 35, - 36, - 37, - 38, - 39, - 40, - 41, - 42, - 43, - 44, - 45, - 46, - 47, - 48, - 49, - 50, - 51, - 52, - 53, - 54, - 55, - 56, - 57, - 58, - 59, - 60, - 61, - 62, - 63, - 64, - 65, - 66, - 67, - 68, - 69, - 70, - 71, - 72, - 73, - 74, - 75, - 76, - 77, - 78, - 79, - 80, - 81, - 82, - 83, - 84, - 85, - 86, - 87, - 88, - 89, - 90, - 91, - 92, - 93, - 94, - 95, - 96, - 97, - 98, - 99, - 100 -) - println(p1.field1) - println(p1.field2) - println(p1.field3) - println(p1.field4) - println(p1.field5) - println(p1.field6) - println(p1.field7) - println(p1.field8) - println(p1.field9) - println(p1.field10) - println(p1.field11) - println(p1.field12) - println(p1.field13) - println(p1.field14) - println(p1.field15) - println(p1.field16) - println(p1.field17) - println(p1.field18) - println(p1.field19) - println(p1.field20) - println(p1.field21) - println(p1.field22) - println(p1.field23) - println(p1.field24) - println(p1.field25) - println(p1.field26) - println(p1.field27) - println(p1.field28) - println(p1.field29) - println(p1.field30) - println(p1.field31) - println(p1.field32) - println(p1.field33) - println(p1.field34) - println(p1.field35) - println(p1.field36) - println(p1.field37) - println(p1.field38) - println(p1.field39) - println(p1.field40) - println(p1.field41) - println(p1.field42) - println(p1.field43) - println(p1.field44) - println(p1.field45) - println(p1.field46) - println(p1.field47) - println(p1.field48) - println(p1.field49) - println(p1.field50) - println(p1.field51) - println(p1.field52) - println(p1.field53) - println(p1.field54) - println(p1.field55) - println(p1.field56) - println(p1.field57) - println(p1.field58) - println(p1.field59) - println(p1.field60) - println(p1.field61) - println(p1.field62) - println(p1.field63) - println(p1.field64) - println(p1.field65) - println(p1.field66) - println(p1.field67) - println(p1.field68) - println(p1.field69) - println(p1.field70) - println(p1.field71) - println(p1.field72) - println(p1.field73) - println(p1.field74) - println(p1.field75) - println(p1.field76) - println(p1.field77) - println(p1.field78) - println(p1.field79) - println(p1.field80) - println(p1.field81) - println(p1.field82) - println(p1.field83) - println(p1.field84) - println(p1.field85) - println(p1.field86) - println(p1.field87) - println(p1.field88) - println(p1.field89) - println(p1.field90) - println(p1.field91) - println(p1.field92) - println(p1.field93) - println(p1.field94) - println(p1.field95) - println(p1.field96) - println(p1.field97) - println(p1.field98) - println(p1.field99) - println(p1.field100) -} \ No newline at end of file diff --git a/examples/ctrc/nooptimized/two_xxl_objects.check b/examples/ctrc/nooptimized/two_xxl_objects.check deleted file mode 100644 index 2a817d143..000000000 --- a/examples/ctrc/nooptimized/two_xxl_objects.check +++ /dev/null @@ -1,2 +0,0 @@ -100 -151 \ No newline at end of file diff --git a/examples/ctrc/nooptimized/two_xxl_objects.effekt b/examples/ctrc/nooptimized/two_xxl_objects.effekt deleted file mode 100644 index 7258d179a..000000000 --- a/examples/ctrc/nooptimized/two_xxl_objects.effekt +++ /dev/null @@ -1,312 +0,0 @@ -// xxl: Person has 100 fields -> need x slots -record Person( - field1: Int, - field2: Int, - field3: Int, - field4: Int, - field5: Int, - field6: Int, - field7: Int, - field8: Int, - field9: Int, - field10: Int, - field11: Int, - field12: Int, - field13: Int, - field14: Int, - field15: Int, - field16: Int, - field17: Int, - field18: Int, - field19: Int, - field20: Int, - field21: Int, - field22: Int, - field23: Int, - field24: Int, - field25: Int, - field26: Int, - field27: Int, - field28: Int, - field29: Int, - field30: Int, - field31: Int, - field32: Int, - field33: Int, - field34: Int, - field35: Int, - field36: Int, - field37: Int, - field38: Int, - field39: Int, - field40: Int, - field41: Int, - field42: Int, - field43: Int, - field44: Int, - field45: Int, - field46: Int, - field47: Int, - field48: Int, - field49: Int, - field50: Int, - field51: Int, - field52: Int, - field53: Int, - field54: Int, - field55: Int, - field56: Int, - field57: Int, - field58: Int, - field59: Int, - field60: Int, - field61: Int, - field62: Int, - field63: Int, - field64: Int, - field65: Int, - field66: Int, - field67: Int, - field68: Int, - field69: Int, - field70: Int, - field71: Int, - field72: Int, - field73: Int, - field74: Int, - field75: Int, - field76: Int, - field77: Int, - field78: Int, - field79: Int, - field80: Int, - field81: Int, - field82: Int, - field83: Int, - field84: Int, - field85: Int, - field86: Int, - field87: Int, - field88: Int, - field89: Int, - field90: Int, - field91: Int, - field92: Int, - field93: Int, - field94: Int, - field95: Int, - field96: Int, - field97: Int, - field98: Int, - field99: Int, - field100: Int -) - -def main() = { - val p1 = Person( - 1, - 2, - 3, - 4, - 5, - 6, - 7, - 8, - 9, - 10, - 11, - 12, - 13, - 14, - 15, - 16, - 17, - 18, - 19, - 20, - 21, - 22, - 23, - 24, - 25, - 26, - 27, - 28, - 29, - 30, - 31, - 32, - 33, - 34, - 35, - 36, - 37, - 38, - 39, - 40, - 41, - 42, - 43, - 44, - 45, - 46, - 47, - 48, - 49, - 50, - 51, - 52, - 53, - 54, - 55, - 56, - 57, - 58, - 59, - 60, - 61, - 62, - 63, - 64, - 65, - 66, - 67, - 68, - 69, - 70, - 71, - 72, - 73, - 74, - 75, - 76, - 77, - 78, - 79, - 80, - 81, - 82, - 83, - 84, - 85, - 86, - 87, - 88, - 89, - 90, - 91, - 92, - 93, - 94, - 95, - 96, - 97, - 98, - 99, - 100 -) - val p2 = Person( - 101, - 102, - 103, - 104, - 105, - 106, - 107, - 108, - 109, - 110, - 111, - 112, - 113, - 114, - 115, - 116, - 117, - 118, - 119, - 120, - 121, - 122, - 123, - 124, - 125, - 126, - 127, - 128, - 129, - 130, - 131, - 132, - 133, - 134, - 135, - 136, - 137, - 138, - 139, - 140, - 141, - 142, - 143, - 144, - 145, - 146, - 147, - 148, - 149, - 150, - 151, - 152, - 153, - 154, - 155, - 156, - 157, - 158, - 159, - 160, - 161, - 162, - 163, - 164, - 165, - 166, - 167, - 168, - 169, - 170, - 171, - 172, - 173, - 174, - 175, - 176, - 177, - 178, - 179, - 180, - 181, - 182, - 183, - 184, - 185, - 186, - 187, - 188, - 189, - 190, - 191, - 192, - 193, - 194, - 195, - 196, - 197, - 198, - 199, - 200 -) - println(p1.field100) - println(p2.field51) -} \ No newline at end of file diff --git a/examples/ctrc/nooptimized/two_xxxl_objects.check b/examples/ctrc/nooptimized/two_xxxl_objects.check deleted file mode 100644 index f10f03bb2..000000000 --- a/examples/ctrc/nooptimized/two_xxxl_objects.check +++ /dev/null @@ -1,2 +0,0 @@ -500 -999 \ No newline at end of file diff --git a/examples/ctrc/nooptimized/two_xxxl_objects.effekt b/examples/ctrc/nooptimized/two_xxxl_objects.effekt deleted file mode 100644 index 0e3ee0511..000000000 --- a/examples/ctrc/nooptimized/two_xxxl_objects.effekt +++ /dev/null @@ -1,1512 +0,0 @@ -// xxxl: Person has 500 fields -> need x slots -record Person( - field1: Int, - field2: Int, - field3: Int, - field4: Int, - field5: Int, - field6: Int, - field7: Int, - field8: Int, - field9: Int, - field10: Int, - field11: Int, - field12: Int, - field13: Int, - field14: Int, - field15: Int, - field16: Int, - field17: Int, - field18: Int, - field19: Int, - field20: Int, - field21: Int, - field22: Int, - field23: Int, - field24: Int, - field25: Int, - field26: Int, - field27: Int, - field28: Int, - field29: Int, - field30: Int, - field31: Int, - field32: Int, - field33: Int, - field34: Int, - field35: Int, - field36: Int, - field37: Int, - field38: Int, - field39: Int, - field40: Int, - field41: Int, - field42: Int, - field43: Int, - field44: Int, - field45: Int, - field46: Int, - field47: Int, - field48: Int, - field49: Int, - field50: Int, - field51: Int, - field52: Int, - field53: Int, - field54: Int, - field55: Int, - field56: Int, - field57: Int, - field58: Int, - field59: Int, - field60: Int, - field61: Int, - field62: Int, - field63: Int, - field64: Int, - field65: Int, - field66: Int, - field67: Int, - field68: Int, - field69: Int, - field70: Int, - field71: Int, - field72: Int, - field73: Int, - field74: Int, - field75: Int, - field76: Int, - field77: Int, - field78: Int, - field79: Int, - field80: Int, - field81: Int, - field82: Int, - field83: Int, - field84: Int, - field85: Int, - field86: Int, - field87: Int, - field88: Int, - field89: Int, - field90: Int, - field91: Int, - field92: Int, - field93: Int, - field94: Int, - field95: Int, - field96: Int, - field97: Int, - field98: Int, - field99: Int, - field100: Int, - field101: Int, - field102: Int, - field103: Int, - field104: Int, - field105: Int, - field106: Int, - field107: Int, - field108: Int, - field109: Int, - field110: Int, - field111: Int, - field112: Int, - field113: Int, - field114: Int, - field115: Int, - field116: Int, - field117: Int, - field118: Int, - field119: Int, - field120: Int, - field121: Int, - field122: Int, - field123: Int, - field124: Int, - field125: Int, - field126: Int, - field127: Int, - field128: Int, - field129: Int, - field130: Int, - field131: Int, - field132: Int, - field133: Int, - field134: Int, - field135: Int, - field136: Int, - field137: Int, - field138: Int, - field139: Int, - field140: Int, - field141: Int, - field142: Int, - field143: Int, - field144: Int, - field145: Int, - field146: Int, - field147: Int, - field148: Int, - field149: Int, - field150: Int, - field151: Int, - field152: Int, - field153: Int, - field154: Int, - field155: Int, - field156: Int, - field157: Int, - field158: Int, - field159: Int, - field160: Int, - field161: Int, - field162: Int, - field163: Int, - field164: Int, - field165: Int, - field166: Int, - field167: Int, - field168: Int, - field169: Int, - field170: Int, - field171: Int, - field172: Int, - field173: Int, - field174: Int, - field175: Int, - field176: Int, - field177: Int, - field178: Int, - field179: Int, - field180: Int, - field181: Int, - field182: Int, - field183: Int, - field184: Int, - field185: Int, - field186: Int, - field187: Int, - field188: Int, - field189: Int, - field190: Int, - field191: Int, - field192: Int, - field193: Int, - field194: Int, - field195: Int, - field196: Int, - field197: Int, - field198: Int, - field199: Int, - field200: Int, - field201: Int, - field202: Int, - field203: Int, - field204: Int, - field205: Int, - field206: Int, - field207: Int, - field208: Int, - field209: Int, - field210: Int, - field211: Int, - field212: Int, - field213: Int, - field214: Int, - field215: Int, - field216: Int, - field217: Int, - field218: Int, - field219: Int, - field220: Int, - field221: Int, - field222: Int, - field223: Int, - field224: Int, - field225: Int, - field226: Int, - field227: Int, - field228: Int, - field229: Int, - field230: Int, - field231: Int, - field232: Int, - field233: Int, - field234: Int, - field235: Int, - field236: Int, - field237: Int, - field238: Int, - field239: Int, - field240: Int, - field241: Int, - field242: Int, - field243: Int, - field244: Int, - field245: Int, - field246: Int, - field247: Int, - field248: Int, - field249: Int, - field250: Int, - field251: Int, - field252: Int, - field253: Int, - field254: Int, - field255: Int, - field256: Int, - field257: Int, - field258: Int, - field259: Int, - field260: Int, - field261: Int, - field262: Int, - field263: Int, - field264: Int, - field265: Int, - field266: Int, - field267: Int, - field268: Int, - field269: Int, - field270: Int, - field271: Int, - field272: Int, - field273: Int, - field274: Int, - field275: Int, - field276: Int, - field277: Int, - field278: Int, - field279: Int, - field280: Int, - field281: Int, - field282: Int, - field283: Int, - field284: Int, - field285: Int, - field286: Int, - field287: Int, - field288: Int, - field289: Int, - field290: Int, - field291: Int, - field292: Int, - field293: Int, - field294: Int, - field295: Int, - field296: Int, - field297: Int, - field298: Int, - field299: Int, - field300: Int, - field301: Int, - field302: Int, - field303: Int, - field304: Int, - field305: Int, - field306: Int, - field307: Int, - field308: Int, - field309: Int, - field310: Int, - field311: Int, - field312: Int, - field313: Int, - field314: Int, - field315: Int, - field316: Int, - field317: Int, - field318: Int, - field319: Int, - field320: Int, - field321: Int, - field322: Int, - field323: Int, - field324: Int, - field325: Int, - field326: Int, - field327: Int, - field328: Int, - field329: Int, - field330: Int, - field331: Int, - field332: Int, - field333: Int, - field334: Int, - field335: Int, - field336: Int, - field337: Int, - field338: Int, - field339: Int, - field340: Int, - field341: Int, - field342: Int, - field343: Int, - field344: Int, - field345: Int, - field346: Int, - field347: Int, - field348: Int, - field349: Int, - field350: Int, - field351: Int, - field352: Int, - field353: Int, - field354: Int, - field355: Int, - field356: Int, - field357: Int, - field358: Int, - field359: Int, - field360: Int, - field361: Int, - field362: Int, - field363: Int, - field364: Int, - field365: Int, - field366: Int, - field367: Int, - field368: Int, - field369: Int, - field370: Int, - field371: Int, - field372: Int, - field373: Int, - field374: Int, - field375: Int, - field376: Int, - field377: Int, - field378: Int, - field379: Int, - field380: Int, - field381: Int, - field382: Int, - field383: Int, - field384: Int, - field385: Int, - field386: Int, - field387: Int, - field388: Int, - field389: Int, - field390: Int, - field391: Int, - field392: Int, - field393: Int, - field394: Int, - field395: Int, - field396: Int, - field397: Int, - field398: Int, - field399: Int, - field400: Int, - field401: Int, - field402: Int, - field403: Int, - field404: Int, - field405: Int, - field406: Int, - field407: Int, - field408: Int, - field409: Int, - field410: Int, - field411: Int, - field412: Int, - field413: Int, - field414: Int, - field415: Int, - field416: Int, - field417: Int, - field418: Int, - field419: Int, - field420: Int, - field421: Int, - field422: Int, - field423: Int, - field424: Int, - field425: Int, - field426: Int, - field427: Int, - field428: Int, - field429: Int, - field430: Int, - field431: Int, - field432: Int, - field433: Int, - field434: Int, - field435: Int, - field436: Int, - field437: Int, - field438: Int, - field439: Int, - field440: Int, - field441: Int, - field442: Int, - field443: Int, - field444: Int, - field445: Int, - field446: Int, - field447: Int, - field448: Int, - field449: Int, - field450: Int, - field451: Int, - field452: Int, - field453: Int, - field454: Int, - field455: Int, - field456: Int, - field457: Int, - field458: Int, - field459: Int, - field460: Int, - field461: Int, - field462: Int, - field463: Int, - field464: Int, - field465: Int, - field466: Int, - field467: Int, - field468: Int, - field469: Int, - field470: Int, - field471: Int, - field472: Int, - field473: Int, - field474: Int, - field475: Int, - field476: Int, - field477: Int, - field478: Int, - field479: Int, - field480: Int, - field481: Int, - field482: Int, - field483: Int, - field484: Int, - field485: Int, - field486: Int, - field487: Int, - field488: Int, - field489: Int, - field490: Int, - field491: Int, - field492: Int, - field493: Int, - field494: Int, - field495: Int, - field496: Int, - field497: Int, - field498: Int, - field499: Int, - field500: Int -) - -def main() = { - val p1 = Person( - 1, - 2, - 3, - 4, - 5, - 6, - 7, - 8, - 9, - 10, - 11, - 12, - 13, - 14, - 15, - 16, - 17, - 18, - 19, - 20, - 21, - 22, - 23, - 24, - 25, - 26, - 27, - 28, - 29, - 30, - 31, - 32, - 33, - 34, - 35, - 36, - 37, - 38, - 39, - 40, - 41, - 42, - 43, - 44, - 45, - 46, - 47, - 48, - 49, - 50, - 51, - 52, - 53, - 54, - 55, - 56, - 57, - 58, - 59, - 60, - 61, - 62, - 63, - 64, - 65, - 66, - 67, - 68, - 69, - 70, - 71, - 72, - 73, - 74, - 75, - 76, - 77, - 78, - 79, - 80, - 81, - 82, - 83, - 84, - 85, - 86, - 87, - 88, - 89, - 90, - 91, - 92, - 93, - 94, - 95, - 96, - 97, - 98, - 99, - 100, - 101, - 102, - 103, - 104, - 105, - 106, - 107, - 108, - 109, - 110, - 111, - 112, - 113, - 114, - 115, - 116, - 117, - 118, - 119, - 120, - 121, - 122, - 123, - 124, - 125, - 126, - 127, - 128, - 129, - 130, - 131, - 132, - 133, - 134, - 135, - 136, - 137, - 138, - 139, - 140, - 141, - 142, - 143, - 144, - 145, - 146, - 147, - 148, - 149, - 150, - 151, - 152, - 153, - 154, - 155, - 156, - 157, - 158, - 159, - 160, - 161, - 162, - 163, - 164, - 165, - 166, - 167, - 168, - 169, - 170, - 171, - 172, - 173, - 174, - 175, - 176, - 177, - 178, - 179, - 180, - 181, - 182, - 183, - 184, - 185, - 186, - 187, - 188, - 189, - 190, - 191, - 192, - 193, - 194, - 195, - 196, - 197, - 198, - 199, - 200, - 201, - 202, - 203, - 204, - 205, - 206, - 207, - 208, - 209, - 210, - 211, - 212, - 213, - 214, - 215, - 216, - 217, - 218, - 219, - 220, - 221, - 222, - 223, - 224, - 225, - 226, - 227, - 228, - 229, - 230, - 231, - 232, - 233, - 234, - 235, - 236, - 237, - 238, - 239, - 240, - 241, - 242, - 243, - 244, - 245, - 246, - 247, - 248, - 249, - 250, - 251, - 252, - 253, - 254, - 255, - 256, - 257, - 258, - 259, - 260, - 261, - 262, - 263, - 264, - 265, - 266, - 267, - 268, - 269, - 270, - 271, - 272, - 273, - 274, - 275, - 276, - 277, - 278, - 279, - 280, - 281, - 282, - 283, - 284, - 285, - 286, - 287, - 288, - 289, - 290, - 291, - 292, - 293, - 294, - 295, - 296, - 297, - 298, - 299, - 300, - 301, - 302, - 303, - 304, - 305, - 306, - 307, - 308, - 309, - 310, - 311, - 312, - 313, - 314, - 315, - 316, - 317, - 318, - 319, - 320, - 321, - 322, - 323, - 324, - 325, - 326, - 327, - 328, - 329, - 330, - 331, - 332, - 333, - 334, - 335, - 336, - 337, - 338, - 339, - 340, - 341, - 342, - 343, - 344, - 345, - 346, - 347, - 348, - 349, - 350, - 351, - 352, - 353, - 354, - 355, - 356, - 357, - 358, - 359, - 360, - 361, - 362, - 363, - 364, - 365, - 366, - 367, - 368, - 369, - 370, - 371, - 372, - 373, - 374, - 375, - 376, - 377, - 378, - 379, - 380, - 381, - 382, - 383, - 384, - 385, - 386, - 387, - 388, - 389, - 390, - 391, - 392, - 393, - 394, - 395, - 396, - 397, - 398, - 399, - 400, - 401, - 402, - 403, - 404, - 405, - 406, - 407, - 408, - 409, - 410, - 411, - 412, - 413, - 414, - 415, - 416, - 417, - 418, - 419, - 420, - 421, - 422, - 423, - 424, - 425, - 426, - 427, - 428, - 429, - 430, - 431, - 432, - 433, - 434, - 435, - 436, - 437, - 438, - 439, - 440, - 441, - 442, - 443, - 444, - 445, - 446, - 447, - 448, - 449, - 450, - 451, - 452, - 453, - 454, - 455, - 456, - 457, - 458, - 459, - 460, - 461, - 462, - 463, - 464, - 465, - 466, - 467, - 468, - 469, - 470, - 471, - 472, - 473, - 474, - 475, - 476, - 477, - 478, - 479, - 480, - 481, - 482, - 483, - 484, - 485, - 486, - 487, - 488, - 489, - 490, - 491, - 492, - 493, - 494, - 495, - 496, - 497, - 498, - 499, - 500 -) - val p2 = Person( - 501, - 502, - 503, - 504, - 505, - 506, - 507, - 508, - 509, - 510, - 511, - 512, - 513, - 514, - 515, - 516, - 517, - 518, - 519, - 520, - 521, - 522, - 523, - 524, - 525, - 526, - 527, - 528, - 529, - 530, - 531, - 532, - 533, - 534, - 535, - 536, - 537, - 538, - 539, - 540, - 541, - 542, - 543, - 544, - 545, - 546, - 547, - 548, - 549, - 550, - 551, - 552, - 553, - 554, - 555, - 556, - 557, - 558, - 559, - 560, - 561, - 562, - 563, - 564, - 565, - 566, - 567, - 568, - 569, - 570, - 571, - 572, - 573, - 574, - 575, - 576, - 577, - 578, - 579, - 580, - 581, - 582, - 583, - 584, - 585, - 586, - 587, - 588, - 589, - 590, - 591, - 592, - 593, - 594, - 595, - 596, - 597, - 598, - 599, - 600, - 601, - 602, - 603, - 604, - 605, - 606, - 607, - 608, - 609, - 610, - 611, - 612, - 613, - 614, - 615, - 616, - 617, - 618, - 619, - 620, - 621, - 622, - 623, - 624, - 625, - 626, - 627, - 628, - 629, - 630, - 631, - 632, - 633, - 634, - 635, - 636, - 637, - 638, - 639, - 640, - 641, - 642, - 643, - 644, - 645, - 646, - 647, - 648, - 649, - 650, - 651, - 652, - 653, - 654, - 655, - 656, - 657, - 658, - 659, - 660, - 661, - 662, - 663, - 664, - 665, - 666, - 667, - 668, - 669, - 670, - 671, - 672, - 673, - 674, - 675, - 676, - 677, - 678, - 679, - 680, - 681, - 682, - 683, - 684, - 685, - 686, - 687, - 688, - 689, - 690, - 691, - 692, - 693, - 694, - 695, - 696, - 697, - 698, - 699, - 700, - 701, - 702, - 703, - 704, - 705, - 706, - 707, - 708, - 709, - 710, - 711, - 712, - 713, - 714, - 715, - 716, - 717, - 718, - 719, - 720, - 721, - 722, - 723, - 724, - 725, - 726, - 727, - 728, - 729, - 730, - 731, - 732, - 733, - 734, - 735, - 736, - 737, - 738, - 739, - 740, - 741, - 742, - 743, - 744, - 745, - 746, - 747, - 748, - 749, - 750, - 751, - 752, - 753, - 754, - 755, - 756, - 757, - 758, - 759, - 760, - 761, - 762, - 763, - 764, - 765, - 766, - 767, - 768, - 769, - 770, - 771, - 772, - 773, - 774, - 775, - 776, - 777, - 778, - 779, - 780, - 781, - 782, - 783, - 784, - 785, - 786, - 787, - 788, - 789, - 790, - 791, - 792, - 793, - 794, - 795, - 796, - 797, - 798, - 799, - 800, - 801, - 802, - 803, - 804, - 805, - 806, - 807, - 808, - 809, - 810, - 811, - 812, - 813, - 814, - 815, - 816, - 817, - 818, - 819, - 820, - 821, - 822, - 823, - 824, - 825, - 826, - 827, - 828, - 829, - 830, - 831, - 832, - 833, - 834, - 835, - 836, - 837, - 838, - 839, - 840, - 841, - 842, - 843, - 844, - 845, - 846, - 847, - 848, - 849, - 850, - 851, - 852, - 853, - 854, - 855, - 856, - 857, - 858, - 859, - 860, - 861, - 862, - 863, - 864, - 865, - 866, - 867, - 868, - 869, - 870, - 871, - 872, - 873, - 874, - 875, - 876, - 877, - 878, - 879, - 880, - 881, - 882, - 883, - 884, - 885, - 886, - 887, - 888, - 889, - 890, - 891, - 892, - 893, - 894, - 895, - 896, - 897, - 898, - 899, - 900, - 901, - 902, - 903, - 904, - 905, - 906, - 907, - 908, - 909, - 910, - 911, - 912, - 913, - 914, - 915, - 916, - 917, - 918, - 919, - 920, - 921, - 922, - 923, - 924, - 925, - 926, - 927, - 928, - 929, - 930, - 931, - 932, - 933, - 934, - 935, - 936, - 937, - 938, - 939, - 940, - 941, - 942, - 943, - 944, - 945, - 946, - 947, - 948, - 949, - 950, - 951, - 952, - 953, - 954, - 955, - 956, - 957, - 958, - 959, - 960, - 961, - 962, - 963, - 964, - 965, - 966, - 967, - 968, - 969, - 970, - 971, - 972, - 973, - 974, - 975, - 976, - 977, - 978, - 979, - 980, - 981, - 982, - 983, - 984, - 985, - 986, - 987, - 988, - 989, - 990, - 991, - 992, - 993, - 994, - 995, - 996, - 997, - 998, - 999, - 1000 -) - println(p1.field500) - println(p2.field499) -} \ No newline at end of file From baa45422e7f963faeb12dbc4b84ad5514acb8459 Mon Sep 17 00:00:00 2001 From: Philipp Schuster Date: Tue, 3 Mar 2026 17:49:48 +0100 Subject: [PATCH 21/27] Replace switch by invoke --- .../effekt/generator/llvm/Transformer.scala | 110 +++++------------- .../scala/effekt/generator/llvm/Tree.scala | 1 + libraries/llvm/rts.ll | 13 +-- 3 files changed, 33 insertions(+), 91 deletions(-) diff --git a/effekt/shared/src/main/scala/effekt/generator/llvm/Transformer.scala b/effekt/shared/src/main/scala/effekt/generator/llvm/Transformer.scala index cb26f4c0a..47328993f 100644 --- a/effekt/shared/src/main/scala/effekt/generator/llvm/Transformer.scala +++ b/effekt/shared/src/main/scala/effekt/generator/llvm/Transformer.scala @@ -421,6 +421,7 @@ object Transformer { val returnAddressType = NamedType("ReturnAddress"); val sharerType = NamedType("Sharer"); val eraserType = NamedType("Eraser"); + val slotType = NamedType("Slot"); val frameHeaderType = NamedType("FrameHeader"); val environmentType = NamedType("Environment"); val objectType = NamedType("Object"); @@ -521,7 +522,32 @@ object Transformer { C.erasers.getOrElseUpdate((types, kind), { kind match { case ObjectEraser => - createEraserForNormalObjects(freshEnvironment) + // Called by @eraseObject. Stores the ChildrenEraser into the + // slot's eraser field, then pushes the slot onto the todo list for later reuse. + val childrenEraser = getEraser(freshEnvironment, ChildrenEraser) + val eraser = ConstantGlobal(freshName("eraser")) + val eraserFieldPtr = LocalReference(PointerType(), freshName("eraserPointer")) + defineFunction(eraser.name, List(Parameter(objectType, "object"))) { + emit(Comment(s"object eraser, ${freshEnvironment.length} free variables")) + emit(GetElementPtr(eraserFieldPtr.name, slotType, LocalReference(objectType, "object"), List(0, 1))) + emit(Store(eraserFieldPtr, childrenEraser, Object)) + emit(Call("", Ccc(), VoidType(), ConstantGlobal("pushOntoTodoList"), List(LocalReference(objectType, "object")))) + RetVoid() + } + eraser + case ChildrenEraser => + // Called by @acquire when a slot is popped from the todo list. + // Loads the object's environment and erases each heap-typed child (Pos, Neg, Stack). + val eraser = ConstantGlobal(freshName("eraser")) + defineFunction(eraser.name, List(Parameter(objectType, "object"))) { + emit(Comment(s"children eraser, ${freshEnvironment.length} free variables")) + val environmentRef = LocalReference(environmentType, freshName("environment")) + emit(Call(environmentRef.name, Ccc(), environmentType, ConstantGlobal("objectEnvironment"), List(LocalReference(objectType, "object")))) + loadEnvironmentAt(environmentRef, freshEnvironment, Object) + eraseValues(freshEnvironment, Set()) + RetVoid() + } + eraser case StackEraser | StackFrameEraser => val eraser = ConstantGlobal(freshName("eraser")); defineFunction(eraser.name, List(Parameter(stackPointerType, "stackPointer"))) { @@ -1122,88 +1148,6 @@ object Transformer { emit(BasicBlock(shareChildrenLabel, allInstructions.toList, RetVoid())) } - /** - * Creates an eraser for normal objects (e.g. Pos and Neg). - * When @eraseObject is called, we also call the eraser. And for Pos and Neg objects, that is the eraser. - * The object is called 2 times. - * 1. Phase: When call @eraseObject -> We call release to prepend the object to our to-do-list. - * 2. Phase: When call acquire -> We call %erase on each child, so the object can be reused again. - * - * @param freshEnvironment the variables of the object - * @return the eraser - */ - private def createEraserForNormalObjects(freshEnvironment: machine.Environment)(using C: ModuleContext): Operand = { - val eraser = ConstantGlobal(freshName("eraser")) - defineFunction(eraser.name, List(Parameter(objectType, "object"))) { - val objectRefCountPtr = LocalReference(PointerType(), freshName("objectReferenceCount")) - val referenceCount = LocalReference(referenceCountType, freshName("referenceCount")) - val pushOntoTodoListLabel = freshName("pushOntoTodoList") - val eraseChildrenLabel = freshName("eraseChildren") - - // Entry block: Check reference count to determine phase - // Switch: if refCount == 0, go to "pushOntoTodoList" (first phase), else "eraseChildren" (second phase) - // Note: When refCount == 0, this is the first call from eraseObject -> just push onto to-do list - // When refCount != 0, this is the second call from acquire -> erase children - emit(GetElementPtr(objectRefCountPtr.name, headerType, LocalReference(objectType, "object"), List(0, 0))) - emit(Load(referenceCount.name, referenceCountType, objectRefCountPtr, Object)) - - createAndEmitPushOntoTodoBasicBasicBlock(pushOntoTodoListLabel) - createAndEmitEraseChildrenBasicBlock(freshEnvironment, eraseChildrenLabel) - - // Return switch terminator from entry block - Switch(referenceCount, eraseChildrenLabel, List((0, pushOntoTodoListLabel))) - } - - eraser - } - - private def createAndEmitPushOntoTodoBasicBasicBlock(releaseLabel: String)(using ModuleContext, FunctionContext): Unit = { - emit(BasicBlock(releaseLabel, List( - Call("", Ccc(), VoidType(), ConstantGlobal("pushOntoTodoList"), List(LocalReference(objectType, "object"))) - ), RetVoid())) - } - - private def createAndEmitEraseChildrenBasicBlock(freshEnvironment: machine.Environment, eraseChildrenLabel: String)(using ModuleContext, FunctionContext): Unit = { - val environmentRef = LocalReference(environmentType, freshName("environment")) - val eraseChildrenInstructions = mutable.ListBuffer[Instruction]() - - // Load environment variables and erase them - val envType = environmentType(freshEnvironment) - - val isAtLeastOneObjectToRelease: Boolean = - freshEnvironment.exists { - case machine.Variable(_, tpe) => - tpe match { - case machine.Positive() | machine.Negative() | machine.Type.Stack() => true - case _ => false - } - } - - if (isAtLeastOneObjectToRelease) { - // Get environment pointer - eraseChildrenInstructions += Call(environmentRef.name, Ccc(), environmentType, ConstantGlobal("objectEnvironment"), List(LocalReference(objectType, "object"))) - - freshEnvironment.zipWithIndex.foreach { case (machine.Variable(varName, tpe), i) => - val fieldPtr = LocalReference(PointerType(), freshName(varName + "_pointer")) - val loadedVarName = freshName(varName) - // Erase the value based on its type - tpe match { - case machine.Positive() => - emitElementPtrAndLoadOfEnvironmentVariable(environmentRef, eraseChildrenInstructions, envType, tpe, i, fieldPtr, loadedVarName, erasePositive) - case machine.Negative() => - emitElementPtrAndLoadOfEnvironmentVariable(environmentRef, eraseChildrenInstructions, envType, tpe, i, fieldPtr, loadedVarName, eraseNegative) - case machine.Type.Stack() => - emitElementPtrAndLoadOfEnvironmentVariable(environmentRef, eraseChildrenInstructions, envType, tpe, i, fieldPtr, loadedVarName, eraseResumption) - case _ => // Int, Byte, Double, Reference, etc. don't need erasing - } - } - emit(BasicBlock(eraseChildrenLabel, eraseChildrenInstructions.toList, RetVoid())) - } else { - // If not: we can return immediately, since we don't need to erase anything - emit(BasicBlock(eraseChildrenLabel, eraseChildrenInstructions.toList, RetVoid())) - } - } - private def emitElementPtrAndLoadOfEnvironmentVariable(environmentRef: LocalReference, eraseChildrenInstructions: ListBuffer[Instruction], envType: llvm.Type, tpe: machine.Type, i: Int, fieldPtr: LocalReference, loadedVarName: String, eraserFunction: ConstantGlobal) = { eraseChildrenInstructions += GetElementPtr(fieldPtr.name, envType, environmentRef, List(0, i)) eraseChildrenInstructions += Load(loadedVarName, transform(tpe), fieldPtr, Object) diff --git a/effekt/shared/src/main/scala/effekt/generator/llvm/Tree.scala b/effekt/shared/src/main/scala/effekt/generator/llvm/Tree.scala index bad907f93..5a76f83f0 100644 --- a/effekt/shared/src/main/scala/effekt/generator/llvm/Tree.scala +++ b/effekt/shared/src/main/scala/effekt/generator/llvm/Tree.scala @@ -102,6 +102,7 @@ export Operand.* enum EraserKind { case ObjectEraser + case ChildrenEraser case StackEraser case StackFrameEraser } diff --git a/libraries/llvm/rts.ll b/libraries/llvm/rts.ll index a88087bc0..9c671edf8 100644 --- a/libraries/llvm/rts.ll +++ b/libraries/llvm/rts.ll @@ -129,10 +129,7 @@ declare ptr @initializeArena() ; list of immediately available slots @freeList = private unnamed_addr global ptr null ; list of slots where we still need to erase the children -; initializes the todoList with a sentinel slot. -; Sentinel Slot: Fakes a block with a RC=1. It is used to mark the end of the To-Do-List. -; But it is not a real heap-object, because it is not 8-byte aligned. -@todoList = private unnamed_addr global ptr inttoptr (i64 1 to ptr) +@todoList = private unnamed_addr global ptr null ; space of unused consecutive slots @bumpList = private unnamed_addr global ptr null @@ -149,8 +146,8 @@ entry: define private ptr @acquire() nounwind { entry: %freeHead = load ptr, ptr @freeList - %isEmpty = icmp eq ptr %freeHead, null - br i1 %isEmpty, label %checkTodo, label %freeReuse + %isFreeEmpty = icmp eq ptr %freeHead, null + br i1 %isFreeEmpty, label %checkTodo, label %freeReuse ; 1. Fast Path: Reuse block from freeList freeReuse: @@ -162,8 +159,8 @@ freeReuse: checkTodo: %todoHead = load ptr, ptr @todoList - %isSentinel = icmp eq ptr %todoHead, inttoptr (i64 1 to ptr) - br i1 %isSentinel, label %bumpAlloc, label %todoReuse + %isTodoEmpty = icmp eq ptr %todoHead, null + br i1 %isTodoEmpty, label %bumpAlloc, label %todoReuse ; 2. Slot Path: Reuse block from To-Do-List. Here, we have to extra call the eraser to ensure that we can reuse it. todoReuse: From 90fefea6a892e8ef12d20da2484102b4ff54d955 Mon Sep 17 00:00:00 2001 From: Philipp Schuster Date: Tue, 3 Mar 2026 18:09:16 +0100 Subject: [PATCH 22/27] Emit instructions into basic block --- .../effekt/generator/llvm/Transformer.scala | 163 +++--------------- 1 file changed, 28 insertions(+), 135 deletions(-) diff --git a/effekt/shared/src/main/scala/effekt/generator/llvm/Transformer.scala b/effekt/shared/src/main/scala/effekt/generator/llvm/Transformer.scala index 47328993f..fa73b3b6e 100644 --- a/effekt/shared/src/main/scala/effekt/generator/llvm/Transformer.scala +++ b/effekt/shared/src/main/scala/effekt/generator/llvm/Transformer.scala @@ -723,49 +723,6 @@ object Transformer { } } - def loadEnvironmentAtDirectly(elementPointer: Operand, environment: machine.Environment, alias: AliasInfo, allInstructions: mutable.ListBuffer[Instruction])(using ModuleContext, FunctionContext, BlockContext): Unit = { - alias match { - // if we have a sharded object - case Object if !fitsInOneSavingSlot(environment) => - // Follow chained ${slotSize}-byte blocks created in produceObject - val chunkedEnvironments = splitEnvironment(environment) - var currentEnvironmentPtr: Operand = elementPointer - - // here we loop over all environments *in* order - chunkedEnvironments.zipWithIndex.foreach { case (chunk, idx) => - val isLast = idx == chunkedEnvironments.length - 1 - if (isLast) { - val tpe = environmentType(chunk) - loadAllVariablesDirectly(currentEnvironmentPtr, chunk, alias, tpe, allInstructions) - } else { - // Here we do the same as for the normal slot plus some extra stuff - - // For non-last chunkedEnvironments, layout is chunk ++ [Pos link] - val tpe = StructureType(chunk.map { case machine.Variable(_, t) => transform(t) } :+ positiveType) // the same as for the normal case + positive Type for the link - loadAllVariablesDirectly(currentEnvironmentPtr, chunk, alias, tpe, allInstructions) - - // Follow link to next block. The Link pointer is the last element of the chunk - val linkPtr = LocalReference(PointerType(), freshName("link_pointer")) - allInstructions += GetElementPtr(linkPtr.name, tpe, currentEnvironmentPtr, List(0, chunk.length)) - - val linkVal = LocalReference(positiveType, freshName("link")) - allInstructions += Load(linkVal.name, positiveType, linkPtr, alias) - - val nextObj = LocalReference(objectType, freshName("next_object")) - allInstructions += ExtractValue(nextObj.name, linkVal, 1) - - val nextEnv = LocalReference(environmentType, freshName("environment")) - allInstructions += Call(nextEnv.name, Ccc(), environmentType, objectEnvironment, List(nextObj)) - currentEnvironmentPtr = nextEnv - } - } - case _: AliasInfo => - val tpe = environmentType(environment) - loadAllVariablesDirectly(elementPointer, environment, alias, tpe, allInstructions) - - } - } - def shareValues(values: machine.Environment, freeInBody: Set[machine.Variable])(using FunctionContext, BlockContext): Unit = { @tailrec def loop(values: machine.Environment): Unit = { @@ -786,29 +743,6 @@ object Transformer { loop(values) } - /* - * Adds all sharing functions to the allInstructions list - */ - def shareValuesDirectly(values: machine.Environment, freeInBody: Set[machine.Variable], allInstructions: ListBuffer[Instruction])(using FunctionContext, BlockContext): Unit = { - @tailrec - def loop(values: machine.Environment): Unit = { - values match { - case Nil => () - case value :: values => - if values.contains(value) then { - shareValueDirectly(value, allInstructions); - loop(values) - } else if freeInBody.contains(value) then { - shareValueDirectly(value, allInstructions); - loop(values) - } else { - loop(values) - } - } - }; - loop(values) - } - def eraseValues(environment: machine.Environment, freeInBody: Set[machine.Variable])(using ModuleContext, FunctionContext, BlockContext): Unit = environment.foreach { value => if !freeInBody.contains(value) then eraseValue(value) @@ -822,17 +756,6 @@ object Transformer { }.map(emit) } - /** - * adds the sharing Functions to the allInstructions list. - */ - def shareValueDirectly(value: machine.Variable, allInstructions: ListBuffer[Instruction])(using FunctionContext, BlockContext): Unit = { - Option(value.tpe).collect { - case machine.Positive() => allInstructions += (Call("_", Ccc(), VoidType(), sharePositive, List(transform(value)))) - case machine.Negative() => allInstructions += Call("_", Ccc(), VoidType(), shareNegative, List(transform(value))) - case machine.Type.Stack() => allInstructions += Call("_", Ccc(), VoidType(), shareResumption, List(transform(value))) - } - } - def eraseValue(value: machine.Variable)(using FunctionContext, BlockContext): Unit = { Option(value.tpe).collect { case machine.Positive() => Call("_", Ccc(), VoidType(), erasePositive, List(transform(value))) @@ -1044,15 +967,6 @@ object Transformer { } } - private def loadAllVariablesDirectly(pointer: Operand, environment: machine.Environment, alias: AliasInfo, typ: Type, allInstructions: mutable.ListBuffer[Instruction])(using ModuleContext, FunctionContext, BlockContext): Unit = { - environment.zipWithIndex.foreach { - case (machine.Variable(name, tpe), i) => - val field = LocalReference(PointerType(), freshName(name + "_pointer")) - allInstructions += GetElementPtr(field.name, typ, pointer, List(0, i)) - allInstructions += Load(name, transform(tpe), field, alias) - } - } - private def createReleaseFunction(releaseLabel: String, environment: machine.Environment, freeInBody: Set[machine.Variable])(using ModuleContext, FunctionContext, BlockContext): Terminator = { val pushOntoFreeListLabel = freshName("pushOntoFreeList") val shareChildrenAndEraseLabel = freshName("shareChildrenAndErase") @@ -1083,75 +997,54 @@ object Transformer { * Each slot is pushed onto the free list. */ private def createReleasePushOntoFreeListBasicBlock(releaseLabel: String, environment: machine.Environment, freeInBody: Set[machine.Variable], `object`: Operand, environmentRef: LocalReference)(using ModuleContext, FunctionContext, BlockContext): Unit = { - val allInstructions = mutable.ListBuffer[Instruction](Call("_", Ccc(), VoidType(), ConstantGlobal("pushOntoFreeList"), List(`object`))) - var currentEnvironmentPtr = environmentRef + implicit val BC = BlockContext() + emit(Call("_", Ccc(), VoidType(), ConstantGlobal("pushOntoFreeList"), List(`object`))) + var currentEnvironmentPtr: Operand = environmentRef val slottedEnvironment = splitEnvironment(environment) - slottedEnvironment.zipWithIndex.foreach { case (slotEnv: machine.Environment, index: Int) => + slottedEnvironment.zipWithIndex.foreach { case (slotEnv, index) => val isLastSlot = index == slottedEnvironment.length - 1 val slotEnvTypes = if (isLastSlot) environmentType(slotEnv) else StructureType(slotEnv.map { case machine.Variable(_, t) => transform(t) } :+ positiveType) - slotEnv.zipWithIndex.foreach { case (variable@machine.Variable(varName, tpe), i) => - val isHeapType = tpe match { - case machine.Positive() | machine.Negative() | machine.Type.Stack() => true - case _ => false - } - - if (isHeapType) { - val variableType = transform(tpe) - val fieldPtr = LocalReference(PointerType(), freshName(varName + "_pointer")) - val loadedVar = LocalReference(variableType, freshName(varName)) - - // Load the variable - allInstructions += GetElementPtr(fieldPtr.name, slotEnvTypes, currentEnvironmentPtr, List(0, i)) - allInstructions += Load(loadedVar.name, variableType, fieldPtr, Object) - - val isVariableFreeInBody = freeInBody.contains(variable) - - if (!isVariableFreeInBody) { - // Variable is used in the scope -> erase it - val erasingFunction = getErasingFunctionForType(variableType) - allInstructions += Call("_", Ccc(), VoidType(), erasingFunction, List(loadedVar)) - } + slotEnv.zipWithIndex.foreach { case (variable @ machine.Variable(varName, tpe), i) => + tpe match { + case machine.Positive() | machine.Negative() | machine.Type.Stack() => + val variableType = transform(tpe) + val fieldPtr = LocalReference(PointerType(), freshName(varName + "_pointer")) + val loadedVar = LocalReference(variableType, freshName(varName)) + emit(GetElementPtr(fieldPtr.name, slotEnvTypes, currentEnvironmentPtr, List(0, i))) + emit(Load(loadedVar.name, variableType, fieldPtr, Object)) + if (!freeInBody.contains(variable)) { + emit(Call("_", Ccc(), VoidType(), getErasingFunctionForType(variableType), List(loadedVar))) + } + case _ => } } if (!isLastSlot) { - // erase the link slot val linkIndexOfSlot = slotEnv.length val linkPtr = LocalReference(PointerType(), freshName("link_pointer")) val linkVal = LocalReference(positiveType, freshName("link")) val nextObj = LocalReference(objectType, freshName("next_object")) val nextEnv = LocalReference(environmentType, freshName("environment")) - - // add all instructions - allInstructions += GetElementPtr(linkPtr.name, slotEnvTypes, currentEnvironmentPtr, List(0, linkIndexOfSlot)) - allInstructions += Load(linkVal.name, positiveType, linkPtr, Object) - allInstructions += ExtractValue(nextObj.name, linkVal, 1) - allInstructions += Call("_", Ccc(), VoidType(), ConstantGlobal("pushOntoFreeList"), List(nextObj)) - allInstructions += Call(nextEnv.name, Ccc(), environmentType, objectEnvironment, List(nextObj)) - - // now we have to follow the link to the next environment + emit(GetElementPtr(linkPtr.name, slotEnvTypes, currentEnvironmentPtr, List(0, linkIndexOfSlot))) + emit(Load(linkVal.name, positiveType, linkPtr, Object)) + emit(ExtractValue(nextObj.name, linkVal, 1)) + emit(Call("_", Ccc(), VoidType(), ConstantGlobal("pushOntoFreeList"), List(nextObj))) + emit(Call(nextEnv.name, Ccc(), environmentType, objectEnvironment, List(nextObj))) currentEnvironmentPtr = nextEnv } } - emit(BasicBlock(releaseLabel, allInstructions.toList, RetVoid())) - } - - private def createReleaseShareChildrenAndEraseBasicBlock(shareChildrenLabel: String, environment: machine.Environment, freeInBody: Set[machine.Variable], `object`: Operand, environmentRef: LocalReference)(using ModuleContext, FunctionContext, BlockContext): Unit = { - val allInstructions = mutable.ListBuffer[Instruction]() - // Step 02: Load all variables - loadEnvironmentAtDirectly(environmentRef, environment, Object, allInstructions) - shareValuesDirectly(environment, freeInBody, allInstructions) - allInstructions += (Call("_", Ccc(), VoidType(), eraseObject, List(`object`))) - emit(BasicBlock(shareChildrenLabel, allInstructions.toList, RetVoid())) + emit(BasicBlock(releaseLabel, BC.instructions, RetVoid())) } - private def emitElementPtrAndLoadOfEnvironmentVariable(environmentRef: LocalReference, eraseChildrenInstructions: ListBuffer[Instruction], envType: llvm.Type, tpe: machine.Type, i: Int, fieldPtr: LocalReference, loadedVarName: String, eraserFunction: ConstantGlobal) = { - eraseChildrenInstructions += GetElementPtr(fieldPtr.name, envType, environmentRef, List(0, i)) - eraseChildrenInstructions += Load(loadedVarName, transform(tpe), fieldPtr, Object) - eraseChildrenInstructions += Call("_", Ccc(), VoidType(), eraserFunction, List(LocalReference(transform(tpe), loadedVarName))) + private def createReleaseShareChildrenAndEraseBasicBlock(label: String, environment: machine.Environment, freeInBody: Set[machine.Variable], `object`: Operand, environmentRef: LocalReference)(using ModuleContext, FunctionContext, BlockContext): Unit = { + implicit val BC = BlockContext() + loadEnvironmentAt(environmentRef, environment, Object) + shareValues(environment, freeInBody) + emit(Call("_", Ccc(), VoidType(), eraseObject, List(`object`))) + emit(BasicBlock(label, BC.instructions, RetVoid())) } /** From 42d07eb5738b3be3fe95db97ca4dd596ab86799f Mon Sep 17 00:00:00 2001 From: Philipp Schuster Date: Tue, 3 Mar 2026 18:35:20 +0100 Subject: [PATCH 23/27] Avoid matching on alias info --- .../effekt/generator/llvm/Transformer.scala | 92 +++++++++---------- 1 file changed, 45 insertions(+), 47 deletions(-) diff --git a/effekt/shared/src/main/scala/effekt/generator/llvm/Transformer.scala b/effekt/shared/src/main/scala/effekt/generator/llvm/Transformer.scala index fa73b3b6e..2569e61b6 100644 --- a/effekt/shared/src/main/scala/effekt/generator/llvm/Transformer.scala +++ b/effekt/shared/src/main/scala/effekt/generator/llvm/Transformer.scala @@ -9,7 +9,6 @@ import effekt.util.messages.ErrorReporter import scala.annotation.tailrec import scala.collection.mutable -import scala.collection.mutable.ListBuffer object Transformer { @@ -497,19 +496,19 @@ object Transformer { def initialEnvironmentPointer = LocalReference(environmentType, "environment") - def loadEnvironment(environmentPointer: Operand, environment: machine.Environment, alias: AliasInfo)(using ModuleContext, FunctionContext, BlockContext): Unit = { + def loadEnvironment(environmentPointer: Operand, environment: machine.Environment)(using ModuleContext, FunctionContext, BlockContext): Unit = { if (environment.isEmpty) { () } else { - loadEnvironmentAt(environmentPointer, environment, alias); + loadObjectEnvironmentAt(environmentPointer, environment); } } - def storeEnvironment(environmentPointer: Operand, environment: machine.Environment, alias: AliasInfo)(using ModuleContext, FunctionContext, BlockContext): Unit = { + def storeEnvironment(environmentPointer: Operand, environment: machine.Environment)(using ModuleContext, FunctionContext, BlockContext): Unit = { if (environment.isEmpty) { () } else { - storeEnvironmentAt(environmentPointer, environment, alias); + storeEnvironmentAt(environmentPointer, environment, Object); } } @@ -543,7 +542,7 @@ object Transformer { emit(Comment(s"children eraser, ${freshEnvironment.length} free variables")) val environmentRef = LocalReference(environmentType, freshName("environment")) emit(Call(environmentRef.name, Ccc(), environmentType, ConstantGlobal("objectEnvironment"), List(LocalReference(objectType, "object")))) - loadEnvironmentAt(environmentRef, freshEnvironment, Object) + loadObjectEnvironmentAt(environmentRef, freshEnvironment) eraseValues(freshEnvironment, Set()) RetVoid() } @@ -555,7 +554,8 @@ object Transformer { val nextStackPointer = LocalReference(stackPointerType, freshName("stackPointer")); emit(GetElementPtr(nextStackPointer.name, environmentType(freshEnvironment), LocalReference(stackPointerType, "stackPointer"), List(-1))); - loadEnvironmentAt(nextStackPointer, freshEnvironment, StackPointer); + + loadEnvironmentAt(nextStackPointer, freshEnvironment, StackPointer, environmentType(environment)) eraseValues(freshEnvironment, Set()); val next = if (kind == StackEraser) freeStack else eraseFrames // TODO: improve this (in RTS?) @@ -580,7 +580,7 @@ object Transformer { val nextStackPointer = LocalReference(stackPointerType, freshName("stackPointer")); emit(GetElementPtr(nextStackPointer.name, environmentType(freshEnvironment), LocalReference(stackPointerType, "stackPointer"), List(-1))); - loadEnvironmentAt(nextStackPointer, freshEnvironment, StackPointer); + loadEnvironmentAt(nextStackPointer, freshEnvironment, StackPointer, environmentType(environment)) shareValues(freshEnvironment, Set.from(freshEnvironment)); @@ -612,7 +612,7 @@ object Transformer { // Step 01: We load the variables of the environment such that the continuation can continue val environmentReference = LocalReference(environmentType, freshName("environment")); emit(Call(environmentReference.name, Ccc(), environmentType, objectEnvironment, List(`object`))); - loadEnvironment(environmentReference, environment, Object) + loadEnvironment(environmentReference, environment) // Step 02: we create the release function for this object val release = ConstantGlobal(freshName("release")); @@ -662,7 +662,7 @@ object Transformer { val stackPointer = LocalReference(stackPointerType, freshName("stackPointer")); val size = ConstantInt(environmentSize(environment)); emit(Call(stackPointer.name, Ccc(), stackPointer.tpe, stackDeallocate, List(stack, size))); - loadEnvironmentAt(stackPointer, environment, StackPointer) + loadEnvironmentAt(stackPointer, environment, StackPointer, environmentType(environment)) } } @@ -681,45 +681,43 @@ object Transformer { } } - def loadEnvironmentAt(elementPointer: Operand, environment: machine.Environment, alias: AliasInfo)(using ModuleContext, FunctionContext, BlockContext): Unit = { - alias match { - // if we have a sharded object - case Object if !fitsInOneSavingSlot(environment) => - // Follow chained ${slotSize}-byte blocks created in produceObject - val chunkedEnvironments = splitEnvironment(environment) - var currentEnvironmentPtr: Operand = elementPointer - - // here we loop over all environments *in* order - chunkedEnvironments.zipWithIndex.foreach { case (chunk, idx) => - val isLast = idx == chunkedEnvironments.length - 1 - if (isLast) { - val tpe = environmentType(chunk) - loadAllVariables(currentEnvironmentPtr, chunk, alias, tpe) - } else { - // Here we do the same as for the normal slot plus some extra stuff + def loadObjectEnvironmentAt(elementPointer: Operand, environment: machine.Environment)(using ModuleContext, FunctionContext, BlockContext): Unit = { + // if we have a sharded object + if !fitsInOneSavingSlot(environment) then { + // Follow chained ${slotSize}-byte blocks created in produceObject + val chunkedEnvironments = splitEnvironment(environment) + var currentEnvironmentPtr: Operand = elementPointer + + // here we loop over all environments *in* order + chunkedEnvironments.zipWithIndex.foreach { case (chunk, idx) => + val isLast = idx == chunkedEnvironments.length - 1 + if (isLast) { + val tpe = environmentType(chunk) + loadEnvironmentAt(currentEnvironmentPtr, chunk, Object, tpe) + } else { + // Here we do the same as for the normal slot plus some extra stuff - // For non-last chunkedEnvironments, layout is chunk ++ [Pos link] - val tpe = StructureType(chunk.map { case machine.Variable(_, t) => transform(t) } :+ positiveType) // the same as for the normal case + positive Type for the link - loadAllVariables(currentEnvironmentPtr, chunk, alias, tpe) + // For non-last chunkedEnvironments, layout is chunk ++ [Pos link] + val tpe = StructureType(chunk.map { case machine.Variable(_, t) => transform(t) } :+ positiveType) // the same as for the normal case + positive Type for the link + loadEnvironmentAt(currentEnvironmentPtr, chunk, Object, tpe) - // Follow link to next block. The Link pointer is the last element of the chunk - val linkPtr = LocalReference(PointerType(), freshName("link_pointer")) - emit(GetElementPtr(linkPtr.name, tpe, currentEnvironmentPtr, List(0, chunk.length))) + // Follow link to next block. The Link pointer is the last element of the chunk + val linkPtr = LocalReference(PointerType(), freshName("link_pointer")) + emit(GetElementPtr(linkPtr.name, tpe, currentEnvironmentPtr, List(0, chunk.length))) - val linkVal = LocalReference(positiveType, freshName("link")) - emit(Load(linkVal.name, positiveType, linkPtr, alias)) + val linkVal = LocalReference(positiveType, freshName("link")) + emit(Load(linkVal.name, positiveType, linkPtr, Object)) - val nextObj = LocalReference(objectType, freshName("next_object")) - emit(ExtractValue(nextObj.name, linkVal, 1)) + val nextObj = LocalReference(objectType, freshName("next_object")) + emit(ExtractValue(nextObj.name, linkVal, 1)) - val nextEnv = LocalReference(environmentType, freshName("environment")) - emit(Call(nextEnv.name, Ccc(), environmentType, objectEnvironment, List(nextObj))) - currentEnvironmentPtr = nextEnv - } + val nextEnv = LocalReference(environmentType, freshName("environment")) + emit(Call(nextEnv.name, Ccc(), environmentType, objectEnvironment, List(nextObj))) + currentEnvironmentPtr = nextEnv } - case _: AliasInfo => - val tpe = environmentType(environment) - loadAllVariables(elementPointer, environment, alias, tpe) + } + } else { + loadEnvironmentAt(elementPointer, environment, Object, environmentType(environment)) } } @@ -919,7 +917,7 @@ object Transformer { emit(Call(lastObjectReference.name, Ccc(), objectType, newObject, List(lastEraser, lastSize))) emit(Call(lastEnvPtr.name, Ccc(), environmentType, objectEnvironment, List(lastObjectReference))) shareValues(lastEnvironment, freeInBody) - storeEnvironment(lastEnvPtr, lastEnvironment, Object) + storeEnvironment(lastEnvPtr, lastEnvironment) // Chain preceding blocks, each storing a boxed link to the next object var headObject: LocalReference = lastObjectReference @@ -954,11 +952,11 @@ object Transformer { emit(Call(objectReference.name, Ccc(), objectType, newObject, List(eraser, size))); emit(Call(environmentReference.name, Ccc(), environmentType, objectEnvironment, List(objectReference))); shareValues(environment, freeInBody); - storeEnvironment(environmentReference, environment, Object); + storeEnvironment(environmentReference, environment); objectReference } - private def loadAllVariables(pointer: Operand, environment: machine.Environment, alias: AliasInfo, typ: Type)(using ModuleContext, FunctionContext, BlockContext): Unit = { + private def loadEnvironmentAt(pointer: Operand, environment: machine.Environment, alias: AliasInfo, typ: Type)(using ModuleContext, FunctionContext, BlockContext): Unit = { environment.zipWithIndex.foreach { case (machine.Variable(name, tpe), i) => val field = LocalReference(PointerType(), freshName(name + "_pointer")) @@ -1041,7 +1039,7 @@ object Transformer { private def createReleaseShareChildrenAndEraseBasicBlock(label: String, environment: machine.Environment, freeInBody: Set[machine.Variable], `object`: Operand, environmentRef: LocalReference)(using ModuleContext, FunctionContext, BlockContext): Unit = { implicit val BC = BlockContext() - loadEnvironmentAt(environmentRef, environment, Object) + loadObjectEnvironmentAt(environmentRef, environment) shareValues(environment, freeInBody) emit(Call("_", Ccc(), VoidType(), eraseObject, List(`object`))) emit(BasicBlock(label, BC.instructions, RetVoid())) From 3b5609f5a6caa2c1f45fee224cc851c19ad31f3a Mon Sep 17 00:00:00 2001 From: Philipp Schuster Date: Wed, 4 Mar 2026 10:09:18 +0100 Subject: [PATCH 24/27] Reuse loading of environment --- .../effekt/generator/llvm/Transformer.scala | 33 +++++++------------ 1 file changed, 12 insertions(+), 21 deletions(-) diff --git a/effekt/shared/src/main/scala/effekt/generator/llvm/Transformer.scala b/effekt/shared/src/main/scala/effekt/generator/llvm/Transformer.scala index 2569e61b6..7d9e2159c 100644 --- a/effekt/shared/src/main/scala/effekt/generator/llvm/Transformer.scala +++ b/effekt/shared/src/main/scala/effekt/generator/llvm/Transformer.scala @@ -555,7 +555,7 @@ object Transformer { val nextStackPointer = LocalReference(stackPointerType, freshName("stackPointer")); emit(GetElementPtr(nextStackPointer.name, environmentType(freshEnvironment), LocalReference(stackPointerType, "stackPointer"), List(-1))); - loadEnvironmentAt(nextStackPointer, freshEnvironment, StackPointer, environmentType(environment)) + loadEnvironmentAt(nextStackPointer, freshEnvironment, StackPointer) eraseValues(freshEnvironment, Set()); val next = if (kind == StackEraser) freeStack else eraseFrames // TODO: improve this (in RTS?) @@ -580,7 +580,7 @@ object Transformer { val nextStackPointer = LocalReference(stackPointerType, freshName("stackPointer")); emit(GetElementPtr(nextStackPointer.name, environmentType(freshEnvironment), LocalReference(stackPointerType, "stackPointer"), List(-1))); - loadEnvironmentAt(nextStackPointer, freshEnvironment, StackPointer, environmentType(environment)) + loadEnvironmentAt(nextStackPointer, freshEnvironment, StackPointer) shareValues(freshEnvironment, Set.from(freshEnvironment)); @@ -662,7 +662,7 @@ object Transformer { val stackPointer = LocalReference(stackPointerType, freshName("stackPointer")); val size = ConstantInt(environmentSize(environment)); emit(Call(stackPointer.name, Ccc(), stackPointer.tpe, stackDeallocate, List(stack, size))); - loadEnvironmentAt(stackPointer, environment, StackPointer, environmentType(environment)) + loadEnvironmentAt(stackPointer, environment, StackPointer) } } @@ -692,32 +692,22 @@ object Transformer { chunkedEnvironments.zipWithIndex.foreach { case (chunk, idx) => val isLast = idx == chunkedEnvironments.length - 1 if (isLast) { - val tpe = environmentType(chunk) - loadEnvironmentAt(currentEnvironmentPtr, chunk, Object, tpe) + loadEnvironmentAt(currentEnvironmentPtr, chunk, Object) } else { - // Here we do the same as for the normal slot plus some extra stuff - - // For non-last chunkedEnvironments, layout is chunk ++ [Pos link] - val tpe = StructureType(chunk.map { case machine.Variable(_, t) => transform(t) } :+ positiveType) // the same as for the normal case + positive Type for the link - loadEnvironmentAt(currentEnvironmentPtr, chunk, Object, tpe) - - // Follow link to next block. The Link pointer is the last element of the chunk - val linkPtr = LocalReference(PointerType(), freshName("link_pointer")) - emit(GetElementPtr(linkPtr.name, tpe, currentEnvironmentPtr, List(0, chunk.length))) - - val linkVal = LocalReference(positiveType, freshName("link")) - emit(Load(linkVal.name, positiveType, linkPtr, Object)) + val link = machine.Variable(freshName("link"), machine.Positive()) + val extendedChunk = chunk :+ link + loadEnvironmentAt(currentEnvironmentPtr, extendedChunk, Object) + // Follow link to next block val nextObj = LocalReference(objectType, freshName("next_object")) - emit(ExtractValue(nextObj.name, linkVal, 1)) - + emit(ExtractValue(nextObj.name, LocalReference(positiveType, link.name), 1)) val nextEnv = LocalReference(environmentType, freshName("environment")) emit(Call(nextEnv.name, Ccc(), environmentType, objectEnvironment, List(nextObj))) currentEnvironmentPtr = nextEnv } } } else { - loadEnvironmentAt(elementPointer, environment, Object, environmentType(environment)) + loadEnvironmentAt(elementPointer, environment, Object) } } @@ -956,7 +946,8 @@ object Transformer { objectReference } - private def loadEnvironmentAt(pointer: Operand, environment: machine.Environment, alias: AliasInfo, typ: Type)(using ModuleContext, FunctionContext, BlockContext): Unit = { + private def loadEnvironmentAt(pointer: Operand, environment: machine.Environment, alias: AliasInfo)(using ModuleContext, FunctionContext, BlockContext): Unit = { + val typ = environmentType(environment) environment.zipWithIndex.foreach { case (machine.Variable(name, tpe), i) => val field = LocalReference(PointerType(), freshName(name + "_pointer")) From fd54b3c45de11254317c4b51144a429505da3d7c Mon Sep 17 00:00:00 2001 From: Philipp Schuster Date: Thu, 5 Mar 2026 10:15:14 +0100 Subject: [PATCH 25/27] Reorder definitions --- .../effekt/generator/llvm/Transformer.scala | 513 +++++++++--------- 1 file changed, 256 insertions(+), 257 deletions(-) diff --git a/effekt/shared/src/main/scala/effekt/generator/llvm/Transformer.scala b/effekt/shared/src/main/scala/effekt/generator/llvm/Transformer.scala index 7d9e2159c..7033c81a9 100644 --- a/effekt/shared/src/main/scala/effekt/generator/llvm/Transformer.scala +++ b/effekt/shared/src/main/scala/effekt/generator/llvm/Transformer.scala @@ -443,6 +443,11 @@ object Transformer { case machine.Type.Reference(tpe) => referenceType } + def environmentType(environment: machine.Environment): Type = + StructureType(environment.map { + case machine.Variable(_, tpe) => transform(tpe) + }) + def environmentSize(environment: machine.Environment): Int = environment.map { case machine.Variable(_, typ) => typeSize(typ) }.sum @@ -494,102 +499,71 @@ object Transformer { def callLabelTransition(name: Operand, arguments: List[Operand])(using BlockContext): Instruction = Call("_", Tailcc(false), VoidType(), name, arguments :+ getStack()) - def initialEnvironmentPointer = LocalReference(environmentType, "environment") + def pushFrameOnto(stack: Operand, environment: machine.Environment, returnAddressName: String, sharer: Operand, eraser: Operand)(using ModuleContext, FunctionContext, BlockContext) = { + val size = environmentSize(environment); - def loadEnvironment(environmentPointer: Operand, environment: machine.Environment)(using ModuleContext, FunctionContext, BlockContext): Unit = { - if (environment.isEmpty) { - () - } else { - loadObjectEnvironmentAt(environmentPointer, environment); - } + val newStack = LocalReference(stackType, freshName("stack")) + emit(Call(newStack.name, Ccc(), stackType, checkLimit, List(stack, ConstantInt(size + 24)))); + setStack(newStack); + + val environmentPointer = LocalReference(stackPointerType, freshName("environmentPointer")); + emit(Call(environmentPointer.name, Ccc(), stackPointerType, stackAllocate, List(newStack, ConstantInt(size)))); + + storeEnvironmentAt(environmentPointer, environment, StackPointer); + + val headerPointer = LocalReference(stackPointerType, freshName("headerPointer")); + emit(Call(headerPointer.name, Ccc(), stackPointerType, stackAllocate, List(newStack, ConstantInt(24)))); + + val returnAddressPointer = LocalReference(PointerType(), freshName("returnAddress_pointer")); + emit(GetElementPtr(returnAddressPointer.name, frameHeaderType, headerPointer, List(0, 0))); + val sharerPointer = LocalReference(PointerType(), freshName("sharer_pointer")); + emit(GetElementPtr(sharerPointer.name, frameHeaderType, headerPointer, List(0, 1))); + val eraserPointer = LocalReference(PointerType(), freshName("eraser_pointer")); + emit(GetElementPtr(eraserPointer.name, frameHeaderType, headerPointer, List(0, 2))); + + emit(Store(returnAddressPointer, ConstantGlobal(returnAddressName), StackPointer)); + emit(Store(sharerPointer, sharer, StackPointer)); + emit(Store(eraserPointer, eraser, StackPointer)); } - def storeEnvironment(environmentPointer: Operand, environment: machine.Environment)(using ModuleContext, FunctionContext, BlockContext): Unit = { + def popEnvironmentFrom(stack: Operand, environment: machine.Environment)(using ModuleContext, FunctionContext, BlockContext): Unit = { if (environment.isEmpty) { () } else { - storeEnvironmentAt(environmentPointer, environment, Object); + val stackPointer = LocalReference(stackPointerType, freshName("stackPointer")); + val size = ConstantInt(environmentSize(environment)); + emit(Call(stackPointer.name, Ccc(), stackPointer.tpe, stackDeallocate, List(stack, size))); + loadEnvironmentAt(stackPointer, environment, StackPointer) } } - def getEraser(environment: machine.Environment, kind: EraserKind)(using C: ModuleContext): Operand = { - val types = environment.map{ _.tpe }; - val freshEnvironment = environment.map{ - case machine.Variable(name, tpe) => machine.Variable(freshName(name), tpe) - }; - - C.erasers.getOrElseUpdate((types, kind), { - kind match { - case ObjectEraser => - // Called by @eraseObject. Stores the ChildrenEraser into the - // slot's eraser field, then pushes the slot onto the todo list for later reuse. - val childrenEraser = getEraser(freshEnvironment, ChildrenEraser) - val eraser = ConstantGlobal(freshName("eraser")) - val eraserFieldPtr = LocalReference(PointerType(), freshName("eraserPointer")) - defineFunction(eraser.name, List(Parameter(objectType, "object"))) { - emit(Comment(s"object eraser, ${freshEnvironment.length} free variables")) - emit(GetElementPtr(eraserFieldPtr.name, slotType, LocalReference(objectType, "object"), List(0, 1))) - emit(Store(eraserFieldPtr, childrenEraser, Object)) - emit(Call("", Ccc(), VoidType(), ConstantGlobal("pushOntoTodoList"), List(LocalReference(objectType, "object")))) - RetVoid() - } - eraser - case ChildrenEraser => - // Called by @acquire when a slot is popped from the todo list. - // Loads the object's environment and erases each heap-typed child (Pos, Neg, Stack). - val eraser = ConstantGlobal(freshName("eraser")) - defineFunction(eraser.name, List(Parameter(objectType, "object"))) { - emit(Comment(s"children eraser, ${freshEnvironment.length} free variables")) - val environmentRef = LocalReference(environmentType, freshName("environment")) - emit(Call(environmentRef.name, Ccc(), environmentType, ConstantGlobal("objectEnvironment"), List(LocalReference(objectType, "object")))) - loadObjectEnvironmentAt(environmentRef, freshEnvironment) - eraseValues(freshEnvironment, Set()) - RetVoid() - } - eraser - case StackEraser | StackFrameEraser => - val eraser = ConstantGlobal(freshName("eraser")); - defineFunction(eraser.name, List(Parameter(stackPointerType, "stackPointer"))) { - emit(Comment(s"${kind} eraser, ${freshEnvironment.length} free variables")) + def popReturnAddressFrom(stack: Operand, returnAddressName: String)(using ModuleContext, FunctionContext, BlockContext): Unit = { - val nextStackPointer = LocalReference(stackPointerType, freshName("stackPointer")); - emit(GetElementPtr(nextStackPointer.name, environmentType(freshEnvironment), LocalReference(stackPointerType, "stackPointer"), List(-1))); + val stackPointer = LocalReference(stackPointerType, freshName("stackPointer")); + // TODO properly find size + val size = ConstantInt(24); + emit(Call(stackPointer.name, Ccc(), stackPointer.tpe, stackDeallocate, List(stack, size))); - loadEnvironmentAt(nextStackPointer, freshEnvironment, StackPointer) + val returnAddressPointer = LocalReference(PointerType(), freshName("returnAddress_pointer")); + emit(GetElementPtr(returnAddressPointer.name, frameHeaderType, stackPointer, List(0, 0))); - eraseValues(freshEnvironment, Set()); - val next = if (kind == StackEraser) freeStack else eraseFrames // TODO: improve this (in RTS?) - emit(Call("_", Ccc(), VoidType(), next, List(nextStackPointer))); - RetVoid() - }; - eraser - } - }) + emit(Load(returnAddressName, returnAddressType, returnAddressPointer, StackPointer)); } - def getSharer(environment: machine.Environment, kind: SharerKind)(using C: ModuleContext): Operand = { - val types = environment.map{ _.tpe }; - val freshEnvironment = environment.map{ - case machine.Variable(name, tpe) => machine.Variable(freshName(name), tpe) - }; - - C.sharers.getOrElseUpdate((types, kind), { - val sharer = ConstantGlobal(freshName("sharer")); - defineFunction(sharer.name, List(Parameter(stackPointerType, "stackPointer"))) { - emit(Comment(s"${kind} sharer, ${freshEnvironment.length} free variables")) - - val nextStackPointer = LocalReference(stackPointerType, freshName("stackPointer")); - emit(GetElementPtr(nextStackPointer.name, environmentType(freshEnvironment), LocalReference(stackPointerType, "stackPointer"), List(-1))); - loadEnvironmentAt(nextStackPointer, freshEnvironment, StackPointer) - - shareValues(freshEnvironment, Set.from(freshEnvironment)); + def loadEnvironment(environmentPointer: Operand, environment: machine.Environment)(using ModuleContext, FunctionContext, BlockContext): Unit = { + if (environment.isEmpty) { + () + } else { + loadObjectEnvironmentAt(environmentPointer, environment); + } + } - if (kind == StackFrameSharer) // TODO: improve this (in RTS?) - emit(Call("_", Ccc(), VoidType(), shareFrames, List(nextStackPointer))); - RetVoid() - } - sharer - }) + def storeEnvironment(environmentPointer: Operand, environment: machine.Environment)(using ModuleContext, FunctionContext, BlockContext): Unit = { + if (environment.isEmpty) { + () + } else { + storeEnvironmentAt(environmentPointer, environment, Object); + } } /** @@ -628,49 +602,6 @@ object Transformer { } } - def pushFrameOnto(stack: Operand, environment: machine.Environment, returnAddressName: String, sharer: Operand, eraser: Operand)(using ModuleContext, FunctionContext, BlockContext) = { - val size = environmentSize(environment); - - val newStack = LocalReference(stackType, freshName("stack")) - emit(Call(newStack.name, Ccc(), stackType, checkLimit, List(stack, ConstantInt(size + 24)))); - setStack(newStack); - - val environmentPointer = LocalReference(stackPointerType, freshName("environmentPointer")); - emit(Call(environmentPointer.name, Ccc(), stackPointerType, stackAllocate, List(newStack, ConstantInt(size)))); - - storeEnvironmentAt(environmentPointer, environment, StackPointer); - - val headerPointer = LocalReference(stackPointerType, freshName("headerPointer")); - emit(Call(headerPointer.name, Ccc(), stackPointerType, stackAllocate, List(newStack, ConstantInt(24)))); - - val returnAddressPointer = LocalReference(PointerType(), freshName("returnAddress_pointer")); - emit(GetElementPtr(returnAddressPointer.name, frameHeaderType, headerPointer, List(0, 0))); - val sharerPointer = LocalReference(PointerType(), freshName("sharer_pointer")); - emit(GetElementPtr(sharerPointer.name, frameHeaderType, headerPointer, List(0, 1))); - val eraserPointer = LocalReference(PointerType(), freshName("eraser_pointer")); - emit(GetElementPtr(eraserPointer.name, frameHeaderType, headerPointer, List(0, 2))); - - emit(Store(returnAddressPointer, ConstantGlobal(returnAddressName), StackPointer)); - emit(Store(sharerPointer, sharer, StackPointer)); - emit(Store(eraserPointer, eraser, StackPointer)); - } - - def popEnvironmentFrom(stack: Operand, environment: machine.Environment)(using ModuleContext, FunctionContext, BlockContext): Unit = { - if (environment.isEmpty) { - () - } else { - val stackPointer = LocalReference(stackPointerType, freshName("stackPointer")); - val size = ConstantInt(environmentSize(environment)); - emit(Call(stackPointer.name, Ccc(), stackPointer.tpe, stackDeallocate, List(stack, size))); - loadEnvironmentAt(stackPointer, environment, StackPointer) - } - } - - def environmentType(environment: machine.Environment): Type = - StructureType(environment.map { - case machine.Variable(_, tpe) => transform(tpe) - }) - def storeEnvironmentAt(pointer: Operand, environment: machine.Environment, alias: AliasInfo)(using ModuleContext, FunctionContext, BlockContext): Unit = { val `type` = environmentType(environment) environment.zipWithIndex.foreach { @@ -711,139 +642,6 @@ object Transformer { } } - def shareValues(values: machine.Environment, freeInBody: Set[machine.Variable])(using FunctionContext, BlockContext): Unit = { - @tailrec - def loop(values: machine.Environment): Unit = { - values match { - case Nil => () - case value :: values => - if values.contains(value) then { - shareValue(value); - loop(values) - } else if freeInBody.contains(value) then { - shareValue(value); - loop(values) - } else { - loop(values) - } - } - }; - loop(values) - } - - def eraseValues(environment: machine.Environment, freeInBody: Set[machine.Variable])(using ModuleContext, FunctionContext, BlockContext): Unit = - environment.foreach { value => - if !freeInBody.contains(value) then eraseValue(value) - } - - def shareValue(value: machine.Variable)(using FunctionContext, BlockContext): Unit = { - Option(value.tpe).collect { - case machine.Positive() => Call("_", Ccc(), VoidType(), sharePositive, List(transform(value))) - case machine.Negative() => Call("_", Ccc(), VoidType(), shareNegative, List(transform(value))) - case machine.Type.Stack() => Call("_", Ccc(), VoidType(), shareResumption, List(transform(value))) - }.map(emit) - } - - def eraseValue(value: machine.Variable)(using FunctionContext, BlockContext): Unit = { - Option(value.tpe).collect { - case machine.Positive() => Call("_", Ccc(), VoidType(), erasePositive, List(transform(value))) - case machine.Negative() => Call("_", Ccc(), VoidType(), eraseNegative, List(transform(value))) - case machine.Type.Stack() => Call("_", Ccc(), VoidType(), eraseResumption, List(transform(value))) - }.map(emit) - } - - def popReturnAddressFrom(stack: Operand, returnAddressName: String)(using ModuleContext, FunctionContext, BlockContext): Unit = { - - val stackPointer = LocalReference(stackPointerType, freshName("stackPointer")); - // TODO properly find size - val size = ConstantInt(24); - emit(Call(stackPointer.name, Ccc(), stackPointer.tpe, stackDeallocate, List(stack, size))); - - val returnAddressPointer = LocalReference(PointerType(), freshName("returnAddress_pointer")); - emit(GetElementPtr(returnAddressPointer.name, frameHeaderType, stackPointer, List(0, 0))); - - emit(Load(returnAddressName, returnAddressType, returnAddressPointer, StackPointer)); - } - - val initializeMemory = ConstantGlobal("initializeMemory"); - val newObject = ConstantGlobal("newObject"); - val objectEnvironment = ConstantGlobal("objectEnvironment"); - - val sharePositive = ConstantGlobal("sharePositive"); - val shareNegative = ConstantGlobal("shareNegative"); - val shareResumption = ConstantGlobal("shareResumption"); - val shareFrames = ConstantGlobal("shareFrames"); - - val eraseObject = ConstantGlobal("eraseObject"); - val erasePositive = ConstantGlobal("erasePositive"); - val eraseNegative = ConstantGlobal("eraseNegative"); - val eraseResumption = ConstantGlobal("eraseResumption"); - val eraseFrames = ConstantGlobal("eraseFrames"); - - val freeStack = ConstantGlobal("freeStack") - - val newReference = ConstantGlobal("newReference") - val getVarPointer = ConstantGlobal("getVarPointer") - - val reset = ConstantGlobal("reset"); - val resume = ConstantGlobal("resume"); - val shift = ConstantGlobal("shift"); - val currentPrompt = ConstantGlobal("currentPrompt"); - val underflowStack = ConstantGlobal("underflowStack"); - val withEmptyStack = ConstantGlobal("withEmptyStack"); - val checkLimit = ConstantGlobal("checkLimit") - val stackAllocate = ConstantGlobal("stackAllocate"); - val stackDeallocate = ConstantGlobal("stackDeallocate"); - - /** - * Extra info in context - */ - class ModuleContext() { - var counter = 0; - var definitions: List[Definition] = List(); - val erasers = mutable.HashMap[(List[machine.Type], EraserKind), Operand](); - val sharers = mutable.HashMap[(List[machine.Type], SharerKind), Operand](); - } - - def emit(definition: Definition)(using C: ModuleContext) = - C.definitions = C.definitions :+ definition - - def freshName(name: String)(using C: ModuleContext): String = { - C.counter = C.counter + 1; - name + "_" + C.counter - } - - class FunctionContext() { - var basicBlocks: List[BasicBlock] = List(); - } - - def emit(basicBlock: BasicBlock)(using C: FunctionContext) = - C.basicBlocks = C.basicBlocks :+ basicBlock - - class BlockContext() { - var stack: Operand = LocalReference(stackType, "stack"); - var instructions: List[Instruction] = List(); - } - - def emit(instruction: Instruction)(using C: BlockContext) = - C.instructions = C.instructions :+ instruction - - def getStack()(using C: BlockContext) = - C.stack - - def setStack(stack: Operand)(using C: BlockContext) = - C.stack = stack; - - val escapeSeqs: Map[Char, String] = Map('\'' -> raw"'", '\"' -> raw"\"", '\\' -> raw"\\", '\n' -> raw"\n", '\t' -> raw"\t", '\r' -> raw"\r") - - def escape(scalaString: String): String = - scalaString.foldLeft(StringBuilder()) { (acc, c) => - escapeSeqs.get(c) match { - case Some(s) => acc ++= s - case None => acc += c - } - }.toString() - /** * if we can fit our object in one single saving block -> Easiest case * Else we have to split our environment into multiple saving slots and reference in a linked list fashion @@ -1045,4 +843,205 @@ object Transformer { case NamedType("Stack") => eraseResumption case _ => ??? } + + def shareValues(values: machine.Environment, freeInBody: Set[machine.Variable])(using FunctionContext, BlockContext): Unit = { + @tailrec + def loop(values: machine.Environment): Unit = { + values match { + case Nil => () + case value :: values => + if values.contains(value) then { + shareValue(value); + loop(values) + } else if freeInBody.contains(value) then { + shareValue(value); + loop(values) + } else { + loop(values) + } + } + }; + loop(values) + } + + def eraseValues(environment: machine.Environment, freeInBody: Set[machine.Variable])(using ModuleContext, FunctionContext, BlockContext): Unit = + environment.foreach { value => + if !freeInBody.contains(value) then eraseValue(value) + } + + def shareValue(value: machine.Variable)(using FunctionContext, BlockContext): Unit = { + Option(value.tpe).collect { + case machine.Positive() => Call("_", Ccc(), VoidType(), sharePositive, List(transform(value))) + case machine.Negative() => Call("_", Ccc(), VoidType(), shareNegative, List(transform(value))) + case machine.Type.Stack() => Call("_", Ccc(), VoidType(), shareResumption, List(transform(value))) + }.map(emit) + } + + def eraseValue(value: machine.Variable)(using FunctionContext, BlockContext): Unit = { + Option(value.tpe).collect { + case machine.Positive() => Call("_", Ccc(), VoidType(), erasePositive, List(transform(value))) + case machine.Negative() => Call("_", Ccc(), VoidType(), eraseNegative, List(transform(value))) + case machine.Type.Stack() => Call("_", Ccc(), VoidType(), eraseResumption, List(transform(value))) + }.map(emit) + } + + def getEraser(environment: machine.Environment, kind: EraserKind)(using C: ModuleContext): Operand = { + val types = environment.map{ _.tpe }; + val freshEnvironment = environment.map{ + case machine.Variable(name, tpe) => machine.Variable(freshName(name), tpe) + }; + + C.erasers.getOrElseUpdate((types, kind), { + kind match { + case ObjectEraser => + // Called by @eraseObject. Stores the ChildrenEraser into the + // slot's eraser field, then pushes the slot onto the todo list for later reuse. + val childrenEraser = getEraser(freshEnvironment, ChildrenEraser) + val eraser = ConstantGlobal(freshName("eraser")) + val eraserFieldPtr = LocalReference(PointerType(), freshName("eraserPointer")) + defineFunction(eraser.name, List(Parameter(objectType, "object"))) { + emit(Comment(s"object eraser, ${freshEnvironment.length} free variables")) + emit(GetElementPtr(eraserFieldPtr.name, slotType, LocalReference(objectType, "object"), List(0, 1))) + emit(Store(eraserFieldPtr, childrenEraser, Object)) + emit(Call("", Ccc(), VoidType(), ConstantGlobal("pushOntoTodoList"), List(LocalReference(objectType, "object")))) + RetVoid() + } + eraser + case ChildrenEraser => + // Called by @acquire when a slot is popped from the todo list. + // Loads the object's environment and erases each heap-typed child (Pos, Neg, Stack). + val eraser = ConstantGlobal(freshName("eraser")) + defineFunction(eraser.name, List(Parameter(objectType, "object"))) { + emit(Comment(s"children eraser, ${freshEnvironment.length} free variables")) + val environmentRef = LocalReference(environmentType, freshName("environment")) + emit(Call(environmentRef.name, Ccc(), environmentType, ConstantGlobal("objectEnvironment"), List(LocalReference(objectType, "object")))) + loadObjectEnvironmentAt(environmentRef, freshEnvironment) + eraseValues(freshEnvironment, Set()) + RetVoid() + } + eraser + case StackEraser | StackFrameEraser => + val eraser = ConstantGlobal(freshName("eraser")); + defineFunction(eraser.name, List(Parameter(stackPointerType, "stackPointer"))) { + emit(Comment(s"${kind} eraser, ${freshEnvironment.length} free variables")) + + val nextStackPointer = LocalReference(stackPointerType, freshName("stackPointer")); + emit(GetElementPtr(nextStackPointer.name, environmentType(freshEnvironment), LocalReference(stackPointerType, "stackPointer"), List(-1))); + + loadEnvironmentAt(nextStackPointer, freshEnvironment, StackPointer) + + eraseValues(freshEnvironment, Set()); + val next = if (kind == StackEraser) freeStack else eraseFrames // TODO: improve this (in RTS?) + emit(Call("_", Ccc(), VoidType(), next, List(nextStackPointer))); + RetVoid() + }; + eraser + } + }) + } + + def getSharer(environment: machine.Environment, kind: SharerKind)(using C: ModuleContext): Operand = { + val types = environment.map{ _.tpe }; + val freshEnvironment = environment.map{ + case machine.Variable(name, tpe) => machine.Variable(freshName(name), tpe) + }; + + C.sharers.getOrElseUpdate((types, kind), { + val sharer = ConstantGlobal(freshName("sharer")); + defineFunction(sharer.name, List(Parameter(stackPointerType, "stackPointer"))) { + emit(Comment(s"${kind} sharer, ${freshEnvironment.length} free variables")) + + val nextStackPointer = LocalReference(stackPointerType, freshName("stackPointer")); + emit(GetElementPtr(nextStackPointer.name, environmentType(freshEnvironment), LocalReference(stackPointerType, "stackPointer"), List(-1))); + loadEnvironmentAt(nextStackPointer, freshEnvironment, StackPointer) + + shareValues(freshEnvironment, Set.from(freshEnvironment)); + + if (kind == StackFrameSharer) // TODO: improve this (in RTS?) + emit(Call("_", Ccc(), VoidType(), shareFrames, List(nextStackPointer))); + RetVoid() + } + sharer + }) + } + + val initializeMemory = ConstantGlobal("initializeMemory"); + val newObject = ConstantGlobal("newObject"); + val objectEnvironment = ConstantGlobal("objectEnvironment"); + + val sharePositive = ConstantGlobal("sharePositive"); + val shareNegative = ConstantGlobal("shareNegative"); + val shareResumption = ConstantGlobal("shareResumption"); + val shareFrames = ConstantGlobal("shareFrames"); + + val eraseObject = ConstantGlobal("eraseObject"); + val erasePositive = ConstantGlobal("erasePositive"); + val eraseNegative = ConstantGlobal("eraseNegative"); + val eraseResumption = ConstantGlobal("eraseResumption"); + val eraseFrames = ConstantGlobal("eraseFrames"); + + val freeStack = ConstantGlobal("freeStack") + + val newReference = ConstantGlobal("newReference") + val getVarPointer = ConstantGlobal("getVarPointer") + + val reset = ConstantGlobal("reset"); + val resume = ConstantGlobal("resume"); + val shift = ConstantGlobal("shift"); + val currentPrompt = ConstantGlobal("currentPrompt"); + val underflowStack = ConstantGlobal("underflowStack"); + val withEmptyStack = ConstantGlobal("withEmptyStack"); + val checkLimit = ConstantGlobal("checkLimit") + val stackAllocate = ConstantGlobal("stackAllocate"); + val stackDeallocate = ConstantGlobal("stackDeallocate"); + + /** + * Extra info in context + */ + class ModuleContext() { + var counter = 0; + var definitions: List[Definition] = List(); + val erasers = mutable.HashMap[(List[machine.Type], EraserKind), Operand](); + val sharers = mutable.HashMap[(List[machine.Type], SharerKind), Operand](); + } + + def emit(definition: Definition)(using C: ModuleContext) = + C.definitions = C.definitions :+ definition + + def freshName(name: String)(using C: ModuleContext): String = { + C.counter = C.counter + 1; + name + "_" + C.counter + } + + class FunctionContext() { + var basicBlocks: List[BasicBlock] = List(); + } + + def emit(basicBlock: BasicBlock)(using C: FunctionContext) = + C.basicBlocks = C.basicBlocks :+ basicBlock + + class BlockContext() { + var stack: Operand = LocalReference(stackType, "stack"); + var instructions: List[Instruction] = List(); + } + + def emit(instruction: Instruction)(using C: BlockContext) = + C.instructions = C.instructions :+ instruction + + def getStack()(using C: BlockContext) = + C.stack + + def setStack(stack: Operand)(using C: BlockContext) = + C.stack = stack; + + val escapeSeqs: Map[Char, String] = Map('\'' -> raw"'", '\"' -> raw"\"", '\\' -> raw"\\", '\n' -> raw"\n", '\t' -> raw"\t", '\r' -> raw"\r") + + def escape(scalaString: String): String = + scalaString.foldLeft(StringBuilder()) { (acc, c) => + escapeSeqs.get(c) match { + case Some(s) => acc ++= s + case None => acc += c + } + }.toString() + } From 26e82528d23e984c1c6e2a37e7b994362724c4dd Mon Sep 17 00:00:00 2001 From: Philipp Schuster Date: Thu, 5 Mar 2026 10:21:03 +0100 Subject: [PATCH 26/27] Inline definitions --- .../effekt/generator/llvm/Transformer.scala | 42 +++++++++---------- 1 file changed, 19 insertions(+), 23 deletions(-) diff --git a/effekt/shared/src/main/scala/effekt/generator/llvm/Transformer.scala b/effekt/shared/src/main/scala/effekt/generator/llvm/Transformer.scala index 7033c81a9..db54a64fb 100644 --- a/effekt/shared/src/main/scala/effekt/generator/llvm/Transformer.scala +++ b/effekt/shared/src/main/scala/effekt/generator/llvm/Transformer.scala @@ -550,22 +550,6 @@ object Transformer { emit(Load(returnAddressName, returnAddressType, returnAddressPointer, StackPointer)); } - def loadEnvironment(environmentPointer: Operand, environment: machine.Environment)(using ModuleContext, FunctionContext, BlockContext): Unit = { - if (environment.isEmpty) { - () - } else { - loadObjectEnvironmentAt(environmentPointer, environment); - } - } - - def storeEnvironment(environmentPointer: Operand, environment: machine.Environment)(using ModuleContext, FunctionContext, BlockContext): Unit = { - if (environment.isEmpty) { - () - } else { - storeEnvironmentAt(environmentPointer, environment, Object); - } - } - /** * Produces an Object. It is always ${slotSize} bytes long */ @@ -584,9 +568,13 @@ object Transformer { () } else { // Step 01: We load the variables of the environment such that the continuation can continue - val environmentReference = LocalReference(environmentType, freshName("environment")); - emit(Call(environmentReference.name, Ccc(), environmentType, objectEnvironment, List(`object`))); - loadEnvironment(environmentReference, environment) + val environmentPointer = LocalReference(environmentType, freshName("environment")); + emit(Call(environmentPointer.name, Ccc(), environmentType, objectEnvironment, List(`object`))); + if (environment.isEmpty) { + () + } else { + loadObjectEnvironmentAt(environmentPointer, environment); + } // Step 02: we create the release function for this object val release = ConstantGlobal(freshName("release")); @@ -705,7 +693,11 @@ object Transformer { emit(Call(lastObjectReference.name, Ccc(), objectType, newObject, List(lastEraser, lastSize))) emit(Call(lastEnvPtr.name, Ccc(), environmentType, objectEnvironment, List(lastObjectReference))) shareValues(lastEnvironment, freeInBody) - storeEnvironment(lastEnvPtr, lastEnvironment) + if (environment.isEmpty) { + () + } else { + storeEnvironmentAt(lastEnvPtr, lastEnvironment, Object); + } // Chain preceding blocks, each storing a boxed link to the next object var headObject: LocalReference = lastObjectReference @@ -733,14 +725,18 @@ object Transformer { */ private def produceSingleObject(role: String, environment: machine.Environment, freeInBody: Set[machine.Variable])(using ModuleContext, FunctionContext, BlockContext): LocalReference = { val objectReference = LocalReference(objectType, freshName(role)) - val environmentReference = LocalReference(environmentType, freshName("environment")) + val environmentPointer = LocalReference(environmentType, freshName("environment")) val size = ConstantInt(environmentSize(environment)) val eraser = getEraser(environment, ObjectEraser) emit(Call(objectReference.name, Ccc(), objectType, newObject, List(eraser, size))); - emit(Call(environmentReference.name, Ccc(), environmentType, objectEnvironment, List(objectReference))); + emit(Call(environmentPointer.name, Ccc(), environmentType, objectEnvironment, List(objectReference))); shareValues(environment, freeInBody); - storeEnvironment(environmentReference, environment); + if (environment.isEmpty) { + () + } else { + storeEnvironmentAt(environmentPointer, environment, Object); + } objectReference } From 5669780032df1d647b16f3ab398b6ca03b0769b6 Mon Sep 17 00:00:00 2001 From: Philipp Schuster Date: Thu, 5 Mar 2026 11:09:47 +0100 Subject: [PATCH 27/27] More refactoring --- .../effekt/generator/llvm/Transformer.scala | 246 +++++++++--------- 1 file changed, 123 insertions(+), 123 deletions(-) diff --git a/effekt/shared/src/main/scala/effekt/generator/llvm/Transformer.scala b/effekt/shared/src/main/scala/effekt/generator/llvm/Transformer.scala index db54a64fb..754e543d1 100644 --- a/effekt/shared/src/main/scala/effekt/generator/llvm/Transformer.scala +++ b/effekt/shared/src/main/scala/effekt/generator/llvm/Transformer.scala @@ -35,9 +35,9 @@ object Transformer { } // context getters - private def MC(using MC: ModuleContext): ModuleContext = MC - private def FC(using FC: FunctionContext): FunctionContext = FC - private def BC(using BC: BlockContext): BlockContext = BC + def MC(using MC: ModuleContext): ModuleContext = MC + def FC(using FC: FunctionContext): FunctionContext = FC + def BC(using BC: BlockContext): BlockContext = BC def transform(declaration: machine.Declaration)(using ErrorReporter): Definition = declaration match { @@ -87,7 +87,7 @@ object Transformer { case machine.Construct(variable, tag, values, rest) => emit(Comment(s"construct ${variable.name}, tag ${tag}, ${values.length} values")) - val fields = produceObject("fields", values, freeVariables(rest)) + val fields = produceObject(values, freeVariables(rest)) val temporaryName = freshName(variable.name + "_temporary") emit(InsertValue(temporaryName, ConstantAggregateZero(positiveType), ConstantInt(tag), 0)) emit(InsertValue(variable.name, LocalReference(positiveType, temporaryName), fields, 1)) @@ -157,7 +157,7 @@ object Transformer { val vtableName = freshName("vtable") emit(GlobalConstant(vtableName, ConstantArray(methodType, clauseNames))) - val vtable = produceObject("closure", closureEnvironment, freeVariables(rest)); + val vtable = produceObject(closureEnvironment, freeVariables(rest)); val temporaryName = freshName("vtable_temporary"); emit(InsertValue(temporaryName, ConstantAggregateZero(negativeType), ConstantGlobal(vtableName), 0)); emit(InsertValue(variable.name, LocalReference(negativeType, temporaryName), vtable, 1)); @@ -550,59 +550,122 @@ object Transformer { emit(Load(returnAddressName, returnAddressType, returnAddressPointer, StackPointer)); } + /** + * if we can fit our object in one single saving block -> Easiest case + * Else we have to split our environment into multiple slots and reference in a linked list fashion + */ + def fitsInOneSlot(environment: machine.Environment): Boolean = { + environmentSize(environment) > 0 && environmentSize(environment) <= 48 + } + /** * Produces an Object. It is always ${slotSize} bytes long */ - def produceObject(role: String, environment: machine.Environment, freeInBody: Set[machine.Variable])(using ModuleContext, FunctionContext, BlockContext): Operand = { + def produceObject(environment: machine.Environment, freeInBody: Set[machine.Variable])(using ModuleContext, FunctionContext, BlockContext): Operand = { if (environment.isEmpty) { ConstantNull(objectType) - } else if (fitsInOneSavingSlot(environment)) { - produceSingleObject(role, environment, freeInBody) + } else if (fitsInOneSlot(environment)) { + produceSingleObject(environment, freeInBody) } else { - produceShardedObject(role, environment, freeInBody) + produceShardedObject(environment, freeInBody) } } def consumeObject(`object`: LocalReference, environment: machine.Environment, freeInBody: Set[machine.Variable])(using ModuleContext, FunctionContext, BlockContext): Unit = { if (environment.isEmpty) { () + } else if (fitsInOneSlot(environment)) { + consumeSingleObject(`object`, environment, freeInBody) } else { - // Step 01: We load the variables of the environment such that the continuation can continue - val environmentPointer = LocalReference(environmentType, freshName("environment")); - emit(Call(environmentPointer.name, Ccc(), environmentType, objectEnvironment, List(`object`))); - if (environment.isEmpty) { - () - } else { - loadObjectEnvironmentAt(environmentPointer, environment); - } + consumeShardedObject(`object`, environment, freeInBody) + } + } - // Step 02: we create the release function for this object - val release = ConstantGlobal(freshName("release")); - defineFunction(release.name, List(Parameter(objectType, "object"))) { - createReleaseFunction(release.name, environment, freeInBody) - } + def produceSingleObject(environment: machine.Environment, freeInBody: Set[machine.Variable])(using ModuleContext, FunctionContext, BlockContext): LocalReference = { + val objectReference = LocalReference(objectType, freshName("object")) + val environmentPointer = LocalReference(environmentType, freshName("environment")) + val size = ConstantInt(environmentSize(environment)) + val eraser = getEraser(environment, ObjectEraser) + + emit(Call(objectReference.name, Ccc(), objectType, newObject, List(eraser, size))); + emit(Call(environmentPointer.name, Ccc(), environmentType, objectEnvironment, List(objectReference))); + shareValues(environment, freeInBody); + storeEnvironmentAt(environmentPointer, environment, Object); - // Step 03: we call the release function - emit(Call("_", Ccc(), VoidType(), release, List(`object`))); + objectReference + } -// shareValues(environment, freeInBody); -// emit(Call("_", Ccc(), VoidType(), eraseObject, List(`object`))); + def consumeSingleObject(`object`: LocalReference, environment: machine.Environment, freeInBody: Set[machine.Variable])(using ModuleContext, FunctionContext, BlockContext): Unit = { + val environmentPointer = LocalReference(environmentType, freshName("environment")) + emit(Call(environmentPointer.name, Ccc(), environmentType, objectEnvironment, List(`object`))) + loadEnvironmentAt(environmentPointer, environment, Object) + val release = ConstantGlobal(freshName("release")) + defineFunction(release.name, List(Parameter(objectType, "object"))) { + createReleaseFunction(release.name, environment, freeInBody) } + emit(Call("_", Ccc(), VoidType(), release, List(`object`))) } - def storeEnvironmentAt(pointer: Operand, environment: machine.Environment, alias: AliasInfo)(using ModuleContext, FunctionContext, BlockContext): Unit = { - val `type` = environmentType(environment) - environment.zipWithIndex.foreach { - case (machine.Variable(name, tpe), i) => - val field = LocalReference(PointerType(), freshName(name + "_pointer")); - emit(GetElementPtr(field.name, `type`, pointer, List(0, i))); - emit(Store(field, transform(machine.Variable(name, tpe)), alias)) + def consumeShardedObject(`object`: LocalReference, environment: machine.Environment, freeInBody: Set[machine.Variable])(using ModuleContext, FunctionContext, BlockContext): Unit = { + val environmentPointer = LocalReference(environmentType, freshName("environment")) + emit(Call(environmentPointer.name, Ccc(), environmentType, objectEnvironment, List(`object`))) + loadObjectEnvironmentAt(environmentPointer, environment) + val release = ConstantGlobal(freshName("release")) + defineFunction(release.name, List(Parameter(objectType, "object"))) { + createReleaseFunction(release.name, environment, freeInBody) + } + emit(Call("_", Ccc(), VoidType(), release, List(`object`))) + } + + /** + * When you have a big object to produce, you shard it into multiple slots instead of one single big slot. + * The end of each slot references to the next one. + * Each slot is 64 byte long + */ + def produceShardedObject(environment: machine.Environment, freeInBody: Set[machine.Variable])(using ModuleContext, FunctionContext, BlockContext): Operand = { + // Split into multiple 64-byte blocks and chain them via a boxed link (%Pos with tag 0 pointing to next %Object) + val shardedEnvironments = splitEnvironment(environment) + + // Allocate the last block first. + val lastEnvironment = shardedEnvironments.last + val lastObjectReference = LocalReference(objectType, freshName("object")) + val lastEnvPtr = LocalReference(environmentType, freshName("environment")) + val lastSize = ConstantInt(environmentSize(lastEnvironment)) + val lastEraser = getEraser(lastEnvironment, ObjectEraser) + + emit(Call(lastObjectReference.name, Ccc(), objectType, newObject, List(lastEraser, lastSize))) + emit(Call(lastEnvPtr.name, Ccc(), environmentType, objectEnvironment, List(lastObjectReference))) + shareValues(lastEnvironment, freeInBody) + if (environment.isEmpty) { + () + } else { + storeEnvironmentAt(lastEnvPtr, lastEnvironment, Object); } + + // Chain preceding blocks, each storing a boxed link to the next object + var headObject: LocalReference = lastObjectReference + + // loop through all shardedEnvironments except the last one in reversed order + shardedEnvironments.init.reverse.foreach { envChunk => + val temporaryName = freshName("link_temporary") + val linkValName = freshName("link") + + // we create a new Positive Object with tag 0... + emit(InsertValue(temporaryName, ConstantAggregateZero(positiveType), ConstantInt(0), 0)) // we create a fake Link Tag 0 that we just use for store a tag in the Pos + emit(InsertValue(linkValName, LocalReference(positiveType, temporaryName), headObject, 1)) + + // ... and inject it into our environment... + val extendedEnv = envChunk :+ machine.Variable(linkValName, machine.Positive()) + + // ...finally, we do the usual behavior when we produce an object + headObject = produceSingleObject(extendedEnv, freeInBody) + } + headObject } def loadObjectEnvironmentAt(elementPointer: Operand, environment: machine.Environment)(using ModuleContext, FunctionContext, BlockContext): Unit = { // if we have a sharded object - if !fitsInOneSavingSlot(environment) then { + if !fitsInOneSlot(environment) then { // Follow chained ${slotSize}-byte blocks created in produceObject val chunkedEnvironments = splitEnvironment(environment) var currentEnvironmentPtr: Operand = elementPointer @@ -631,18 +694,10 @@ object Transformer { } /** - * if we can fit our object in one single saving block -> Easiest case - * Else we have to split our environment into multiple saving slots and reference in a linked list fashion - */ - private def fitsInOneSavingSlot(environment: machine.Environment): Boolean = { - environmentSize(environment) > 0 && environmentSize(environment) <= 48 - } - - /** - * Splits the environment into multiple environment such that you can store one object in multiple saving slots. + * Splits the environment into multiple environment such that you can store one object in multiple slots. * Is required to do fixed-sized-allocation. */ - private def splitEnvironment(environment: machine.Environment): List[machine.Environment] = { + def splitEnvironment(environment: machine.Environment): List[machine.Environment] = { val headerSize = 16 // we use 16 byte for the last saving block only, the others are 32 bytes val linkSize = 16 // how much bytes we need to store the link to the next block (%Pos object) @@ -674,83 +729,8 @@ object Transformer { result.reverse } - /** - * When you have a big object to produce, you shard it into multiple slots instead of one single big slot. - * The end of each slot references to the next one. - * Each slot is 64 byte long - */ - private def produceShardedObject(role: String, environment: machine.Environment, freeInBody: Set[machine.Variable])(using ModuleContext, FunctionContext, BlockContext): Operand = { - // Split into multiple 64-byte blocks and chain them via a boxed link (%Pos with tag 0 pointing to next %Object) - val shardedEnvironments = splitEnvironment(environment) - // Allocate the last block first. - val lastEnvironment = shardedEnvironments.last - val lastObjectReference = LocalReference(objectType, freshName(role)) - val lastEnvPtr = LocalReference(environmentType, freshName("environment")) - val lastSize = ConstantInt(environmentSize(lastEnvironment)) - val lastEraser = getEraser(lastEnvironment, ObjectEraser) - - emit(Call(lastObjectReference.name, Ccc(), objectType, newObject, List(lastEraser, lastSize))) - emit(Call(lastEnvPtr.name, Ccc(), environmentType, objectEnvironment, List(lastObjectReference))) - shareValues(lastEnvironment, freeInBody) - if (environment.isEmpty) { - () - } else { - storeEnvironmentAt(lastEnvPtr, lastEnvironment, Object); - } - - // Chain preceding blocks, each storing a boxed link to the next object - var headObject: LocalReference = lastObjectReference - - // loop through all shardedEnvironments except the last one in reversed order - shardedEnvironments.init.reverse.foreach { envChunk => - val temporaryName = freshName("link_temporary") - val linkValName = freshName("link") - - // we create a new Positive Object with tag 0... - emit(InsertValue(temporaryName, ConstantAggregateZero(positiveType), ConstantInt(0), 0)) // we create a fake Link Tag 0 that we just use for store a tag in the Pos - emit(InsertValue(linkValName, LocalReference(positiveType, temporaryName), headObject, 1)) - - // ... and inject it into our environment... - val extendedEnv = envChunk :+ machine.Variable(linkValName, machine.Positive()) - - // ...finally, we do the usual behavior when we produce an object - headObject = produceSingleObject(role, extendedEnv, freeInBody) - } - headObject - } - - /** - * Creates a new object and stores its environment in it - */ - private def produceSingleObject(role: String, environment: machine.Environment, freeInBody: Set[machine.Variable])(using ModuleContext, FunctionContext, BlockContext): LocalReference = { - val objectReference = LocalReference(objectType, freshName(role)) - val environmentPointer = LocalReference(environmentType, freshName("environment")) - val size = ConstantInt(environmentSize(environment)) - val eraser = getEraser(environment, ObjectEraser) - - emit(Call(objectReference.name, Ccc(), objectType, newObject, List(eraser, size))); - emit(Call(environmentPointer.name, Ccc(), environmentType, objectEnvironment, List(objectReference))); - shareValues(environment, freeInBody); - if (environment.isEmpty) { - () - } else { - storeEnvironmentAt(environmentPointer, environment, Object); - } - objectReference - } - - private def loadEnvironmentAt(pointer: Operand, environment: machine.Environment, alias: AliasInfo)(using ModuleContext, FunctionContext, BlockContext): Unit = { - val typ = environmentType(environment) - environment.zipWithIndex.foreach { - case (machine.Variable(name, tpe), i) => - val field = LocalReference(PointerType(), freshName(name + "_pointer")) - emit(GetElementPtr(field.name, typ, pointer, List(0, i))) - emit(Load(name, transform(tpe), field, alias)) - } - } - - private def createReleaseFunction(releaseLabel: String, environment: machine.Environment, freeInBody: Set[machine.Variable])(using ModuleContext, FunctionContext, BlockContext): Terminator = { + def createReleaseFunction(releaseLabel: String, environment: machine.Environment, freeInBody: Set[machine.Variable])(using ModuleContext, FunctionContext, BlockContext): Terminator = { val pushOntoFreeListLabel = freshName("pushOntoFreeList") val shareChildrenAndEraseLabel = freshName("shareChildrenAndErase") val objectReference = LocalReference(objectType, "object") @@ -779,7 +759,7 @@ object Transformer { * It might be that an object consists of several slots. * Each slot is pushed onto the free list. */ - private def createReleasePushOntoFreeListBasicBlock(releaseLabel: String, environment: machine.Environment, freeInBody: Set[machine.Variable], `object`: Operand, environmentRef: LocalReference)(using ModuleContext, FunctionContext, BlockContext): Unit = { + def createReleasePushOntoFreeListBasicBlock(releaseLabel: String, environment: machine.Environment, freeInBody: Set[machine.Variable], `object`: Operand, environmentRef: LocalReference)(using ModuleContext, FunctionContext, BlockContext): Unit = { implicit val BC = BlockContext() emit(Call("_", Ccc(), VoidType(), ConstantGlobal("pushOntoFreeList"), List(`object`))) var currentEnvironmentPtr: Operand = environmentRef @@ -822,7 +802,7 @@ object Transformer { emit(BasicBlock(releaseLabel, BC.instructions, RetVoid())) } - private def createReleaseShareChildrenAndEraseBasicBlock(label: String, environment: machine.Environment, freeInBody: Set[machine.Variable], `object`: Operand, environmentRef: LocalReference)(using ModuleContext, FunctionContext, BlockContext): Unit = { + def createReleaseShareChildrenAndEraseBasicBlock(label: String, environment: machine.Environment, freeInBody: Set[machine.Variable], `object`: Operand, environmentRef: LocalReference)(using ModuleContext, FunctionContext, BlockContext): Unit = { implicit val BC = BlockContext() loadObjectEnvironmentAt(environmentRef, environment) shareValues(environment, freeInBody) @@ -833,13 +813,33 @@ object Transformer { /** * Loads the right erasing function for the given type */ - private def getErasingFunctionForType(tpe: Type) = tpe match { + def getErasingFunctionForType(tpe: Type) = tpe match { case NamedType("Pos") => erasePositive case NamedType("Neg") => eraseNegative case NamedType("Stack") => eraseResumption case _ => ??? } + def storeEnvironmentAt(pointer: Operand, environment: machine.Environment, alias: AliasInfo)(using ModuleContext, FunctionContext, BlockContext): Unit = { + val `type` = environmentType(environment) + environment.zipWithIndex.foreach { + case (machine.Variable(name, tpe), i) => + val field = LocalReference(PointerType(), freshName(name + "_pointer")); + emit(GetElementPtr(field.name, `type`, pointer, List(0, i))); + emit(Store(field, transform(machine.Variable(name, tpe)), alias)) + } + } + + def loadEnvironmentAt(pointer: Operand, environment: machine.Environment, alias: AliasInfo)(using ModuleContext, FunctionContext, BlockContext): Unit = { + val typ = environmentType(environment) + environment.zipWithIndex.foreach { + case (machine.Variable(name, tpe), i) => + val field = LocalReference(PointerType(), freshName(name + "_pointer")) + emit(GetElementPtr(field.name, typ, pointer, List(0, i))) + emit(Load(name, transform(tpe), field, alias)) + } + } + def shareValues(values: machine.Environment, freeInBody: Set[machine.Variable])(using FunctionContext, BlockContext): Unit = { @tailrec def loop(values: machine.Environment): Unit = {