Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
Help
Support
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
2
2025ustc-jianmu-compiler
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
1
Issues
1
List
Boards
Labels
Service Desk
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
compiler_staff
2025ustc-jianmu-compiler
Commits
52615882
Commit
52615882
authored
Oct 10, 2025
by
Yang
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
pulish lab2
parent
5e3c0318
Changes
11
Hide whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
226 additions
and
1 deletion
+226
-1
include/lightir/BasicBlock.hpp
include/lightir/BasicBlock.hpp
+1
-0
include/lightir/Function.hpp
include/lightir/Function.hpp
+2
-0
include/lightir/IRBuilder.hpp
include/lightir/IRBuilder.hpp
+3
-0
include/lightir/Instruction.hpp
include/lightir/Instruction.hpp
+2
-1
src/cminusfc/main.cpp
src/cminusfc/main.cpp
+2
-0
src/lightir/BasicBlock.cpp
src/lightir/BasicBlock.cpp
+5
-0
src/lightir/Function.cpp
src/lightir/Function.cpp
+104
-0
src/lightir/Instruction.cpp
src/lightir/Instruction.cpp
+10
-0
tests/2-ir-gen/autogen/answers/lv2/alloca_in_loop.out
tests/2-ir-gen/autogen/answers/lv2/alloca_in_loop.out
+1
-0
tests/2-ir-gen/autogen/testcases/lv2/alloca_in_loop.cminus
tests/2-ir-gen/autogen/testcases/lv2/alloca_in_loop.cminus
+11
-0
tests/2-ir-gen/warmup/ta_gcd/gcd_array.ll
tests/2-ir-gen/warmup/ta_gcd/gcd_array.ll
+85
-0
No files found.
include/lightir/BasicBlock.hpp
View file @
52615882
...
@@ -30,6 +30,7 @@ class BasicBlock : public Value, public llvm::ilist_node<BasicBlock> {
...
@@ -30,6 +30,7 @@ class BasicBlock : public Value, public llvm::ilist_node<BasicBlock> {
void
add_succ_basic_block
(
BasicBlock
*
bb
)
{
succ_bbs_
.
push_back
(
bb
);
}
void
add_succ_basic_block
(
BasicBlock
*
bb
)
{
succ_bbs_
.
push_back
(
bb
);
}
void
remove_pre_basic_block
(
BasicBlock
*
bb
)
{
pre_bbs_
.
remove
(
bb
);
}
void
remove_pre_basic_block
(
BasicBlock
*
bb
)
{
pre_bbs_
.
remove
(
bb
);
}
void
remove_succ_basic_block
(
BasicBlock
*
bb
)
{
succ_bbs_
.
remove
(
bb
);
}
void
remove_succ_basic_block
(
BasicBlock
*
bb
)
{
succ_bbs_
.
remove
(
bb
);
}
BasicBlock
*
get_entry_block_of_same_function
();
// If the Block is terminated by ret/br
// If the Block is terminated by ret/br
bool
is_terminated
()
const
;
bool
is_terminated
()
const
;
...
...
include/lightir/Function.hpp
View file @
52615882
...
@@ -46,6 +46,8 @@ class Function : public Value, public llvm::ilist_node<Function> {
...
@@ -46,6 +46,8 @@ class Function : public Value, public llvm::ilist_node<Function> {
void
set_instr_name
();
void
set_instr_name
();
std
::
string
print
();
std
::
string
print
();
// 用于检查函数的基本块是否存在问题
void
check_for_block_relation_error
();
private:
private:
llvm
::
ilist
<
BasicBlock
>
basic_blocks_
;
llvm
::
ilist
<
BasicBlock
>
basic_blocks_
;
...
...
include/lightir/IRBuilder.hpp
View file @
52615882
...
@@ -86,6 +86,9 @@ class IRBuilder {
...
@@ -86,6 +86,9 @@ class IRBuilder {
AllocaInst
*
create_alloca
(
Type
*
ty
)
{
AllocaInst
*
create_alloca
(
Type
*
ty
)
{
return
AllocaInst
::
create_alloca
(
ty
,
this
->
BB_
);
return
AllocaInst
::
create_alloca
(
ty
,
this
->
BB_
);
}
}
AllocaInst
*
create_alloca_begin
(
Type
*
ty
)
{
return
AllocaInst
::
create_alloca_begin
(
ty
,
this
->
BB_
);
}
ZextInst
*
create_zext
(
Value
*
val
,
Type
*
ty
)
{
ZextInst
*
create_zext
(
Value
*
val
,
Type
*
ty
)
{
return
ZextInst
::
create_zext
(
val
,
ty
,
this
->
BB_
);
return
ZextInst
::
create_zext
(
val
,
ty
,
this
->
BB_
);
}
}
...
...
include/lightir/Instruction.hpp
View file @
52615882
...
@@ -289,7 +289,8 @@ class AllocaInst : public BaseInst<AllocaInst> {
...
@@ -289,7 +289,8 @@ class AllocaInst : public BaseInst<AllocaInst> {
public:
public:
static
AllocaInst
*
create_alloca
(
Type
*
ty
,
BasicBlock
*
bb
);
static
AllocaInst
*
create_alloca
(
Type
*
ty
,
BasicBlock
*
bb
);
static
AllocaInst
*
create_alloca_begin
(
Type
*
ty
,
BasicBlock
*
bb
);
Type
*
get_alloca_type
()
const
{
Type
*
get_alloca_type
()
const
{
return
get_type
()
->
get_pointer_element_type
();
return
get_type
()
->
get_pointer_element_type
();
};
};
...
...
src/cminusfc/main.cpp
View file @
52615882
...
@@ -95,9 +95,11 @@ void Config::check() {
...
@@ -95,9 +95,11 @@ void Config::check() {
if
(
input_file
.
empty
())
{
if
(
input_file
.
empty
())
{
print_err
(
"no input file"
);
print_err
(
"no input file"
);
}
}
/*
if (input_file.extension() != ".cminus") {
if (input_file.extension() != ".cminus") {
print_err("file format not recognized");
print_err("file format not recognized");
}
}
*/
if
(
output_file
.
empty
())
{
if
(
output_file
.
empty
())
{
output_file
=
input_file
.
stem
();
output_file
=
input_file
.
stem
();
}
}
...
...
src/lightir/BasicBlock.cpp
View file @
52615882
...
@@ -69,3 +69,8 @@ std::string BasicBlock::print() {
...
@@ -69,3 +69,8 @@ std::string BasicBlock::print() {
return
bb_ir
;
return
bb_ir
;
}
}
BasicBlock
*
BasicBlock
::
get_entry_block_of_same_function
(){
assert
((
not
(
parent_
==
nullptr
))
&&
"bb have no parent function"
);
return
parent_
->
get_entry_block
();
}
\ No newline at end of file
src/lightir/Function.cpp
View file @
52615882
#include "Function.hpp"
#include "Function.hpp"
#include "IRprinter.hpp"
#include "IRprinter.hpp"
#include "Module.hpp"
#include "Module.hpp"
#include "Instruction.hpp"
#include <cassert>
#include <unordered_set>
#include <queue>
Function
::
Function
(
FunctionType
*
ty
,
const
std
::
string
&
name
,
Module
*
parent
)
Function
::
Function
(
FunctionType
*
ty
,
const
std
::
string
&
name
,
Module
*
parent
)
:
Value
(
ty
,
name
),
parent_
(
parent
),
seq_cnt_
(
0
)
{
:
Value
(
ty
,
name
),
parent_
(
parent
),
seq_cnt_
(
0
)
{
...
@@ -129,3 +133,103 @@ std::string Argument::print() {
...
@@ -129,3 +133,103 @@ std::string Argument::print() {
arg_ir
+=
this
->
get_name
();
arg_ir
+=
this
->
get_name
();
return
arg_ir
;
return
arg_ir
;
}
}
void
Function
::
check_for_block_relation_error
()
{
// 检查函数的基本块表是否包含所有且仅包含 get_parent 是本函数的基本块
std
::
unordered_set
<
BasicBlock
*>
bbs
;
for
(
auto
&
bb
:
basic_blocks_
)
{
bbs
.
emplace
(
&
bb
);
}
for
(
auto
&
bb
:
basic_blocks_
)
{
assert
((
bb
.
get_parent
()
==
this
)
&&
"函数 F 的基本块表中包含基本块 a, 但 a 的 get_parent 方法不返回 F"
);
for
(
auto
i
:
bb
.
get_succ_basic_blocks
())
{
assert
((
bbs
.
count
(
i
))
&&
"函数 F 的基本块表中包含基本块 a, a 的后继块表中的某基本块 b 不在 F 的基本块表中"
);
}
for
(
auto
i
:
bb
.
get_pre_basic_blocks
())
{
assert
((
bbs
.
count
(
i
))
&&
"函数 F 的基本块表中包含基本块 a, a 的前驱块表中的某基本块 b 不在 F 的基本块表中"
);
}
}
// 检查基本块的前驱和后继表不包含重复的基本块
for
(
auto
&
bb
:
basic_blocks_
)
{
bbs
.
clear
();
for
(
auto
suc
:
bb
.
get_succ_basic_blocks
()){
assert
((
!
bbs
.
count
(
suc
))
&&
"基本块的后继表中包含重复项目"
);
bbs
.
emplace
(
suc
);
}
for
(
auto
suc
:
bb
.
get_pre_basic_blocks
()){
assert
((
!
bbs
.
count
(
suc
))
&&
"基本块的前驱表中包含重复项目"
);
bbs
.
emplace
(
suc
);
}
}
// 检查基本块基本信息
for
(
auto
&
bb
:
basic_blocks_
)
{
assert
((
!
bb
.
get_instructions
().
empty
())
&&
"发现了空基本块"
);
auto
b
=
&
bb
.
get_instructions
().
back
();
assert
((
b
->
is_br
()
||
b
->
is_ret
())
&&
"发现了无 terminator 基本块"
);
assert
((
b
->
is_br
()
||
bb
.
get_succ_basic_blocks
().
empty
())
&&
"某基本块末尾是 ret 指令但是后继块表不是空的, 或者末尾是 br 但后继表为空"
);
}
// 检查基本块前驱后继关系是否是与 branch 指令对应
for
(
auto
&
bb
:
basic_blocks_
)
{
if
(
!
bb
.
get_succ_basic_blocks
().
empty
()){
std
::
unordered_set
<
BasicBlock
*>
suc_table
;
std
::
unordered_set
<
BasicBlock
*>
br_get
;
for
(
auto
suc
:
bb
.
get_succ_basic_blocks
())
suc_table
.
emplace
(
suc
);
auto
&
ops
=
bb
.
get_instructions
().
back
().
get_operands
();
for
(
auto
i
:
ops
)
{
auto
bb2
=
dynamic_cast
<
BasicBlock
*>
(
i
);
if
(
bb2
!=
nullptr
)
br_get
.
emplace
(
bb2
);
}
for
(
auto
i
:
suc_table
)
assert
(
br_get
.
count
(
i
)
&&
"基本块 A 的后继块有 B,但 B 并未在 A 的 br 指令中出现"
);
for
(
auto
i
:
br_get
)
assert
(
suc_table
.
count
(
i
)
&&
"基本块 A 的后继块没有 B,但 B 在 A 的 br 指令中出现了"
);
for
(
auto
i
:
suc_table
)
{
bool
ok
=
false
;
for
(
auto
j
:
i
->
get_pre_basic_blocks
())
{
if
(
j
==
i
){
ok
=
true
;
break
;
}
}
assert
(
ok
&&
"基本块 A 的后继块表中有 B,但 B 的前驱表中没有 A"
);
}
}
}
// 检查基本块前驱后继关系是否是与 branch 指令对应
for
(
auto
&
bb
:
basic_blocks_
)
{
for
(
auto
pre
:
bb
.
get_pre_basic_blocks
())
{
bool
ok
=
false
;
for
(
auto
i
:
pre
->
get_succ_basic_blocks
())
{
if
(
i
==
&
bb
)
{
ok
=
true
;
break
;
}
}
if
(
!
ok
)
assert
(
false
&&
"基本块 A 的后继块表中没有 B,但 B 的前驱表中有 A"
);
}
}
// 检查指令 parent 设置
for
(
auto
&
bb
:
basic_blocks_
)
{
for
(
auto
&
inst
:
bb
.
get_instructions
())
{
assert
((
inst
.
get_parent
()
==
&
bb
)
&&
"基本块 A 指令表包含指令 b, 但是 b 的 get_parent 函数不返回 A"
);
}
}
}
src/lightir/Instruction.cpp
View file @
52615882
...
@@ -298,6 +298,16 @@ AllocaInst *AllocaInst::create_alloca(Type *ty, BasicBlock *bb) {
...
@@ -298,6 +298,16 @@ AllocaInst *AllocaInst::create_alloca(Type *ty, BasicBlock *bb) {
return
create
(
ty
,
bb
);
return
create
(
ty
,
bb
);
}
}
AllocaInst
*
AllocaInst
::
create_alloca_begin
(
Type
*
ty
,
BasicBlock
*
bb
)
{
auto
ret
=
create
(
ty
,
nullptr
);
if
(
bb
!=
nullptr
)
{
ret
->
set_parent
(
bb
);
bb
->
add_instr_begin
(
ret
);
}
return
ret
;
}
ZextInst
::
ZextInst
(
Value
*
val
,
Type
*
ty
,
BasicBlock
*
bb
)
ZextInst
::
ZextInst
(
Value
*
val
,
Type
*
ty
,
BasicBlock
*
bb
)
:
BaseInst
<
ZextInst
>
(
ty
,
zext
,
bb
)
{
:
BaseInst
<
ZextInst
>
(
ty
,
zext
,
bb
)
{
assert
(
val
->
get_type
()
->
is_integer_type
()
&&
assert
(
val
->
get_type
()
->
is_integer_type
()
&&
...
...
tests/2-ir-gen/autogen/answers/lv2/alloca_in_loop.out
0 → 100644
View file @
52615882
0
tests/2-ir-gen/autogen/testcases/lv2/alloca_in_loop.cminus
0 → 100644
View file @
52615882
void main(void) {
int i;
i = 0;
while (i < 16384) {
int a[16384];
a[1] = i;
i = i + 1;
}
output(0);
return;
}
tests/2-ir-gen/warmup/ta_gcd/gcd_array.ll
0 → 100644
View file @
52615882
@x
=
global
[
1
x
i32
]
zeroinitializer
@y
=
global
[
1
x
i32
]
zeroinitializer
define
i32
@gcd
(
i32
%0
,
i32
%1
)
{
%3
=
alloca
i32
%4
=
alloca
i32
%5
=
alloca
i32
store
i32
%0
,
i32
*
%4
store
i32
%1
,
i32
*
%5
%6
=
load
i32
,
i32
*
%5
%7
=
icmp
eq
i32
%6
,
0
br
i1
%7
,
label
%8
,
label
%10
8
:
%9
=
load
i32
,
i32
*
%4
store
i32
%9
,
i32
*
%3
br
label
%20
10
:
%11
=
load
i32
,
i32
*
%5
%12
=
load
i32
,
i32
*
%4
%13
=
load
i32
,
i32
*
%4
%14
=
load
i32
,
i32
*
%5
%15
=
sdiv
i32
%13
,
%14
%16
=
load
i32
,
i32
*
%5
%17
=
mul
i32
%15
,
%16
%18
=
sub
i32
%12
,
%17
%19
=
call
i32
@gcd
(
i32
%11
,
i32
%18
)
store
i32
%19
,
i32
*
%3
br
label
%20
20
:
%21
=
load
i32
,
i32
*
%3
ret
i32
%21
}
define
i32
@funArray
(
i32
*
%0
,
i32
*
%1
)
{
%3
=
alloca
i32
*
%4
=
alloca
i32
*
%5
=
alloca
i32
%6
=
alloca
i32
%7
=
alloca
i32
store
i32
*
%0
,
i32
**
%3
store
i32
*
%1
,
i32
**
%4
%8
=
load
i32
*,
i32
**
%3
%9
=
getelementptr
i32
,
i32
*
%8
,
i64
0
%10
=
load
i32
,
i32
*
%9
store
i32
%10
,
i32
*
%5
%11
=
load
i32
*,
i32
**
%4
%12
=
getelementptr
i32
,
i32
*
%11
,
i64
0
%13
=
load
i32
,
i32
*
%12
store
i32
%13
,
i32
*
%6
%14
=
load
i32
,
i32
*
%5
%15
=
load
i32
,
i32
*
%6
%16
=
icmp
slt
i32
%14
,
%15
br
i1
%16
,
label
%17
,
label
%21
17
:
%18
=
load
i32
,
i32
*
%5
store
i32
%18
,
i32
*
%7
%19
=
load
i32
,
i32
*
%6
store
i32
%19
,
i32
*
%5
%20
=
load
i32
,
i32
*
%7
store
i32
%20
,
i32
*
%6
br
label
%21
21
:
%22
=
load
i32
,
i32
*
%5
%23
=
load
i32
,
i32
*
%6
%24
=
call
i32
@gcd
(
i32
%22
,
i32
%23
)
ret
i32
%24
}
define
i32
@main
()
{
%1
=
alloca
i32
store
i32
0
,
i32
*
%1
%2
=
getelementptr
[
1
x
i32
],
[
1
x
i32
]*
@x
,
i64
0
,
i64
0
store
i32
90
,
i32
*
%2
%3
=
getelementptr
[
1
x
i32
],
[
1
x
i32
]*
@y
,
i64
0
,
i64
0
store
i32
18
,
i32
*
%3
%4
=
getelementptr
[
1
x
i32
],
[
1
x
i32
]*
@x
,
i64
0
,
i64
0
%5
=
getelementptr
[
1
x
i32
],
[
1
x
i32
]*
@y
,
i64
0
,
i64
0
%6
=
call
i32
@funArray
(
i32
*
%4
,
i32
*
%5
)
ret
i32
%6
}
\ No newline at end of file
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment