121 lines
No EOL
2.8 KiB
LLVM
121 lines
No EOL
2.8 KiB
LLVM
@test_case = global [8 x i64] [i64 10, i64 9, i64 2, i64 5, i64 3, i64 7, i64 101, i64 18]
|
|
@memo = global [8 x i64] [i64 -1, i64 -1, i64 -1, i64 -1, i64 -1, i64 -1, i64 -1, i64 -1]
|
|
|
|
define i64 @max_in_memo() {
|
|
%max = alloca i64
|
|
store i64 -1, i64* %max
|
|
|
|
; loop variable, we can skip index 0 because it's the base case
|
|
%i = alloca i64
|
|
store i64 0, i64* %i
|
|
|
|
br label %loop
|
|
|
|
loop:
|
|
%i_val = load i64, i64* %i
|
|
%cmp1 = icmp eq i64 %i_val, 8
|
|
|
|
br i1 %cmp1, label %after_loop, label %loop_body
|
|
|
|
loop_body:
|
|
%memo_val_ptr = getelementptr [8 x i64], [8 x i64]* @memo, i32 0, i64 %i_val
|
|
%memo_val = load i64, i64* %memo_val_ptr
|
|
%max_val1 = load i64, i64* %max
|
|
%cmp2 = icmp sgt i64 %memo_val, %max_val1
|
|
|
|
br i1 %cmp2, label %new_max, label %repeat_loop
|
|
|
|
new_max:
|
|
store i64 %memo_val, i64* %max
|
|
|
|
br label %repeat_loop
|
|
|
|
repeat_loop:
|
|
%new_i_val = add i64 %i_val, 1
|
|
store i64 %new_i_val, i64* %i
|
|
|
|
br label %loop
|
|
|
|
after_loop:
|
|
%max_val2 = load i64, i64* %max
|
|
|
|
ret i64 %max_val2
|
|
}
|
|
|
|
define i64 @lis(i64 %idx) {
|
|
%max = alloca i64
|
|
store i64 1, i64* %max
|
|
|
|
; loop variable
|
|
%i = alloca i64
|
|
store i64 0, i64* %i
|
|
|
|
br label %loop
|
|
|
|
loop:
|
|
%i_val = load i64, i64* %i
|
|
%cmp1 = icmp eq i64 %i_val, %idx
|
|
|
|
br i1 %cmp1, label %after_loop, label %loop_body
|
|
|
|
loop_body:
|
|
%memo_val_ptr = getelementptr [8 x i64], [8 x i64]* @memo, i32 0, i64 %i_val
|
|
%memo_val1 = load i64, i64* %memo_val_ptr
|
|
|
|
; check if we've previously memoized the result for this subproblem
|
|
%cmp2 = icmp eq i64 %memo_val1, -1
|
|
|
|
br i1 %cmp2, label %recurse, label %after_memo
|
|
|
|
recurse:
|
|
%res = call i64 @lis(i64 %i_val)
|
|
store i64 %res, i64* %memo_val_ptr
|
|
|
|
br label %after_memo
|
|
|
|
after_memo:
|
|
%arr_i_ptr = getelementptr [8 x i64], [8 x i64]* @test_case, i32 0, i64 %i_val
|
|
%arr_i_val = load i64, i64* %arr_i_ptr
|
|
|
|
%arr_idx_ptr = getelementptr [8 x i64], [8 x i64]* @test_case, i32 0, i64 %idx
|
|
%arr_idx_val = load i64, i64* %arr_idx_ptr
|
|
|
|
%cmp3 = icmp slt i64 %arr_i_val, %arr_idx_val
|
|
br i1 %cmp3, label %can_incr_subseq, label %repeat_loop
|
|
|
|
can_incr_subseq:
|
|
%max_val1 = load i64, i64* %max
|
|
|
|
; index again because we could've recursed and updated subproblem value
|
|
%memo_val2 = load i64, i64* %memo_val_ptr
|
|
%curr_max = add i64 %memo_val2, 1
|
|
|
|
%cmp4 = icmp sgt i64 %curr_max, %max_val1
|
|
|
|
br i1 %cmp4, label %new_max_found, label %repeat_loop
|
|
|
|
new_max_found:
|
|
store i64 %curr_max, i64* %max
|
|
|
|
br label %repeat_loop
|
|
|
|
repeat_loop:
|
|
%new_i_val = add i64 %i_val, 1
|
|
store i64 %new_i_val, i64* %i
|
|
|
|
br label %loop
|
|
|
|
after_loop:
|
|
%memo_idx_ptr = getelementptr [8 x i64], [8 x i64]* @memo, i32 0, i64 %idx
|
|
%max_val2 = load i64, i64* %max
|
|
store i64 %max_val2, i64* %memo_idx_ptr
|
|
|
|
ret i64 %max_val2
|
|
}
|
|
|
|
define i64 @main(i64 %argc, i8** %arcv) {
|
|
%res = call i64 @lis(i64 7)
|
|
%ans = call i64 @max_in_memo()
|
|
|
|
ret i64 %ans
|
|
} |