Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
Help
Support
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
2
2022fall-Compiler_CMinus
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Service Desk
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Metrics
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
李晓奇
2022fall-Compiler_CMinus
Commits
a0b2bd9d
Commit
a0b2bd9d
authored
Oct 10, 2022
by
李晓奇
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
finish part1: hand write .ll file
parent
3b086a0e
Changes
8
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
252 additions
and
172 deletions
+252
-172
include/lightir/Type.h
include/lightir/Type.h
+19
-13
tests/2-ir-gen-warmup/c_cases/.gitignore
tests/2-ir-gen-warmup/c_cases/.gitignore
+1
-0
tests/2-ir-gen-warmup/stu_ll/assign_hand.ll
tests/2-ir-gen-warmup/stu_ll/assign_hand.ll
+14
-0
tests/2-ir-gen-warmup/stu_ll/fun_hand.ll
tests/2-ir-gen-warmup/stu_ll/fun_hand.ll
+9
-0
tests/2-ir-gen-warmup/stu_ll/if_hand.ll
tests/2-ir-gen-warmup/stu_ll/if_hand.ll
+11
-0
tests/2-ir-gen-warmup/stu_ll/while_hand.ll
tests/2-ir-gen-warmup/stu_ll/while_hand.ll
+25
-0
tests/2-ir-gen-warmup/ta_gcd/.gitignore
tests/2-ir-gen-warmup/ta_gcd/.gitignore
+1
-0
tests/2-ir-gen-warmup/ta_gcd/gcd_array_generator.cpp
tests/2-ir-gen-warmup/ta_gcd/gcd_array_generator.cpp
+172
-159
No files found.
include/lightir/Type.h
View file @
a0b2bd9d
...
@@ -11,7 +11,8 @@ class ArrayType;
...
@@ -11,7 +11,8 @@ class ArrayType;
class
PointerType
;
class
PointerType
;
class
FloatType
;
class
FloatType
;
class
Type
{
class
Type
{
public:
public:
enum
TypeID
{
enum
TypeID
{
VoidTyID
,
// Void
VoidTyID
,
// Void
...
@@ -73,11 +74,12 @@ class Type {
...
@@ -73,11 +74,12 @@ class Type {
std
::
string
print
();
std
::
string
print
();
private:
private:
TypeID
tid_
;
TypeID
tid_
;
Module
*
m_
;
Module
*
m_
;
};
};
class
IntegerType
:
public
Type
{
class
IntegerType
:
public
Type
{
public:
public:
explicit
IntegerType
(
unsigned
num_bits
,
Module
*
m
);
explicit
IntegerType
(
unsigned
num_bits
,
Module
*
m
);
...
@@ -89,7 +91,8 @@ class IntegerType : public Type {
...
@@ -89,7 +91,8 @@ class IntegerType : public Type {
unsigned
num_bits_
;
unsigned
num_bits_
;
};
};
class
FunctionType
:
public
Type
{
class
FunctionType
:
public
Type
{
public:
public:
FunctionType
(
Type
*
result
,
std
::
vector
<
Type
*>
params
);
FunctionType
(
Type
*
result
,
std
::
vector
<
Type
*>
params
);
...
@@ -100,17 +103,18 @@ class FunctionType : public Type {
...
@@ -100,17 +103,18 @@ class FunctionType : public Type {
unsigned
get_num_of_args
()
const
;
unsigned
get_num_of_args
()
const
;
Type
*
get_param_type
(
unsigned
i
)
const
;
Type
*
get_param_type
(
unsigned
i
)
const
;
std
::
vector
<
Type
*>::
iterator
param_begin
()
{
return
args_
.
begin
();
}
std
::
vector
<
Type
*>::
iterator
param_begin
()
{
return
args_
.
begin
();
}
std
::
vector
<
Type
*>::
iterator
param_end
()
{
return
args_
.
end
();
}
std
::
vector
<
Type
*>::
iterator
param_end
()
{
return
args_
.
end
();
}
Type
*
get_return_type
()
const
;
Type
*
get_return_type
()
const
;
private:
private:
Type
*
result_
;
Type
*
result_
;
std
::
vector
<
Type
*>
args_
;
std
::
vector
<
Type
*>
args_
;
};
};
class
ArrayType
:
public
Type
{
class
ArrayType
:
public
Type
{
public:
public:
ArrayType
(
Type
*
contained
,
unsigned
num_elements
);
ArrayType
(
Type
*
contained
,
unsigned
num_elements
);
...
@@ -118,15 +122,16 @@ class ArrayType : public Type {
...
@@ -118,15 +122,16 @@ class ArrayType : public Type {
static
ArrayType
*
get
(
Type
*
contained
,
unsigned
num_elements
);
static
ArrayType
*
get
(
Type
*
contained
,
unsigned
num_elements
);
Type
*
get_element_type
()
const
{
return
contained_
;
}
Type
*
get_element_type
()
const
{
return
contained_
;
}
unsigned
get_num_of_elements
()
const
{
return
num_elements_
;
}
unsigned
get_num_of_elements
()
const
{
return
num_elements_
;
}
private:
private:
Type
*
contained_
;
// The element type of the array.
Type
*
contained_
;
// The element type of the array.
unsigned
num_elements_
;
// Number of elements in the array.
unsigned
num_elements_
;
// Number of elements in the array.
};
};
class
PointerType
:
public
Type
{
class
PointerType
:
public
Type
{
public:
public:
PointerType
(
Type
*
contained
);
PointerType
(
Type
*
contained
);
Type
*
get_element_type
()
const
{
return
contained_
;
}
Type
*
get_element_type
()
const
{
return
contained_
;
}
...
@@ -137,7 +142,8 @@ class PointerType : public Type {
...
@@ -137,7 +142,8 @@ class PointerType : public Type {
Type
*
contained_
;
// The element type of the ptr.
Type
*
contained_
;
// The element type of the ptr.
};
};
class
FloatType
:
public
Type
{
class
FloatType
:
public
Type
{
public:
public:
FloatType
(
Module
*
m
);
FloatType
(
Module
*
m
);
static
FloatType
*
get
(
Module
*
m
);
static
FloatType
*
get
(
Module
*
m
);
...
@@ -145,4 +151,4 @@ class FloatType : public Type {
...
@@ -145,4 +151,4 @@ class FloatType : public Type {
private:
private:
};
};
#endif // SYSYC_TYPE_H
#endif // SYSYC_TYPE_H
\ No newline at end of file
tests/2-ir-gen-warmup/c_cases/.gitignore
0 → 100644
View file @
a0b2bd9d
*.ll
tests/2-ir-gen-warmup/stu_ll/assign_hand.ll
View file @
a0b2bd9d
define
dso_local
i32
@main
()
#0
{
%a
=
alloca
[
10
x
i32
],
align
4
; ptr is the pointer with type i32*
%ptr
=
getelementptr
[
10
x
i32
],
[
10
x
i32
]*
%a
,
i64
0
,
i64
0
%a0
=
getelementptr
i32
,
i32
*
%ptr
,
i64
0
%a1
=
getelementptr
i32
,
i32
*
%ptr
,
i64
1
store
i32
10
,
i32
*
%a0
%v1
=
load
i32
,
i32
*
%a0
%v2
=
mul
i32
%v1
,
2
store
i32
%v2
,
i32
*
%a1
%r
=
load
i32
,
i32
*
%a1
ret
i32
%r
}
tests/2-ir-gen-warmup/stu_ll/fun_hand.ll
View file @
a0b2bd9d
define
dso_local
i32
@callee
(
i32
%0
)
#0
{
%r
=
mul
i32
%0
,
2
ret
i32
%r
}
define
dso_local
i32
@main
()
#0
{
%r
=
call
i32
@callee
(
i32
110
)
ret
i32
%r
}
tests/2-ir-gen-warmup/stu_ll/if_hand.ll
View file @
a0b2bd9d
define
i32
@main
(){
%a_ptr
=
alloca
float
store
float
0x40163851E0000000
,
float
*
%a_ptr
%a
=
load
float
,
float
*
%a_ptr
%cond
=
fcmp
ugt
float
%a
,
1.000000e+00
br
i1
%cond
,
label
%1
,
label
%2
1
:
ret
i32
233
2
:
ret
i32
0
}
tests/2-ir-gen-warmup/stu_ll/while_hand.ll
View file @
a0b2bd9d
define
dso_local
i32
@main
()
#0
{
%pa
=
alloca
i32
%pi
=
alloca
i32
store
i32
10
,
i32
*
%pa
store
i32
0
,
i32
*
%pi
br
label
%loop_head
loop_head:
%i
=
load
i32
,
i32
*
%pi
%cond
=
icmp
slt
i32
%i
,
10
br
i1
%cond
,
label
%loop_body
,
label
%over
loop_body:
%i_1
=
add
i32
%i
,
1
store
i32
%i_1
,
i32
*
%pi
%newi
=
load
i32
,
i32
*
%pi
%a
=
load
i32
,
i32
*
%pa
%a_i
=
add
i32
%a
,
%newi
store
i32
%a_i
,
i32
*
%pa
br
label
%loop_head
over:
%r
=
load
i32
,
i32
*
%pa
ret
i32
%r
}
tests/2-ir-gen-warmup/ta_gcd/.gitignore
0 → 100644
View file @
a0b2bd9d
*.ll
tests/2-ir-gen-warmup/ta_gcd/gcd_array_generator.cpp
View file @
a0b2bd9d
...
@@ -8,163 +8,176 @@
...
@@ -8,163 +8,176 @@
#include <iostream>
#include <iostream>
#include <memory>
#include <memory>
#ifdef DEBUG // 用于调试信息,大家可以在编译过程中通过" -DDEBUG"来开启这一选项
/* #ifdef DEBUG // 用于调试信息,大家可以在编译过程中通过" -DDEBUG"来开启这一选项
#define DEBUG_OUTPUT std::cout << __LINE__ << std::endl; // 输出行号的简单示例
* #define DEBUG_OUTPUT std::cout << __LINE__ << std::endl; //
#else
* 输出行号的简单示例 #else #define DEBUG_OUTPUT #endif */
#define DEBUG_OUTPUT
#endif
#define DEBUG_OUTPUT std::cout << __LINE__ << std::endl; // 输出行号的简单示例
#define CONST_INT(num) ConstantInt::get(num, module)
#define CONST_INT(num) ConstantInt::get(num, mod)
#define CONST_FP(num) ConstantFP::get(num, module) // 得到常数值的表示,方便后面多次用到
#define CONST_FP(num) \
ConstantFP::get(num, mod) // 得到常数值的表示,方便后面多次用到
int
main
()
{
auto
module
=
new
Module
(
"Cminus code"
);
// module name是什么无关紧要
int
main
()
auto
builder
=
new
IRBuilder
(
nullptr
,
module
);
{
Type
*
Int32Type
=
Type
::
get_int32_type
(
module
);
auto
mod
=
new
Module
(
"Cminus code"
);
// module name是什么无关紧要
auto
builder
=
new
IRBuilder
(
nullptr
,
mod
);
// 全局数组,x,y
Type
*
Int32Type
=
Type
::
get_int32_type
(
mod
);
auto
*
arrayType
=
ArrayType
::
get
(
Int32Type
,
1
);
auto
initializer
=
ConstantZero
::
get
(
Int32Type
,
module
);
// 全局数组,x,y
auto
x
=
GlobalVariable
::
create
(
"x"
,
module
,
arrayType
,
false
,
initializer
);
// 参数解释: 名字name,所属module,全局变量类型type,
auto
*
arrayType
=
ArrayType
::
get
(
Int32Type
,
1
);
auto
y
=
GlobalVariable
::
create
(
"y"
,
module
,
arrayType
,
false
,
initializer
);
// 是否是常量定义(cminus中没有常量概念,应全都是false),初始化常量(ConstantZero类)
auto
initializer
=
ConstantZero
::
get
(
Int32Type
,
mod
);
// 参数解释: 名字name,所属module,全局变量类型type,
// gcd函数
auto
x
=
GlobalVariable
::
create
(
"x"
,
mod
,
arrayType
,
false
,
initializer
);
// 函数参数类型的vector
// 是否是常量定义(cminus中没有常量概念,应全都是false),初始化常量(ConstantZero类)
std
::
vector
<
Type
*>
Ints
(
2
,
Int32Type
);
auto
y
=
GlobalVariable
::
create
(
"y"
,
mod
,
arrayType
,
false
,
initializer
);
//通过返回值类型与参数类型列表得到函数类型
// gcd函数
auto
gcdFunTy
=
FunctionType
::
get
(
Int32Type
,
Ints
);
// 函数参数类型的vector
std
::
vector
<
Type
*>
Ints
(
2
,
Int32Type
);
// 由函数类型得到函数
auto
gcdFun
=
Function
::
create
(
gcdFunTy
,
// 通过返回值类型与参数类型列表得到函数类型
"gcd"
,
module
);
auto
gcdFunTy
=
FunctionType
::
get
(
Int32Type
,
Ints
);
// BB的名字在生成中无所谓,但是可以方便阅读
// 由函数类型得到函数
auto
bb
=
BasicBlock
::
create
(
module
,
"entry"
,
gcdFun
);
auto
gcdFun
=
Function
::
create
(
gcdFunTy
,
"gcd"
,
mod
);
builder
->
set_insert_point
(
bb
);
// 一个BB的开始,将当前插入指令点的位置设在bb
// BB的名字在生成中无所谓,但是可以方便阅读
auto
bb
=
BasicBlock
::
create
(
mod
,
"entry"
,
gcdFun
);
auto
retAlloca
=
builder
->
create_alloca
(
Int32Type
);
// 在内存中分配返回值的位置
auto
uAlloca
=
builder
->
create_alloca
(
Int32Type
);
// 在内存中分配参数u的位置
builder
->
set_insert_point
(
bb
);
// 一个BB的开始,将当前插入指令点的位置设在bb
auto
vAlloca
=
builder
->
create_alloca
(
Int32Type
);
// 在内存中分配参数v的位置
auto
retAlloca
=
std
::
vector
<
Value
*>
args
;
// 获取gcd函数的形参,通过Function中的iterator
builder
->
create_alloca
(
Int32Type
);
// 在内存中分配返回值的位置
for
(
auto
arg
=
gcdFun
->
arg_begin
();
arg
!=
gcdFun
->
arg_end
();
arg
++
)
{
auto
uAlloca
=
builder
->
create_alloca
(
Int32Type
);
// 在内存中分配参数u的位置
args
.
push_back
(
*
arg
);
// * 号运算符是从迭代器中取出迭代器当前指向的元素
auto
vAlloca
=
builder
->
create_alloca
(
Int32Type
);
// 在内存中分配参数v的位置
}
std
::
vector
<
Value
*>
args
;
// 获取gcd函数的形参,通过Function中的iterator
builder
->
create_store
(
args
[
0
],
uAlloca
);
// 将参数u store下来
for
(
auto
arg
=
gcdFun
->
arg_begin
();
arg
!=
gcdFun
->
arg_end
();
arg
++
)
{
builder
->
create_store
(
args
[
1
],
vAlloca
);
// 将参数v store下来
args
.
push_back
(
*
arg
);
// * 号运算符是从迭代器中取出迭代器当前指向的元素
}
auto
vLoad
=
builder
->
create_load
(
vAlloca
);
// 将参数v load上来
auto
icmp
=
builder
->
create_icmp_eq
(
vLoad
,
CONST_INT
(
0
));
// v和0的比较,注意ICMPEQ
builder
->
create_store
(
args
[
0
],
uAlloca
);
// 将参数u store下来
builder
->
create_store
(
args
[
1
],
vAlloca
);
// 将参数v store下来
auto
trueBB
=
BasicBlock
::
create
(
module
,
"trueBB"
,
gcdFun
);
// true分支
auto
falseBB
=
BasicBlock
::
create
(
module
,
"falseBB"
,
gcdFun
);
// false分支
auto
vLoad
=
builder
->
create_load
(
vAlloca
);
// 将参数v load上来
auto
retBB
=
BasicBlock
::
create
(
auto
icmp
=
module
,
""
,
gcdFun
);
// return分支,提前create,以便true分支可以br
builder
->
create_icmp_eq
(
vLoad
,
CONST_INT
(
0
));
// v和0的比较,注意ICMPEQ
auto
br
=
builder
->
create_cond_br
(
icmp
,
trueBB
,
falseBB
);
// 条件BR
auto
trueBB
=
BasicBlock
::
create
(
mod
,
"trueBB"
,
gcdFun
);
// true分支
DEBUG_OUTPUT
// 调试的时候故意留下来的,以醒目地提醒你这个调试用的宏定义方法
auto
falseBB
=
BasicBlock
::
create
(
mod
,
"falseBB"
,
gcdFun
);
// false分支
builder
->
set_insert_point
(
trueBB
);
// if true; 分支的开始需要SetInsertPoint设置
auto
retBB
=
BasicBlock
::
create
(
auto
uLoad
=
builder
->
create_load
(
uAlloca
);
mod
,
""
,
gcdFun
);
// return分支,提前create,以便true分支可以br
builder
->
create_store
(
uLoad
,
retAlloca
);
builder
->
create_br
(
retBB
);
// br retBB
auto
br
=
builder
->
create_cond_br
(
icmp
,
trueBB
,
falseBB
);
// 条件BR
DEBUG_OUTPUT
// 调试的时候故意留下来的,以醒目地提醒你这个调试用的宏定义方法
builder
->
set_insert_point
(
falseBB
);
// if false
builder
->
set_insert_point
(
uLoad
=
builder
->
create_load
(
uAlloca
);
trueBB
);
// if true; 分支的开始需要SetInsertPoint设置
vLoad
=
builder
->
create_load
(
vAlloca
);
auto
uLoad
=
builder
->
create_load
(
uAlloca
);
auto
div
=
builder
->
create_isdiv
(
uLoad
,
vLoad
);
// SDIV - div with S flag
builder
->
create_store
(
uLoad
,
retAlloca
);
auto
mul
=
builder
->
create_imul
(
div
,
vLoad
);
// MUL - mul
builder
->
create_br
(
retBB
);
// br retBB
auto
sub
=
builder
->
create_isub
(
uLoad
,
mul
);
// the same
auto
call
=
builder
->
create_call
(
gcdFun
,
{
vLoad
,
sub
});
// 创建call指令
builder
->
set_insert_point
(
falseBB
);
// if false
// {vLoad, sub} - 参数array
uLoad
=
builder
->
create_load
(
uAlloca
);
builder
->
create_store
(
call
,
retAlloca
);
vLoad
=
builder
->
create_load
(
vAlloca
);
builder
->
create_br
(
retBB
);
// br retBB
auto
div
=
builder
->
create_isdiv
(
uLoad
,
vLoad
);
// SDIV - div with S flag
auto
mul
=
builder
->
create_imul
(
div
,
vLoad
);
// MUL - mul
builder
->
set_insert_point
(
retBB
);
// ret分支
auto
sub
=
builder
->
create_isub
(
uLoad
,
mul
);
// the same
auto
retLoad
=
builder
->
create_load
(
retAlloca
);
auto
call
=
builder
->
create_call
(
gcdFun
,
{
vLoad
,
sub
});
// 创建call指令
builder
->
create_ret
(
retLoad
);
// {vLoad, sub} - 参数array
builder
->
create_store
(
call
,
retAlloca
);
// funArray函数
builder
->
create_br
(
retBB
);
// br retBB
auto
Int32PtrType
=
Type
::
get_int32_ptr_type
(
module
);
// 单个参数的类型,指针
std
::
vector
<
Type
*>
IntPtrs
(
2
,
Int32PtrType
);
// 参数列表类型
builder
->
set_insert_point
(
retBB
);
// ret分支
auto
funArrayFunType
=
FunctionType
::
get
(
Int32Type
,
IntPtrs
);
// 函数类型
auto
retLoad
=
builder
->
create_load
(
retAlloca
);
auto
funArrayFun
=
Function
::
create
(
funArrayFunType
,
"funArray"
,
module
);
builder
->
create_ret
(
retLoad
);
bb
=
BasicBlock
::
create
(
module
,
"entry"
,
funArrayFun
);
builder
->
set_insert_point
(
bb
);
// funArray函数
auto
upAlloca
=
builder
->
create_alloca
(
Int32PtrType
);
// u的存放
auto
Int32PtrType
=
Type
::
get_int32_ptr_type
(
mod
);
// 单个参数的类型,指针
auto
vpAlloca
=
builder
->
create_alloca
(
Int32PtrType
);
// v的存放
std
::
vector
<
Type
*>
IntPtrs
(
2
,
Int32PtrType
);
// 参数列表类型
auto
aAlloca
=
builder
->
create_alloca
(
Int32Type
);
// a的存放
auto
funArrayFunType
=
FunctionType
::
get
(
Int32Type
,
IntPtrs
);
// 函数类型
auto
bAlloca
=
builder
->
create_alloca
(
Int32Type
);
// b的存放
auto
funArrayFun
=
Function
::
create
(
funArrayFunType
,
"funArray"
,
mod
);
auto
tempAlloca
=
builder
->
create_alloca
(
Int32Type
);
// temp的存放
bb
=
BasicBlock
::
create
(
mod
,
"entry"
,
funArrayFun
);
builder
->
set_insert_point
(
bb
);
std
::
vector
<
Value
*>
args1
;
//获取funArrayFun函数的形参,通过Function中的iterator
auto
upAlloca
=
builder
->
create_alloca
(
Int32PtrType
);
// u的存放
for
(
auto
arg
=
funArrayFun
->
arg_begin
();
arg
!=
funArrayFun
->
arg_end
();
arg
++
)
{
auto
vpAlloca
=
builder
->
create_alloca
(
Int32PtrType
);
// v的存放
args1
.
push_back
(
*
arg
);
// * 号运算符是从迭代器中取出迭代器当前指向的元素
auto
aAlloca
=
builder
->
create_alloca
(
Int32Type
);
// a的存放
}
auto
bAlloca
=
builder
->
create_alloca
(
Int32Type
);
// b的存放
builder
->
create_store
(
args1
[
0
],
upAlloca
);
// 将参数u store下来
auto
tempAlloca
=
builder
->
create_alloca
(
Int32Type
);
// temp的存放
builder
->
create_store
(
args1
[
1
],
vpAlloca
);
// 将参数v store下来
std
::
vector
<
Value
*>
auto
u0pLoad
=
builder
->
create_load
(
upAlloca
);
// 读取u
args1
;
//获取funArrayFun函数的形参,通过Function中的iterator
auto
u0GEP
=
builder
->
create_gep
(
u0pLoad
,
{
CONST_INT
(
0
)});
// GEP: 获取u[0]地址
for
(
auto
arg
=
funArrayFun
->
arg_begin
();
arg
!=
funArrayFun
->
arg_end
();
auto
u0Load
=
builder
->
create_load
(
u0GEP
);
// 从u[0]地址 读取u[0]
arg
++
)
{
builder
->
create_store
(
u0Load
,
aAlloca
);
// 将u[0] 写入 a
args1
.
push_back
(
*
arg
);
// * 号运算符是从迭代器中取出迭代器当前指向的元素
auto
v0pLoad
=
builder
->
create_load
(
vpAlloca
);
// 同上
}
auto
v0GEP
=
builder
->
create_gep
(
v0pLoad
,
{
CONST_INT
(
0
)});
builder
->
create_store
(
args1
[
0
],
upAlloca
);
// 将参数u store下来
auto
v0Load
=
builder
->
create_load
(
v0GEP
);
builder
->
create_store
(
args1
[
1
],
vpAlloca
);
// 将参数v store下来
builder
->
create_store
(
v0Load
,
bAlloca
);
auto
u0pLoad
=
builder
->
create_load
(
upAlloca
);
// 读取u
auto
aLoad
=
builder
->
create_load
(
aAlloca
);
auto
u0GEP
=
auto
bLoad
=
builder
->
create_load
(
bAlloca
);
builder
->
create_gep
(
u0pLoad
,
{
CONST_INT
(
0
)});
// GEP: 获取u[0]地址
icmp
=
builder
->
create_icmp_lt
(
aLoad
,
bLoad
);
auto
u0Load
=
builder
->
create_load
(
u0GEP
);
// 从u[0]地址 读取u[0]
trueBB
=
BasicBlock
::
create
(
module
,
"trueBB"
,
funArrayFun
);
builder
->
create_store
(
u0Load
,
aAlloca
);
// 将u[0] 写入 a
falseBB
=
BasicBlock
::
create
(
module
,
"falseBB"
,
funArrayFun
);
auto
v0pLoad
=
builder
->
create_load
(
vpAlloca
);
// 同上
builder
->
create_cond_br
(
icmp
,
trueBB
,
falseBB
);
auto
v0GEP
=
builder
->
create_gep
(
v0pLoad
,
{
CONST_INT
(
0
)});
auto
v0Load
=
builder
->
create_load
(
v0GEP
);
builder
->
set_insert_point
(
trueBB
);
builder
->
create_store
(
v0Load
,
bAlloca
);
builder
->
create_store
(
aLoad
,
tempAlloca
);
builder
->
create_store
(
bLoad
,
aAlloca
);
auto
aLoad
=
builder
->
create_load
(
aAlloca
);
auto
tempLoad
=
builder
->
create_load
(
tempAlloca
);
auto
bLoad
=
builder
->
create_load
(
bAlloca
);
builder
->
create_store
(
tempLoad
,
bAlloca
);
icmp
=
builder
->
create_icmp_lt
(
aLoad
,
bLoad
);
builder
->
create_br
(
falseBB
);
// 注意在下一个BB之前要Br一下
trueBB
=
BasicBlock
::
create
(
mod
,
"trueBB"
,
funArrayFun
);
falseBB
=
BasicBlock
::
create
(
mod
,
"falseBB"
,
funArrayFun
);
builder
->
set_insert_point
(
falseBB
);
builder
->
create_cond_br
(
icmp
,
trueBB
,
falseBB
);
aLoad
=
builder
->
create_load
(
aAlloca
);
bLoad
=
builder
->
create_load
(
bAlloca
);
builder
->
set_insert_point
(
trueBB
);
call
=
builder
->
create_call
(
gcdFun
,
{
aLoad
,
bLoad
});
builder
->
create_store
(
aLoad
,
tempAlloca
);
builder
->
create_ret
(
call
);
builder
->
create_store
(
bLoad
,
aAlloca
);
auto
tempLoad
=
builder
->
create_load
(
tempAlloca
);
builder
->
create_store
(
tempLoad
,
bAlloca
);
// main函数
builder
->
create_br
(
falseBB
);
// 注意在下一个BB之前要Br一下
auto
mainFun
=
Function
::
create
(
FunctionType
::
get
(
Int32Type
,
{}),
"main"
,
module
);
builder
->
set_insert_point
(
falseBB
);
bb
=
BasicBlock
::
create
(
module
,
"entry"
,
mainFun
);
aLoad
=
builder
->
create_load
(
aAlloca
);
// BasicBlock的名字在生成中无所谓,但是可以方便阅读
bLoad
=
builder
->
create_load
(
bAlloca
);
builder
->
set_insert_point
(
bb
);
call
=
builder
->
create_call
(
gcdFun
,
{
aLoad
,
bLoad
});
builder
->
create_ret
(
call
);
retAlloca
=
builder
->
create_alloca
(
Int32Type
);
builder
->
create_store
(
CONST_INT
(
0
),
retAlloca
);
// 默认 ret 0
// main函数
auto
mainFun
=
auto
x0GEP
=
builder
->
create_gep
(
x
,
{
CONST_INT
(
0
),
CONST_INT
(
0
)});
// GEP: 这里为什么是{0, 0}呢? (实验报告相关)
Function
::
create
(
FunctionType
::
get
(
Int32Type
,
{}),
"main"
,
mod
);
builder
->
create_store
(
CONST_INT
(
90
),
x0GEP
);
bb
=
BasicBlock
::
create
(
mod
,
"entry"
,
mainFun
);
auto
y0GEP
=
builder
->
create_gep
(
y
,
{
CONST_INT
(
0
),
CONST_INT
(
0
)});
// GEP: 这里为什么是{0, 0}呢? (实验报告相关)
// BasicBlock的名字在生成中无所谓,但是可以方便阅读
builder
->
create_store
(
CONST_INT
(
18
),
y0GEP
);
builder
->
set_insert_point
(
bb
);
x0GEP
=
builder
->
create_gep
(
x
,
{
CONST_INT
(
0
),
CONST_INT
(
0
)});
retAlloca
=
builder
->
create_alloca
(
Int32Type
);
y0GEP
=
builder
->
create_gep
(
y
,
{
CONST_INT
(
0
),
CONST_INT
(
0
)});
builder
->
create_store
(
CONST_INT
(
0
),
retAlloca
);
// 默认 ret 0
call
=
builder
->
create_call
(
funArrayFun
,
{
x0GEP
,
y0GEP
});
// 为什么这里传的是{x0GEP, y0GEP}呢?
//
// GEP: 这里为什么是{0, 0}呢? (实验报告相关)
builder
->
create_ret
(
call
);
auto
x0GEP
=
builder
->
create_gep
(
x
,
{
CONST_INT
(
0
),
CONST_INT
(
0
)});
// 尽管已经有很多注释,但可能还是会遇到很多bug
builder
->
create_store
(
CONST_INT
(
90
),
x0GEP
);
// 所以强烈建议配置AutoComplete,效率会大大提高!
//
// 如果猜不到某个IR指令对应的C++的函数,建议把指令翻译成英语然后在method列表中搜索一下。
// GEP: 这里为什么是{0, 0}呢? (实验报告相关)
// 最后,这个例子只涉及到了一些基本的指令生成,
auto
y0GEP
=
builder
->
create_gep
(
y
,
{
CONST_INT
(
0
),
CONST_INT
(
0
)});
// 对于额外的指令,包括数组,在之后的实验中可能需要大家自己搜索一下思考一下,
builder
->
create_store
(
CONST_INT
(
18
),
y0GEP
);
// 还有涉及到的C++语法,可以及时提问或者向大家提供指导哦!
// 对于这个例子里的代码风格/用法,如果有好的建议也欢迎提出!
x0GEP
=
builder
->
create_gep
(
x
,
{
CONST_INT
(
0
),
CONST_INT
(
0
)});
std
::
cout
<<
module
->
print
();
y0GEP
=
builder
->
create_gep
(
y
,
{
CONST_INT
(
0
),
CONST_INT
(
0
)});
delete
module
;
//
return
0
;
// 为什么这里传的是{x0GEP, y0GEP}呢?
call
=
builder
->
create_call
(
funArrayFun
,
{
x0GEP
,
y0GEP
});
builder
->
create_ret
(
call
);
// 尽管已经有很多注释,但可能还是会遇到很多bug
// 所以强烈建议配置AutoComplete,效率会大大提高!
// 如果猜不到某个IR指令对应的C++的函数,建议把指令翻译成英语然后在method列表中搜索一下。
// 最后,这个例子只涉及到了一些基本的指令生成,
// 对于额外的指令,包括数组,在之后的实验中可能需要大家自己搜索一下思考一下,
// 还有涉及到的C++语法,可以及时提问或者向大家提供指导哦!
// 对于这个例子里的代码风格/用法,如果有好的建议也欢迎提出!
std
::
cout
<<
mod
->
print
();
delete
mod
;
return
0
;
}
}
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