forked from NUDT-compiler/nudt-compiler-cpp
Compare commits
24 Commits
| Author | SHA1 | Date |
|---|---|---|
|
|
f27138e6fb | 2 hours ago |
|
|
e26b9f8a43 | 3 hours ago |
|
|
6b6de49fcf | 2 days ago |
|
|
f4658ec3fa | 2 days ago |
|
|
8ce783c967 | 2 days ago |
|
|
539e92d6bb | 3 days ago |
|
|
2660960674 | 6 days ago |
|
|
23c274eab6 | 1 week ago |
|
|
99826566e6 | 1 week ago |
|
|
19928c4945 | 1 week ago |
|
|
827558938b | 1 week ago |
|
|
c7e8b28d29 | 1 week ago |
|
|
e3de2c59af | 1 week ago |
|
|
3c6ffe8e3e | 4 weeks ago |
|
|
de126b93d6 | 4 weeks ago |
|
|
310c7c3697 | 4 weeks ago |
|
|
248db05cf4 | 4 weeks ago |
|
|
feaba9abd4 | 4 weeks ago |
|
|
1ff1b543d1 | 4 weeks ago |
|
|
80c46cee7e | 1 month ago |
|
|
19ef82738f | 1 month ago |
|
|
4693253459 | 1 month ago |
|
|
fd45b74e2e | 1 month ago |
|
|
74bcb45776 | 1 month ago |
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,3 @@
|
|||||||
|
bash scripts/run_ir_test.sh --run # 优化模式,计时
|
||||||
|
bash scripts/run_ir_test.sh --run --O0 # 无优化,计时
|
||||||
|
bash scripts/bench_ir.sh # 同时对比 O0 vs O1
|
||||||
@ -0,0 +1,272 @@
|
|||||||
|
@MAX = global i32 1000000000
|
||||||
|
@TWO = global i32 2
|
||||||
|
@THREE = global i32 3
|
||||||
|
@FIVE = global i32 5
|
||||||
|
|
||||||
|
declare void @putch(i32)
|
||||||
|
declare void @memset(i32*, i32, i32)
|
||||||
|
declare i32 @getfarray(float*)
|
||||||
|
declare float @getfloat()
|
||||||
|
declare void @putfloat(float)
|
||||||
|
declare void @putint(i32)
|
||||||
|
declare void @putfarray(i32, float*)
|
||||||
|
|
||||||
|
define float @float_abs(float %x) {
|
||||||
|
entry:
|
||||||
|
%0 = alloca float
|
||||||
|
store float %x, float* %0
|
||||||
|
%2 = load float, float* %0
|
||||||
|
%3 = sitofp i32 0 to float
|
||||||
|
%4 = fcmp olt float %2, %3
|
||||||
|
br i1 %4, label %L0.if.then, label %L1.if.end
|
||||||
|
L0.if.then:
|
||||||
|
%6 = load float, float* %0
|
||||||
|
%7 = fsub float 0x0, %6
|
||||||
|
ret float %7
|
||||||
|
L1.if.end:
|
||||||
|
%9 = load float, float* %0
|
||||||
|
ret float %9
|
||||||
|
}
|
||||||
|
|
||||||
|
define float @circle_area(i32 %radius) {
|
||||||
|
entry:
|
||||||
|
%0 = alloca i32
|
||||||
|
store i32 %radius, i32* %0
|
||||||
|
%2 = load i32, i32* %0
|
||||||
|
%3 = sitofp i32 %2 to float
|
||||||
|
%4 = fmul float 0x400921FB60000000, %3
|
||||||
|
%5 = load i32, i32* %0
|
||||||
|
%6 = sitofp i32 %5 to float
|
||||||
|
%7 = fmul float %4, %6
|
||||||
|
%8 = load i32, i32* %0
|
||||||
|
%9 = load i32, i32* %0
|
||||||
|
%10 = mul i32 %8, %9
|
||||||
|
%11 = sitofp i32 %10 to float
|
||||||
|
%12 = fmul float %11, 0x400921FB60000000
|
||||||
|
%13 = fadd float %7, %12
|
||||||
|
%14 = sitofp i32 2 to float
|
||||||
|
%15 = fdiv float %13, %14
|
||||||
|
ret float %15
|
||||||
|
}
|
||||||
|
|
||||||
|
define i32 @float_eq(float %a, float %b) {
|
||||||
|
entry:
|
||||||
|
%0 = alloca float
|
||||||
|
%1 = alloca float
|
||||||
|
store float %a, float* %0
|
||||||
|
store float %b, float* %1
|
||||||
|
%4 = load float, float* %0
|
||||||
|
%5 = load float, float* %1
|
||||||
|
%6 = fsub float %4, %5
|
||||||
|
%7 = call float @float_abs(float %6)
|
||||||
|
%8 = fcmp olt float %7, 0x3EB0C6F7A0000000
|
||||||
|
br i1 %8, label %L2.if.then, label %L3.if.else
|
||||||
|
L2.if.then:
|
||||||
|
%10 = sitofp i32 1 to float
|
||||||
|
%11 = fmul float %10, 0x4000000000000000
|
||||||
|
%12 = sitofp i32 2 to float
|
||||||
|
%13 = fdiv float %11, %12
|
||||||
|
%14 = fptosi float %13 to i32
|
||||||
|
ret i32 %14
|
||||||
|
L3.if.else:
|
||||||
|
ret i32 0
|
||||||
|
L4.if.end:
|
||||||
|
ret i32 0
|
||||||
|
}
|
||||||
|
|
||||||
|
define void @error() {
|
||||||
|
entry:
|
||||||
|
call void @putch(i32 101)
|
||||||
|
call void @putch(i32 114)
|
||||||
|
call void @putch(i32 114)
|
||||||
|
call void @putch(i32 111)
|
||||||
|
call void @putch(i32 114)
|
||||||
|
call void @putch(i32 10)
|
||||||
|
ret void
|
||||||
|
}
|
||||||
|
|
||||||
|
define void @ok() {
|
||||||
|
entry:
|
||||||
|
call void @putch(i32 111)
|
||||||
|
call void @putch(i32 107)
|
||||||
|
call void @putch(i32 10)
|
||||||
|
ret void
|
||||||
|
}
|
||||||
|
|
||||||
|
define void @assert(i32 %cond) {
|
||||||
|
entry:
|
||||||
|
%0 = alloca i32
|
||||||
|
store i32 %cond, i32* %0
|
||||||
|
%2 = load i32, i32* %0
|
||||||
|
%3 = icmp eq i32 %2, 0
|
||||||
|
%4 = zext i1 %3 to i32
|
||||||
|
%5 = icmp ne i32 %4, 0
|
||||||
|
br i1 %5, label %L5.if.then, label %L6.if.else
|
||||||
|
L5.if.then:
|
||||||
|
call void @error()
|
||||||
|
br label %L7.if.end
|
||||||
|
L6.if.else:
|
||||||
|
call void @ok()
|
||||||
|
br label %L7.if.end
|
||||||
|
L7.if.end:
|
||||||
|
ret void
|
||||||
|
}
|
||||||
|
|
||||||
|
define void @assert_not(i32 %cond) {
|
||||||
|
entry:
|
||||||
|
%0 = alloca i32
|
||||||
|
store i32 %cond, i32* %0
|
||||||
|
%2 = load i32, i32* %0
|
||||||
|
%3 = icmp ne i32 %2, 0
|
||||||
|
br i1 %3, label %L8.if.then, label %L9.if.else
|
||||||
|
L8.if.then:
|
||||||
|
call void @error()
|
||||||
|
br label %L10.if.end
|
||||||
|
L9.if.else:
|
||||||
|
call void @ok()
|
||||||
|
br label %L10.if.end
|
||||||
|
L10.if.end:
|
||||||
|
ret void
|
||||||
|
}
|
||||||
|
|
||||||
|
define i32 @main() {
|
||||||
|
entry:
|
||||||
|
%0 = alloca i32
|
||||||
|
%1 = alloca i32
|
||||||
|
%2 = alloca i32
|
||||||
|
%3 = alloca i32
|
||||||
|
%4 = alloca float, i32 10
|
||||||
|
%5 = alloca i32
|
||||||
|
%6 = alloca float
|
||||||
|
%7 = alloca float
|
||||||
|
%8 = alloca float
|
||||||
|
%9 = call i32 @float_eq(float 0x3FB4000000000000, float 0xC0E01D0000000000)
|
||||||
|
call void @assert_not(i32 %9)
|
||||||
|
%11 = call i32 @float_eq(float 0x4057C21FC0000000, float 0x4041475CE0000000)
|
||||||
|
call void @assert_not(i32 %11)
|
||||||
|
%13 = call i32 @float_eq(float 0x4041475CE0000000, float 0x4041475CE0000000)
|
||||||
|
call void @assert(i32 %13)
|
||||||
|
%15 = fptosi float 0x4016000000000000 to i32
|
||||||
|
%16 = call float @circle_area(i32 %15)
|
||||||
|
%17 = load i32, i32* @FIVE
|
||||||
|
%18 = call float @circle_area(i32 %17)
|
||||||
|
%19 = call i32 @float_eq(float %16, float %18)
|
||||||
|
call void @assert(i32 %19)
|
||||||
|
%21 = call i32 @float_eq(float 0x406D200000000000, float 0x40AFFE0000000000)
|
||||||
|
call void @assert_not(i32 %21)
|
||||||
|
%23 = fcmp one float 0x3FF8000000000000, 0x0
|
||||||
|
br i1 %23, label %L11.if.then, label %L12.if.end
|
||||||
|
L11.if.then:
|
||||||
|
call void @ok()
|
||||||
|
br label %L12.if.end
|
||||||
|
L12.if.end:
|
||||||
|
%27 = fcmp oeq float 0x400A666660000000, 0x0
|
||||||
|
%28 = zext i1 %27 to i32
|
||||||
|
%29 = icmp eq i32 %28, 0
|
||||||
|
%30 = zext i1 %29 to i32
|
||||||
|
%31 = icmp ne i32 %30, 0
|
||||||
|
br i1 %31, label %L13.if.then, label %L14.if.end
|
||||||
|
L13.if.then:
|
||||||
|
call void @ok()
|
||||||
|
br label %L14.if.end
|
||||||
|
L14.if.end:
|
||||||
|
%35 = fcmp one float 0x0, 0x0
|
||||||
|
%36 = zext i1 %35 to i32
|
||||||
|
store i32 %36, i32* %0
|
||||||
|
br i1 %35, label %L15.and.rhs, label %L16.and.end
|
||||||
|
L15.and.rhs:
|
||||||
|
%39 = icmp ne i32 3, 0
|
||||||
|
%40 = zext i1 %39 to i32
|
||||||
|
store i32 %40, i32* %0
|
||||||
|
br label %L16.and.end
|
||||||
|
L16.and.end:
|
||||||
|
%43 = load i32, i32* %0
|
||||||
|
%44 = icmp ne i32 %43, 0
|
||||||
|
br i1 %44, label %L17.if.then, label %L18.if.end
|
||||||
|
L17.if.then:
|
||||||
|
call void @error()
|
||||||
|
br label %L18.if.end
|
||||||
|
L18.if.end:
|
||||||
|
%48 = icmp ne i32 0, 0
|
||||||
|
%49 = zext i1 %48 to i32
|
||||||
|
store i32 %49, i32* %1
|
||||||
|
br i1 %48, label %L20.or.end, label %L19.or.rhs
|
||||||
|
L19.or.rhs:
|
||||||
|
%52 = fcmp one float 0x3FD3333340000000, 0x0
|
||||||
|
%53 = zext i1 %52 to i32
|
||||||
|
store i32 %53, i32* %1
|
||||||
|
br label %L20.or.end
|
||||||
|
L20.or.end:
|
||||||
|
%56 = load i32, i32* %1
|
||||||
|
%57 = icmp ne i32 %56, 0
|
||||||
|
br i1 %57, label %L21.if.then, label %L22.if.end
|
||||||
|
L21.if.then:
|
||||||
|
call void @ok()
|
||||||
|
br label %L22.if.end
|
||||||
|
L22.if.end:
|
||||||
|
store i32 1, i32* %2
|
||||||
|
store i32 0, i32* %3
|
||||||
|
call void @memset(float* %4, i32 0, i32 40)
|
||||||
|
%64 = getelementptr float, float* %4, i32 0
|
||||||
|
store float 0x3FF0000000000000, float* %64
|
||||||
|
%66 = getelementptr float, float* %4, i32 1
|
||||||
|
store i32 2, float* %66
|
||||||
|
%68 = getelementptr float, float* %4, i32 0
|
||||||
|
%69 = call i32 @getfarray(float* %68)
|
||||||
|
store i32 %69, i32* %5
|
||||||
|
br label %L23.while.cond
|
||||||
|
L23.while.cond:
|
||||||
|
%72 = load i32, i32* %2
|
||||||
|
%73 = load i32, i32* @MAX
|
||||||
|
%74 = icmp slt i32 %72, %73
|
||||||
|
br i1 %74, label %L24.while.body, label %L25.while.end
|
||||||
|
L24.while.body:
|
||||||
|
%76 = call float @getfloat()
|
||||||
|
store float %76, float* %6
|
||||||
|
%78 = load float, float* %6
|
||||||
|
%79 = fmul float 0x400921FB60000000, %78
|
||||||
|
%80 = load float, float* %6
|
||||||
|
%81 = fmul float %79, %80
|
||||||
|
store float %81, float* %7
|
||||||
|
%83 = load float, float* %6
|
||||||
|
%84 = fptosi float %83 to i32
|
||||||
|
%85 = call float @circle_area(i32 %84)
|
||||||
|
store float %85, float* %8
|
||||||
|
%87 = load i32, i32* %3
|
||||||
|
%88 = getelementptr float, float* %4, i32 %87
|
||||||
|
%89 = load float, float* %88
|
||||||
|
%90 = load float, float* %6
|
||||||
|
%91 = fadd float %89, %90
|
||||||
|
%92 = load i32, i32* %3
|
||||||
|
%93 = getelementptr float, float* %4, i32 %92
|
||||||
|
store float %91, float* %93
|
||||||
|
%95 = load float, float* %7
|
||||||
|
call void @putfloat(float %95)
|
||||||
|
call void @putch(i32 32)
|
||||||
|
%98 = load float, float* %8
|
||||||
|
%99 = fptosi float %98 to i32
|
||||||
|
call void @putint(i32 %99)
|
||||||
|
call void @putch(i32 10)
|
||||||
|
%102 = load i32, i32* %2
|
||||||
|
%103 = fsub float 0x0, 0x4024000000000000
|
||||||
|
%104 = fsub float 0x0, %103
|
||||||
|
%105 = sitofp i32 %102 to float
|
||||||
|
%106 = fmul float %105, %104
|
||||||
|
%107 = fptosi float %106 to i32
|
||||||
|
store i32 %107, i32* %2
|
||||||
|
%109 = load i32, i32* %3
|
||||||
|
%110 = add i32 %109, 1
|
||||||
|
store i32 %110, i32* %3
|
||||||
|
br label %L23.while.cond
|
||||||
|
L25.while.end:
|
||||||
|
%113 = load i32, i32* %5
|
||||||
|
%114 = getelementptr float, float* %4, i32 0
|
||||||
|
call void @putfarray(i32 %113, float* %114)
|
||||||
|
%116 = srem i32 0, 256
|
||||||
|
%117 = add i32 %116, 256
|
||||||
|
%118 = srem i32 %117, 256
|
||||||
|
call void @putint(i32 %118)
|
||||||
|
call void @putch(i32 10)
|
||||||
|
ret i32 0
|
||||||
|
}
|
||||||
|
|
||||||
@ -0,0 +1,309 @@
|
|||||||
|
.text
|
||||||
|
.global main
|
||||||
|
.type main, @function
|
||||||
|
main:
|
||||||
|
addi sp, sp, -272
|
||||||
|
sw ra, 264(sp)
|
||||||
|
sw s0, 256(sp)
|
||||||
|
addi a0, sp, -4
|
||||||
|
li a1, 0
|
||||||
|
li a2, 32
|
||||||
|
call
|
||||||
|
addi a0, sp, -8
|
||||||
|
li a1, 0
|
||||||
|
li a2, 32
|
||||||
|
call
|
||||||
|
li t2, 1
|
||||||
|
addi t0, sp, -8
|
||||||
|
li t1, 0
|
||||||
|
slli t1, t1, 2
|
||||||
|
add t0, t0, t1
|
||||||
|
sw t2, 0(t0)
|
||||||
|
li t2, 2
|
||||||
|
addi t0, sp, -8
|
||||||
|
li t1, 1
|
||||||
|
slli t1, t1, 2
|
||||||
|
add t0, t0, t1
|
||||||
|
sw t2, 0(t0)
|
||||||
|
li t2, 3
|
||||||
|
addi t0, sp, -8
|
||||||
|
li t1, 2
|
||||||
|
slli t1, t1, 2
|
||||||
|
add t0, t0, t1
|
||||||
|
sw t2, 0(t0)
|
||||||
|
li t2, 4
|
||||||
|
addi t0, sp, -8
|
||||||
|
li t1, 3
|
||||||
|
slli t1, t1, 2
|
||||||
|
add t0, t0, t1
|
||||||
|
sw t2, 0(t0)
|
||||||
|
li t2, 5
|
||||||
|
addi t0, sp, -8
|
||||||
|
li t1, 4
|
||||||
|
slli t1, t1, 2
|
||||||
|
add t0, t0, t1
|
||||||
|
sw t2, 0(t0)
|
||||||
|
li t2, 6
|
||||||
|
addi t0, sp, -8
|
||||||
|
li t1, 5
|
||||||
|
slli t1, t1, 2
|
||||||
|
add t0, t0, t1
|
||||||
|
sw t2, 0(t0)
|
||||||
|
li t2, 7
|
||||||
|
addi t0, sp, -8
|
||||||
|
li t1, 6
|
||||||
|
slli t1, t1, 2
|
||||||
|
add t0, t0, t1
|
||||||
|
sw t2, 0(t0)
|
||||||
|
li t2, 8
|
||||||
|
addi t0, sp, -8
|
||||||
|
li t1, 7
|
||||||
|
slli t1, t1, 2
|
||||||
|
add t0, t0, t1
|
||||||
|
sw t2, 0(t0)
|
||||||
|
addi a0, sp, -44
|
||||||
|
li a1, 0
|
||||||
|
li a2, 32
|
||||||
|
call
|
||||||
|
li t2, 1
|
||||||
|
addi t0, sp, -44
|
||||||
|
li t1, 0
|
||||||
|
slli t1, t1, 2
|
||||||
|
add t0, t0, t1
|
||||||
|
sw t2, 0(t0)
|
||||||
|
li t2, 2
|
||||||
|
addi t0, sp, -44
|
||||||
|
li t1, 1
|
||||||
|
slli t1, t1, 2
|
||||||
|
add t0, t0, t1
|
||||||
|
sw t2, 0(t0)
|
||||||
|
li t2, 3
|
||||||
|
addi t0, sp, -44
|
||||||
|
li t1, 2
|
||||||
|
slli t1, t1, 2
|
||||||
|
add t0, t0, t1
|
||||||
|
sw t2, 0(t0)
|
||||||
|
li t2, 4
|
||||||
|
addi t0, sp, -44
|
||||||
|
li t1, 3
|
||||||
|
slli t1, t1, 2
|
||||||
|
add t0, t0, t1
|
||||||
|
sw t2, 0(t0)
|
||||||
|
li t2, 5
|
||||||
|
addi t0, sp, -44
|
||||||
|
li t1, 4
|
||||||
|
slli t1, t1, 2
|
||||||
|
add t0, t0, t1
|
||||||
|
sw t2, 0(t0)
|
||||||
|
li t2, 6
|
||||||
|
addi t0, sp, -44
|
||||||
|
li t1, 5
|
||||||
|
slli t1, t1, 2
|
||||||
|
add t0, t0, t1
|
||||||
|
sw t2, 0(t0)
|
||||||
|
li t2, 7
|
||||||
|
addi t0, sp, -44
|
||||||
|
li t1, 6
|
||||||
|
slli t1, t1, 2
|
||||||
|
add t0, t0, t1
|
||||||
|
sw t2, 0(t0)
|
||||||
|
li t2, 8
|
||||||
|
addi t0, sp, -44
|
||||||
|
li t1, 7
|
||||||
|
slli t1, t1, 2
|
||||||
|
add t0, t0, t1
|
||||||
|
sw t2, 0(t0)
|
||||||
|
addi a0, sp, -80
|
||||||
|
li a1, 0
|
||||||
|
li a2, 32
|
||||||
|
call
|
||||||
|
li t2, 1
|
||||||
|
addi t0, sp, -80
|
||||||
|
li t1, 0
|
||||||
|
slli t1, t1, 2
|
||||||
|
add t0, t0, t1
|
||||||
|
sw t2, 0(t0)
|
||||||
|
li t2, 2
|
||||||
|
addi t0, sp, -80
|
||||||
|
li t1, 1
|
||||||
|
slli t1, t1, 2
|
||||||
|
add t0, t0, t1
|
||||||
|
sw t2, 0(t0)
|
||||||
|
li t2, 3
|
||||||
|
addi t0, sp, -80
|
||||||
|
li t1, 2
|
||||||
|
slli t1, t1, 2
|
||||||
|
add t0, t0, t1
|
||||||
|
sw t2, 0(t0)
|
||||||
|
li t2, 5
|
||||||
|
addi t0, sp, -80
|
||||||
|
li t1, 4
|
||||||
|
slli t1, t1, 2
|
||||||
|
add t0, t0, t1
|
||||||
|
sw t2, 0(t0)
|
||||||
|
li t2, 7
|
||||||
|
addi t0, sp, -80
|
||||||
|
li t1, 6
|
||||||
|
slli t1, t1, 2
|
||||||
|
add t0, t0, t1
|
||||||
|
sw t2, 0(t0)
|
||||||
|
li t2, 8
|
||||||
|
addi t0, sp, -80
|
||||||
|
li t1, 7
|
||||||
|
slli t1, t1, 2
|
||||||
|
add t0, t0, t1
|
||||||
|
sw t2, 0(t0)
|
||||||
|
li t0, 2
|
||||||
|
li t1, 2
|
||||||
|
mul t0, t0, t1
|
||||||
|
sw t0, -112(sp)
|
||||||
|
li t0, 1
|
||||||
|
lw t1, -112(sp)
|
||||||
|
add t0, t0, t1
|
||||||
|
sw t0, -116(sp)
|
||||||
|
addi t0, sp, -80
|
||||||
|
lw t1, -116(sp)
|
||||||
|
slli t1, t1, 2
|
||||||
|
add t0, t0, t1
|
||||||
|
lw t0, 0(t0)
|
||||||
|
sw t0, -124(sp)
|
||||||
|
li t0, 2
|
||||||
|
li t1, 2
|
||||||
|
mul t0, t0, t1
|
||||||
|
sw t0, -128(sp)
|
||||||
|
li t0, 1
|
||||||
|
lw t1, -128(sp)
|
||||||
|
add t0, t0, t1
|
||||||
|
sw t0, -132(sp)
|
||||||
|
addi t0, sp, -44
|
||||||
|
lw t1, -132(sp)
|
||||||
|
slli t1, t1, 2
|
||||||
|
add t0, t0, t1
|
||||||
|
lw t0, 0(t0)
|
||||||
|
sw t0, -140(sp)
|
||||||
|
addi a0, sp, -108
|
||||||
|
li a1, 0
|
||||||
|
li a2, 32
|
||||||
|
call
|
||||||
|
lw t2, -124(sp)
|
||||||
|
addi t0, sp, -108
|
||||||
|
li t1, 0
|
||||||
|
slli t1, t1, 2
|
||||||
|
add t0, t0, t1
|
||||||
|
sw t2, 0(t0)
|
||||||
|
lw t2, -140(sp)
|
||||||
|
addi t0, sp, -108
|
||||||
|
li t1, 1
|
||||||
|
slli t1, t1, 2
|
||||||
|
add t0, t0, t1
|
||||||
|
sw t2, 0(t0)
|
||||||
|
li t2, 3
|
||||||
|
addi t0, sp, -108
|
||||||
|
li t1, 2
|
||||||
|
slli t1, t1, 2
|
||||||
|
add t0, t0, t1
|
||||||
|
sw t2, 0(t0)
|
||||||
|
li t2, 4
|
||||||
|
addi t0, sp, -108
|
||||||
|
li t1, 3
|
||||||
|
slli t1, t1, 2
|
||||||
|
add t0, t0, t1
|
||||||
|
sw t2, 0(t0)
|
||||||
|
li t2, 5
|
||||||
|
addi t0, sp, -108
|
||||||
|
li t1, 4
|
||||||
|
slli t1, t1, 2
|
||||||
|
add t0, t0, t1
|
||||||
|
sw t2, 0(t0)
|
||||||
|
li t2, 6
|
||||||
|
addi t0, sp, -108
|
||||||
|
li t1, 5
|
||||||
|
slli t1, t1, 2
|
||||||
|
add t0, t0, t1
|
||||||
|
sw t2, 0(t0)
|
||||||
|
li t2, 7
|
||||||
|
addi t0, sp, -108
|
||||||
|
li t1, 6
|
||||||
|
slli t1, t1, 2
|
||||||
|
add t0, t0, t1
|
||||||
|
sw t2, 0(t0)
|
||||||
|
li t2, 8
|
||||||
|
addi t0, sp, -108
|
||||||
|
li t1, 7
|
||||||
|
slli t1, t1, 2
|
||||||
|
add t0, t0, t1
|
||||||
|
sw t2, 0(t0)
|
||||||
|
li t0, 3
|
||||||
|
li t1, 2
|
||||||
|
mul t0, t0, t1
|
||||||
|
sw t0, -176(sp)
|
||||||
|
li t0, 1
|
||||||
|
lw t1, -176(sp)
|
||||||
|
add t0, t0, t1
|
||||||
|
sw t0, -180(sp)
|
||||||
|
addi t0, sp, -108
|
||||||
|
lw t1, -180(sp)
|
||||||
|
slli t1, t1, 2
|
||||||
|
add t0, t0, t1
|
||||||
|
lw t0, 0(t0)
|
||||||
|
sw t0, -188(sp)
|
||||||
|
li t0, 0
|
||||||
|
li t1, 2
|
||||||
|
mul t0, t0, t1
|
||||||
|
sw t0, -192(sp)
|
||||||
|
li t0, 0
|
||||||
|
lw t1, -192(sp)
|
||||||
|
add t0, t0, t1
|
||||||
|
sw t0, -196(sp)
|
||||||
|
addi t0, sp, -108
|
||||||
|
lw t1, -196(sp)
|
||||||
|
slli t1, t1, 2
|
||||||
|
add t0, t0, t1
|
||||||
|
lw t0, 0(t0)
|
||||||
|
sw t0, -204(sp)
|
||||||
|
lw t0, -188(sp)
|
||||||
|
lw t1, -204(sp)
|
||||||
|
add t0, t0, t1
|
||||||
|
sw t0, -208(sp)
|
||||||
|
li t0, 0
|
||||||
|
li t1, 2
|
||||||
|
mul t0, t0, t1
|
||||||
|
sw t0, -212(sp)
|
||||||
|
li t0, 1
|
||||||
|
lw t1, -212(sp)
|
||||||
|
add t0, t0, t1
|
||||||
|
sw t0, -216(sp)
|
||||||
|
addi t0, sp, -108
|
||||||
|
lw t1, -216(sp)
|
||||||
|
slli t1, t1, 2
|
||||||
|
add t0, t0, t1
|
||||||
|
lw t0, 0(t0)
|
||||||
|
sw t0, -224(sp)
|
||||||
|
lw t0, -208(sp)
|
||||||
|
lw t1, -224(sp)
|
||||||
|
add t0, t0, t1
|
||||||
|
sw t0, -228(sp)
|
||||||
|
li t0, 2
|
||||||
|
li t1, 2
|
||||||
|
mul t0, t0, t1
|
||||||
|
sw t0, -232(sp)
|
||||||
|
li t0, 0
|
||||||
|
lw t1, -232(sp)
|
||||||
|
add t0, t0, t1
|
||||||
|
sw t0, -236(sp)
|
||||||
|
addi t0, sp, -4
|
||||||
|
lw t1, -236(sp)
|
||||||
|
slli t1, t1, 2
|
||||||
|
add t0, t0, t1
|
||||||
|
lw t0, 0(t0)
|
||||||
|
sw t0, -244(sp)
|
||||||
|
lw t0, -228(sp)
|
||||||
|
lw t1, -244(sp)
|
||||||
|
add t0, t0, t1
|
||||||
|
sw t0, -248(sp)
|
||||||
|
lw a0, -248(sp)
|
||||||
|
lw ra, 264(sp)
|
||||||
|
lw s0, 256(sp)
|
||||||
|
addi sp, sp, 272
|
||||||
|
ret
|
||||||
|
.size main, .-main
|
||||||
@ -0,0 +1,147 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
# 优化效果对比:测量 O0 vs O1 的编译时间和运行时间
|
||||||
|
# 用法: bash scripts/bench_ir.sh [--test-dir=<dir>] [--result-dir=<dir>]
|
||||||
|
|
||||||
|
set -uo pipefail
|
||||||
|
|
||||||
|
PROJECT_ROOT=$(cd "$(dirname "$0")/.." ; pwd)
|
||||||
|
TEST_CASE_DIR="${PROJECT_ROOT}/test/test_case"
|
||||||
|
RESULT_DIR="${PROJECT_ROOT}/test/test_result/bench"
|
||||||
|
|
||||||
|
while [[ $# -gt 0 ]]; do
|
||||||
|
case "$1" in
|
||||||
|
--test-dir=*) TEST_CASE_DIR="${1#*=}" ;;
|
||||||
|
--result-dir=*) RESULT_DIR="${1#*=}" ;;
|
||||||
|
*) echo "未知参数: $1" >&2; exit 1 ;;
|
||||||
|
esac
|
||||||
|
shift
|
||||||
|
done
|
||||||
|
|
||||||
|
compiler="${PROJECT_ROOT}/build/bin/compiler"
|
||||||
|
[[ -x "$compiler" ]] || { echo "错误:未找到编译器 $compiler" >&2; exit 1; }
|
||||||
|
command -v llc >/dev/null 2>&1 || { echo "错误:未找到 llc" >&2; exit 1; }
|
||||||
|
command -v clang >/dev/null 2>&1 || { echo "错误:未找到 clang" >&2; exit 1; }
|
||||||
|
|
||||||
|
mkdir -p "$RESULT_DIR"
|
||||||
|
|
||||||
|
# 时间测量:使用 date +%s.%N
|
||||||
|
now() { date +%s.%N; }
|
||||||
|
elapsed() { python3 -c "print(f'{float($2)-float($1):.4f}')" 2>/dev/null || awk "BEGIN{printf \"%.4f\\n\",$2-$1}"; }
|
||||||
|
|
||||||
|
summary_file="${RESULT_DIR}/summary.csv"
|
||||||
|
echo "test,opt,compile_s,exec_s,compile+exec_s" > "$summary_file"
|
||||||
|
|
||||||
|
total=0
|
||||||
|
o0_ct_total=0; o1_ct_total=0
|
||||||
|
o0_et_total=0; o1_et_total=0
|
||||||
|
|
||||||
|
echo "=== 优化效果对比 O0 vs O1 ==="
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
while read -r test_file; do
|
||||||
|
full_path=$(readlink -f "$test_file")
|
||||||
|
tcdir=$(readlink -f "$TEST_CASE_DIR")
|
||||||
|
rel="${full_path#$tcdir}"
|
||||||
|
[[ "${rel:0:1}" != "/" ]] && rel="/$rel"
|
||||||
|
|
||||||
|
base=$(basename "$test_file")
|
||||||
|
stem="${base%.sy}"
|
||||||
|
idir=$(dirname "$test_file")
|
||||||
|
stdin="${idir}/${stem}.in"
|
||||||
|
expected="${idir}/${stem}.out"
|
||||||
|
|
||||||
|
total=$((total+1))
|
||||||
|
printf "[%4d] %s" "$total" "$rel"
|
||||||
|
|
||||||
|
o0_ll="${RESULT_DIR}/O0/${rel%.sy}.ll"
|
||||||
|
o1_ll="${RESULT_DIR}/O1/${rel%.sy}.ll"
|
||||||
|
mkdir -p "$(dirname "$o0_ll")" "$(dirname "$o1_ll")"
|
||||||
|
|
||||||
|
# --- 编译 O0 ---
|
||||||
|
t1=$(now)
|
||||||
|
"$compiler" "$test_file" -IR -o "$o0_ll" 2>/dev/null; rc0=$?
|
||||||
|
t2=$(now)
|
||||||
|
if [[ $rc0 -ne 0 ]]; then
|
||||||
|
echo " | O0编译失败"
|
||||||
|
echo "$stem,O0,-,-,-" >> "$summary_file"
|
||||||
|
echo "$stem,O1,-,-,-" >> "$summary_file"
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
o0_ct=$(elapsed "$t1" "$t2")
|
||||||
|
|
||||||
|
# --- 编译 O1 ---
|
||||||
|
t1=$(now)
|
||||||
|
"$compiler" "$test_file" -IR -o "$o1_ll" -O1 2>/dev/null; rc1=$?
|
||||||
|
t2=$(now)
|
||||||
|
if [[ $rc1 -ne 0 ]]; then
|
||||||
|
echo " | O1编译失败"
|
||||||
|
echo "$stem,O0,$o0_ct,-,-" >> "$summary_file"
|
||||||
|
echo "$stem,O1,-,-,-" >> "$summary_file"
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
o1_ct=$(elapsed "$t1" "$t2")
|
||||||
|
|
||||||
|
# --- llc + clang O0 ---
|
||||||
|
o0_obj="${RESULT_DIR}/O0/${stem}.o"
|
||||||
|
o1_obj="${RESULT_DIR}/O1/${stem}.o"
|
||||||
|
o0_exe="${RESULT_DIR}/O0/${stem}.exe"
|
||||||
|
o1_exe="${RESULT_DIR}/O1/${stem}.exe"
|
||||||
|
|
||||||
|
llc -filetype=obj "$o0_ll" -o "$o0_obj" 2>/dev/null
|
||||||
|
llc -filetype=obj "$o1_ll" -o "$o1_obj" 2>/dev/null
|
||||||
|
clang "$o0_obj" "${PROJECT_ROOT}/sylib/sylib.c" -o "$o0_exe" -lm 2>/dev/null
|
||||||
|
clang "$o1_obj" "${PROJECT_ROOT}/sylib/sylib.c" -o "$o1_exe" -lm 2>/dev/null
|
||||||
|
|
||||||
|
# --- 运行 O0 ---
|
||||||
|
t1=$(now)
|
||||||
|
sr0=0
|
||||||
|
if [[ -f "$stdin" ]]; then
|
||||||
|
(ulimit -s unlimited; "$o0_exe" < "$stdin") > /dev/null 2>&1 || sr0=$?
|
||||||
|
else
|
||||||
|
(ulimit -s unlimited; "$o0_exe") > /dev/null 2>&1 || sr0=$?
|
||||||
|
fi
|
||||||
|
t2=$(now)
|
||||||
|
o0_et=$(elapsed "$t1" "$t2")
|
||||||
|
|
||||||
|
# --- 运行 O1 ---
|
||||||
|
t1=$(now)
|
||||||
|
sr1=0
|
||||||
|
if [[ -f "$stdin" ]]; then
|
||||||
|
(ulimit -s unlimited; "$o1_exe" < "$stdin") > /dev/null 2>&1 || sr1=$?
|
||||||
|
else
|
||||||
|
(ulimit -s unlimited; "$o1_exe") > /dev/null 2>&1 || sr1=$?
|
||||||
|
fi
|
||||||
|
t2=$(now)
|
||||||
|
o1_et=$(elapsed "$t1" "$t2")
|
||||||
|
|
||||||
|
# 验证一致性
|
||||||
|
flag=""
|
||||||
|
if [[ $sr0 -ne $sr1 ]]; then
|
||||||
|
flag=" EXIT:O0=$sr0 O1=$sr1"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 累计 & 比率
|
||||||
|
o0_ct_total=$(awk "BEGIN{printf \"%.4f\",$o0_ct_total+$o0_ct}")
|
||||||
|
o1_ct_total=$(awk "BEGIN{printf \"%.4f\",$o1_ct_total+$o1_ct}")
|
||||||
|
o0_et_total=$(awk "BEGIN{printf \"%.4f\",$o0_et_total+$o0_et}")
|
||||||
|
o1_et_total=$(awk "BEGIN{printf \"%.4f\",$o1_et_total+$o1_et}")
|
||||||
|
|
||||||
|
cspd=$(awk "BEGIN{if($o1_ct>0)printf \"%.1fx\",$o0_ct/$o1_ct; else print \"-\"}")
|
||||||
|
espd=$(awk "BEGIN{if($o1_et>0)printf \"%.1fx\",$o0_et/$o1_et; else print \"-\"}")
|
||||||
|
|
||||||
|
printf " | 编译 O0:%.4fs O1:%.4fs(%s) 运行 O0:%.4fs O1:%.4fs(%s)%s\n" \
|
||||||
|
"$o0_ct" "$o1_ct" "$cspd" "$o0_et" "$o1_et" "$espd" "$flag"
|
||||||
|
|
||||||
|
echo "$stem,O0,$o0_ct,$o0_et,$(awk "BEGIN{printf \"%.4f\",$o0_ct+$o0_et}")" >> "$summary_file"
|
||||||
|
echo "$stem,O1,$o1_ct,$o1_et,$(awk "BEGIN{printf \"%.4f\",$o1_ct+$o1_et}")" >> "$summary_file"
|
||||||
|
|
||||||
|
done < <(find "$TEST_CASE_DIR" -name "*.sy" | sort)
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "============================================"
|
||||||
|
echo "总用例: $total"
|
||||||
|
echo "O0 编译总耗时: ${o0_ct_total}s"
|
||||||
|
echo "O1 编译总耗时: ${o1_ct_total}s"
|
||||||
|
echo "O0 运行总耗时: ${o0_et_total}s"
|
||||||
|
echo "O1 运行总耗时: ${o1_et_total}s"
|
||||||
|
echo "CSV: $summary_file"
|
||||||
@ -0,0 +1,100 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
import sys
|
||||||
|
|
||||||
|
def read_file(filepath):
|
||||||
|
"""读取文件内容,返回行列表"""
|
||||||
|
try:
|
||||||
|
with open(filepath, 'r', encoding='utf-8') as f:
|
||||||
|
return f.readlines()
|
||||||
|
except FileNotFoundError:
|
||||||
|
print(f"错误:文件 '{filepath}' 不存在")
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
def get_context(line, pos, context_len=10):
|
||||||
|
"""获取字符上下文"""
|
||||||
|
start = max(0, pos - context_len)
|
||||||
|
end = min(len(line), pos + context_len + 1)
|
||||||
|
prefix = "..." if start > 0 else ""
|
||||||
|
suffix = "..." if end < len(line) else ""
|
||||||
|
return prefix + line[start:end] + suffix
|
||||||
|
|
||||||
|
def compare_files(file1, file2):
|
||||||
|
"""比较两个文件,输出详细差异"""
|
||||||
|
lines1 = read_file(file1)
|
||||||
|
lines2 = read_file(file2)
|
||||||
|
|
||||||
|
print(f"比较文件: {file1} vs {file2}")
|
||||||
|
print("=" * 80)
|
||||||
|
|
||||||
|
max_lines = max(len(lines1), len(lines2))
|
||||||
|
differences = 0
|
||||||
|
|
||||||
|
for line_num in range(max_lines):
|
||||||
|
line1 = lines1[line_num] if line_num < len(lines1) else None
|
||||||
|
line2 = lines2[line_num] if line_num < len(lines2) else None
|
||||||
|
|
||||||
|
if line1 is None:
|
||||||
|
print(f"\n[新增行] 第 {line_num + 1} 行")
|
||||||
|
print(f" + {repr(line2)}")
|
||||||
|
differences += 1
|
||||||
|
continue
|
||||||
|
|
||||||
|
if line2 is None:
|
||||||
|
print(f"\n[删除行] 第 {line_num + 1} 行")
|
||||||
|
print(f" - {repr(line1)}")
|
||||||
|
differences += 1
|
||||||
|
continue
|
||||||
|
|
||||||
|
if line1 == line2:
|
||||||
|
continue
|
||||||
|
|
||||||
|
# 行内容不同,逐字符比较
|
||||||
|
print(f"\n[差异行] 第 {line_num + 1} 行")
|
||||||
|
|
||||||
|
max_chars = max(len(line1), len(line2))
|
||||||
|
for char_pos in range(max_chars):
|
||||||
|
char1 = line1[char_pos] if char_pos < len(line1) else None
|
||||||
|
char2 = line2[char_pos] if char_pos < len(line2) else None
|
||||||
|
|
||||||
|
if char1 == char2:
|
||||||
|
continue
|
||||||
|
|
||||||
|
# 找到差异字符
|
||||||
|
context1 = get_context(line1, char_pos) if line1 else ""
|
||||||
|
context2 = get_context(line2, char_pos) if line2 else ""
|
||||||
|
|
||||||
|
print(f" 字符位置 {char_pos + 1}:")
|
||||||
|
if char1 is not None:
|
||||||
|
print(f" - {repr(char1)} | 上下文: {repr(context1)}")
|
||||||
|
else:
|
||||||
|
print(f" - (缺失)")
|
||||||
|
if char2 is not None:
|
||||||
|
print(f" + {repr(char2)} | 上下文: {repr(context2)}")
|
||||||
|
else:
|
||||||
|
print(f" + (缺失)")
|
||||||
|
differences += 1
|
||||||
|
|
||||||
|
# 跳过一些连续差异,避免输出过多
|
||||||
|
while char_pos + 1 < max_chars:
|
||||||
|
next_char1 = line1[char_pos + 1] if char_pos + 1 < len(line1) else None
|
||||||
|
next_char2 = line2[char_pos + 1] if char_pos + 1 < len(line2) else None
|
||||||
|
if next_char1 != next_char2:
|
||||||
|
char_pos += 1
|
||||||
|
else:
|
||||||
|
break
|
||||||
|
|
||||||
|
print("\n" + "=" * 80)
|
||||||
|
print(f"比较完成,共发现 {differences} 处差异")
|
||||||
|
|
||||||
|
def main():
|
||||||
|
if len(sys.argv) != 3:
|
||||||
|
print("用法: python diff.py <文件1> <文件2>")
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
file1 = sys.argv[1]
|
||||||
|
file2 = sys.argv[2]
|
||||||
|
|
||||||
|
compare_files(file1, file2)
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
Binary file not shown.
@ -0,0 +1,101 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
PROJECT_ROOT=$(cd "$(dirname "$0")/.." ; pwd)
|
||||||
|
|
||||||
|
if [[ $# -lt 1 || $# -gt 3 ]]; then
|
||||||
|
echo "用法: $0 <input.sy> [output_dir] [--run]" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
input=$1
|
||||||
|
out_dir="test/test_result/mir"
|
||||||
|
run_exec=false
|
||||||
|
input_dir=$(dirname "$input")
|
||||||
|
|
||||||
|
shift
|
||||||
|
while [[ $# -gt 0 ]]; do
|
||||||
|
case "$1" in
|
||||||
|
--run)
|
||||||
|
run_exec=true
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
out_dir="$1"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
shift
|
||||||
|
done
|
||||||
|
|
||||||
|
if [[ ! -f "$input" ]]; then
|
||||||
|
echo "输入文件不存在: $input" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
compiler="$PROJECT_ROOT/build/bin/compiler"
|
||||||
|
if [[ ! -x "$compiler" ]]; then
|
||||||
|
echo "未找到编译器: $compiler ,请先构建。" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
mkdir -p "$out_dir"
|
||||||
|
base=$(basename "$input")
|
||||||
|
stem=${base%.sy}
|
||||||
|
mir_file="$out_dir/$stem.mir"
|
||||||
|
asm_file="$out_dir/$stem.s"
|
||||||
|
exe="$out_dir/$stem"
|
||||||
|
stdin_file="$input_dir/$stem.in"
|
||||||
|
expected_file="$input_dir/$stem.out"
|
||||||
|
|
||||||
|
# 生成 MIR
|
||||||
|
"$compiler" --emit-mir "$input" > "$mir_file"
|
||||||
|
echo "MIR 已生成: $mir_file"
|
||||||
|
|
||||||
|
# 生成汇编
|
||||||
|
"$compiler" --emit-asm "$input" > "$asm_file"
|
||||||
|
echo "汇编已生成: $asm_file"
|
||||||
|
|
||||||
|
if [[ "$run_exec" == true ]]; then
|
||||||
|
if ! command -v riscv64-linux-gnu-gcc >/dev/null 2>&1; then
|
||||||
|
echo "未找到 riscv64-linux-gnu-gcc" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
if ! command -v qemu-riscv64 >/dev/null 2>&1; then
|
||||||
|
echo "未找到 qemu-riscv64" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
riscv64-linux-gnu-gcc -static "$asm_file" -o "$exe" -no-pie
|
||||||
|
|
||||||
|
stdout_file="$out_dir/$stem.stdout"
|
||||||
|
actual_file="$out_dir/$stem.actual.out"
|
||||||
|
echo "运行 $exe ..."
|
||||||
|
set +e
|
||||||
|
if [[ -f "$stdin_file" ]]; then
|
||||||
|
qemu-riscv64 "$exe" < "$stdin_file" > "$stdout_file"
|
||||||
|
else
|
||||||
|
qemu-riscv64 "$exe" > "$stdout_file"
|
||||||
|
fi
|
||||||
|
status=$?
|
||||||
|
set -e
|
||||||
|
cat "$stdout_file"
|
||||||
|
echo "退出码: $status"
|
||||||
|
{
|
||||||
|
cat "$stdout_file"
|
||||||
|
if [[ -s "$stdout_file" ]] && (( $(tail -c 1 "$stdout_file" | wc -l) == 0 )); then
|
||||||
|
printf '\n'
|
||||||
|
fi
|
||||||
|
printf '%s\n' "$status"
|
||||||
|
} > "$actual_file"
|
||||||
|
|
||||||
|
if [[ -f "$expected_file" ]]; then
|
||||||
|
if diff -u "$expected_file" "$actual_file"; then
|
||||||
|
echo "输出匹配: $expected_file"
|
||||||
|
else
|
||||||
|
echo "输出不匹配: $expected_file" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
echo "未找到预期输出文件,跳过比对: $expected_file"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
@ -1,4 +1,205 @@
|
|||||||
// 支配树分析:
|
// 支配树分析:
|
||||||
// - 构建/查询 Dominator Tree 及相关关系
|
// - 构建/查询 Dominator Tree 及相关关系
|
||||||
// - 为 mem2reg、CFG 优化与循环分析提供基础能力
|
// - 使用 Cooper-Harvey-Kennedy 算法,近线性时间复杂度
|
||||||
|
|
||||||
|
#include "ir/IR.h"
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
#include <functional>
|
||||||
|
#include <queue>
|
||||||
|
#include <unordered_map>
|
||||||
|
#include <unordered_set>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
namespace ir {
|
||||||
|
|
||||||
|
void DominatorTree::Compute(Function& func) {
|
||||||
|
func.RebuildCFG();
|
||||||
|
|
||||||
|
// Build block list and reverse postorder (RPO)
|
||||||
|
std::vector<BasicBlock*> blocks;
|
||||||
|
std::unordered_map<BasicBlock*, int> rpo;
|
||||||
|
{
|
||||||
|
std::vector<BasicBlock*> rpo_vec;
|
||||||
|
std::unordered_set<BasicBlock*> visited;
|
||||||
|
std::function<void(BasicBlock*)> dfs = [&](BasicBlock* bb) {
|
||||||
|
if (!bb || visited.count(bb)) return;
|
||||||
|
visited.insert(bb);
|
||||||
|
for (auto* succ : bb->GetSuccessors()) {
|
||||||
|
dfs(succ);
|
||||||
|
}
|
||||||
|
rpo_vec.push_back(bb);
|
||||||
|
};
|
||||||
|
dfs(func.GetEntry());
|
||||||
|
// Reverse to get RPO (postorder reversed)
|
||||||
|
std::reverse(rpo_vec.begin(), rpo_vec.end());
|
||||||
|
blocks = rpo_vec;
|
||||||
|
for (int i = 0; i < (int)blocks.size(); ++i) {
|
||||||
|
rpo[blocks[i]] = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (blocks.empty()) return;
|
||||||
|
int n = (int)blocks.size();
|
||||||
|
|
||||||
|
auto* entry = func.GetEntry();
|
||||||
|
if (!entry) return;
|
||||||
|
|
||||||
|
// ─── 1. CHK algorithm for immediate dominators ─────────────────────────
|
||||||
|
idom_.clear();
|
||||||
|
idom_[entry] = entry; // entry is its own dominator
|
||||||
|
|
||||||
|
// Intersect: find common ancestor of b1 and b2 walking up the dom tree
|
||||||
|
// Uses RPO number: a dominator always has lower RPO number
|
||||||
|
auto intersect = [&](BasicBlock* b1, BasicBlock* b2) -> BasicBlock* {
|
||||||
|
auto i1 = rpo.find(b1), i2 = rpo.find(b2);
|
||||||
|
if (i1 == rpo.end() || i2 == rpo.end()) return entry;
|
||||||
|
int r1 = i1->second, r2 = i2->second;
|
||||||
|
while (b1 != b2) {
|
||||||
|
while (r1 > r2) {
|
||||||
|
auto it = idom_.find(b1);
|
||||||
|
if (it == idom_.end() || it->second == b1) return b1;
|
||||||
|
b1 = it->second;
|
||||||
|
r1 = rpo[b1];
|
||||||
|
}
|
||||||
|
while (r2 > r1) {
|
||||||
|
auto it = idom_.find(b2);
|
||||||
|
if (it == idom_.end() || it->second == b2) return b2;
|
||||||
|
b2 = it->second;
|
||||||
|
r2 = rpo[b2];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return b1;
|
||||||
|
};
|
||||||
|
|
||||||
|
bool changed = true;
|
||||||
|
while (changed) {
|
||||||
|
changed = false;
|
||||||
|
// Process in RPO (skip entry which is first in RPO)
|
||||||
|
for (int i = 1; i < n; ++i) {
|
||||||
|
auto* bb = blocks[i];
|
||||||
|
// Find first predecessor with defined IDOM
|
||||||
|
BasicBlock* new_idom = nullptr;
|
||||||
|
for (auto* pred : bb->GetPredecessors()) {
|
||||||
|
if (idom_.count(pred) && pred != bb) {
|
||||||
|
new_idom = pred;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!new_idom) continue;
|
||||||
|
|
||||||
|
// Intersect with remaining predecessors
|
||||||
|
for (auto* pred : bb->GetPredecessors()) {
|
||||||
|
if (pred == new_idom || pred == bb) continue;
|
||||||
|
if (idom_.count(pred)) {
|
||||||
|
new_idom = intersect(pred, new_idom);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
auto old = idom_.find(bb);
|
||||||
|
if (old == idom_.end() || old->second != new_idom) {
|
||||||
|
idom_[bb] = new_idom;
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Entry is its own IDOM, set to nullptr for external queries
|
||||||
|
idom_[entry] = nullptr;
|
||||||
|
|
||||||
|
// Unreached blocks get entry as IDOM
|
||||||
|
for (auto* bb : blocks) {
|
||||||
|
if (!idom_.count(bb)) idom_[bb] = entry;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ─── 2. Build children map and dom levels ──────────────────────────────
|
||||||
|
children_.clear();
|
||||||
|
dom_level_.clear();
|
||||||
|
for (auto& [child, parent] : idom_) {
|
||||||
|
if (parent) children_[parent].push_back(child);
|
||||||
|
}
|
||||||
|
|
||||||
|
// BFS to compute dom levels
|
||||||
|
std::queue<BasicBlock*> q;
|
||||||
|
dom_level_[entry] = 0;
|
||||||
|
q.push(entry);
|
||||||
|
while (!q.empty()) {
|
||||||
|
auto* cur = q.front();
|
||||||
|
q.pop();
|
||||||
|
size_t cur_level = dom_level_[cur];
|
||||||
|
auto it = children_.find(cur);
|
||||||
|
if (it != children_.end()) {
|
||||||
|
for (auto* child : it->second) {
|
||||||
|
dom_level_[child] = cur_level + 1;
|
||||||
|
q.push(child);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ─── 3. Compute dominance frontier ─────────────────────────────────────
|
||||||
|
df_.clear();
|
||||||
|
for (int i = 0; i < n; ++i) {
|
||||||
|
auto* b = blocks[i];
|
||||||
|
if (b->GetPredecessors().size() < 2) continue;
|
||||||
|
for (auto* p : b->GetPredecessors()) {
|
||||||
|
auto* runner = p;
|
||||||
|
auto* b_idom = GetIDom(b);
|
||||||
|
while (runner != b_idom) {
|
||||||
|
if (!runner) break;
|
||||||
|
df_[runner].push_back(b);
|
||||||
|
runner = GetIDom(runner);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Deduplicate DF entries
|
||||||
|
for (auto& [bb, vec] : df_) {
|
||||||
|
std::sort(vec.begin(), vec.end());
|
||||||
|
vec.erase(std::unique(vec.begin(), vec.end()), vec.end());
|
||||||
|
}
|
||||||
|
|
||||||
|
// ─── 4. Compute DFS order of dominator tree ────────────────────────────
|
||||||
|
df_order_.clear();
|
||||||
|
visited_.clear();
|
||||||
|
std::function<void(BasicBlock*)> dfs_tree = [&](BasicBlock* bb) {
|
||||||
|
if (!bb || visited_.count(bb)) return;
|
||||||
|
visited_.insert(bb);
|
||||||
|
df_order_.push_back(bb);
|
||||||
|
auto it = children_.find(bb);
|
||||||
|
if (it != children_.end()) {
|
||||||
|
for (auto* child : it->second) {
|
||||||
|
dfs_tree(child);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
dfs_tree(entry);
|
||||||
|
}
|
||||||
|
|
||||||
|
BasicBlock* DominatorTree::GetIDom(BasicBlock* bb) const {
|
||||||
|
auto it = idom_.find(bb);
|
||||||
|
return (it != idom_.end()) ? it->second : nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::vector<BasicBlock*>& DominatorTree::GetChildren(
|
||||||
|
BasicBlock* bb) const {
|
||||||
|
static const std::vector<BasicBlock*> empty;
|
||||||
|
auto it = children_.find(bb);
|
||||||
|
return (it != children_.end()) ? it->second : empty;
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::vector<BasicBlock*>& DominatorTree::GetDominanceFrontier(
|
||||||
|
BasicBlock* bb) const {
|
||||||
|
static const std::vector<BasicBlock*> empty;
|
||||||
|
auto it = df_.find(bb);
|
||||||
|
return (it != df_.end()) ? it->second : empty;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool DominatorTree::Dominates(BasicBlock* a, BasicBlock* b) const {
|
||||||
|
if (a == b) return true;
|
||||||
|
BasicBlock* runner = b;
|
||||||
|
while (runner) {
|
||||||
|
runner = GetIDom(runner);
|
||||||
|
if (runner == a) return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace ir
|
||||||
|
|||||||
@ -1,4 +1,187 @@
|
|||||||
// IR 常量折叠:
|
// IR 常量折叠:
|
||||||
// - 折叠可判定的常量表达式
|
// - 折叠可判定的常量表达式
|
||||||
// - 简化常量控制流分支(按实现范围裁剪)
|
// - 简化常量控制流分支
|
||||||
|
|
||||||
|
#include "ir/IR.h"
|
||||||
|
|
||||||
|
#include <unordered_set>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
namespace ir {
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
// 在释放指令前断开其 use-def 链,避免其他值的 uses_ 中有悬空指针
|
||||||
|
static void DetachAndRemove(Instruction* inst) {
|
||||||
|
// 先断开自身对操作数的引用,清除 use-def 链
|
||||||
|
for (size_t i = 0; i < inst->GetNumOperands(); ++i)
|
||||||
|
inst->SetOperand(i, nullptr);
|
||||||
|
// 然后从父块中移除(清除父指针后不会再次尝试访问)
|
||||||
|
if (auto* parent = inst->GetParent()) {
|
||||||
|
parent->RemoveInstruction(inst);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool FoldICmp(ICmpInst* cmp, Context& ctx) {
|
||||||
|
auto* lhs = dynamic_cast<ConstantInt*>(cmp->GetLhs());
|
||||||
|
auto* rhs = dynamic_cast<ConstantInt*>(cmp->GetRhs());
|
||||||
|
if (!lhs || !rhs) return false;
|
||||||
|
|
||||||
|
int lv = lhs->GetValue(), rv = rhs->GetValue();
|
||||||
|
bool result = false;
|
||||||
|
switch (cmp->GetPredicate()) {
|
||||||
|
case ICmpPredicate::EQ: result = lv == rv; break;
|
||||||
|
case ICmpPredicate::NE: result = lv != rv; break;
|
||||||
|
case ICmpPredicate::SLT: result = lv < rv; break;
|
||||||
|
case ICmpPredicate::SLE: result = lv <= rv; break;
|
||||||
|
case ICmpPredicate::SGT: result = lv > rv; break;
|
||||||
|
case ICmpPredicate::SGE: result = lv >= rv; break;
|
||||||
|
}
|
||||||
|
cmp->ReplaceAllUsesWith(ctx.GetConstInt(result ? 1 : 0));
|
||||||
|
DetachAndRemove(cmp);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool FoldFCmp(FCmpInst* cmp, Context& ctx) {
|
||||||
|
auto* lhs = dynamic_cast<ConstantFloat*>(cmp->GetLhs());
|
||||||
|
auto* rhs = dynamic_cast<ConstantFloat*>(cmp->GetRhs());
|
||||||
|
if (!lhs || !rhs) return false;
|
||||||
|
|
||||||
|
float lv = lhs->GetValue(), rv = rhs->GetValue();
|
||||||
|
bool result = false;
|
||||||
|
switch (cmp->GetPredicate()) {
|
||||||
|
case FCmpPredicate::OEQ: result = lv == rv; break;
|
||||||
|
case FCmpPredicate::ONE: result = lv != rv; break;
|
||||||
|
case FCmpPredicate::OLT: result = lv < rv; break;
|
||||||
|
case FCmpPredicate::OLE: result = lv <= rv; break;
|
||||||
|
case FCmpPredicate::OGT: result = lv > rv; break;
|
||||||
|
case FCmpPredicate::OGE: result = lv >= rv; break;
|
||||||
|
}
|
||||||
|
cmp->ReplaceAllUsesWith(ctx.GetConstInt(result ? 1 : 0));
|
||||||
|
DetachAndRemove(cmp);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool FoldZExt(ZExtInst* zext, Context& ctx) {
|
||||||
|
auto* src = dynamic_cast<ConstantInt*>(zext->GetSrc());
|
||||||
|
if (!src) return false;
|
||||||
|
zext->ReplaceAllUsesWith(ctx.GetConstInt(src->GetValue() != 0 ? 1 : 0));
|
||||||
|
DetachAndRemove(zext);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool FoldSIToFP(SIToFPInst* inst, Context& ctx) {
|
||||||
|
auto* src = dynamic_cast<ConstantInt*>(inst->GetSrc());
|
||||||
|
if (!src) return false;
|
||||||
|
inst->ReplaceAllUsesWith(ctx.GetConstFloat(static_cast<float>(src->GetValue())));
|
||||||
|
DetachAndRemove(inst);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool FoldFPToSI(FPToSIInst* inst, Context& ctx) {
|
||||||
|
auto* src = dynamic_cast<ConstantFloat*>(inst->GetSrc());
|
||||||
|
if (!src) return false;
|
||||||
|
inst->ReplaceAllUsesWith(ctx.GetConstInt(static_cast<int>(src->GetValue())));
|
||||||
|
DetachAndRemove(inst);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fold constant binary operations (int and float)
|
||||||
|
bool FoldBinaryWithCtx(BinaryInst* bin, Context& ctx) {
|
||||||
|
auto* lhs_c = dynamic_cast<ConstantInt*>(bin->GetLhs());
|
||||||
|
auto* rhs_c = dynamic_cast<ConstantInt*>(bin->GetRhs());
|
||||||
|
auto* lhs_f = dynamic_cast<ConstantFloat*>(bin->GetLhs());
|
||||||
|
auto* rhs_f = dynamic_cast<ConstantFloat*>(bin->GetRhs());
|
||||||
|
|
||||||
|
if (lhs_c && rhs_c) {
|
||||||
|
int lv = lhs_c->GetValue(), rv = rhs_c->GetValue();
|
||||||
|
int result = 0;
|
||||||
|
bool valid = true;
|
||||||
|
switch (bin->GetOpcode()) {
|
||||||
|
case Opcode::Add: result = lv + rv; break;
|
||||||
|
case Opcode::Sub: result = lv - rv; break;
|
||||||
|
case Opcode::Mul: result = lv * rv; break;
|
||||||
|
case Opcode::Div: if (rv != 0) result = lv / rv; else valid = false; break;
|
||||||
|
case Opcode::Mod: if (rv != 0) result = lv % rv; else valid = false; break;
|
||||||
|
default: valid = false; break;
|
||||||
|
}
|
||||||
|
if (valid) {
|
||||||
|
bin->ReplaceAllUsesWith(ctx.GetConstInt(result));
|
||||||
|
DetachAndRemove(bin);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (lhs_f && rhs_f) {
|
||||||
|
float lv = lhs_f->GetValue(), rv = rhs_f->GetValue();
|
||||||
|
float result = 0.0f;
|
||||||
|
bool valid = true;
|
||||||
|
switch (bin->GetOpcode()) {
|
||||||
|
case Opcode::FAdd: result = lv + rv; break;
|
||||||
|
case Opcode::FSub: result = lv - rv; break;
|
||||||
|
case Opcode::FMul: result = lv * rv; break;
|
||||||
|
case Opcode::FDiv: if (rv != 0.0f) result = lv / rv; else valid = false; break;
|
||||||
|
default: valid = false; break;
|
||||||
|
}
|
||||||
|
if (valid) {
|
||||||
|
bin->ReplaceAllUsesWith(ctx.GetConstFloat(result));
|
||||||
|
DetachAndRemove(bin);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
bool RunConstFold(Function& func, Context& ctx) {
|
||||||
|
bool changed = false;
|
||||||
|
std::unordered_set<void*> removed;
|
||||||
|
|
||||||
|
bool any_changed = true;
|
||||||
|
while (any_changed) {
|
||||||
|
any_changed = false;
|
||||||
|
for (auto& bb : func.GetBlocks()) {
|
||||||
|
// 每轮重新收集(因为指令列表在变化)
|
||||||
|
std::vector<Instruction*> insts;
|
||||||
|
for (auto& inst : bb->GetInstructions())
|
||||||
|
insts.push_back(inst.get());
|
||||||
|
|
||||||
|
for (auto* inst : insts) {
|
||||||
|
if (removed.count(inst)) continue;
|
||||||
|
bool folded = false;
|
||||||
|
switch (inst->GetOpcode()) {
|
||||||
|
case Opcode::Add: case Opcode::Sub: case Opcode::Mul:
|
||||||
|
case Opcode::Div: case Opcode::Mod:
|
||||||
|
case Opcode::FAdd: case Opcode::FSub:
|
||||||
|
case Opcode::FMul: case Opcode::FDiv:
|
||||||
|
folded = FoldBinaryWithCtx(static_cast<BinaryInst*>(inst), ctx);
|
||||||
|
break;
|
||||||
|
case Opcode::ICmp:
|
||||||
|
folded = FoldICmp(static_cast<ICmpInst*>(inst), ctx);
|
||||||
|
break;
|
||||||
|
case Opcode::FCmp:
|
||||||
|
folded = FoldFCmp(static_cast<FCmpInst*>(inst), ctx);
|
||||||
|
break;
|
||||||
|
case Opcode::ZExt:
|
||||||
|
folded = FoldZExt(static_cast<ZExtInst*>(inst), ctx);
|
||||||
|
break;
|
||||||
|
case Opcode::SIToFP:
|
||||||
|
folded = FoldSIToFP(static_cast<SIToFPInst*>(inst), ctx);
|
||||||
|
break;
|
||||||
|
case Opcode::FPToSI:
|
||||||
|
folded = FoldFPToSI(static_cast<FPToSIInst*>(inst), ctx);
|
||||||
|
break;
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
if (folded) {
|
||||||
|
removed.insert(inst);
|
||||||
|
any_changed = true;
|
||||||
|
changed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return changed;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace ir
|
||||||
|
|||||||
Binary file not shown.
@ -1,4 +1,83 @@
|
|||||||
// SysY 运行库实现:
|
#include<stdio.h>
|
||||||
// - 按实验/评测规范提供 I/O 等函数实现
|
#include<stdarg.h>
|
||||||
// - 与编译器生成的目标代码链接,支撑运行时行为
|
#include<sys/time.h>
|
||||||
|
#include"sylib.h"
|
||||||
|
/* Input & output functions */
|
||||||
|
int getint(){int t; scanf("%d",&t); return t; }
|
||||||
|
int getch(){char c; scanf("%c",&c); return (int)c; }
|
||||||
|
float getfloat(){
|
||||||
|
float n;
|
||||||
|
scanf("%a", &n);
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
|
||||||
|
int getarray(int a[]){
|
||||||
|
int n;
|
||||||
|
scanf("%d",&n);
|
||||||
|
for(int i=0;i<n;i++)scanf("%d",&a[i]);
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
|
||||||
|
int getfarray(float a[]) {
|
||||||
|
int n;
|
||||||
|
scanf("%d", &n);
|
||||||
|
for (int i = 0; i < n; i++) {
|
||||||
|
scanf("%a", &a[i]);
|
||||||
|
}
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
void putint(int a){ printf("%d",a);}
|
||||||
|
void putch(int a){ printf("%c",a); }
|
||||||
|
void putarray(int n,int a[]){
|
||||||
|
printf("%d:",n);
|
||||||
|
for(int i=0;i<n;i++)printf(" %d",a[i]);
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
void putfloat(float a) {
|
||||||
|
printf("%a", a);
|
||||||
|
}
|
||||||
|
void putfarray(int n, float a[]) {
|
||||||
|
printf("%d:", n);
|
||||||
|
for (int i = 0; i < n; i++) {
|
||||||
|
printf(" %a", a[i]);
|
||||||
|
}
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
void putf(char a[], ...) {
|
||||||
|
va_list args;
|
||||||
|
va_start(args, a);
|
||||||
|
vfprintf(stdout, a, args);
|
||||||
|
va_end(args);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Timing function implementation */
|
||||||
|
__attribute((constructor)) void before_main(){
|
||||||
|
for(int i=0;i<_SYSY_N;i++)
|
||||||
|
_sysy_h[i] = _sysy_m[i]= _sysy_s[i] = _sysy_us[i] =0;
|
||||||
|
_sysy_idx=1;
|
||||||
|
}
|
||||||
|
__attribute((destructor)) void after_main(){
|
||||||
|
for(int i=1;i<_sysy_idx;i++){
|
||||||
|
fprintf(stderr,"Timer@%04d-%04d: %dH-%dM-%dS-%dus\n",\
|
||||||
|
_sysy_l1[i],_sysy_l2[i],_sysy_h[i],_sysy_m[i],_sysy_s[i],_sysy_us[i]);
|
||||||
|
_sysy_us[0]+= _sysy_us[i];
|
||||||
|
_sysy_s[0] += _sysy_s[i]; _sysy_us[0] %= 1000000;
|
||||||
|
_sysy_m[0] += _sysy_m[i]; _sysy_s[0] %= 60;
|
||||||
|
_sysy_h[0] += _sysy_h[i]; _sysy_m[0] %= 60;
|
||||||
|
}
|
||||||
|
fprintf(stderr,"TOTAL: %dH-%dM-%dS-%dus\n",_sysy_h[0],_sysy_m[0],_sysy_s[0],_sysy_us[0]);
|
||||||
|
}
|
||||||
|
void _sysy_starttime(int lineno){
|
||||||
|
_sysy_l1[_sysy_idx] = lineno;
|
||||||
|
gettimeofday(&_sysy_start,NULL);
|
||||||
|
}
|
||||||
|
void _sysy_stoptime(int lineno){
|
||||||
|
gettimeofday(&_sysy_end,NULL);
|
||||||
|
_sysy_l2[_sysy_idx] = lineno;
|
||||||
|
_sysy_us[_sysy_idx] += 1000000 * ( _sysy_end.tv_sec - _sysy_start.tv_sec ) + _sysy_end.tv_usec - _sysy_start.tv_usec;
|
||||||
|
_sysy_s[_sysy_idx] += _sysy_us[_sysy_idx] / 1000000 ; _sysy_us[_sysy_idx] %= 1000000;
|
||||||
|
_sysy_m[_sysy_idx] += _sysy_s[_sysy_idx] / 60 ; _sysy_s[_sysy_idx] %= 60;
|
||||||
|
_sysy_h[_sysy_idx] += _sysy_m[_sysy_idx] / 60 ; _sysy_m[_sysy_idx] %= 60;
|
||||||
|
_sysy_idx ++;
|
||||||
|
}
|
||||||
|
|||||||
@ -1,4 +1,31 @@
|
|||||||
// SysY 运行库头文件:
|
#ifndef __SYLIB_H_
|
||||||
// - 声明运行库函数原型(供编译器生成 call 或链接阶段引用)
|
#define __SYLIB_H_
|
||||||
// - 与 sylib.c 配套,按规范逐步补齐声明
|
|
||||||
|
|
||||||
|
#include<stdio.h>
|
||||||
|
#include<stdarg.h>
|
||||||
|
#include<sys/time.h>
|
||||||
|
/* Input & output functions */
|
||||||
|
int getint(),getch(),getarray(int a[]);
|
||||||
|
float getfloat();
|
||||||
|
int getfarray(float a[]);
|
||||||
|
|
||||||
|
void putint(int a),putch(int a),putarray(int n,int a[]);
|
||||||
|
void putfloat(float a);
|
||||||
|
void putfarray(int n, float a[]);
|
||||||
|
|
||||||
|
void putf(char a[], ...);
|
||||||
|
|
||||||
|
/* Timing function implementation */
|
||||||
|
struct timeval _sysy_start,_sysy_end;
|
||||||
|
#define starttime() _sysy_starttime(__LINE__)
|
||||||
|
#define stoptime() _sysy_stoptime(__LINE__)
|
||||||
|
#define _SYSY_N 1024
|
||||||
|
int _sysy_l1[_SYSY_N],_sysy_l2[_SYSY_N];
|
||||||
|
int _sysy_h[_SYSY_N], _sysy_m[_SYSY_N],_sysy_s[_SYSY_N],_sysy_us[_SYSY_N];
|
||||||
|
int _sysy_idx;
|
||||||
|
__attribute((constructor)) void before_main();
|
||||||
|
__attribute((destructor)) void after_main();
|
||||||
|
void _sysy_starttime(int lineno);
|
||||||
|
void _sysy_stoptime(int lineno);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|||||||
@ -0,0 +1,7 @@
|
|||||||
|
// test/test_case/functional/test_riscv.sy
|
||||||
|
int main() {
|
||||||
|
int a = 10;
|
||||||
|
int b = 20;
|
||||||
|
int c = a + b;
|
||||||
|
return c; // 应该返回30
|
||||||
|
}
|
||||||
@ -0,0 +1 @@
|
|||||||
|
3
|
||||||
@ -0,0 +1,3 @@
|
|||||||
|
int main(){
|
||||||
|
return 3;
|
||||||
|
}
|
||||||
@ -0,0 +1 @@
|
|||||||
|
10
|
||||||
@ -0,0 +1,8 @@
|
|||||||
|
//test domain of global var define and local define
|
||||||
|
int a = 3;
|
||||||
|
int b = 5;
|
||||||
|
|
||||||
|
int main(){
|
||||||
|
int a = 5;
|
||||||
|
return a + b;
|
||||||
|
}
|
||||||
@ -0,0 +1 @@
|
|||||||
|
5
|
||||||
@ -0,0 +1,8 @@
|
|||||||
|
//test local var define
|
||||||
|
int main(){
|
||||||
|
int a, b0, _c;
|
||||||
|
a = 1;
|
||||||
|
b0 = 2;
|
||||||
|
_c = 3;
|
||||||
|
return b0 + _c;
|
||||||
|
}
|
||||||
@ -0,0 +1 @@
|
|||||||
|
0
|
||||||
@ -0,0 +1,4 @@
|
|||||||
|
int a[10][10];
|
||||||
|
int main(){
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
@ -0,0 +1 @@
|
|||||||
|
14
|
||||||
@ -0,0 +1,9 @@
|
|||||||
|
//test array define
|
||||||
|
int main(){
|
||||||
|
int a[4][2] = {};
|
||||||
|
int b[4][2] = {1, 2, 3, 4, 5, 6, 7, 8};
|
||||||
|
int c[4][2] = {{1, 2}, {3, 4}, {5, 6}, {7, 8}};
|
||||||
|
int d[4][2] = {1, 2, {3}, {5}, 7 , 8};
|
||||||
|
int e[4][2] = {{d[2][1], c[2][1]}, {3, 4}, {5, 6}, {7, 8}};
|
||||||
|
return e[3][1] + e[0][0] + e[0][1] + a[2][0];
|
||||||
|
}
|
||||||
@ -0,0 +1 @@
|
|||||||
|
21
|
||||||
@ -0,0 +1,9 @@
|
|||||||
|
int main(){
|
||||||
|
const int a[4][2] = {{1, 2}, {3, 4}, {}, 7};
|
||||||
|
|
||||||
|
int b[4][2] = {};
|
||||||
|
int c[4][2] = {1, 2, 3, 4, 5, 6, 7, 8};
|
||||||
|
int d[3 + 1][2] = {1, 2, {3}, {5}, a[3][0], 8};
|
||||||
|
int e[4][2][1] = {{d[2][1], {c[2][1]}}, {3, 4}, {5, 6}, {7, 8}};
|
||||||
|
return e[3][1][0] + e[0][0][0] + e[0][1][0] + d[3][0];
|
||||||
|
}
|
||||||
@ -0,0 +1,6 @@
|
|||||||
|
//test const gloal var define
|
||||||
|
const int a = 10, b = 5;
|
||||||
|
|
||||||
|
int main(){
|
||||||
|
return b;
|
||||||
|
}
|
||||||
@ -0,0 +1,5 @@
|
|||||||
|
//test const local var define
|
||||||
|
int main(){
|
||||||
|
const int a = 10, b = 5;
|
||||||
|
return b;
|
||||||
|
}
|
||||||
@ -0,0 +1,5 @@
|
|||||||
|
const int a[5]={0,1,2,3,4};
|
||||||
|
|
||||||
|
int main(){
|
||||||
|
return a[4];
|
||||||
|
}
|
||||||
@ -0,0 +1 @@
|
|||||||
|
9
|
||||||
@ -0,0 +1,11 @@
|
|||||||
|
int a;
|
||||||
|
int func(int p){
|
||||||
|
p = p - 1;
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
int main(){
|
||||||
|
int b;
|
||||||
|
a = 10;
|
||||||
|
b = func(a);
|
||||||
|
return b;
|
||||||
|
}
|
||||||
@ -0,0 +1 @@
|
|||||||
|
4
|
||||||
@ -0,0 +1,8 @@
|
|||||||
|
int defn(){
|
||||||
|
return 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(){
|
||||||
|
int a=defn();
|
||||||
|
return a;
|
||||||
|
}
|
||||||
@ -0,0 +1 @@
|
|||||||
|
9
|
||||||
@ -0,0 +1,7 @@
|
|||||||
|
//test add
|
||||||
|
int main(){
|
||||||
|
int a, b;
|
||||||
|
a = 10;
|
||||||
|
b = -1;
|
||||||
|
return a + b;
|
||||||
|
}
|
||||||
@ -0,0 +1 @@
|
|||||||
|
15
|
||||||
@ -0,0 +1,5 @@
|
|||||||
|
//test addc
|
||||||
|
const int a = 10;
|
||||||
|
int main(){
|
||||||
|
return a + 5;
|
||||||
|
}
|
||||||
@ -0,0 +1 @@
|
|||||||
|
248
|
||||||
@ -0,0 +1,7 @@
|
|||||||
|
//test sub
|
||||||
|
const int a = 10;
|
||||||
|
int main(){
|
||||||
|
int b;
|
||||||
|
b = 2;
|
||||||
|
return b - a;
|
||||||
|
}
|
||||||
@ -0,0 +1 @@
|
|||||||
|
8
|
||||||
@ -0,0 +1,6 @@
|
|||||||
|
//test subc
|
||||||
|
int main(){
|
||||||
|
int a;
|
||||||
|
a = 10;
|
||||||
|
return a - 2;
|
||||||
|
}
|
||||||
@ -0,0 +1 @@
|
|||||||
|
50
|
||||||
@ -0,0 +1,7 @@
|
|||||||
|
//test mul
|
||||||
|
int main(){
|
||||||
|
int a, b;
|
||||||
|
a = 10;
|
||||||
|
b = 5;
|
||||||
|
return a * b;
|
||||||
|
}
|
||||||
@ -0,0 +1 @@
|
|||||||
|
25
|
||||||
@ -0,0 +1,5 @@
|
|||||||
|
//test mulc
|
||||||
|
const int a = 5;
|
||||||
|
int main(){
|
||||||
|
return a * 5;
|
||||||
|
}
|
||||||
@ -0,0 +1 @@
|
|||||||
|
2
|
||||||
@ -0,0 +1,7 @@
|
|||||||
|
//test div
|
||||||
|
int main(){
|
||||||
|
int a, b;
|
||||||
|
a = 10;
|
||||||
|
b = 5;
|
||||||
|
return a / b;
|
||||||
|
}
|
||||||
@ -0,0 +1 @@
|
|||||||
|
2
|
||||||
@ -0,0 +1,5 @@
|
|||||||
|
//test divc
|
||||||
|
const int a = 10;
|
||||||
|
int main(){
|
||||||
|
return a / 5;
|
||||||
|
}
|
||||||
@ -0,0 +1 @@
|
|||||||
|
3
|
||||||
@ -0,0 +1,6 @@
|
|||||||
|
//test mod
|
||||||
|
int main(){
|
||||||
|
int a;
|
||||||
|
a = 10;
|
||||||
|
return a / 3;
|
||||||
|
}
|
||||||
@ -0,0 +1 @@
|
|||||||
|
1
|
||||||
@ -0,0 +1,6 @@
|
|||||||
|
//test rem
|
||||||
|
int main(){
|
||||||
|
int a;
|
||||||
|
a = 10;
|
||||||
|
return a % 3;
|
||||||
|
}
|
||||||
@ -0,0 +1,2 @@
|
|||||||
|
-5
|
||||||
|
0
|
||||||
@ -0,0 +1,25 @@
|
|||||||
|
// test if-else-if
|
||||||
|
int ifElseIf() {
|
||||||
|
int a;
|
||||||
|
a = 5;
|
||||||
|
int b;
|
||||||
|
b = 10;
|
||||||
|
if(a == 6 || b == 0xb) {
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (b == 10 && a == 1)
|
||||||
|
a = 25;
|
||||||
|
else if (b == 10 && a == -5)
|
||||||
|
a = a + 15;
|
||||||
|
else
|
||||||
|
a = -+a;
|
||||||
|
}
|
||||||
|
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(){
|
||||||
|
putint(ifElseIf());
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue