Skip to content

Examples

Each example shows a small Haskell module and its intermediate programs. Select a tab to see the program in that language.

The manual build compiles each example with the compiler libraries of the same commit. Thus, the output on this page always agrees with the compiler of this version of the manual. If the compiler cannot compile an example, the manual build fails. The compiler made these programs at the default optimization level. The Lir is for the target linux-amd64.

The Haskell sources are in the directory docs/aihc-manual/pipeline-examples. To add an example, add a directory with an Example.hs file and a description.md file. An example can use the types of GHC.Types, but not the Prelude.

A polymorphic function

twice applies a function two times. In System FC, a Λ binds the type variable a as an explicit type parameter.

module Example where

twice :: (a -> a) -> a -> a
twice f x = f (f x)
scope 1 = "" Example
scope 2 = "aihc-prim" GHC.Types

import headers
  constructors [2.cLifted, 2.cUnlifted] 2.tLevity :: sType;
  2.sLiftedRep :: tRuntimeRep;
  constructors [2.cAddrRep, 2.cBoxedRep, 2.cDoubleRep, 2.cFloatRep, 2.cInt16Rep, 2.cInt32Rep, 2.cInt64Rep, 2.cInt8Rep, 2.cIntRep, 2.cSumRep, 2.cTupleRep, 2.cVecRep, 2.cWord16Rep, 2.cWord32Rep, 2.cWord64Rep, 2.cWord8Rep, 2.cWordRep] 2.tRuntimeRep :: sType;
  2.tTYPE :: ∀(rep : tRuntimeRep). sType;
  2.sType :: sType;
  2.cBoxedRep :: tLevity → tRuntimeRep;
  2.cLifted :: tLevity

import synonyms
  2.sLiftedRep = cBoxedRep cLifted;
  2.sType = tTYPE sLiftedRep

pub val 1.vtwice :: ∀(a : sType). (a → a) → a → a
  = Λ(a : sType). λ(x : a → a) (y : a).
    x (x y)
scope 1 = "" Example

pub global 1.twice = (P1.$twice$p_p$p/2)

1.$twice_argument_thunk (x :: BoxedRep Lifted) (y :: BoxedRep Lifted) -> BoxedRep Lifted =
  function_whnf :: BoxedRep Lifted <-
    eval @(BoxedRep Lifted) (x :: BoxedRep Lifted)
  apply @(BoxedRep Lifted) (function_whnf :: BoxedRep Lifted) (y :: BoxedRep Lifted)

pub 1.$twice$p_p$p (x :: BoxedRep Lifted) (y :: BoxedRep Lifted) -> BoxedRep Lifted =
  function_whnf :: BoxedRep Lifted <-
    eval @(BoxedRep Lifted) (x :: BoxedRep Lifted)
  argument :: BoxedRep Lifted <-
    store (F1.$twice_argument_thunk (x :: BoxedRep Lifted) (y :: BoxedRep Lifted))
  apply @(BoxedRep Lifted) (function_whnf :: BoxedRep Lifted) (argument :: BoxedRep Lifted)
extern func @aihc_heap_collect_replay(ptr, i64, i64, ptr, ptr, i64) -> i64 cc c

extern func @aihc_lir_apply_p(ptr, ptr, ptr, ptr, ptr, ptr)

extern func @aihc_lir_eval(ptr, ptr, ptr, ptr, ptr)

extern func @aihc_lir_resume(ptr, ptr)

extern func @aihc_replay_suspend(ptr, ptr) -> ptr cc c

extern func @aihc_stack_grow(ptr, ptr, i64, ptr) -> ptr cc c

extern data @aihc_lir_cps_update_info

func @aihc_f__Example___stwice__uargument__uthunk(%hp_0: ptr, %sp_1: ptr, %base_2: ptr, %thunk_6: ptr, %$cps_return_5: ptr) {
entry:
  %stored_7 = load ptr [%thunk_6 + 16] align 8 region heap
  %stored_8 = load ptr [%thunk_6 + 24] align 8 region heap
  jump eval_check_9(%stored_7)

eval_check_9(%current_12: ptr):
  %header_word_13 = load.dependent i64 [%current_12] region heap
  %info_word_14 = and i64 %header_word_13, -4
  %header_15 = ptr.from_int %info_word_14
  %needs_eval_16 = load.invariant i8 [%header_15 + 44] align 1
  %needs_eval_17 = zext i8 %needs_eval_16 to i64
  %not_value_18 = ne i64 %needs_eval_17, 0
  br %not_value_18, eval_not_value_19, eval_ready_10

cold eval_not_value_19:
  %indirection_23 = eq i64 %needs_eval_17, 2
  br %indirection_23, eval_follow_20, eval_thunk_21

cold eval_thunk_21:
  %tag_24 = and i64 %header_word_13, 3
  %claimed_25 = eq i64 %tag_24, 1
  br %claimed_25, eval_owner_22, eval_slow_11

cold eval_owner_22:
  %word_26 = load.dependent ptr [%current_12 + 8] region heap
  %header_word_27 = load.dependent i64 [%word_26] region heap
  %info_word_28 = and i64 %header_word_27, -4
  %header_29 = ptr.from_int %info_word_28
  %word_kind_30 = load.invariant i8 [%header_29 + 43] align 1
  %word_kind_31 = zext i8 %word_kind_30 to i64
  %thread_32 = eq i64 %word_kind_31, 7
  %queue_33 = eq i64 %word_kind_31, 15
  %owned_34 = or i1 %thread_32, %queue_33
  br %owned_34, eval_slow_11, eval_check_9(%word_26)

cold eval_follow_20:
  %next_35 = load.dependent ptr [%current_12 + 8] region heap
  jump eval_check_9(%next_35)

eval_ready_10:
  tailcall @aihc_f__Example___stwice__uargument__uthunk__ucont(%hp_0, %sp_1, %base_2, %$cps_return_5, %stored_8, %current_12)

eval_slow_11:
  %tag_40 = and i64 %header_word_13, 1
  %unclaimed_41 = eq i64 %tag_40, 0
  br %unclaimed_41, force_thunk_36, force_helper_39

force_thunk_36:
  %kind_42 = load.invariant i8 [%header_15 + 43] align 1
  %kind_43 = zext i8 %kind_42 to i64
  %thunk_44 = eq i64 %kind_43, 2
  br %thunk_44, force_stack_37, force_helper_39

force_stack_37:
  %sp_45 = ptr.add %sp_1, 48
  %sp_limit_46 = load ptr [%base_2 + 88] align 1 word
  %stack_fits_47 = le.u ptr %sp_45, %sp_limit_46
  %hp_limit_48 = load ptr [%base_2 + 24] align 1 word
  %heap_fits_49 = le.u ptr %hp_0, %hp_limit_48
  %fits_50 = and i1 %stack_fits_47, %heap_fits_49
  br %fits_50, force_enter_38, force_helper_39

cold force_helper_39:
  tailcall @aihc_lir_force_pp(%hp_0, %sp_1, %base_2, %current_12, @aihc_lir_info_3, %$cps_return_5, %stored_8)

force_enter_38:
  store ptr @aihc_lir_info_3, [%sp_1] align 8 region stack
  store ptr %$cps_return_5, [%sp_1 + 8] align 8 region stack
  store ptr %stored_8, [%sp_1 + 16] align 8 region stack
  %update_51 = ptr.add %sp_1, 24
  store ptr @aihc_lir_cps_update_info, [%update_51] align 8 region stack
  store ptr %sp_1, [%update_51 + 8] align 8 region stack
  store ptr %current_12, [%update_51 + 16] align 8 region stack
  %entry_52 = load.invariant code [%header_15 + 24] align 1 word
  tailcall.indirect %entry_52(%hp_0, %sp_45, %base_2, %current_12, %update_51) : (ptr, ptr, ptr, ptr, ptr)
}

export func @aihc_f__Example___stwice__sp__up__sp(%hp_53: ptr, %sp_54: ptr, %base_55: ptr, %x_56: ptr, %y_57: ptr, %$cps_return_58: ptr) {
entry:
  jump eval_check_59(%x_56)

eval_check_59(%current_62: ptr):
  %header_word_63 = load.dependent i64 [%current_62] region heap
  %info_word_64 = and i64 %header_word_63, -4
  %header_65 = ptr.from_int %info_word_64
  %needs_eval_66 = load.invariant i8 [%header_65 + 44] align 1
  %needs_eval_67 = zext i8 %needs_eval_66 to i64
  %not_value_68 = ne i64 %needs_eval_67, 0
  br %not_value_68, eval_not_value_69, eval_ready_60

cold eval_not_value_69:
  %indirection_73 = eq i64 %needs_eval_67, 2
  br %indirection_73, eval_follow_70, eval_thunk_71

cold eval_thunk_71:
  %tag_74 = and i64 %header_word_63, 3
  %claimed_75 = eq i64 %tag_74, 1
  br %claimed_75, eval_owner_72, eval_slow_61

cold eval_owner_72:
  %word_76 = load.dependent ptr [%current_62 + 8] region heap
  %header_word_77 = load.dependent i64 [%word_76] region heap
  %info_word_78 = and i64 %header_word_77, -4
  %header_79 = ptr.from_int %info_word_78
  %word_kind_80 = load.invariant i8 [%header_79 + 43] align 1
  %word_kind_81 = zext i8 %word_kind_80 to i64
  %thread_82 = eq i64 %word_kind_81, 7
  %queue_83 = eq i64 %word_kind_81, 15
  %owned_84 = or i1 %thread_82, %queue_83
  br %owned_84, eval_slow_61, eval_check_59(%word_76)

cold eval_follow_70:
  %next_85 = load.dependent ptr [%current_62 + 8] region heap
  jump eval_check_59(%next_85)

eval_ready_60:
  tailcall @aihc_f__Example___stwice__sp__up__sp__ucont(%hp_53, %sp_54, %base_55, %$cps_return_58, %current_62, %y_57, %current_62)

eval_slow_61:
  %tag_90 = and i64 %header_word_63, 1
  %unclaimed_91 = eq i64 %tag_90, 0
  br %unclaimed_91, force_thunk_86, force_helper_89

force_thunk_86:
  %kind_92 = load.invariant i8 [%header_65 + 43] align 1
  %kind_93 = zext i8 %kind_92 to i64
  %thunk_94 = eq i64 %kind_93, 2
  br %thunk_94, force_stack_87, force_helper_89

force_stack_87:
  %sp_95 = ptr.add %sp_54, 56
  %sp_limit_96 = load ptr [%base_55 + 88] align 1 word
  %stack_fits_97 = le.u ptr %sp_95, %sp_limit_96
  %hp_limit_98 = load ptr [%base_55 + 24] align 1 word
  %heap_fits_99 = le.u ptr %hp_53, %hp_limit_98
  %fits_100 = and i1 %stack_fits_97, %heap_fits_99
  br %fits_100, force_enter_88, force_helper_89

cold force_helper_89:
  tailcall @aihc_lir_force_ppp(%hp_53, %sp_54, %base_55, %current_62, @aihc_lir_info_2, %$cps_return_58, %current_62, %y_57)

force_enter_88:
  store ptr @aihc_lir_info_2, [%sp_54] align 8 region stack
  store ptr %$cps_return_58, [%sp_54 + 8] align 8 region stack
  store ptr %current_62, [%sp_54 + 16] align 8 region stack
  store ptr %y_57, [%sp_54 + 24] align 8 region stack
  %update_101 = ptr.add %sp_54, 32
  store ptr @aihc_lir_cps_update_info, [%update_101] align 8 region stack
  store ptr %sp_54, [%update_101 + 8] align 8 region stack
  store ptr %current_62, [%update_101 + 16] align 8 region stack
  %entry_102 = load.invariant code [%header_65 + 24] align 1 word
  tailcall.indirect %entry_102(%hp_53, %sp_95, %base_55, %current_62, %update_101) : (ptr, ptr, ptr, ptr, ptr)
}

func @aihc_f__Example___stwice__uargument__uthunk__ucont(%hp_103: ptr, %sp_104: ptr, %base_105: ptr, %$cps_return_106: ptr, %y_107: ptr, %function_whnf_108: ptr) {
entry:
  %header_word_109 = load i64 [%function_whnf_108] align 8
  %info_word_110 = and i64 %header_word_109, -4
  %header_111 = ptr.from_int %info_word_110
  %kind_112 = load.invariant i8 [%header_111 + 43] align 1
  %kind_113 = zext i8 %kind_112 to i64
  %arity_114 = load.invariant i8 [%header_111 + 41] align 1
  %arity_115 = zext i8 %arity_114 to i64
  %closure_116 = eq i64 %kind_113, 1
  %saturated_117 = eq i64 %arity_115, 1
  %fast_118 = and i1 %closure_116, %saturated_117
  br %fast_118, apply_enter_119, apply_helper_120

cold apply_helper_120:
  tailcall @aihc_lir_apply_p(%hp_103, %sp_104, %base_105, %function_whnf_108, %$cps_return_106, %y_107)

apply_enter_119:
  %entry_121 = load.invariant code [%header_111 + 24] align 1 word
  tailcall.indirect %entry_121(%hp_103, %sp_104, %base_105, %function_whnf_108, %$cps_return_106, %y_107) : (ptr, ptr, ptr, ptr, ptr, ptr)
}

data @aihc_lir_bitmap_0 align 1 = { bytes "\x00\x01\x01\x01\x01" }

data @aihc_f__Example___stwice__sp__up__sp__ucont_ri align 8 = { code @aihc_f__Example___stwice__sp__up__sp__ucont, ptr @aihc_lir_bitmap_0, ptr null, code @aihc_lir_replay_entry_pppp, ptr null, i8 5, i8 1, i8 0, i8 1, i8 0, i8 0, i16 0 }

func @aihc_f__Example___stwice__sp__up__sp__ucont(%hp_122: ptr, %sp_123: ptr, %base_124: ptr, %$cps_return_125: ptr, %x_126: ptr, %y_127: ptr, %function_whnf_128: ptr) {
entry:
  %roots_129 = stack.alloc 32 align 8
  %hp_limit_130 = load ptr [%base_124 + 24] align 1 word
  %heap_end_131 = ptr.add %hp_122, 32
  %heap_fits_132 = le.u ptr %heap_end_131, %hp_limit_130
  br %heap_fits_132, gc_reserved_134(%$cps_return_125, %function_whnf_128, %x_126, %y_127, %hp_122), gc_collect_133

cold gc_collect_133:
  tailcall @aihc_lir_collect_replay_pppp(%hp_122, %sp_123, %base_124, %$cps_return_125, %x_126, %y_127, %function_whnf_128, @aihc_f__Example___stwice__sp__up__sp__ucont_ri, 4)

gc_reserved_134(%$cps_return$gc_135: ptr, %function_whnf$gc_136: ptr, %x$gc_137: ptr, %y$gc_138: ptr, %hp_139: ptr):
  %hp_140 = ptr.add %hp_139, 32
  store ptr @aihc_lir_info_4, [%hp_139] align 8 region heap
  store ptr %x$gc_137, [%hp_139 + 16] align 8 region heap
  store ptr %y$gc_138, [%hp_139 + 24] align 8 region heap
  %header_word_141 = load i64 [%function_whnf$gc_136] align 8
  %info_word_142 = and i64 %header_word_141, -4
  %header_143 = ptr.from_int %info_word_142
  %kind_144 = load.invariant i8 [%header_143 + 43] align 1
  %kind_145 = zext i8 %kind_144 to i64
  %arity_146 = load.invariant i8 [%header_143 + 41] align 1
  %arity_147 = zext i8 %arity_146 to i64
  %closure_148 = eq i64 %kind_145, 1
  %saturated_149 = eq i64 %arity_147, 1
  %fast_150 = and i1 %closure_148, %saturated_149
  br %fast_150, apply_enter_151, apply_helper_152

cold apply_helper_152:
  tailcall @aihc_lir_apply_p(%hp_140, %sp_123, %base_124, %function_whnf$gc_136, %$cps_return$gc_135, %hp_139)

apply_enter_151:
  %entry_153 = load.invariant code [%header_143 + 24] align 1 word
  tailcall.indirect %entry_153(%hp_140, %sp_123, %base_124, %function_whnf$gc_136, %$cps_return$gc_135, %hp_139) : (ptr, ptr, ptr, ptr, ptr, ptr)
}

export data mut @_Example_twice align 8 = { ptr @aihc_lir_info_0 }

data @aihc_lir_bitmap_1 align 1 = { bytes "\x01\x01" }

func @aihc_lir_info_0_e(%hp_154: ptr, %sp_155: ptr, %base_156: ptr, %object_157: ptr, %continuation_158: ptr, %supplied_159: ptr, %supplied_160: ptr) {
entry:
  tailcall @aihc_f__Example___stwice__sp__up__sp(%hp_154, %sp_155, %base_156, %supplied_159, %supplied_160, %continuation_158)
}

data @aihc_lir_info_0 align 8 = { code @aihc_f__Example___stwice__sp__up__sp, ptr @aihc_lir_bitmap_1, ptr @aihc_lir_info_1, code @aihc_lir_info_0_e, ptr null, i8 0, i8 2, i8 0, i8 1, i8 0, i8 1, i16 0 }

func @aihc_lir_info_1_e(%hp_161: ptr, %sp_162: ptr, %base_163: ptr, %object_164: ptr, %continuation_165: ptr, %supplied_166: ptr) {
entry:
  %stored_167 = load ptr [%object_164 + 8] align 8
  tailcall @aihc_f__Example___stwice__sp__up__sp(%hp_161, %sp_162, %base_163, %stored_167, %supplied_166, %continuation_165)
}

data @aihc_lir_info_1 align 8 = { code @aihc_f__Example___stwice__sp__up__sp, ptr @aihc_lir_bitmap_1, ptr null, code @aihc_lir_info_1_e, ptr null, i8 1, i8 1, i8 0, i8 1, i8 0, i8 2, i16 0 }

data @aihc_lir_bitmap_2 align 1 = { bytes "\x01\x01\x01\x01" }

func @aihc_lir_info_2_e(%hp_168: ptr, %sp_169: ptr, %base_170: ptr, %object_171: ptr, %supplied_173: ptr) {
entry:
  %stored_174 = load ptr [%object_171 + 8] align 8
  %stored_175 = load ptr [%object_171 + 16] align 8
  %stored_176 = load ptr [%object_171 + 24] align 8
  tailcall @aihc_f__Example___stwice__sp__up__sp__ucont(%hp_168, %sp_169, %base_170, %stored_174, %stored_175, %stored_176, %supplied_173)
}

data @aihc_lir_info_2 align 8 = { code @aihc_f__Example___stwice__sp__up__sp__ucont, ptr @aihc_lir_bitmap_2, ptr null, code @aihc_lir_info_2_e, ptr null, i8 3, i8 1, i8 1, i8 1, i8 0, i8 4, i16 0 }

data @aihc_lir_bitmap_3 align 1 = { bytes "\x01\x01\x01" }

func @aihc_lir_info_3_e(%hp_177: ptr, %sp_178: ptr, %base_179: ptr, %object_180: ptr, %supplied_182: ptr) {
entry:
  %stored_183 = load ptr [%object_180 + 8] align 8
  %stored_184 = load ptr [%object_180 + 16] align 8
  tailcall @aihc_f__Example___stwice__uargument__uthunk__ucont(%hp_177, %sp_178, %base_179, %stored_183, %stored_184, %supplied_182)
}

data @aihc_lir_info_3 align 8 = { code @aihc_f__Example___stwice__uargument__uthunk__ucont, ptr @aihc_lir_bitmap_3, ptr null, code @aihc_lir_info_3_e, ptr null, i8 2, i8 1, i8 1, i8 1, i8 0, i8 3, i16 0 }

data @aihc_lir_bitmap_4 align 1 = { bytes "\x00\x01\x01" }

data @aihc_lir_info_4 align 8 = { code @aihc_f__Example___stwice__uargument__uthunk, ptr @aihc_lir_bitmap_4, ptr null, code @aihc_f__Example___stwice__uargument__uthunk, ptr null, i8 3, i8 0, i8 0, i8 2, i8 1, i8 4, i16 0 }

func @aihc_lir_collect_replay_pppp(%hp_185: ptr, %sp_186: ptr, %base_187: ptr, %value_188: ptr, %value_189: ptr, %value_190: ptr, %value_191: ptr, %info_192: ptr, %words_193: i64) {
entry:
  %code_194 = load.invariant code [%info_192] align 1 word
  %srt_195 = load.invariant ptr [%info_192 + 32] align 1 word
  %roots_196 = stack.alloc 32 align 8
  store ptr %value_188, [%roots_196] align 8
  store ptr %value_189, [%roots_196 + 8] align 8
  store ptr %value_190, [%roots_196 + 16] align 8
  store ptr %value_191, [%roots_196 + 24] align 8
  store ptr %hp_185, [%base_187 + 16] align 1 word
  store ptr %sp_186, [%base_187 + 32] align 1 word
  %result_197 = call @aihc_heap_collect_replay(%base_187, %words_193, 4, %roots_196, %srt_195, 6)
  %value_198 = load ptr [%roots_196] align 8
  %value_199 = load ptr [%roots_196 + 8] align 8
  %value_200 = load ptr [%roots_196 + 16] align 8
  %value_201 = load ptr [%roots_196 + 24] align 8
  %hp_202 = load ptr [%base_187 + 16] align 1 word
  %suspended_203 = ne i64 %result_197, 0
  br %suspended_203, suspend_204, enter_205

cold suspend_204:
  store ptr %info_192, [%hp_202] align 8 region heap
  store i64 -1, [%hp_202 + 8] align 8 region heap
  store ptr %value_198, [%hp_202 + 16] align 8 region heap
  store ptr %value_199, [%hp_202 + 24] align 8 region heap
  store ptr %value_200, [%hp_202 + 32] align 8 region heap
  store ptr %value_201, [%hp_202 + 40] align 8 region heap
  %hp_206 = ptr.add %hp_202, 48
  store ptr %hp_206, [%base_187 + 16] align 1 word
  store ptr %sp_186, [%base_187 + 32] align 1 word
  %result_207 = call @aihc_replay_suspend(%base_187, %hp_202)
  tailcall @aihc_lir_resume(%base_187, %result_207)

enter_205:
  tailcall.indirect %code_194(%hp_202, %sp_186, %base_187, %value_198, %value_199, %value_200, %value_201) : (ptr, ptr, ptr, ptr, ptr, ptr, ptr)
}

func @aihc_lir_replay_entry_pppp(%hp_208: ptr, %sp_209: ptr, %base_210: ptr, %closure_211: ptr, %continuation_212: ptr) {
entry:
  %index_213 = load i64 [%closure_211 + 8] align 8 region heap
  %argument_214 = load ptr [%closure_211 + 16] align 8 region heap
  %is_continuation_215 = eq i64 %index_213, 0
  %argument_216 = select ptr %is_continuation_215, %continuation_212, %argument_214
  %argument_217 = load ptr [%closure_211 + 24] align 8 region heap
  %is_continuation_218 = eq i64 %index_213, 1
  %argument_219 = select ptr %is_continuation_218, %continuation_212, %argument_217
  %argument_220 = load ptr [%closure_211 + 32] align 8 region heap
  %is_continuation_221 = eq i64 %index_213, 2
  %argument_222 = select ptr %is_continuation_221, %continuation_212, %argument_220
  %argument_223 = load ptr [%closure_211 + 40] align 8 region heap
  %is_continuation_224 = eq i64 %index_213, 3
  %argument_225 = select ptr %is_continuation_224, %continuation_212, %argument_223
  %header_word_226 = load i64 [%closure_211] align 8 region heap
  %info_word_227 = and i64 %header_word_226, -4
  %header_228 = ptr.from_int %info_word_227
  %code_229 = load.invariant code [%header_228] align 1 word
  tailcall.indirect %code_229(%hp_208, %sp_209, %base_210, %argument_216, %argument_219, %argument_222, %argument_225) : (ptr, ptr, ptr, ptr, ptr, ptr, ptr)
}

func @aihc_lir_force_pp(%hp_230: ptr, %sp_231: ptr, %base_232: ptr, %value_233: ptr, %info_234: ptr, %field_235: ptr, %field_236: ptr) {
entry:
  %sp_237 = ptr.add %sp_231, 24
  %sp_limit_238 = load ptr [%base_232 + 88] align 1 word
  %stack_fits_239 = le.u ptr %sp_237, %sp_limit_238
  br %stack_fits_239, stack_pushed_241(%sp_231, %sp_237, %field_235), stack_grow_240

cold stack_grow_240:
  store ptr %hp_230, [%base_232 + 16] align 1 word
  %result_242 = call @aihc_stack_grow(%base_232, %sp_231, 3, %field_235)
  %sp_243 = ptr.add %result_242, 24
  %parent_244 = ptr.add %result_242, -16
  jump stack_pushed_241(%result_242, %sp_243, %parent_244)

stack_pushed_241(%frame_245: ptr, %sp_246: ptr, %parent_247: ptr):
  store ptr %info_234, [%frame_245] align 8 region stack
  store ptr %parent_247, [%frame_245 + 8] align 8 region stack
  store ptr %field_236, [%frame_245 + 16] align 8 region stack
  tailcall @aihc_lir_eval(%hp_230, %sp_246, %base_232, %value_233, %frame_245)
}

func @aihc_lir_force_ppp(%hp_248: ptr, %sp_249: ptr, %base_250: ptr, %value_251: ptr, %info_252: ptr, %field_253: ptr, %field_254: ptr, %field_255: ptr) {
entry:
  %sp_256 = ptr.add %sp_249, 32
  %sp_limit_257 = load ptr [%base_250 + 88] align 1 word
  %stack_fits_258 = le.u ptr %sp_256, %sp_limit_257
  br %stack_fits_258, stack_pushed_260(%sp_249, %sp_256, %field_253), stack_grow_259

cold stack_grow_259:
  store ptr %hp_248, [%base_250 + 16] align 1 word
  %result_261 = call @aihc_stack_grow(%base_250, %sp_249, 4, %field_253)
  %sp_262 = ptr.add %result_261, 32
  %parent_263 = ptr.add %result_261, -16
  jump stack_pushed_260(%result_261, %sp_262, %parent_263)

stack_pushed_260(%frame_264: ptr, %sp_265: ptr, %parent_266: ptr):
  store ptr %info_252, [%frame_264] align 8 region stack
  store ptr %parent_266, [%frame_264 + 8] align 8 region stack
  store ptr %field_254, [%frame_264 + 16] align 8 region stack
  store ptr %field_255, [%frame_264 + 24] align 8 region stack
  tailcall @aihc_lir_eval(%hp_248, %sp_265, %base_250, %value_251, %frame_264)
}

A data type and a pattern match

next matches on the constructors of a data type. In System FC, the equations become one case expression.

module Example where

data Color = Red | Green | Blue

next :: Color -> Color
next Red = Green
next Green = Blue
next Blue = Red
scope 1 = "" Example
scope 2 = "aihc-prim" GHC.Types

import headers
  constructors [2.cLifted, 2.cUnlifted] 2.tLevity :: sType;
  2.sLiftedRep :: tRuntimeRep;
  constructors [2.cAddrRep, 2.cBoxedRep, 2.cDoubleRep, 2.cFloatRep, 2.cInt16Rep, 2.cInt32Rep, 2.cInt64Rep, 2.cInt8Rep, 2.cIntRep, 2.cSumRep, 2.cTupleRep, 2.cVecRep, 2.cWord16Rep, 2.cWord32Rep, 2.cWord64Rep, 2.cWord8Rep, 2.cWordRep] 2.tRuntimeRep :: sType;
  2.tTYPE :: ∀(rep : tRuntimeRep). sType;
  2.sType :: sType;
  2.cBoxedRep :: tLevity → tRuntimeRep;
  2.cLifted :: tLevity

import synonyms
  2.sLiftedRep = cBoxedRep cLifted;
  2.sType = tTYPE sLiftedRep

pub type 1.tColor :: sType {
  pub 1.cRed :: tColor;
  pub 1.cGreen :: tColor;
  pub 1.cBlue :: tColor
}

pub val 1.vnext :: tColor → tColor
  = λ(x : tColor).
    case x of {
      cRed →
        cGreen;
      cGreen →
        cBlue;
      cBlue →
        cRed
    }
scope 1 = "" Example

pub constructor 1.Red []

pub constructor 1.Green%1 []

pub constructor 1.Blue%2 []

pub global 1.next = (P1.$next$p$p/1)

pub 1.$next$p$p (x :: BoxedRep Lifted) -> BoxedRep Lifted =
  case_value :: BoxedRep Lifted <-
    eval @(BoxedRep Lifted) (x :: BoxedRep Lifted)
  case (case_value :: BoxedRep Lifted) as case_value%1 :: BoxedRep Lifted of
    data 1.Red ->
      constant global-ref 1.Green
    data 1.Green%1 ->
      constant global-ref 1.Blue
    data 1.Blue%2 ->
      constant global-ref 1.Red
extern func @aihc_lir_continue_p(ptr, ptr, ptr, ptr, ptr)

extern func @aihc_lir_eval(ptr, ptr, ptr, ptr, ptr)

extern func @aihc_stack_grow(ptr, ptr, i64, ptr) -> ptr cc c

extern data @aihc_lir_cps_update_info

export func @aihc_f__Example___snext__sp__sp(%hp_0: ptr, %sp_1: ptr, %base_2: ptr, %x_3: ptr, %$cps_return_4: ptr) {
entry:
  jump eval_check_5(%x_3)

eval_check_5(%current_8: ptr):
  %header_word_9 = load.dependent i64 [%current_8] region heap
  %info_word_10 = and i64 %header_word_9, -4
  %header_11 = ptr.from_int %info_word_10
  %needs_eval_12 = load.invariant i8 [%header_11 + 44] align 1
  %needs_eval_13 = zext i8 %needs_eval_12 to i64
  %not_value_14 = ne i64 %needs_eval_13, 0
  br %not_value_14, eval_not_value_15, eval_ready_6

cold eval_not_value_15:
  %indirection_19 = eq i64 %needs_eval_13, 2
  br %indirection_19, eval_follow_16, eval_thunk_17

cold eval_thunk_17:
  %tag_20 = and i64 %header_word_9, 3
  %claimed_21 = eq i64 %tag_20, 1
  br %claimed_21, eval_owner_18, eval_slow_7

cold eval_owner_18:
  %word_22 = load.dependent ptr [%current_8 + 8] region heap
  %header_word_23 = load.dependent i64 [%word_22] region heap
  %info_word_24 = and i64 %header_word_23, -4
  %header_25 = ptr.from_int %info_word_24
  %word_kind_26 = load.invariant i8 [%header_25 + 43] align 1
  %word_kind_27 = zext i8 %word_kind_26 to i64
  %thread_28 = eq i64 %word_kind_27, 7
  %queue_29 = eq i64 %word_kind_27, 15
  %owned_30 = or i1 %thread_28, %queue_29
  br %owned_30, eval_slow_7, eval_check_5(%word_22)

cold eval_follow_16:
  %next_31 = load.dependent ptr [%current_8 + 8] region heap
  jump eval_check_5(%next_31)

eval_ready_6:
  tailcall @aihc_f__Example___snext__sp__sp__ucont(%hp_0, %sp_1, %base_2, %$cps_return_4, %current_8)

eval_slow_7:
  %tag_36 = and i64 %header_word_9, 1
  %unclaimed_37 = eq i64 %tag_36, 0
  br %unclaimed_37, force_thunk_32, force_helper_35

force_thunk_32:
  %kind_38 = load.invariant i8 [%header_11 + 43] align 1
  %kind_39 = zext i8 %kind_38 to i64
  %thunk_40 = eq i64 %kind_39, 2
  br %thunk_40, force_stack_33, force_helper_35

force_stack_33:
  %sp_41 = ptr.add %sp_1, 40
  %sp_limit_42 = load ptr [%base_2 + 88] align 1 word
  %stack_fits_43 = le.u ptr %sp_41, %sp_limit_42
  %hp_limit_44 = load ptr [%base_2 + 24] align 1 word
  %heap_fits_45 = le.u ptr %hp_0, %hp_limit_44
  %fits_46 = and i1 %stack_fits_43, %heap_fits_45
  br %fits_46, force_enter_34, force_helper_35

cold force_helper_35:
  tailcall @aihc_lir_force_p(%hp_0, %sp_1, %base_2, %current_8, @aihc_lir_info_1, %$cps_return_4)

force_enter_34:
  store ptr @aihc_lir_info_1, [%sp_1] align 8 region stack
  store ptr %$cps_return_4, [%sp_1 + 8] align 8 region stack
  %update_47 = ptr.add %sp_1, 16
  store ptr @aihc_lir_cps_update_info, [%update_47] align 8 region stack
  store ptr %sp_1, [%update_47 + 8] align 8 region stack
  store ptr %current_8, [%update_47 + 16] align 8 region stack
  %entry_48 = load.invariant code [%header_11 + 24] align 1 word
  tailcall.indirect %entry_48(%hp_0, %sp_41, %base_2, %current_8, %update_47) : (ptr, ptr, ptr, ptr, ptr)
}

func @aihc_f__Example___snext__sp__sp__ucont(%hp_49: ptr, %sp_50: ptr, %base_51: ptr, %$cps_return_52: ptr, %case_value_53: ptr) {
entry:
  %header_word_57 = load i64 [%case_value_53] align 8 region heap
  %info_word_58 = and i64 %header_word_57, -4
  %header_59 = ptr.from_int %info_word_58
  %matches_60 = eq ptr %header_59, @aihc_c__Example_Red_0
  br %matches_60, alt_54, check_61

check_61:
  %matches_62 = eq ptr %header_59, @aihc_c__Example_Green_0
  br %matches_62, alt_55, alt_56

alt_54:
  %header_word_63 = load i64 [%$cps_return_52] align 8 region stack
  %info_word_64 = and i64 %header_word_63, -4
  %header_65 = ptr.from_int %info_word_64
  %entry_66 = load.invariant code [%header_65 + 24] align 1 word
  %forward_69 = eq code %entry_66, null
  br %forward_69, continue_slow_67, continue_enter_68

cold continue_slow_67:
  tailcall @aihc_lir_continue_p(%hp_49, %sp_50, %base_51, %$cps_return_52, @_Example_Green)

continue_enter_68:
  tailcall.indirect %entry_66(%hp_49, %$cps_return_52, %base_51, %$cps_return_52, @_Example_Green) : (ptr, ptr, ptr, ptr, ptr)

alt_55:
  %header_word_70 = load i64 [%$cps_return_52] align 8 region stack
  %info_word_71 = and i64 %header_word_70, -4
  %header_72 = ptr.from_int %info_word_71
  %entry_73 = load.invariant code [%header_72 + 24] align 1 word
  %forward_76 = eq code %entry_73, null
  br %forward_76, continue_slow_74, continue_enter_75

cold continue_slow_74:
  tailcall @aihc_lir_continue_p(%hp_49, %sp_50, %base_51, %$cps_return_52, @_Example_Blue)

continue_enter_75:
  tailcall.indirect %entry_73(%hp_49, %$cps_return_52, %base_51, %$cps_return_52, @_Example_Blue) : (ptr, ptr, ptr, ptr, ptr)

alt_56:
  %header_word_77 = load i64 [%$cps_return_52] align 8 region stack
  %info_word_78 = and i64 %header_word_77, -4
  %header_79 = ptr.from_int %info_word_78
  %entry_80 = load.invariant code [%header_79 + 24] align 1 word
  %forward_83 = eq code %entry_80, null
  br %forward_83, continue_slow_81, continue_enter_82

cold continue_slow_81:
  tailcall @aihc_lir_continue_p(%hp_49, %sp_50, %base_51, %$cps_return_52, @_Example_Red)

continue_enter_82:
  tailcall.indirect %entry_80(%hp_49, %$cps_return_52, %base_51, %$cps_return_52, @_Example_Red) : (ptr, ptr, ptr, ptr, ptr)
}

export data mut @_Example_next align 8 = { ptr @aihc_lir_info_0 }

export data mut @_Example_Red align 8 = { ptr @aihc_c__Example_Red_0 }

export data mut @_Example_Green align 8 = { ptr @aihc_c__Example_Green_0 }

export data mut @_Example_Blue align 8 = { ptr @aihc_c__Example_Blue_0 }

export data @aihc_c__Example_Red_0 align 8 = { ptr @aihc_c__Example_Red_0, ptr null, ptr null, code null, ptr null, i8 0, i8 0, i8 0, i8 0, i8 0, i8 1, i16 0 }

export data @aihc_c__Example_Green_0 align 8 = { ptr @aihc_c__Example_Green_0, ptr null, ptr null, code null, ptr null, i8 0, i8 0, i8 0, i8 0, i8 0, i8 1, i16 1 }

export data @aihc_c__Example_Blue_0 align 8 = { ptr @aihc_c__Example_Blue_0, ptr null, ptr null, code null, ptr null, i8 0, i8 0, i8 0, i8 0, i8 0, i8 1, i16 2 }

data @aihc_lir_bitmap_0 align 1 = { bytes "\x01" }

func @aihc_lir_info_0_e(%hp_84: ptr, %sp_85: ptr, %base_86: ptr, %object_87: ptr, %continuation_88: ptr, %supplied_89: ptr) {
entry:
  tailcall @aihc_f__Example___snext__sp__sp(%hp_84, %sp_85, %base_86, %supplied_89, %continuation_88)
}

data @aihc_lir_info_0 align 8 = { code @aihc_f__Example___snext__sp__sp, ptr @aihc_lir_bitmap_0, ptr null, code @aihc_lir_info_0_e, ptr null, i8 0, i8 1, i8 0, i8 1, i8 0, i8 1, i16 0 }

data @aihc_lir_bitmap_1 align 1 = { bytes "\x01\x01" }

func @aihc_lir_info_1_e(%hp_90: ptr, %sp_91: ptr, %base_92: ptr, %object_93: ptr, %supplied_95: ptr) {
entry:
  %stored_96 = load ptr [%object_93 + 8] align 8
  tailcall @aihc_f__Example___snext__sp__sp__ucont(%hp_90, %sp_91, %base_92, %stored_96, %supplied_95)
}

data @aihc_lir_info_1 align 8 = { code @aihc_f__Example___snext__sp__sp__ucont, ptr @aihc_lir_bitmap_1, ptr null, code @aihc_lir_info_1_e, ptr null, i8 1, i8 1, i8 1, i8 1, i8 0, i8 2, i16 0 }

func @aihc_lir_force_p(%hp_97: ptr, %sp_98: ptr, %base_99: ptr, %value_100: ptr, %info_101: ptr, %field_102: ptr) {
entry:
  %sp_103 = ptr.add %sp_98, 16
  %sp_limit_104 = load ptr [%base_99 + 88] align 1 word
  %stack_fits_105 = le.u ptr %sp_103, %sp_limit_104
  br %stack_fits_105, stack_pushed_107(%sp_98, %sp_103, %field_102), stack_grow_106

cold stack_grow_106:
  store ptr %hp_97, [%base_99 + 16] align 1 word
  %result_108 = call @aihc_stack_grow(%base_99, %sp_98, 2, %field_102)
  %sp_109 = ptr.add %result_108, 16
  %parent_110 = ptr.add %result_108, -16
  jump stack_pushed_107(%result_108, %sp_109, %parent_110)

stack_pushed_107(%frame_111: ptr, %sp_112: ptr, %parent_113: ptr):
  store ptr %info_101, [%frame_111] align 8 region stack
  store ptr %parent_113, [%frame_111 + 8] align 8 region stack
  tailcall @aihc_lir_eval(%hp_97, %sp_112, %base_99, %value_100, %frame_111)
}

A recursive function

append joins two lists. The recursive call is lazy: the tail of the result is not evaluated until a consumer needs it.

module Example where

append :: [a] -> [a] -> [a]
append [] ys = ys
append (x : xs) ys = x : append xs ys
scope 1 = "" Example
scope 2 = "aihc-prim" GHC.Types

import headers
  constructors [2.cLifted, 2.cUnlifted] 2.tLevity :: sType;
  2.sLiftedRep :: tRuntimeRep;
  constructors [2.cAddrRep, 2.cBoxedRep, 2.cDoubleRep, 2.cFloatRep, 2.cInt16Rep, 2.cInt32Rep, 2.cInt64Rep, 2.cInt8Rep, 2.cIntRep, 2.cSumRep, 2.cTupleRep, 2.cVecRep, 2.cWord16Rep, 2.cWord32Rep, 2.cWord64Rep, 2.cWord8Rep, 2.cWordRep] 2.tRuntimeRep :: sType;
  2.tTYPE :: ∀(rep : tRuntimeRep). sType;
  2.sType :: sType;
  constructors [2.c[], 2.c:] 2.t[] :: ∀(a : sType). sType;
  2.c: :: ∀(a : sType). a → t[] a → t[] a;
  2.cBoxedRep :: tLevity → tRuntimeRep;
  2.cLifted :: tLevity;
  2.c[] :: ∀(a : sType). t[] a

import synonyms
  2.sLiftedRep = cBoxedRep cLifted;
  2.sType = tTYPE sLiftedRep

pub val 1.vappend :: ∀(a : sType). t[] a → t[] a → t[] a
  = Λ(a : sType). λ(x : t[] a) (y : t[] a).
    case x of {
      c[] →
        y;
      c: (x{1} : a) (xs : t[] a) →
        c: @a x{1} (vappend @a xs y)
    }
scope 1 = "" Example

scope 2 = "aihc-prim" GHC.Types

pub global 1.append = (P1.$append$p_p$p/2)

pub 1.$append$p_p$p (x :: BoxedRep Lifted) (y :: BoxedRep Lifted) -> BoxedRep Lifted =
  case_value :: BoxedRep Lifted <-
    eval @(BoxedRep Lifted) (x :: BoxedRep Lifted)
  case (case_value :: BoxedRep Lifted) as case_value%1 :: BoxedRep Lifted of
    data 2."[]" ->
      eval @(BoxedRep Lifted) (y :: BoxedRep Lifted)
    data 2.:%1 (x%1 :: BoxedRep Lifted) (xs :: BoxedRep Lifted) ->
      argument :: BoxedRep Lifted <-
        store (F1.$append$p_p$p (xs :: BoxedRep Lifted) (y :: BoxedRep Lifted))
      store (C2.: (x%1 :: BoxedRep Lifted) (argument :: BoxedRep Lifted))
extern func @aihc_heap_collect_replay(ptr, i64, i64, ptr, ptr, i64) -> i64 cc c

extern func @aihc_lir_continue_p(ptr, ptr, ptr, ptr, ptr)

extern func @aihc_lir_eval(ptr, ptr, ptr, ptr, ptr)

extern func @aihc_lir_resume(ptr, ptr)

extern func @aihc_replay_suspend(ptr, ptr) -> ptr cc c

extern func @aihc_stack_grow(ptr, ptr, i64, ptr) -> ptr cc c

extern data @aihc_c_aihc__mprim_GHC__dTypes___k__j_0

extern data @aihc_c_aihc__mprim_GHC__dTypes___o_0

extern data @aihc_lir_cps_update_info

export func @aihc_f__Example___sappend__sp__up__sp(%hp_0: ptr, %sp_1: ptr, %base_2: ptr, %x_3: ptr, %y_4: ptr, %$cps_return_5: ptr) {
entry:
  jump eval_check_6(%x_3)

eval_check_6(%current_9: ptr):
  %header_word_10 = load.dependent i64 [%current_9] region heap
  %info_word_11 = and i64 %header_word_10, -4
  %header_12 = ptr.from_int %info_word_11
  %needs_eval_13 = load.invariant i8 [%header_12 + 44] align 1
  %needs_eval_14 = zext i8 %needs_eval_13 to i64
  %not_value_15 = ne i64 %needs_eval_14, 0
  br %not_value_15, eval_not_value_16, eval_ready_7

cold eval_not_value_16:
  %indirection_20 = eq i64 %needs_eval_14, 2
  br %indirection_20, eval_follow_17, eval_thunk_18

cold eval_thunk_18:
  %tag_21 = and i64 %header_word_10, 3
  %claimed_22 = eq i64 %tag_21, 1
  br %claimed_22, eval_owner_19, eval_slow_8

cold eval_owner_19:
  %word_23 = load.dependent ptr [%current_9 + 8] region heap
  %header_word_24 = load.dependent i64 [%word_23] region heap
  %info_word_25 = and i64 %header_word_24, -4
  %header_26 = ptr.from_int %info_word_25
  %word_kind_27 = load.invariant i8 [%header_26 + 43] align 1
  %word_kind_28 = zext i8 %word_kind_27 to i64
  %thread_29 = eq i64 %word_kind_28, 7
  %queue_30 = eq i64 %word_kind_28, 15
  %owned_31 = or i1 %thread_29, %queue_30
  br %owned_31, eval_slow_8, eval_check_6(%word_23)

cold eval_follow_17:
  %next_32 = load.dependent ptr [%current_9 + 8] region heap
  jump eval_check_6(%next_32)

eval_ready_7:
  tailcall @aihc_f__Example___sappend__sp__up__sp__ucont(%hp_0, %sp_1, %base_2, %$cps_return_5, %y_4, %current_9)

eval_slow_8:
  %tag_37 = and i64 %header_word_10, 1
  %unclaimed_38 = eq i64 %tag_37, 0
  br %unclaimed_38, force_thunk_33, force_helper_36

force_thunk_33:
  %kind_39 = load.invariant i8 [%header_12 + 43] align 1
  %kind_40 = zext i8 %kind_39 to i64
  %thunk_41 = eq i64 %kind_40, 2
  br %thunk_41, force_stack_34, force_helper_36

force_stack_34:
  %sp_42 = ptr.add %sp_1, 48
  %sp_limit_43 = load ptr [%base_2 + 88] align 1 word
  %stack_fits_44 = le.u ptr %sp_42, %sp_limit_43
  %hp_limit_45 = load ptr [%base_2 + 24] align 1 word
  %heap_fits_46 = le.u ptr %hp_0, %hp_limit_45
  %fits_47 = and i1 %stack_fits_44, %heap_fits_46
  br %fits_47, force_enter_35, force_helper_36

cold force_helper_36:
  tailcall @aihc_lir_force_pp(%hp_0, %sp_1, %base_2, %current_9, @aihc_lir_info_2, %$cps_return_5, %y_4)

force_enter_35:
  store ptr @aihc_lir_info_2, [%sp_1] align 8 region stack
  store ptr %$cps_return_5, [%sp_1 + 8] align 8 region stack
  store ptr %y_4, [%sp_1 + 16] align 8 region stack
  %update_48 = ptr.add %sp_1, 24
  store ptr @aihc_lir_cps_update_info, [%update_48] align 8 region stack
  store ptr %sp_1, [%update_48 + 8] align 8 region stack
  store ptr %current_9, [%update_48 + 16] align 8 region stack
  %entry_49 = load.invariant code [%header_12 + 24] align 1 word
  tailcall.indirect %entry_49(%hp_0, %sp_42, %base_2, %current_9, %update_48) : (ptr, ptr, ptr, ptr, ptr)
}

data @aihc_lir_bitmap_0 align 1 = { bytes "\x00\x01\x01\x01" }

data @aihc_f__Example___sappend__sp__up__sp__ucont_ri align 8 = { code @aihc_f__Example___sappend__sp__up__sp__ucont, ptr @aihc_lir_bitmap_0, ptr null, code @aihc_lir_replay_entry_ppp, ptr null, i8 4, i8 1, i8 0, i8 1, i8 0, i8 0, i16 0 }

func @aihc_f__Example___sappend__sp__up__sp__ucont(%hp_50: ptr, %sp_51: ptr, %base_52: ptr, %$cps_return_53: ptr, %y_54: ptr, %case_value_55: ptr) {
entry:
  %roots_56 = stack.alloc 24 align 8
  %hp_limit_57 = load ptr [%base_52 + 24] align 1 word
  %heap_end_58 = ptr.add %hp_50, 56
  %heap_fits_59 = le.u ptr %heap_end_58, %hp_limit_57
  br %heap_fits_59, gc_reserved_61(%$cps_return_53, %case_value_55, %y_54, %hp_50), gc_collect_60

cold gc_collect_60:
  tailcall @aihc_lir_collect_replay_ppp(%hp_50, %sp_51, %base_52, %$cps_return_53, %y_54, %case_value_55, @aihc_f__Example___sappend__sp__up__sp__ucont_ri, 7)

gc_reserved_61(%$cps_return$gc_62: ptr, %case_value$gc_63: ptr, %y$gc_64: ptr, %hp_65: ptr):
  %header_word_68 = load i64 [%case_value$gc_63] align 8 region heap
  %info_word_69 = and i64 %header_word_68, -4
  %header_70 = ptr.from_int %info_word_69
  %matches_71 = eq ptr %header_70, @aihc_c_aihc__mprim_GHC__dTypes___k__j_0
  br %matches_71, alt_66, alt_67

alt_66:
  tailcall @aihc_lir_eval(%hp_65, %sp_51, %base_52, %y$gc_64, %$cps_return$gc_62)

alt_67:
  %x_72 = load ptr [%case_value$gc_63 + 8] align 8 region heap
  %xs_73 = load ptr [%case_value$gc_63 + 16] align 8 region heap
  %hp_74 = ptr.add %hp_65, 32
  store ptr @aihc_lir_info_3, [%hp_65] align 8 region heap
  store ptr %xs_73, [%hp_65 + 16] align 8 region heap
  store ptr %y$gc_64, [%hp_65 + 24] align 8 region heap
  %hp_75 = ptr.add %hp_74, 24
  store ptr @aihc_c_aihc__mprim_GHC__dTypes___o_0, [%hp_74] align 8 region heap
  store ptr %x_72, [%hp_74 + 8] align 8 region heap
  store ptr %hp_65, [%hp_74 + 16] align 8 region heap
  %header_word_76 = load i64 [%$cps_return$gc_62] align 8 region stack
  %info_word_77 = and i64 %header_word_76, -4
  %header_78 = ptr.from_int %info_word_77
  %entry_79 = load.invariant code [%header_78 + 24] align 1 word
  %forward_82 = eq code %entry_79, null
  br %forward_82, continue_slow_80, continue_enter_81

cold continue_slow_80:
  tailcall @aihc_lir_continue_p(%hp_75, %sp_51, %base_52, %$cps_return$gc_62, %hp_74)

continue_enter_81:
  tailcall.indirect %entry_79(%hp_75, %$cps_return$gc_62, %base_52, %$cps_return$gc_62, %hp_74) : (ptr, ptr, ptr, ptr, ptr)
}

export data mut @_Example_append align 8 = { ptr @aihc_lir_info_0 }

data @aihc_lir_bitmap_1 align 1 = { bytes "\x01\x01" }

func @aihc_lir_info_0_e(%hp_83: ptr, %sp_84: ptr, %base_85: ptr, %object_86: ptr, %continuation_87: ptr, %supplied_88: ptr, %supplied_89: ptr) {
entry:
  tailcall @aihc_f__Example___sappend__sp__up__sp(%hp_83, %sp_84, %base_85, %supplied_88, %supplied_89, %continuation_87)
}

data @aihc_lir_info_0 align 8 = { code @aihc_f__Example___sappend__sp__up__sp, ptr @aihc_lir_bitmap_1, ptr @aihc_lir_info_1, code @aihc_lir_info_0_e, ptr null, i8 0, i8 2, i8 0, i8 1, i8 0, i8 1, i16 0 }

func @aihc_lir_info_1_e(%hp_90: ptr, %sp_91: ptr, %base_92: ptr, %object_93: ptr, %continuation_94: ptr, %supplied_95: ptr) {
entry:
  %stored_96 = load ptr [%object_93 + 8] align 8
  tailcall @aihc_f__Example___sappend__sp__up__sp(%hp_90, %sp_91, %base_92, %stored_96, %supplied_95, %continuation_94)
}

data @aihc_lir_info_1 align 8 = { code @aihc_f__Example___sappend__sp__up__sp, ptr @aihc_lir_bitmap_1, ptr null, code @aihc_lir_info_1_e, ptr null, i8 1, i8 1, i8 0, i8 1, i8 0, i8 2, i16 0 }

data @aihc_lir_bitmap_2 align 1 = { bytes "\x01\x01\x01" }

func @aihc_lir_info_2_e(%hp_97: ptr, %sp_98: ptr, %base_99: ptr, %object_100: ptr, %supplied_102: ptr) {
entry:
  %stored_103 = load ptr [%object_100 + 8] align 8
  %stored_104 = load ptr [%object_100 + 16] align 8
  tailcall @aihc_f__Example___sappend__sp__up__sp__ucont(%hp_97, %sp_98, %base_99, %stored_103, %stored_104, %supplied_102)
}

data @aihc_lir_info_2 align 8 = { code @aihc_f__Example___sappend__sp__up__sp__ucont, ptr @aihc_lir_bitmap_2, ptr null, code @aihc_lir_info_2_e, ptr null, i8 2, i8 1, i8 1, i8 1, i8 0, i8 3, i16 0 }

data @aihc_lir_bitmap_3 align 1 = { bytes "\x00\x01\x01" }

func @aihc_lir_info_3_e(%hp_105: ptr, %sp_106: ptr, %base_107: ptr, %object_108: ptr, %continuation_109: ptr) {
entry:
  %stored_110 = load ptr [%object_108 + 16] align 8
  %stored_111 = load ptr [%object_108 + 24] align 8
  tailcall @aihc_f__Example___sappend__sp__up__sp(%hp_105, %sp_106, %base_107, %stored_110, %stored_111, %continuation_109)
}

data @aihc_lir_info_3 align 8 = { code @aihc_f__Example___sappend__sp__up__sp, ptr @aihc_lir_bitmap_3, ptr null, code @aihc_lir_info_3_e, ptr null, i8 3, i8 0, i8 0, i8 2, i8 1, i8 4, i16 0 }

func @aihc_lir_collect_replay_ppp(%hp_112: ptr, %sp_113: ptr, %base_114: ptr, %value_115: ptr, %value_116: ptr, %value_117: ptr, %info_118: ptr, %words_119: i64) {
entry:
  %code_120 = load.invariant code [%info_118] align 1 word
  %srt_121 = load.invariant ptr [%info_118 + 32] align 1 word
  %roots_122 = stack.alloc 24 align 8
  store ptr %value_115, [%roots_122] align 8
  store ptr %value_116, [%roots_122 + 8] align 8
  store ptr %value_117, [%roots_122 + 16] align 8
  store ptr %hp_112, [%base_114 + 16] align 1 word
  store ptr %sp_113, [%base_114 + 32] align 1 word
  %result_123 = call @aihc_heap_collect_replay(%base_114, %words_119, 3, %roots_122, %srt_121, 5)
  %value_124 = load ptr [%roots_122] align 8
  %value_125 = load ptr [%roots_122 + 8] align 8
  %value_126 = load ptr [%roots_122 + 16] align 8
  %hp_127 = load ptr [%base_114 + 16] align 1 word
  %suspended_128 = ne i64 %result_123, 0
  br %suspended_128, suspend_129, enter_130

cold suspend_129:
  store ptr %info_118, [%hp_127] align 8 region heap
  store i64 -1, [%hp_127 + 8] align 8 region heap
  store ptr %value_124, [%hp_127 + 16] align 8 region heap
  store ptr %value_125, [%hp_127 + 24] align 8 region heap
  store ptr %value_126, [%hp_127 + 32] align 8 region heap
  %hp_131 = ptr.add %hp_127, 40
  store ptr %hp_131, [%base_114 + 16] align 1 word
  store ptr %sp_113, [%base_114 + 32] align 1 word
  %result_132 = call @aihc_replay_suspend(%base_114, %hp_127)
  tailcall @aihc_lir_resume(%base_114, %result_132)

enter_130:
  tailcall.indirect %code_120(%hp_127, %sp_113, %base_114, %value_124, %value_125, %value_126) : (ptr, ptr, ptr, ptr, ptr, ptr)
}

func @aihc_lir_replay_entry_ppp(%hp_133: ptr, %sp_134: ptr, %base_135: ptr, %closure_136: ptr, %continuation_137: ptr) {
entry:
  %index_138 = load i64 [%closure_136 + 8] align 8 region heap
  %argument_139 = load ptr [%closure_136 + 16] align 8 region heap
  %is_continuation_140 = eq i64 %index_138, 0
  %argument_141 = select ptr %is_continuation_140, %continuation_137, %argument_139
  %argument_142 = load ptr [%closure_136 + 24] align 8 region heap
  %is_continuation_143 = eq i64 %index_138, 1
  %argument_144 = select ptr %is_continuation_143, %continuation_137, %argument_142
  %argument_145 = load ptr [%closure_136 + 32] align 8 region heap
  %is_continuation_146 = eq i64 %index_138, 2
  %argument_147 = select ptr %is_continuation_146, %continuation_137, %argument_145
  %header_word_148 = load i64 [%closure_136] align 8 region heap
  %info_word_149 = and i64 %header_word_148, -4
  %header_150 = ptr.from_int %info_word_149
  %code_151 = load.invariant code [%header_150] align 1 word
  tailcall.indirect %code_151(%hp_133, %sp_134, %base_135, %argument_141, %argument_144, %argument_147) : (ptr, ptr, ptr, ptr, ptr, ptr)
}

func @aihc_lir_force_pp(%hp_152: ptr, %sp_153: ptr, %base_154: ptr, %value_155: ptr, %info_156: ptr, %field_157: ptr, %field_158: ptr) {
entry:
  %sp_159 = ptr.add %sp_153, 24
  %sp_limit_160 = load ptr [%base_154 + 88] align 1 word
  %stack_fits_161 = le.u ptr %sp_159, %sp_limit_160
  br %stack_fits_161, stack_pushed_163(%sp_153, %sp_159, %field_157), stack_grow_162

cold stack_grow_162:
  store ptr %hp_152, [%base_154 + 16] align 1 word
  %result_164 = call @aihc_stack_grow(%base_154, %sp_153, 3, %field_157)
  %sp_165 = ptr.add %result_164, 24
  %parent_166 = ptr.add %result_164, -16
  jump stack_pushed_163(%result_164, %sp_165, %parent_166)

stack_pushed_163(%frame_167: ptr, %sp_168: ptr, %parent_169: ptr):
  store ptr %info_156, [%frame_167] align 8 region stack
  store ptr %parent_169, [%frame_167 + 8] align 8 region stack
  store ptr %field_158, [%frame_167 + 16] align 8 region stack
  tailcall @aihc_lir_eval(%hp_152, %sp_168, %base_154, %value_155, %frame_167)
}

A type class

The class Default has one method. In System FC, the class becomes a dictionary data type, and the instance becomes a dictionary value.

module Example where

data Switch = Off | On

class Default a where
  def :: a

instance Default Switch where
  def = Off
scope 1 = "" Example
scope 2 = "aihc-prim" GHC.Types

import headers
  constructors [2.cLifted, 2.cUnlifted] 2.tLevity :: sType;
  2.sLiftedRep :: tRuntimeRep;
  constructors [2.cAddrRep, 2.cBoxedRep, 2.cDoubleRep, 2.cFloatRep, 2.cInt16Rep, 2.cInt32Rep, 2.cInt64Rep, 2.cInt8Rep, 2.cIntRep, 2.cSumRep, 2.cTupleRep, 2.cVecRep, 2.cWord16Rep, 2.cWord32Rep, 2.cWord64Rep, 2.cWord8Rep, 2.cWordRep] 2.tRuntimeRep :: sType;
  2.tTYPE :: ∀(rep : tRuntimeRep). sType;
  2.sType :: sType;
  2.cBoxedRep :: tLevity → tRuntimeRep;
  2.cLifted :: tLevity

import synonyms
  2.sLiftedRep = cBoxedRep cLifted;
  2.sType = tTYPE sLiftedRep

pub type 1.tSwitch :: sType {
  pub 1.cOff :: tSwitch;
  pub 1.cOn :: tSwitch
}

pub type 1.t$Dict$Default (a : sType) :: sType {
  pub 1.c$Dict$Default :: ∀(a : sType). a → t$Dict$Default a
}

pub val 1.vdef :: ∀(a : sType). t$Dict$Default a → a
  = Λ(a : sType). λ($dDefault : t$Dict$Default a).
    let! c$Dict$Default ($cdef : a) = $dDefault;
    $cdef

pub val 1.v$fDefaultSwitch :: t$Dict$Default tSwitch
  = c$Dict$Default @tSwitch v$fDefaultSwitch$cdef

val 1.v$fDefaultSwitch$cdef :: tSwitch
  = cOff
scope 1 = "" Example

pub constructor 1.Off []

pub constructor 1.On%1 []

pub constructor 1.$Dict$Default [BoxedRep Lifted]

pub global 1.def = (P1.$def$p$p/1)

pub global 1.$fDefaultSwitch = (C1.$Dict$Default global-ref 1.$fDefaultSwitch$cdef)

global 1.$fDefaultSwitch$cdef = (C1.Off)

pub 1.$def$p$p ($dDefault :: BoxedRep Lifted) -> BoxedRep Lifted =
  case_value :: BoxedRep Lifted <-
    eval @(BoxedRep Lifted) ($dDefault :: BoxedRep Lifted)
  $cdef :: BoxedRep Lifted <-
    fetch (C1.$Dict$Default) (case_value :: BoxedRep Lifted)
  eval @(BoxedRep Lifted) ($cdef :: BoxedRep Lifted)
extern func @aihc_lir_eval(ptr, ptr, ptr, ptr, ptr)

extern func @aihc_stack_grow(ptr, ptr, i64, ptr) -> ptr cc c

extern data @aihc_lir_cps_update_info

export func @aihc_f__Example___sdef__sp__sp(%hp_0: ptr, %sp_1: ptr, %base_2: ptr, %$dDefault_3: ptr, %$cps_return_4: ptr) {
entry:
  jump eval_check_5(%$dDefault_3)

eval_check_5(%current_8: ptr):
  %header_word_9 = load.dependent i64 [%current_8] region heap
  %info_word_10 = and i64 %header_word_9, -4
  %header_11 = ptr.from_int %info_word_10
  %needs_eval_12 = load.invariant i8 [%header_11 + 44] align 1
  %needs_eval_13 = zext i8 %needs_eval_12 to i64
  %not_value_14 = ne i64 %needs_eval_13, 0
  br %not_value_14, eval_not_value_15, eval_ready_6

cold eval_not_value_15:
  %indirection_19 = eq i64 %needs_eval_13, 2
  br %indirection_19, eval_follow_16, eval_thunk_17

cold eval_thunk_17:
  %tag_20 = and i64 %header_word_9, 3
  %claimed_21 = eq i64 %tag_20, 1
  br %claimed_21, eval_owner_18, eval_slow_7

cold eval_owner_18:
  %word_22 = load.dependent ptr [%current_8 + 8] region heap
  %header_word_23 = load.dependent i64 [%word_22] region heap
  %info_word_24 = and i64 %header_word_23, -4
  %header_25 = ptr.from_int %info_word_24
  %word_kind_26 = load.invariant i8 [%header_25 + 43] align 1
  %word_kind_27 = zext i8 %word_kind_26 to i64
  %thread_28 = eq i64 %word_kind_27, 7
  %queue_29 = eq i64 %word_kind_27, 15
  %owned_30 = or i1 %thread_28, %queue_29
  br %owned_30, eval_slow_7, eval_check_5(%word_22)

cold eval_follow_16:
  %next_31 = load.dependent ptr [%current_8 + 8] region heap
  jump eval_check_5(%next_31)

eval_ready_6:
  tailcall @aihc_f__Example___sdef__sp__sp__ucont(%hp_0, %sp_1, %base_2, %$cps_return_4, %current_8)

eval_slow_7:
  %tag_36 = and i64 %header_word_9, 1
  %unclaimed_37 = eq i64 %tag_36, 0
  br %unclaimed_37, force_thunk_32, force_helper_35

force_thunk_32:
  %kind_38 = load.invariant i8 [%header_11 + 43] align 1
  %kind_39 = zext i8 %kind_38 to i64
  %thunk_40 = eq i64 %kind_39, 2
  br %thunk_40, force_stack_33, force_helper_35

force_stack_33:
  %sp_41 = ptr.add %sp_1, 40
  %sp_limit_42 = load ptr [%base_2 + 88] align 1 word
  %stack_fits_43 = le.u ptr %sp_41, %sp_limit_42
  %hp_limit_44 = load ptr [%base_2 + 24] align 1 word
  %heap_fits_45 = le.u ptr %hp_0, %hp_limit_44
  %fits_46 = and i1 %stack_fits_43, %heap_fits_45
  br %fits_46, force_enter_34, force_helper_35

cold force_helper_35:
  tailcall @aihc_lir_force_p(%hp_0, %sp_1, %base_2, %current_8, @aihc_lir_info_1, %$cps_return_4)

force_enter_34:
  store ptr @aihc_lir_info_1, [%sp_1] align 8 region stack
  store ptr %$cps_return_4, [%sp_1 + 8] align 8 region stack
  %update_47 = ptr.add %sp_1, 16
  store ptr @aihc_lir_cps_update_info, [%update_47] align 8 region stack
  store ptr %sp_1, [%update_47 + 8] align 8 region stack
  store ptr %current_8, [%update_47 + 16] align 8 region stack
  %entry_48 = load.invariant code [%header_11 + 24] align 1 word
  tailcall.indirect %entry_48(%hp_0, %sp_41, %base_2, %current_8, %update_47) : (ptr, ptr, ptr, ptr, ptr)
}

func @aihc_f__Example___sdef__sp__sp__ucont(%hp_49: ptr, %sp_50: ptr, %base_51: ptr, %$cps_return_52: ptr, %case_value_53: ptr) {
entry:
  %$cdef_54 = load ptr [%case_value_53 + 8] align 8 region heap
  tailcall @aihc_lir_eval(%hp_49, %sp_50, %base_51, %$cdef_54, %$cps_return_52)
}

export data mut @_Example_def align 8 = { ptr @aihc_lir_info_0 }

export data mut @_Example___sfDefaultSwitch align 8 = { ptr @aihc_c__Example___sDict__sDefault_0, ptr @_Example___sfDefaultSwitch__scdef }

data mut @_Example___sfDefaultSwitch__scdef align 8 = { ptr @aihc_c__Example_Off_0 }

export data mut @_Example_Off align 8 = { ptr @aihc_c__Example_Off_0 }

export data mut @_Example_On align 8 = { ptr @aihc_c__Example_On_0 }

export data @aihc_c__Example_Off_0 align 8 = { ptr @aihc_c__Example_Off_0, ptr null, ptr null, code null, ptr null, i8 0, i8 0, i8 0, i8 0, i8 0, i8 1, i16 0 }

export data @aihc_c__Example_On_0 align 8 = { ptr @aihc_c__Example_On_0, ptr null, ptr null, code null, ptr null, i8 0, i8 0, i8 0, i8 0, i8 0, i8 1, i16 1 }

data @aihc_lir_bitmap_0 align 1 = { bytes "\x01" }

export data @aihc_c__Example___sDict__sDefault_0 align 8 = { ptr @aihc_c__Example___sDict__sDefault_0, ptr @aihc_lir_bitmap_0, ptr null, code null, ptr null, i8 1, i8 0, i8 0, i8 0, i8 0, i8 2, i16 0 }

export data @aihc_constructor__Example___sDict__sDefault_partial align 8 = { ptr @aihc_c__Example___sDict__sDefault_0, ptr @aihc_lir_bitmap_0, ptr @aihc_c__Example___sDict__sDefault_0, code null, ptr null, i8 1, i8 1, i8 0, i8 3, i8 0, i8 0, i16 0 }

func @aihc_lir_info_0_e(%hp_55: ptr, %sp_56: ptr, %base_57: ptr, %object_58: ptr, %continuation_59: ptr, %supplied_60: ptr) {
entry:
  tailcall @aihc_f__Example___sdef__sp__sp(%hp_55, %sp_56, %base_57, %supplied_60, %continuation_59)
}

data @aihc_lir_info_0 align 8 = { code @aihc_f__Example___sdef__sp__sp, ptr @aihc_lir_bitmap_0, ptr null, code @aihc_lir_info_0_e, ptr null, i8 0, i8 1, i8 0, i8 1, i8 0, i8 1, i16 0 }

data @aihc_lir_bitmap_1 align 1 = { bytes "\x01\x01" }

func @aihc_lir_info_1_e(%hp_61: ptr, %sp_62: ptr, %base_63: ptr, %object_64: ptr, %supplied_66: ptr) {
entry:
  %stored_67 = load ptr [%object_64 + 8] align 8
  tailcall @aihc_f__Example___sdef__sp__sp__ucont(%hp_61, %sp_62, %base_63, %stored_67, %supplied_66)
}

data @aihc_lir_info_1 align 8 = { code @aihc_f__Example___sdef__sp__sp__ucont, ptr @aihc_lir_bitmap_1, ptr null, code @aihc_lir_info_1_e, ptr null, i8 1, i8 1, i8 1, i8 1, i8 0, i8 2, i16 0 }

func @aihc_lir_force_p(%hp_68: ptr, %sp_69: ptr, %base_70: ptr, %value_71: ptr, %info_72: ptr, %field_73: ptr) {
entry:
  %sp_74 = ptr.add %sp_69, 16
  %sp_limit_75 = load ptr [%base_70 + 88] align 1 word
  %stack_fits_76 = le.u ptr %sp_74, %sp_limit_75
  br %stack_fits_76, stack_pushed_78(%sp_69, %sp_74, %field_73), stack_grow_77

cold stack_grow_77:
  store ptr %hp_68, [%base_70 + 16] align 1 word
  %result_79 = call @aihc_stack_grow(%base_70, %sp_69, 2, %field_73)
  %sp_80 = ptr.add %result_79, 16
  %parent_81 = ptr.add %result_79, -16
  jump stack_pushed_78(%result_79, %sp_80, %parent_81)

stack_pushed_78(%frame_82: ptr, %sp_83: ptr, %parent_84: ptr):
  store ptr %info_72, [%frame_82] align 8 region stack
  store ptr %parent_84, [%frame_82 + 8] align 8 region stack
  tailcall @aihc_lir_eval(%hp_68, %sp_83, %base_70, %value_71, %frame_82)
}