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.
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.
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.
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.
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)
}