mirror of
https://github.com/c3lang/c3c.git
synced 2026-02-27 12:01:16 +00:00
368 lines
13 KiB
C
368 lines
13 KiB
C
// #target: macos-x64
|
|
module fasta;
|
|
|
|
const IM = 139968u;
|
|
const IA = 3877u;
|
|
const IC = 29573u;
|
|
const SEED = 42u;
|
|
|
|
uint seed = SEED;
|
|
|
|
fn float fasta_rand(float maxval)
|
|
{
|
|
seed = (seed * IA + IC) % IM;
|
|
return maxval * seed / IM;
|
|
}
|
|
|
|
private char[] alu =
|
|
"GGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGG"
|
|
"GAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGA"
|
|
"CCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAAT"
|
|
"ACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCA"
|
|
"GCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGG"
|
|
"AGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCC"
|
|
"AGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAA";
|
|
|
|
extern fn int atoi(char *s);
|
|
extern fn int printf(char *s, ...);
|
|
extern fn void putchar(int c);
|
|
|
|
char[] iub = "acgtBDHKMNRSVWY";
|
|
double[] iub_p = {
|
|
0.27,
|
|
0.12,
|
|
0.12,
|
|
0.27,
|
|
0.02,
|
|
0.02,
|
|
0.02,
|
|
0.02,
|
|
0.02,
|
|
0.02,
|
|
0.02,
|
|
0.02,
|
|
0.02,
|
|
0.02,
|
|
0.02 };
|
|
|
|
char[] homosapiens = "acgt";
|
|
double[] homosapiens_p = {
|
|
0.3029549426680,
|
|
0.1979883004921,
|
|
0.1975473066391,
|
|
0.3015094502008
|
|
};
|
|
|
|
const LINELEN = 60;
|
|
|
|
// slowest character-at-a-time output
|
|
fn void repeat_fasta(char[] seq, int n)
|
|
{
|
|
usz len = seq.len;
|
|
int i = void;
|
|
for (i = 0; i < n; i++)
|
|
{
|
|
putchar(seq[i % len]);
|
|
if (i % LINELEN == LINELEN - 1) putchar('\n');
|
|
}
|
|
if (i % LINELEN != 0) putchar('\n');
|
|
}
|
|
|
|
fn void random_fasta(char[] symb, double[] probability, int n)
|
|
{
|
|
assert(symb.len == probability.len);
|
|
int len = probability.len;
|
|
int i = void;
|
|
for (i = 0; i < n; i++)
|
|
{
|
|
double v = fasta_rand(1.0);
|
|
/* slowest idiomatic linear lookup. Fast if len is short though. */
|
|
int j = void;
|
|
for (j = 0; j < len - 1; j++)
|
|
{
|
|
v -= probability[j];
|
|
if (v < 0) break;
|
|
}
|
|
putchar(symb[j]);
|
|
if (i % LINELEN == LINELEN - 1) putchar('\n');
|
|
}
|
|
if (i % LINELEN != 0) putchar('\n');
|
|
}
|
|
|
|
fn int main(int argc, char **argv)
|
|
{
|
|
int n = 1000;
|
|
if (argc > 1) n = atoi(argv[1]);
|
|
|
|
printf(">ONE Homo sapiens alu\n");
|
|
repeat_fasta(alu, n * 2);
|
|
|
|
printf(">TWO IUB ambiguity codes\n");
|
|
random_fasta(iub, iub_p, n * 3);
|
|
|
|
printf(">THREE Homo sapiens frequency\n");
|
|
random_fasta(homosapiens, homosapiens_p, n * 5);
|
|
|
|
return 0;
|
|
}
|
|
|
|
/* #expect: fasta.ll
|
|
|
|
%"char[]" = type { ptr, i64 }
|
|
%"double[]" = type { ptr, i64 }
|
|
|
|
@fasta_IM = local_unnamed_addr constant i32 139968, align 4
|
|
@fasta_IA = local_unnamed_addr constant i32 3877, align 4
|
|
@fasta_IC = local_unnamed_addr constant i32 29573, align 4
|
|
@fasta_SEED = local_unnamed_addr constant i32 42, align 4
|
|
@fasta_seed = local_unnamed_addr global i32 42, align 4
|
|
@.str = private unnamed_addr constant [288 x i8] c"GGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTGGGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGAGACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAAAATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAATCCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAACCCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTGCACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAA\00", align 1
|
|
@fasta_alu = protected unnamed_addr global %"char[]" { ptr @.str, i64 287 }, align 8
|
|
@.str.11 = private unnamed_addr constant [16 x i8] c"acgtBDHKMNRSVWY\00", align 1
|
|
@fasta_iub = local_unnamed_addr global %"char[]" { ptr @.str.11, i64 15 }, align 8
|
|
@.taddr = private global [15 x double] [double 2.700000e-01, double 1.200000e-01, double 1.200000e-01, double 2.700000e-01, double 2.000000e-02, double 2.000000e-02, double 2.000000e-02, double 2.000000e-02, double 2.000000e-02, double 2.000000e-02, double 2.000000e-02, double 2.000000e-02, double 2.000000e-02, double 2.000000e-02, double 2.000000e-02], align 8
|
|
@fasta_iub_p = local_unnamed_addr global %"double[]" { ptr @.taddr, i64 15 }, align 8
|
|
@.str.12 = private unnamed_addr constant [5 x i8] c"acgt\00", align 1
|
|
@fasta_homosapiens = local_unnamed_addr global %"char[]" { ptr @.str.12, i64 4 }, align 8
|
|
@.taddr.13 = private global [4 x double] [double 0x3FD3639D20BAEB5B, double 0x3FC957AE3DCD561B, double 0x3FC9493AEAB6C2BF, double 0x3FD34BEE4B030838], align 8
|
|
@fasta_homosapiens_p = local_unnamed_addr global %"double[]" { ptr @.taddr.13, i64 4 }, align 8
|
|
@fasta_LINELEN = local_unnamed_addr constant i32 60, align 4
|
|
@.str.14 = private unnamed_addr constant [23 x i8] c">ONE Homo sapiens alu\0A\00", align 1
|
|
@.str.15 = private unnamed_addr constant [26 x i8] c">TWO IUB ambiguity codes\0A\00", align 1
|
|
@.str.16 = private unnamed_addr constant [31 x i8] c">THREE Homo sapiens frequency\0A\00", align 1
|
|
|
|
; Function Attrs: nounwind
|
|
define float @fasta_fasta_rand(float %0) #0 {
|
|
entry:
|
|
%1 = load i32, ptr @fasta_seed, align 4
|
|
%mul = mul i32 %1, 3877
|
|
%add = add i32 %mul, 29573
|
|
%umod = urem i32 %add, 139968
|
|
store i32 %umod, ptr @fasta_seed, align 4
|
|
%2 = load i32, ptr @fasta_seed, align 4
|
|
%uifp = uitofp i32 %2 to float
|
|
%fmul = fmul float %0, %uifp
|
|
%fdiv = fdiv float %fmul, 1.399680e+05
|
|
ret float %fdiv
|
|
}
|
|
|
|
; Function Attrs: nounwind
|
|
declare i32 @atoi(ptr) #0
|
|
|
|
; Function Attrs: nounwind
|
|
declare i32 @printf(ptr, ...) #0
|
|
|
|
; Function Attrs: nounwind
|
|
declare void @putchar(i32) #0
|
|
|
|
; Function Attrs: nounwind
|
|
define void @fasta_repeat_fasta(ptr %0, i64 %1, i32 %2) #0 {
|
|
entry:
|
|
%seq = alloca %"char[]", align 8
|
|
%len = alloca i64, align 8
|
|
%i = alloca i32, align 4
|
|
%3 = getelementptr inbounds { ptr, i64 }, ptr %seq, i32 0, i32 0
|
|
store ptr %0, ptr %3, align 8
|
|
%4 = getelementptr inbounds { ptr, i64 }, ptr %seq, i32 0, i32 1
|
|
store i64 %1, ptr %4, align 8
|
|
%5 = getelementptr inbounds %"char[]", ptr %seq, i32 0, i32 1
|
|
%6 = load i64, ptr %5, align 8
|
|
store i64 %6, ptr %len, align 8
|
|
store i32 0, ptr %i, align 4
|
|
br label %loop.cond
|
|
|
|
loop.cond: ; preds = %if.exit, %entry
|
|
%7 = load i32, ptr %i, align 4
|
|
%lt = icmp slt i32 %7, %2
|
|
br i1 %lt, label %loop.body, label %loop.exit
|
|
|
|
loop.body: ; preds = %loop.cond
|
|
%8 = getelementptr inbounds %"char[]", ptr %seq, i32 0, i32 0
|
|
%9 = load ptr, ptr %8, align 8
|
|
%10 = load i32, ptr %i, align 4
|
|
%sisiext = sext i32 %10 to i64
|
|
%11 = load i64, ptr %len, align 8
|
|
%smod = srem i64 %sisiext, %11
|
|
%ptroffset = getelementptr inbounds i8, ptr %9, i64 %smod
|
|
%12 = load i8, ptr %ptroffset, align 1
|
|
%uisiext = zext i8 %12 to i32
|
|
call void @putchar(i32 %uisiext)
|
|
%13 = load i32, ptr %i, align 4
|
|
%smod1 = srem i32 %13, 60
|
|
%eq = icmp eq i32 %smod1, 59
|
|
br i1 %eq, label %if.then, label %if.exit
|
|
|
|
if.then: ; preds = %loop.body
|
|
call void @putchar(i32 10)
|
|
br label %if.exit
|
|
|
|
if.exit: ; preds = %if.then, %loop.body
|
|
%14 = load i32, ptr %i, align 4
|
|
%add = add i32 %14, 1
|
|
store i32 %add, ptr %i, align 4
|
|
br label %loop.cond
|
|
|
|
loop.exit: ; preds = %loop.cond
|
|
%15 = load i32, ptr %i, align 4
|
|
%smod2 = srem i32 %15, 60
|
|
%neq = icmp ne i32 %smod2, 0
|
|
br i1 %neq, label %if.then3, label %if.exit4
|
|
|
|
if.then3: ; preds = %loop.exit
|
|
call void @putchar(i32 10)
|
|
br label %if.exit4
|
|
|
|
if.exit4: ; preds = %if.then3, %loop.exit
|
|
ret void
|
|
}
|
|
|
|
; Function Attrs: nounwind
|
|
define void @fasta_random_fasta(ptr %0, i64 %1, ptr %2, i64 %3, i32 %4) #0 {
|
|
entry:
|
|
%symb = alloca %"char[]", align 8
|
|
%probability = alloca %"double[]", align 8
|
|
%len = alloca i32, align 4
|
|
%i = alloca i32, align 4
|
|
%v = alloca double, align 8
|
|
%j = alloca i32, align 4
|
|
%5 = getelementptr inbounds { ptr, i64 }, ptr %symb, i32 0, i32 0
|
|
store ptr %0, ptr %5, align 8
|
|
%6 = getelementptr inbounds { ptr, i64 }, ptr %symb, i32 0, i32 1
|
|
store i64 %1, ptr %6, align 8
|
|
%7 = getelementptr inbounds { ptr, i64 }, ptr %probability, i32 0, i32 0
|
|
store ptr %2, ptr %7, align 8
|
|
%8 = getelementptr inbounds { ptr, i64 }, ptr %probability, i32 0, i32 1
|
|
store i64 %3, ptr %8, align 8
|
|
%9 = getelementptr inbounds %"char[]", ptr %symb, i32 0, i32 1
|
|
%10 = load i64, ptr %9, align 8
|
|
%11 = getelementptr inbounds %"double[]", ptr %probability, i32 0, i32 1
|
|
%12 = load i64, ptr %11, align 8
|
|
%eq = icmp eq i64 %10, %12
|
|
call void @llvm.assume(i1 %eq)
|
|
%13 = getelementptr inbounds %"double[]", ptr %probability, i32 0, i32 1
|
|
%14 = load i64, ptr %13, align 8
|
|
%uisitrunc = trunc i64 %14 to i32
|
|
store i32 %uisitrunc, ptr %len, align 4
|
|
store i32 0, ptr %i, align 4
|
|
br label %loop.cond
|
|
|
|
loop.cond: ; preds = %if.exit9, %entry
|
|
%15 = load i32, ptr %i, align 4
|
|
%lt = icmp slt i32 %15, %4
|
|
br i1 %lt, label %loop.body, label %loop.exit11
|
|
|
|
loop.body: ; preds = %loop.cond
|
|
%16 = call float @fasta_fasta_rand(float 1.000000e+00)
|
|
%fpfpext = fpext float %16 to double
|
|
store double %fpfpext, ptr %v, align 8
|
|
store i32 0, ptr %j, align 4
|
|
br label %loop.cond1
|
|
|
|
loop.cond1: ; preds = %if.exit, %loop.body
|
|
%17 = load i32, ptr %j, align 4
|
|
%18 = load i32, ptr %len, align 4
|
|
%sub = sub i32 %18, 1
|
|
%lt2 = icmp slt i32 %17, %sub
|
|
br i1 %lt2, label %loop.body3, label %loop.exit
|
|
|
|
loop.body3: ; preds = %loop.cond1
|
|
%19 = load double, ptr %v, align 8
|
|
%20 = getelementptr inbounds %"double[]", ptr %probability, i32 0, i32 0
|
|
%21 = load ptr, ptr %20, align 8
|
|
%22 = load i32, ptr %j, align 4
|
|
%sisiext = sext i32 %22 to i64
|
|
%ptroffset = getelementptr inbounds double, ptr %21, i64 %sisiext
|
|
%23 = load double, ptr %ptroffset, align 8
|
|
%fsub = fsub double %19, %23
|
|
store double %fsub, ptr %v, align 8
|
|
%24 = load double, ptr %v, align 8
|
|
%lt4 = fcmp olt double %24, 0.000000e+00
|
|
br i1 %lt4, label %if.then, label %if.exit
|
|
|
|
if.then: ; preds = %loop.body3
|
|
br label %loop.exit
|
|
|
|
if.exit: ; preds = %loop.body3
|
|
%25 = load i32, ptr %j, align 4
|
|
%add = add i32 %25, 1
|
|
store i32 %add, ptr %j, align 4
|
|
br label %loop.cond1
|
|
|
|
loop.exit: ; preds = %if.then, %loop.cond1
|
|
%26 = getelementptr inbounds %"char[]", ptr %symb, i32 0, i32 0
|
|
%27 = load ptr, ptr %26, align 8
|
|
%28 = load i32, ptr %j, align 4
|
|
%sisiext5 = sext i32 %28 to i64
|
|
%ptroffset6 = getelementptr inbounds i8, ptr %27, i64 %sisiext5
|
|
%29 = load i8, ptr %ptroffset6, align 1
|
|
%uisiext = zext i8 %29 to i32
|
|
call void @putchar(i32 %uisiext)
|
|
%30 = load i32, ptr %i, align 4
|
|
%smod = srem i32 %30, 60
|
|
%eq7 = icmp eq i32 %smod, 59
|
|
br i1 %eq7, label %if.then8, label %if.exit9
|
|
|
|
if.then8: ; preds = %loop.exit
|
|
call void @putchar(i32 10)
|
|
br label %if.exit9
|
|
|
|
if.exit9: ; preds = %if.then8, %loop.exit
|
|
%31 = load i32, ptr %i, align 4
|
|
%add10 = add i32 %31, 1
|
|
store i32 %add10, ptr %i, align 4
|
|
br label %loop.cond
|
|
|
|
loop.exit11: ; preds = %loop.cond
|
|
%32 = load i32, ptr %i, align 4
|
|
%smod12 = srem i32 %32, 60
|
|
%neq = icmp ne i32 %smod12, 0
|
|
br i1 %neq, label %if.then13, label %if.exit14
|
|
|
|
if.then13: ; preds = %loop.exit11
|
|
call void @putchar(i32 10)
|
|
br label %if.exit14
|
|
|
|
if.exit14: ; preds = %if.then13, %loop.exit11
|
|
ret void
|
|
}
|
|
|
|
; Function Attrs: nounwind
|
|
define i32 @main(i32 %0, ptr %1) #0 {
|
|
entry:
|
|
%n = alloca i32, align 4
|
|
store i32 1000, ptr %n, align 4
|
|
%gt = icmp sgt i32 %0, 1
|
|
br i1 %gt, label %if.then, label %if.exit
|
|
|
|
if.then: ; preds = %entry
|
|
%ptroffset = getelementptr inbounds ptr, ptr %1, i64 1
|
|
%2 = load ptr, ptr %ptroffset, align 8
|
|
%3 = call i32 @atoi(ptr %2)
|
|
store i32 %3, ptr %n, align 4
|
|
br label %if.exit
|
|
|
|
if.exit: ; preds = %if.then, %entry
|
|
%4 = call i32 (ptr, ...) @printf(ptr @.str.14)
|
|
%lo = load ptr, ptr @fasta_alu, align 8
|
|
%hi = load i64, ptr getelementptr inbounds (%"char[]", ptr @fasta_alu, i32 0, i32 1), align 8
|
|
%5 = load i32, ptr %n, align 4
|
|
%mul = mul i32 %5, 2
|
|
call void @fasta_repeat_fasta(ptr %lo, i64 %hi, i32 %mul)
|
|
%6 = call i32 (ptr, ...) @printf(ptr @.str.15)
|
|
%lo1 = load ptr, ptr @fasta_iub, align 8
|
|
%hi2 = load i64, ptr getelementptr inbounds (%"char[]", ptr @fasta_iub, i32 0, i32 1), align 8
|
|
%lo3 = load ptr, ptr @fasta_iub_p, align 8
|
|
%hi4 = load i64, ptr getelementptr inbounds (%"double[]", ptr @fasta_iub_p, i32 0, i32 1), align 8
|
|
%7 = load i32, ptr %n, align 4
|
|
%mul5 = mul i32 %7, 3
|
|
call void @fasta_random_fasta(ptr %lo1, i64 %hi2, ptr %lo3, i64 %hi4, i32 %mul5)
|
|
%8 = call i32 (ptr, ...) @printf(ptr @.str.16)
|
|
%lo6 = load ptr, ptr @fasta_homosapiens, align 8
|
|
%hi7 = load i64, ptr getelementptr inbounds (%"char[]", ptr @fasta_homosapiens, i32 0, i32 1), align 8
|
|
%lo8 = load ptr, ptr @fasta_homosapiens_p, align 8
|
|
%hi9 = load i64, ptr getelementptr inbounds (%"double[]", ptr @fasta_homosapiens_p, i32 0, i32 1), align 8
|
|
%9 = load i32, ptr %n, align 4
|
|
%mul10 = mul i32 %9, 5
|
|
call void @fasta_random_fasta(ptr %lo6, i64 %hi7, ptr %lo8, i64 %hi9, i32 %mul10)
|
|
ret i32 0
|
|
}
|