Skip to content

Instantly share code, notes, and snippets.

@mbillingr
Last active June 15, 2019 10:52
Show Gist options
  • Select an option

  • Save mbillingr/41bcde4fa1468d11bd74fbbb1d781cd8 to your computer and use it in GitHub Desktop.

Select an option

Save mbillingr/41bcde4fa1468d11bd74fbbb1d781cd8 to your computer and use it in GitHub Desktop.
Tailcall experiments in LLVM IR
%T = type { i8, i64 }
declare %T* @allocate_new_pair()
declare %T @number(i32 %num)
define i1 @is_null(%T %obj) {
%tag = extractvalue %T %obj, 0
%cond = icmp eq i8 %tag, 0
br i1 %cond, label %yes, label %no
yes:
ret i1 1
no:
ret i1 0
}
define %T @car(%T %obj) {
%payload = extractvalue %T %obj, 1
%car-ptr = inttoptr i64 %payload to %T*
%car = load %T, %T* %car-ptr
ret %T %car
}
define %T @cdr(%T %obj) {
%payload = extractvalue %T %obj, 1
%next = add i64 %payload, 16 ; add size of %T
%car-ptr = inttoptr i64 %next to %T*
%cdr = load %T, %T* %car-ptr
ret %T %cdr
}
define %T @cons(%T %car, %T %cdr) {
%ptr = tail call %T* @allocate_new_pair()
; TODO: store car and cdr at appropriate positions
%payload = ptrtoint %T* %ptr to i64
%tmp = insertvalue %T { i8 1, i64 undef }, i64 %payload, 1
ret %T %tmp
}
define %T @length(%T %seq, i32 %acc) {
%cond = call i1 @is_null(%T %seq)
br i1 %cond, label %base_case, label %recurse
base_case:
%tmp = tail call %T @number(i32 %acc)
ret %T %tmp
recurse:
%acc.1 = add i32 %acc, 1
%seq.1 = tail call %T @cdr(%T %seq)
%tmp.1 = tail call %T @length(%T %seq.1, i32 %acc.1)
ret %T %tmp.1
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment