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
4b7accb1
Commit
4b7accb1
authored
Oct 10, 2022
by
李晓奇
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
finish part2: write cpp to generate .ll file
parent
a0b2bd9d
Changes
11
Hide whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
532 additions
and
185 deletions
+532
-185
.gitignore
.gitignore
+1
-0
include/lightir/Function.h
include/lightir/Function.h
+23
-15
include/lightir/IRBuilder.h
include/lightir/IRBuilder.h
+113
-40
include/lightir/Instruction.h
include/lightir/Instruction.h
+178
-86
tests/2-ir-gen-warmup/CMakeLists.txt
tests/2-ir-gen-warmup/CMakeLists.txt
+32
-32
tests/2-ir-gen-warmup/stu_cpp/assign_generator.cpp
tests/2-ir-gen-warmup/stu_cpp/assign_generator.cpp
+38
-0
tests/2-ir-gen-warmup/stu_cpp/fun_generator.cpp
tests/2-ir-gen-warmup/stu_cpp/fun_generator.cpp
+42
-0
tests/2-ir-gen-warmup/stu_cpp/if_generator.cpp
tests/2-ir-gen-warmup/stu_cpp/if_generator.cpp
+38
-0
tests/2-ir-gen-warmup/stu_cpp/while_generator.cpp
tests/2-ir-gen-warmup/stu_cpp/while_generator.cpp
+53
-0
tests/2-ir-gen-warmup/stu_ll/assign_hand.ll
tests/2-ir-gen-warmup/stu_ll/assign_hand.ll
+4
-4
tests/2-ir-gen-warmup/ta_gcd/gcd_array_generator.cpp
tests/2-ir-gen-warmup/ta_gcd/gcd_array_generator.cpp
+10
-8
No files found.
.gitignore
View file @
4b7accb1
...
...
@@ -2,5 +2,6 @@ build
Documentations/1-parser/*.pdf
compile_commands.json
.cache
todo.txt
tmp.cminus
include/lightir/Function.h
View file @
4b7accb1
...
...
@@ -18,11 +18,13 @@ class Argument;
class
Type
;
class
FunctionType
;
class
Function
:
public
Value
,
public
llvm
::
ilist_node
<
Function
>
{
class
Function
:
public
Value
,
public
llvm
::
ilist_node
<
Function
>
{
public:
Function
(
FunctionType
*
ty
,
const
std
::
string
&
name
,
Module
*
parent
);
virtual
~
Function
();
static
Function
*
create
(
FunctionType
*
ty
,
const
std
::
string
&
name
,
Module
*
parent
);
static
Function
*
create
(
FunctionType
*
ty
,
const
std
::
string
&
name
,
Module
*
parent
);
FunctionType
*
get_function_type
()
const
;
...
...
@@ -38,15 +40,15 @@ class Function : public Value, public llvm::ilist_node<Function> {
std
::
list
<
Argument
*>::
iterator
arg_begin
()
{
return
arguments_
.
begin
();
}
std
::
list
<
Argument
*>::
iterator
arg_end
()
{
return
arguments_
.
end
();
}
void
remove
(
BasicBlock
*
bb
);
void
remove
(
BasicBlock
*
bb
);
BasicBlock
*
get_entry_block
()
{
return
&*
basic_blocks_
.
begin
();
}
llvm
::
ilist
<
BasicBlock
>
&
get_basic_blocks
()
{
return
basic_blocks_
;
}
std
::
list
<
Argument
*>
&
get_args
()
{
return
arguments_
;
}
std
::
list
<
Argument
*>
&
get_args
()
{
return
arguments_
;
}
bool
is_declaration
()
{
return
basic_blocks_
.
empty
();
}
void
set_instr_name
();
void
set_instr_name
();
std
::
string
print
();
private:
...
...
@@ -54,27 +56,33 @@ class Function : public Value, public llvm::ilist_node<Function> {
private:
llvm
::
ilist
<
BasicBlock
>
basic_blocks_
;
// basic blocks
std
::
list
<
Argument
*>
arguments_
;
// arguments
Module
*
parent_
;
unsigned
seq_cnt_
;
std
::
list
<
Argument
*>
arguments_
;
// arguments
Module
*
parent_
;
unsigned
seq_cnt_
;
// unsigned num_args_;
// We don't need this, all value inside function should be unnamed
// std::map<std::string, Value*> sym_table_; // Symbol table of args/instructions
// std::map<std::string, Value*> sym_table_; // Symbol table of
// args/instructions
};
// Argument of Function, does not contain actual value
class
Argument
:
public
Value
{
class
Argument
:
public
Value
{
public:
/// Argument constructor.
explicit
Argument
(
Type
*
ty
,
const
std
::
string
&
name
=
""
,
Function
*
f
=
nullptr
,
unsigned
arg_no
=
0
)
:
Value
(
ty
,
name
),
parent_
(
f
),
arg_no_
(
arg_no
)
{}
explicit
Argument
(
Type
*
ty
,
const
std
::
string
&
name
=
""
,
Function
*
f
=
nullptr
,
unsigned
arg_no
=
0
)
:
Value
(
ty
,
name
),
parent_
(
f
),
arg_no_
(
arg_no
)
{
}
virtual
~
Argument
()
{}
inline
const
Function
*
get_parent
()
const
{
return
parent_
;
}
inline
Function
*
get_parent
()
{
return
parent_
;
}
inline
Function
*
get_parent
()
{
return
parent_
;
}
/// For example in "void foo(int a, float b)" a is 0 and b is 1.
unsigned
get_arg_no
()
const
{
unsigned
get_arg_no
()
const
{
assert
(
parent_
&&
"can't get number of unparented arg"
);
return
arg_no_
;
}
...
...
@@ -83,7 +91,7 @@ class Argument : public Value {
private:
Function
*
parent_
;
unsigned
arg_no_
;
// argument No.
unsigned
arg_no_
;
// argument No.
};
#endif // SYSYC_FUNCTION_H
include/lightir/IRBuilder.h
View file @
4b7accb1
...
...
@@ -6,96 +6,169 @@
#include "Instruction.h"
#include "Value.h"
class
IRBuilder
{
class
IRBuilder
{
private:
BasicBlock
*
BB_
;
Module
*
m_
;
Module
*
m_
;
public:
IRBuilder
(
BasicBlock
*
bb
,
Module
*
m
)
:
BB_
(
bb
),
m_
(
m
){};
~
IRBuilder
()
=
default
;
Module
*
get_module
()
{
return
m_
;
}
Module
*
get_module
()
{
return
m_
;
}
BasicBlock
*
get_insert_block
()
{
return
this
->
BB_
;
}
void
set_insert_point
(
BasicBlock
*
bb
)
{
this
->
BB_
=
bb
;
}
// 在某个基本块中插入指令
BinaryInst
*
create_iadd
(
Value
*
lhs
,
Value
*
rhs
)
{
void
set_insert_point
(
BasicBlock
*
bb
)
{
this
->
BB_
=
bb
;
}
// 在某个基本块中插入指令
BinaryInst
*
create_iadd
(
Value
*
lhs
,
Value
*
rhs
)
{
return
BinaryInst
::
create_add
(
lhs
,
rhs
,
this
->
BB_
,
m_
);
}
// 创建加法指令(以及其他算术指令)
BinaryInst
*
create_isub
(
Value
*
lhs
,
Value
*
rhs
)
{
return
BinaryInst
::
create_sub
(
lhs
,
rhs
,
this
->
BB_
,
m_
);
}
BinaryInst
*
create_imul
(
Value
*
lhs
,
Value
*
rhs
)
{
return
BinaryInst
::
create_mul
(
lhs
,
rhs
,
this
->
BB_
,
m_
);
}
BinaryInst
*
create_isdiv
(
Value
*
lhs
,
Value
*
rhs
)
{
return
BinaryInst
::
create_sdiv
(
lhs
,
rhs
,
this
->
BB_
,
m_
);
}
BinaryInst
*
create_isub
(
Value
*
lhs
,
Value
*
rhs
)
{
return
BinaryInst
::
create_sub
(
lhs
,
rhs
,
this
->
BB_
,
m_
);
}
BinaryInst
*
create_imul
(
Value
*
lhs
,
Value
*
rhs
)
{
return
BinaryInst
::
create_mul
(
lhs
,
rhs
,
this
->
BB_
,
m_
);
}
BinaryInst
*
create_isdiv
(
Value
*
lhs
,
Value
*
rhs
)
{
return
BinaryInst
::
create_sdiv
(
lhs
,
rhs
,
this
->
BB_
,
m_
);
}
CmpInst
*
create_icmp_eq
(
Value
*
lhs
,
Value
*
rhs
)
{
CmpInst
*
create_icmp_eq
(
Value
*
lhs
,
Value
*
rhs
)
{
return
CmpInst
::
create_cmp
(
CmpInst
::
EQ
,
lhs
,
rhs
,
this
->
BB_
,
m_
);
}
CmpInst
*
create_icmp_ne
(
Value
*
lhs
,
Value
*
rhs
)
{
CmpInst
*
create_icmp_ne
(
Value
*
lhs
,
Value
*
rhs
)
{
return
CmpInst
::
create_cmp
(
CmpInst
::
NE
,
lhs
,
rhs
,
this
->
BB_
,
m_
);
}
CmpInst
*
create_icmp_gt
(
Value
*
lhs
,
Value
*
rhs
)
{
CmpInst
*
create_icmp_gt
(
Value
*
lhs
,
Value
*
rhs
)
{
return
CmpInst
::
create_cmp
(
CmpInst
::
GT
,
lhs
,
rhs
,
this
->
BB_
,
m_
);
}
CmpInst
*
create_icmp_ge
(
Value
*
lhs
,
Value
*
rhs
)
{
CmpInst
*
create_icmp_ge
(
Value
*
lhs
,
Value
*
rhs
)
{
return
CmpInst
::
create_cmp
(
CmpInst
::
GE
,
lhs
,
rhs
,
this
->
BB_
,
m_
);
}
CmpInst
*
create_icmp_lt
(
Value
*
lhs
,
Value
*
rhs
)
{
CmpInst
*
create_icmp_lt
(
Value
*
lhs
,
Value
*
rhs
)
{
return
CmpInst
::
create_cmp
(
CmpInst
::
LT
,
lhs
,
rhs
,
this
->
BB_
,
m_
);
}
CmpInst
*
create_icmp_le
(
Value
*
lhs
,
Value
*
rhs
)
{
CmpInst
*
create_icmp_le
(
Value
*
lhs
,
Value
*
rhs
)
{
return
CmpInst
::
create_cmp
(
CmpInst
::
LE
,
lhs
,
rhs
,
this
->
BB_
,
m_
);
}
CallInst
*
create_call
(
Value
*
func
,
std
::
vector
<
Value
*>
args
)
{
assert
(
dynamic_cast
<
Function
*>
(
func
)
&&
"func must be Function * type"
);
CallInst
*
create_call
(
Value
*
func
,
std
::
vector
<
Value
*>
args
)
{
assert
(
dynamic_cast
<
Function
*>
(
func
)
&&
"func must be Function * type"
);
return
CallInst
::
create
(
static_cast
<
Function
*>
(
func
),
args
,
this
->
BB_
);
}
BranchInst
*
create_br
(
BasicBlock
*
if_true
)
{
return
BranchInst
::
create_br
(
if_true
,
this
->
BB_
);
}
BranchInst
*
create_cond_br
(
Value
*
cond
,
BasicBlock
*
if_true
,
BasicBlock
*
if_false
)
{
BranchInst
*
create_br
(
BasicBlock
*
if_true
)
{
return
BranchInst
::
create_br
(
if_true
,
this
->
BB_
);
}
BranchInst
*
create_cond_br
(
Value
*
cond
,
BasicBlock
*
if_true
,
BasicBlock
*
if_false
)
{
return
BranchInst
::
create_cond_br
(
cond
,
if_true
,
if_false
,
this
->
BB_
);
}
ReturnInst
*
create_ret
(
Value
*
val
)
{
return
ReturnInst
::
create_ret
(
val
,
this
->
BB_
);
}
ReturnInst
*
create_void_ret
()
{
return
ReturnInst
::
create_void_ret
(
this
->
BB_
);
}
ReturnInst
*
create_ret
(
Value
*
val
)
{
return
ReturnInst
::
create_ret
(
val
,
this
->
BB_
);
}
ReturnInst
*
create_void_ret
()
{
return
ReturnInst
::
create_void_ret
(
this
->
BB_
);
}
GetElementPtrInst
*
create_gep
(
Value
*
ptr
,
std
::
vector
<
Value
*>
idxs
)
{
GetElementPtrInst
*
create_gep
(
Value
*
ptr
,
std
::
vector
<
Value
*>
idxs
)
{
return
GetElementPtrInst
::
create_gep
(
ptr
,
idxs
,
this
->
BB_
);
}
StoreInst
*
create_store
(
Value
*
val
,
Value
*
ptr
)
{
return
StoreInst
::
create_store
(
val
,
ptr
,
this
->
BB_
);
}
LoadInst
*
create_load
(
Type
*
ty
,
Value
*
ptr
)
{
return
LoadInst
::
create_load
(
ty
,
ptr
,
this
->
BB_
);
}
LoadInst
*
create_load
(
Value
*
ptr
)
{
assert
(
ptr
->
get_type
()
->
is_pointer_type
()
&&
"ptr must be pointer type"
);
return
LoadInst
::
create_load
(
ptr
->
get_type
()
->
get_pointer_element_type
(),
ptr
,
this
->
BB_
);
StoreInst
*
create_store
(
Value
*
val
,
Value
*
ptr
)
{
return
StoreInst
::
create_store
(
val
,
ptr
,
this
->
BB_
);
}
LoadInst
*
create_load
(
Type
*
ty
,
Value
*
ptr
)
{
return
LoadInst
::
create_load
(
ty
,
ptr
,
this
->
BB_
);
}
LoadInst
*
create_load
(
Value
*
ptr
)
{
assert
(
ptr
->
get_type
()
->
is_pointer_type
()
&&
"ptr must be pointer type"
);
return
LoadInst
::
create_load
(
ptr
->
get_type
()
->
get_pointer_element_type
(),
ptr
,
this
->
BB_
);
}
AllocaInst
*
create_alloca
(
Type
*
ty
)
{
return
AllocaInst
::
create_alloca
(
ty
,
this
->
BB_
);
}
ZextInst
*
create_zext
(
Value
*
val
,
Type
*
ty
)
{
return
ZextInst
::
create_zext
(
val
,
ty
,
this
->
BB_
);
}
AllocaInst
*
create_alloca
(
Type
*
ty
)
{
return
AllocaInst
::
create_alloca
(
ty
,
this
->
BB_
);
}
ZextInst
*
create_zext
(
Value
*
val
,
Type
*
ty
)
{
return
ZextInst
::
create_zext
(
val
,
ty
,
this
->
BB_
);
}
SiToFpInst
*
create_sitofp
(
Value
*
val
,
Type
*
ty
)
{
return
SiToFpInst
::
create_sitofp
(
val
,
ty
,
this
->
BB_
);
}
FpToSiInst
*
create_fptosi
(
Value
*
val
,
Type
*
ty
)
{
return
FpToSiInst
::
create_fptosi
(
val
,
ty
,
this
->
BB_
);
}
SiToFpInst
*
create_sitofp
(
Value
*
val
,
Type
*
ty
)
{
return
SiToFpInst
::
create_sitofp
(
val
,
ty
,
this
->
BB_
);
}
FpToSiInst
*
create_fptosi
(
Value
*
val
,
Type
*
ty
)
{
return
FpToSiInst
::
create_fptosi
(
val
,
ty
,
this
->
BB_
);
}
FCmpInst
*
create_fcmp_ne
(
Value
*
lhs
,
Value
*
rhs
)
{
FCmpInst
*
create_fcmp_ne
(
Value
*
lhs
,
Value
*
rhs
)
{
return
FCmpInst
::
create_fcmp
(
FCmpInst
::
NE
,
lhs
,
rhs
,
this
->
BB_
,
m_
);
}
FCmpInst
*
create_fcmp_lt
(
Value
*
lhs
,
Value
*
rhs
)
{
FCmpInst
*
create_fcmp_lt
(
Value
*
lhs
,
Value
*
rhs
)
{
return
FCmpInst
::
create_fcmp
(
FCmpInst
::
LT
,
lhs
,
rhs
,
this
->
BB_
,
m_
);
}
FCmpInst
*
create_fcmp_le
(
Value
*
lhs
,
Value
*
rhs
)
{
FCmpInst
*
create_fcmp_le
(
Value
*
lhs
,
Value
*
rhs
)
{
return
FCmpInst
::
create_fcmp
(
FCmpInst
::
LE
,
lhs
,
rhs
,
this
->
BB_
,
m_
);
}
FCmpInst
*
create_fcmp_ge
(
Value
*
lhs
,
Value
*
rhs
)
{
FCmpInst
*
create_fcmp_ge
(
Value
*
lhs
,
Value
*
rhs
)
{
return
FCmpInst
::
create_fcmp
(
FCmpInst
::
GE
,
lhs
,
rhs
,
this
->
BB_
,
m_
);
}
FCmpInst
*
create_fcmp_gt
(
Value
*
lhs
,
Value
*
rhs
)
{
FCmpInst
*
create_fcmp_gt
(
Value
*
lhs
,
Value
*
rhs
)
{
return
FCmpInst
::
create_fcmp
(
FCmpInst
::
GT
,
lhs
,
rhs
,
this
->
BB_
,
m_
);
}
FCmpInst
*
create_fcmp_eq
(
Value
*
lhs
,
Value
*
rhs
)
{
FCmpInst
*
create_fcmp_eq
(
Value
*
lhs
,
Value
*
rhs
)
{
return
FCmpInst
::
create_fcmp
(
FCmpInst
::
EQ
,
lhs
,
rhs
,
this
->
BB_
,
m_
);
}
BinaryInst
*
create_fadd
(
Value
*
lhs
,
Value
*
rhs
)
{
return
BinaryInst
::
create_fadd
(
lhs
,
rhs
,
this
->
BB_
,
m_
);
}
BinaryInst
*
create_fsub
(
Value
*
lhs
,
Value
*
rhs
)
{
return
BinaryInst
::
create_fsub
(
lhs
,
rhs
,
this
->
BB_
,
m_
);
}
BinaryInst
*
create_fmul
(
Value
*
lhs
,
Value
*
rhs
)
{
return
BinaryInst
::
create_fmul
(
lhs
,
rhs
,
this
->
BB_
,
m_
);
}
BinaryInst
*
create_fdiv
(
Value
*
lhs
,
Value
*
rhs
)
{
return
BinaryInst
::
create_fdiv
(
lhs
,
rhs
,
this
->
BB_
,
m_
);
}
BinaryInst
*
create_fadd
(
Value
*
lhs
,
Value
*
rhs
)
{
return
BinaryInst
::
create_fadd
(
lhs
,
rhs
,
this
->
BB_
,
m_
);
}
BinaryInst
*
create_fsub
(
Value
*
lhs
,
Value
*
rhs
)
{
return
BinaryInst
::
create_fsub
(
lhs
,
rhs
,
this
->
BB_
,
m_
);
}
BinaryInst
*
create_fmul
(
Value
*
lhs
,
Value
*
rhs
)
{
return
BinaryInst
::
create_fmul
(
lhs
,
rhs
,
this
->
BB_
,
m_
);
}
BinaryInst
*
create_fdiv
(
Value
*
lhs
,
Value
*
rhs
)
{
return
BinaryInst
::
create_fdiv
(
lhs
,
rhs
,
this
->
BB_
,
m_
);
}
};
#endif // SYSYC_IRBUILDER_H
include/lightir/Instruction.h
View file @
4b7accb1
...
...
@@ -9,7 +9,8 @@
class
BasicBlock
;
class
Function
;
class
Instruction
:
public
User
,
public
llvm
::
ilist_node
<
Instruction
>
{
class
Instruction
:
public
User
,
public
llvm
::
ilist_node
<
Instruction
>
{
public:
enum
OpID
{
// Terminator Instructions
...
...
@@ -47,42 +48,88 @@ class Instruction : public User, public llvm::ilist_node<Instruction> {
Instruction
(
Type
*
ty
,
OpID
id
,
unsigned
num_ops
);
virtual
~
Instruction
()
=
default
;
inline
const
BasicBlock
*
get_parent
()
const
{
return
parent_
;
}
inline
BasicBlock
*
get_parent
()
{
return
parent_
;
}
inline
BasicBlock
*
get_parent
()
{
return
parent_
;
}
void
set_parent
(
BasicBlock
*
parent
)
{
this
->
parent_
=
parent
;
}
// Return the function this instruction belongs to.
Function
*
get_function
();
Module
*
get_module
();
Module
*
get_module
();
OpID
get_instr_type
()
const
{
return
op_id_
;
}
std
::
string
get_instr_op_name
()
{
OpID
get_instr_type
()
const
{
return
op_id_
;
}
std
::
string
get_instr_op_name
()
{
switch
(
op_id_
)
{
case
ret
:
return
"ret"
;
break
;
case
br
:
return
"br"
;
break
;
case
add
:
return
"add"
;
break
;
case
sub
:
return
"sub"
;
break
;
case
mul
:
return
"mul"
;
break
;
case
sdiv
:
return
"sdiv"
;
break
;
case
fadd
:
return
"fadd"
;
break
;
case
fsub
:
return
"fsub"
;
break
;
case
fmul
:
return
"fmul"
;
break
;
case
fdiv
:
return
"fdiv"
;
break
;
case
alloca
:
return
"alloca"
;
break
;
case
load
:
return
"load"
;
break
;
case
store
:
return
"store"
;
break
;
case
cmp
:
return
"cmp"
;
break
;
case
fcmp
:
return
"fcmp"
;
break
;
case
phi
:
return
"phi"
;
break
;
case
call
:
return
"call"
;
break
;
case
getelementptr
:
return
"getelementptr"
;
break
;
case
zext
:
return
"zext"
;
break
;
case
fptosi
:
return
"fptosi"
;
break
;
case
sitofp
:
return
"sitofp"
;
break
;
default:
return
""
;
break
;
case
ret
:
return
"ret"
;
break
;
case
br
:
return
"br"
;
break
;
case
add
:
return
"add"
;
break
;
case
sub
:
return
"sub"
;
break
;
case
mul
:
return
"mul"
;
break
;
case
sdiv
:
return
"sdiv"
;
break
;
case
fadd
:
return
"fadd"
;
break
;
case
fsub
:
return
"fsub"
;
break
;
case
fmul
:
return
"fmul"
;
break
;
case
fdiv
:
return
"fdiv"
;
break
;
case
alloca
:
return
"alloca"
;
break
;
case
load
:
return
"load"
;
break
;
case
store
:
return
"store"
;
break
;
case
cmp
:
return
"cmp"
;
break
;
case
fcmp
:
return
"fcmp"
;
break
;
case
phi
:
return
"phi"
;
break
;
case
call
:
return
"call"
;
break
;
case
getelementptr
:
return
"getelementptr"
;
break
;
case
zext
:
return
"zext"
;
break
;
case
fptosi
:
return
"fptosi"
;
break
;
case
sitofp
:
return
"sitofp"
;
break
;
default:
return
""
;
break
;
}
}
bool
is_void
()
{
bool
is_void
()
{
return
((
op_id_
==
ret
)
||
(
op_id_
==
br
)
||
(
op_id_
==
store
)
||
(
op_id_
==
call
&&
this
->
get_type
()
->
is_void_type
()));
}
...
...
@@ -113,42 +160,52 @@ class Instruction : public User, public llvm::ilist_node<Instruction> {
bool
is_gep
()
{
return
op_id_
==
getelementptr
;
}
bool
is_zext
()
{
return
op_id_
==
zext
;
}
bool
isBinary
()
{
return
(
is_add
()
||
is_sub
()
||
is_mul
()
||
is_div
()
||
is_fadd
()
||
is_fsub
()
||
is_fmul
()
||
is_fdiv
())
&&
bool
isBinary
()
{
return
(
is_add
()
||
is_sub
()
||
is_mul
()
||
is_div
()
||
is_fadd
()
||
is_fsub
()
||
is_fmul
()
||
is_fdiv
())
&&
(
get_num_operand
()
==
2
);
}
bool
isTerminator
()
{
return
is_br
()
||
is_ret
();
}
private:
OpID
op_id_
;
unsigned
num_ops_
;
OpID
op_id_
;
unsigned
num_ops_
;
BasicBlock
*
parent_
;
};
namespace
detail
{
template
<
typename
T
>
struct
tag
{
using
type
=
T
;
};
template
<
typename
...
Ts
>
struct
select_last
{
// Use a fold-expression to fold the comma operator over the parameter pack.
using
type
=
typename
decltype
((
tag
<
Ts
>
{},
...))
::
type
;
};
template
<
typename
...
Ts
>
using
select_last_t
=
typename
select_last
<
Ts
...
>::
type
;
namespace
detail
{
template
<
typename
T
>
struct
tag
{
using
type
=
T
;
};
template
<
typename
...
Ts
>
struct
select_last
{
// Use a fold-expression to fold the comma operator over the parameter
// pack.
using
type
=
typename
decltype
((
tag
<
Ts
>
{},
...))
::
type
;
};
template
<
typename
...
Ts
>
using
select_last_t
=
typename
select_last
<
Ts
...
>::
type
;
};
// namespace detail
template
<
class
>
inline
constexpr
bool
always_false_v
=
false
;
template
<
typename
Inst
>
class
BaseInst
:
public
Instruction
{
class
BaseInst
:
public
Instruction
{
protected:
template
<
typename
...
Args
>
static
Inst
*
create
(
Args
&&
...
args
)
{
if
constexpr
(
std
::
is_same_v
<
std
::
decay_t
<
detail
::
select_last_t
<
Args
...
>>
,
BasicBlock
*>
)
{
static
Inst
*
create
(
Args
&&
...
args
)
{
if
constexpr
(
std
::
is_same_v
<
std
::
decay_t
<
detail
::
select_last_t
<
Args
...
>>
,
BasicBlock
*>
)
{
auto
ptr
=
new
Inst
(
std
::
forward
<
Args
>
(
args
)...);
return
ptr
;
}
else
...
...
@@ -156,10 +213,13 @@ class BaseInst : public Instruction {
}
template
<
typename
...
Args
>
BaseInst
(
Args
&&
...
args
)
:
Instruction
(
std
::
forward
<
Args
>
(
args
)...)
{}
BaseInst
(
Args
&&
...
args
)
:
Instruction
(
std
::
forward
<
Args
>
(
args
)...)
{
}
};
class
BinaryInst
:
public
BaseInst
<
BinaryInst
>
{
class
BinaryInst
:
public
BaseInst
<
BinaryInst
>
{
friend
BaseInst
<
BinaryInst
>
;
private:
...
...
@@ -167,28 +227,36 @@ class BinaryInst : public BaseInst<BinaryInst> {
public:
// create add instruction, auto insert to bb
static
BinaryInst
*
create_add
(
Value
*
v1
,
Value
*
v2
,
BasicBlock
*
bb
,
Module
*
m
);
static
BinaryInst
*
create_add
(
Value
*
v1
,
Value
*
v2
,
BasicBlock
*
bb
,
Module
*
m
);
// create sub instruction, auto insert to bb
static
BinaryInst
*
create_sub
(
Value
*
v1
,
Value
*
v2
,
BasicBlock
*
bb
,
Module
*
m
);
static
BinaryInst
*
create_sub
(
Value
*
v1
,
Value
*
v2
,
BasicBlock
*
bb
,
Module
*
m
);
// create mul instruction, auto insert to bb
static
BinaryInst
*
create_mul
(
Value
*
v1
,
Value
*
v2
,
BasicBlock
*
bb
,
Module
*
m
);
static
BinaryInst
*
create_mul
(
Value
*
v1
,
Value
*
v2
,
BasicBlock
*
bb
,
Module
*
m
);
// create Div instruction, auto insert to bb
static
BinaryInst
*
create_sdiv
(
Value
*
v1
,
Value
*
v2
,
BasicBlock
*
bb
,
Module
*
m
);
static
BinaryInst
*
create_sdiv
(
Value
*
v1
,
Value
*
v2
,
BasicBlock
*
bb
,
Module
*
m
);
// create fadd instruction, auto insert to bb
static
BinaryInst
*
create_fadd
(
Value
*
v1
,
Value
*
v2
,
BasicBlock
*
bb
,
Module
*
m
);
static
BinaryInst
*
create_fadd
(
Value
*
v1
,
Value
*
v2
,
BasicBlock
*
bb
,
Module
*
m
);
// create fsub instruction, auto insert to bb
static
BinaryInst
*
create_fsub
(
Value
*
v1
,
Value
*
v2
,
BasicBlock
*
bb
,
Module
*
m
);
static
BinaryInst
*
create_fsub
(
Value
*
v1
,
Value
*
v2
,
BasicBlock
*
bb
,
Module
*
m
);
// create fmul instruction, auto insert to bb
static
BinaryInst
*
create_fmul
(
Value
*
v1
,
Value
*
v2
,
BasicBlock
*
bb
,
Module
*
m
);
static
BinaryInst
*
create_fmul
(
Value
*
v1
,
Value
*
v2
,
BasicBlock
*
bb
,
Module
*
m
);
// create fDiv instruction, auto insert to bb
static
BinaryInst
*
create_fdiv
(
Value
*
v1
,
Value
*
v2
,
BasicBlock
*
bb
,
Module
*
m
);
static
BinaryInst
*
create_fdiv
(
Value
*
v1
,
Value
*
v2
,
BasicBlock
*
bb
,
Module
*
m
);
virtual
std
::
string
print
()
override
;
...
...
@@ -196,7 +264,8 @@ class BinaryInst : public BaseInst<BinaryInst> {
void
assertValid
();
};
class
CmpInst
:
public
BaseInst
<
CmpInst
>
{
class
CmpInst
:
public
BaseInst
<
CmpInst
>
{
friend
BaseInst
<
CmpInst
>
;
public:
...
...
@@ -213,7 +282,8 @@ class CmpInst : public BaseInst<CmpInst> {
CmpInst
(
Type
*
ty
,
CmpOp
op
,
Value
*
lhs
,
Value
*
rhs
,
BasicBlock
*
bb
);
public:
static
CmpInst
*
create_cmp
(
CmpOp
op
,
Value
*
lhs
,
Value
*
rhs
,
BasicBlock
*
bb
,
Module
*
m
);
static
CmpInst
*
create_cmp
(
CmpOp
op
,
Value
*
lhs
,
Value
*
rhs
,
BasicBlock
*
bb
,
Module
*
m
);
CmpOp
get_cmp_op
()
{
return
cmp_op_
;
}
...
...
@@ -225,7 +295,8 @@ class CmpInst : public BaseInst<CmpInst> {
void
assertValid
();
};
class
FCmpInst
:
public
BaseInst
<
FCmpInst
>
{
class
FCmpInst
:
public
BaseInst
<
FCmpInst
>
{
friend
BaseInst
<
FCmpInst
>
;
public:
...
...
@@ -242,7 +313,8 @@ class FCmpInst : public BaseInst<FCmpInst> {
FCmpInst
(
Type
*
ty
,
CmpOp
op
,
Value
*
lhs
,
Value
*
rhs
,
BasicBlock
*
bb
);
public:
static
FCmpInst
*
create_fcmp
(
CmpOp
op
,
Value
*
lhs
,
Value
*
rhs
,
BasicBlock
*
bb
,
Module
*
m
);
static
FCmpInst
*
create_fcmp
(
CmpOp
op
,
Value
*
lhs
,
Value
*
rhs
,
BasicBlock
*
bb
,
Module
*
m
);
CmpOp
get_cmp_op
()
{
return
cmp_op_
;
}
...
...
@@ -254,28 +326,33 @@ class FCmpInst : public BaseInst<FCmpInst> {
void
assert_valid
();
};
class
CallInst
:
public
BaseInst
<
CallInst
>
{
class
CallInst
:
public
BaseInst
<
CallInst
>
{
friend
BaseInst
<
CallInst
>
;
protected:
CallInst
(
Function
*
func
,
std
::
vector
<
Value
*>
args
,
BasicBlock
*
bb
);
public:
static
CallInst
*
create
(
Function
*
func
,
std
::
vector
<
Value
*>
args
,
BasicBlock
*
bb
);
FunctionType
*
get_function_type
()
const
;
static
CallInst
*
create
(
Function
*
func
,
std
::
vector
<
Value
*>
args
,
BasicBlock
*
bb
);
FunctionType
*
get_function_type
()
const
;
virtual
std
::
string
print
()
override
;
};
class
BranchInst
:
public
BaseInst
<
BranchInst
>
{
class
BranchInst
:
public
BaseInst
<
BranchInst
>
{
friend
BaseInst
<
BranchInst
>
;
private:
BranchInst
(
Value
*
cond
,
BasicBlock
*
if_true
,
BasicBlock
*
if_false
,
BasicBlock
*
bb
);
BranchInst
(
Value
*
cond
,
BasicBlock
*
if_true
,
BasicBlock
*
if_false
,
BasicBlock
*
bb
);
BranchInst
(
BasicBlock
*
if_true
,
BasicBlock
*
bb
);
public:
static
BranchInst
*
create_cond_br
(
Value
*
cond
,
BasicBlock
*
if_true
,
BasicBlock
*
if_false
,
BasicBlock
*
bb
);
static
BranchInst
*
create_cond_br
(
Value
*
cond
,
BasicBlock
*
if_true
,
BasicBlock
*
if_false
,
BasicBlock
*
bb
);
static
BranchInst
*
create_br
(
BasicBlock
*
if_true
,
BasicBlock
*
bb
);
bool
is_cond_br
()
const
;
...
...
@@ -283,7 +360,8 @@ class BranchInst : public BaseInst<BranchInst> {
virtual
std
::
string
print
()
override
;
};
class
ReturnInst
:
public
BaseInst
<
ReturnInst
>
{
class
ReturnInst
:
public
BaseInst
<
ReturnInst
>
{
friend
BaseInst
<
ReturnInst
>
;
private:
...
...
@@ -293,12 +371,13 @@ class ReturnInst : public BaseInst<ReturnInst> {
public:
static
ReturnInst
*
create_ret
(
Value
*
val
,
BasicBlock
*
bb
);
static
ReturnInst
*
create_void_ret
(
BasicBlock
*
bb
);
bool
is_void_ret
()
const
;
bool
is_void_ret
()
const
;
virtual
std
::
string
print
()
override
;
};
class
GetElementPtrInst
:
public
BaseInst
<
GetElementPtrInst
>
{
class
GetElementPtrInst
:
public
BaseInst
<
GetElementPtrInst
>
{
friend
BaseInst
<
GetElementPtrInst
>
;
private:
...
...
@@ -306,8 +385,9 @@ class GetElementPtrInst : public BaseInst<GetElementPtrInst> {
public:
static
Type
*
get_element_type
(
Value
*
ptr
,
std
::
vector
<
Value
*>
idxs
);
static
GetElementPtrInst
*
create_gep
(
Value
*
ptr
,
std
::
vector
<
Value
*>
idxs
,
BasicBlock
*
bb
);
Type
*
get_element_type
()
const
;
static
GetElementPtrInst
*
create_gep
(
Value
*
ptr
,
std
::
vector
<
Value
*>
idxs
,
BasicBlock
*
bb
);
Type
*
get_element_type
()
const
;
virtual
std
::
string
print
()
override
;
...
...
@@ -315,7 +395,8 @@ class GetElementPtrInst : public BaseInst<GetElementPtrInst> {
Type
*
element_ty_
;
};
class
StoreInst
:
public
BaseInst
<
StoreInst
>
{
class
StoreInst
:
public
BaseInst
<
StoreInst
>
{
friend
BaseInst
<
StoreInst
>
;
private:
...
...
@@ -330,7 +411,8 @@ class StoreInst : public BaseInst<StoreInst> {
virtual
std
::
string
print
()
override
;
};
class
LoadInst
:
public
BaseInst
<
LoadInst
>
{
class
LoadInst
:
public
BaseInst
<
LoadInst
>
{
friend
BaseInst
<
LoadInst
>
;
private:
...
...
@@ -338,14 +420,15 @@ class LoadInst : public BaseInst<LoadInst> {
public:
static
LoadInst
*
create_load
(
Type
*
ty
,
Value
*
ptr
,
BasicBlock
*
bb
);
Value
*
get_lval
()
{
return
this
->
get_operand
(
0
);
}
Value
*
get_lval
()
{
return
this
->
get_operand
(
0
);
}
Type
*
get_load_type
()
const
;
virtual
std
::
string
print
()
override
;
};
class
AllocaInst
:
public
BaseInst
<
AllocaInst
>
{
class
AllocaInst
:
public
BaseInst
<
AllocaInst
>
{
friend
BaseInst
<
AllocaInst
>
;
private:
...
...
@@ -362,7 +445,8 @@ class AllocaInst : public BaseInst<AllocaInst> {
Type
*
alloca_ty_
;
};
class
ZextInst
:
public
BaseInst
<
ZextInst
>
{
class
ZextInst
:
public
BaseInst
<
ZextInst
>
{
friend
BaseInst
<
ZextInst
>
;
private:
...
...
@@ -379,7 +463,8 @@ class ZextInst : public BaseInst<ZextInst> {
Type
*
dest_ty_
;
};
class
FpToSiInst
:
public
BaseInst
<
FpToSiInst
>
{
class
FpToSiInst
:
public
BaseInst
<
FpToSiInst
>
{
friend
BaseInst
<
FpToSiInst
>
;
private:
...
...
@@ -396,7 +481,8 @@ class FpToSiInst : public BaseInst<FpToSiInst> {
Type
*
dest_ty_
;
};
class
SiToFpInst
:
public
BaseInst
<
SiToFpInst
>
{
class
SiToFpInst
:
public
BaseInst
<
SiToFpInst
>
{
friend
BaseInst
<
SiToFpInst
>
;
private:
...
...
@@ -413,19 +499,25 @@ class SiToFpInst : public BaseInst<SiToFpInst> {
Type
*
dest_ty_
;
};
class
PhiInst
:
public
BaseInst
<
PhiInst
>
{
class
PhiInst
:
public
BaseInst
<
PhiInst
>
{
friend
BaseInst
<
PhiInst
>
;
private:
PhiInst
(
OpID
op
,
std
::
vector
<
Value
*>
vals
,
std
::
vector
<
BasicBlock
*>
val_bbs
,
Type
*
ty
,
BasicBlock
*
bb
);
PhiInst
(
Type
*
ty
,
OpID
op
,
unsigned
num_ops
,
BasicBlock
*
bb
)
:
BaseInst
<
PhiInst
>
(
ty
,
op
,
num_ops
,
bb
)
{}
PhiInst
(
OpID
op
,
std
::
vector
<
Value
*>
vals
,
std
::
vector
<
BasicBlock
*>
val_bbs
,
Type
*
ty
,
BasicBlock
*
bb
);
PhiInst
(
Type
*
ty
,
OpID
op
,
unsigned
num_ops
,
BasicBlock
*
bb
)
:
BaseInst
<
PhiInst
>
(
ty
,
op
,
num_ops
,
bb
)
{
}
Value
*
l_val_
;
public:
static
PhiInst
*
create_phi
(
Type
*
ty
,
BasicBlock
*
bb
);
Value
*
get_lval
()
{
return
l_val_
;
}
void
set_lval
(
Value
*
l_val
)
{
l_val_
=
l_val
;
}
void
add_phi_pair_operand
(
Value
*
val
,
Value
*
pre_bb
)
{
Value
*
get_lval
()
{
return
l_val_
;
}
void
set_lval
(
Value
*
l_val
)
{
l_val_
=
l_val
;
}
void
add_phi_pair_operand
(
Value
*
val
,
Value
*
pre_bb
)
{
this
->
add_operand
(
val
);
this
->
add_operand
(
pre_bb
);
}
...
...
tests/2-ir-gen-warmup/CMakeLists.txt
View file @
4b7accb1
...
...
@@ -8,35 +8,35 @@ target_link_libraries(
IR_lib
)
#
add_executable(
#
stu_assign_generator
#
stu_cpp/assign_generator.cpp
#
)
#
target_link_libraries(
#
stu_assign_generator
#
IR_lib
#
)
#
add_executable(
#
stu_fun_generator
#
stu_cpp/fun_generator.cpp
#
)
#
target_link_libraries(
#
stu_fun_generator
#
IR_lib
#
)
#
add_executable(
#
stu_if_generator
#
stu_cpp/if_generator.cpp
#
)
#
target_link_libraries(
#
stu_if_generator
#
IR_lib
#
)
#
add_executable(
#
stu_while_generator
#
stu_cpp/while_generator.cpp
#
)
#
target_link_libraries(
#
stu_while_generator
#
IR_lib
#
)
add_executable
(
stu_assign_generator
stu_cpp/assign_generator.cpp
)
target_link_libraries
(
stu_assign_generator
IR_lib
)
add_executable
(
stu_fun_generator
stu_cpp/fun_generator.cpp
)
target_link_libraries
(
stu_fun_generator
IR_lib
)
add_executable
(
stu_if_generator
stu_cpp/if_generator.cpp
)
target_link_libraries
(
stu_if_generator
IR_lib
)
add_executable
(
stu_while_generator
stu_cpp/while_generator.cpp
)
target_link_libraries
(
stu_while_generator
IR_lib
)
tests/2-ir-gen-warmup/stu_cpp/assign_generator.cpp
View file @
4b7accb1
#include "Module.h"
#include "IRBuilder.h"
#include "Type.h"
#include "Constant.h"
#include <iostream>
#include <vector>
int
main
()
{
auto
mod
=
new
Module
(
"assign.c"
);
auto
bud
=
new
IRBuilder
(
nullptr
,
mod
);
auto
I32Type
=
Type
::
get_int32_type
(
mod
);
auto
I32x10Type
=
Type
::
get_array_type
(
I32Type
,
10
);
std
::
vector
<
Type
*>
NoneArg
;
auto
mainTp
=
FunctionType
::
get
(
I32Type
,
NoneArg
);
auto
mainFunc
=
Function
::
create
(
mainTp
,
"main"
,
mod
);
auto
bb
=
BasicBlock
::
create
(
mod
,
"entry"
,
mainFunc
);
bud
->
set_insert_point
(
bb
);
auto
arr_ptr
=
bud
->
create_alloca
(
I32x10Type
);
auto
a0_ptr
=
bud
->
create_gep
(
arr_ptr
,
{
ConstantInt
::
get
(
0
,
mod
),
ConstantInt
::
get
(
0
,
mod
)});
auto
a1_ptr
=
bud
->
create_gep
(
arr_ptr
,
{
ConstantInt
::
get
(
0
,
mod
),
ConstantInt
::
get
(
0
,
mod
)});
bud
->
create_store
(
ConstantInt
::
get
(
10
,
mod
),
a0_ptr
);
auto
a0_load
=
bud
->
create_load
(
a0_ptr
);
auto
mul
=
bud
->
create_imul
(
a0_load
,
ConstantInt
::
get
(
2
,
mod
));
bud
->
create_store
(
mul
,
a1_ptr
);
auto
a1_load
=
bud
->
create_load
(
a1_ptr
);
bud
->
create_ret
(
a1_load
);
std
::
cout
<<
mod
->
print
();
delete
mod
;
return
0
;
}
tests/2-ir-gen-warmup/stu_cpp/fun_generator.cpp
View file @
4b7accb1
#include "BasicBlock.h"
#include "Constant.h"
#include "Function.h"
#include "IRBuilder.h"
#include "Module.h"
#include "Type.h"
#include <iostream>
int
main
()
{
auto
mod
=
new
Module
(
"Cminus code"
);
// module name是什么无关紧要
auto
bud
=
new
IRBuilder
(
nullptr
,
mod
);
Type
*
I32Type
=
Type
::
get_int32_type
(
mod
);
std
::
vector
<
Type
*>
OneIntArg
(
1
,
I32Type
);
auto
calleeTp
=
FunctionType
::
get
(
I32Type
,
OneIntArg
);
auto
calleeFunc
=
Function
::
create
(
calleeTp
,
"callee"
,
mod
);
auto
bb
=
BasicBlock
::
create
(
mod
,
"entry"
,
calleeFunc
);
bud
->
set_insert_point
(
bb
);
std
::
vector
<
Value
*>
arg_vs
;
for
(
auto
arg
=
calleeFunc
->
arg_begin
();
arg
!=
calleeFunc
->
arg_end
();
arg
++
)
arg_vs
.
push_back
(
*
arg
);
auto
mul
=
bud
->
create_imul
(
arg_vs
[
0
],
ConstantInt
::
get
(
2
,
mod
));
bud
->
create_ret
(
mul
);
auto
mainTp
=
FunctionType
::
get
(
I32Type
,
{});
auto
mainFunc
=
Function
::
create
(
mainTp
,
"main"
,
mod
);
bb
=
BasicBlock
::
create
(
mod
,
"entry"
,
mainFunc
);
bud
->
set_insert_point
(
bb
);
auto
call
=
bud
->
create_call
(
calleeFunc
,
{
ConstantInt
::
get
(
110
,
mod
)});
bud
->
create_ret
(
call
);
std
::
cout
<<
mod
->
print
();
delete
mod
;
return
0
;
}
tests/2-ir-gen-warmup/stu_cpp/if_generator.cpp
View file @
4b7accb1
#include "BasicBlock.h"
#include "Constant.h"
#include "Function.h"
#include "IRBuilder.h"
#include "Module.h"
#include "Type.h"
#include <iostream>
int
main
()
{
auto
mod
=
new
Module
(
"if.c"
);
auto
bud
=
new
IRBuilder
(
nullptr
,
mod
);
Type
*
I32Type
=
Type
::
get_int32_type
(
mod
);
Type
*
floatType
=
Type
::
get_float_type
(
mod
);
auto
mainTp
=
FunctionType
::
get
(
I32Type
,
{});
auto
mainFunc
=
Function
::
create
(
mainTp
,
"main"
,
mod
);
auto
bb
=
BasicBlock
::
create
(
mod
,
"entry"
,
mainFunc
);
bud
->
set_insert_point
(
bb
);
auto
aAlloc
=
bud
->
create_alloca
(
floatType
);
bud
->
create_store
(
ConstantFP
::
get
(
5.555
,
mod
),
aAlloc
);
auto
aValue
=
bud
->
create_load
(
aAlloc
);
auto
cond
=
bud
->
create_fcmp_gt
(
aValue
,
ConstantFP
::
get
(
1
,
mod
));
auto
TBB
=
BasicBlock
::
create
(
mod
,
"trueCase"
,
mainFunc
);
auto
FBB
=
BasicBlock
::
create
(
mod
,
"falseCase"
,
mainFunc
);
bud
->
create_cond_br
(
cond
,
TBB
,
FBB
);
bud
->
set_insert_point
(
TBB
);
bud
->
create_ret
(
ConstantInt
::
get
(
233
,
mod
));
bud
->
set_insert_point
(
FBB
);
bud
->
create_ret
(
ConstantInt
::
get
(
0
,
mod
));
std
::
cout
<<
mod
->
print
();
delete
mod
;
return
0
;
}
tests/2-ir-gen-warmup/stu_cpp/while_generator.cpp
View file @
4b7accb1
#include "BasicBlock.h"
#include "Constant.h"
#include "Function.h"
#include "IRBuilder.h"
#include "Module.h"
#include "Type.h"
#include <iostream>
int
main
()
{
auto
mod
=
new
Module
(
"while.c"
);
auto
bud
=
new
IRBuilder
(
nullptr
,
mod
);
Type
*
I32Type
=
Type
::
get_int32_type
(
mod
);
// main函数
auto
mainFunc
=
Function
::
create
(
FunctionType
::
get
(
I32Type
,
{}),
"main"
,
mod
);
auto
bb
=
BasicBlock
::
create
(
mod
,
"entry"
,
mainFunc
);
auto
judge
=
BasicBlock
::
create
(
mod
,
"judge"
,
mainFunc
);
auto
loop
=
BasicBlock
::
create
(
mod
,
"loop"
,
mainFunc
);
auto
exit
=
BasicBlock
::
create
(
mod
,
"exit"
,
mainFunc
);
bud
->
set_insert_point
(
bb
);
auto
aAlloc
=
bud
->
create_alloca
(
I32Type
);
auto
iAlloc
=
bud
->
create_alloca
(
I32Type
);
bud
->
create_store
(
ConstantInt
::
get
(
10
,
mod
),
aAlloc
);
bud
->
create_store
(
ConstantInt
::
get
(
0
,
mod
),
iAlloc
);
bud
->
create_br
(
judge
);
bud
->
set_insert_point
(
judge
);
auto
iV
=
bud
->
create_load
(
iAlloc
);
auto
cond
=
bud
->
create_icmp_lt
(
iV
,
ConstantInt
::
get
(
10
,
mod
));
bud
->
create_cond_br
(
cond
,
loop
,
exit
);
bud
->
set_insert_point
(
loop
);
auto
add
=
bud
->
create_iadd
(
iV
,
ConstantInt
::
get
(
1
,
mod
));
bud
->
create_store
(
add
,
iAlloc
);
//
auto
aV
=
bud
->
create_load
(
aAlloc
);
auto
aadd
=
bud
->
create_iadd
(
add
,
aV
);
bud
->
create_store
(
aadd
,
aAlloc
);
bud
->
create_br
(
judge
);
bud
->
set_insert_point
(
exit
);
aV
=
bud
->
create_load
(
aAlloc
);
bud
->
create_ret
(
aV
);
std
::
cout
<<
mod
->
print
();
delete
mod
;
return
0
;
}
tests/2-ir-gen-warmup/stu_ll/assign_hand.ll
View file @
4b7accb1
define
dso_local
i32
@main
()
#0
{
%a
=
alloca
[
10
x
i32
]
,
align
4
%a
=
alloca
[
10
x
i32
]
; 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
;
%a0 = getelementptr i32, i32* %ptr, i64 0
%a1
=
getelementptr
i32
,
i32
*
%ptr
,
i64
1
store
i32
10
,
i32
*
%
a0
%v1
=
load
i32
,
i32
*
%
a0
store
i32
10
,
i32
*
%
ptr
%v1
=
load
i32
,
i32
*
%
ptr
%v2
=
mul
i32
%v1
,
2
store
i32
%v2
,
i32
*
%a1
%r
=
load
i32
,
i32
*
%a1
...
...
tests/2-ir-gen-warmup/ta_gcd/gcd_array_generator.cpp
View file @
4b7accb1
...
...
@@ -12,12 +12,13 @@
* #define DEBUG_OUTPUT std::cout << __LINE__ << std::endl; //
* 输出行号的简单示例 #else #define DEBUG_OUTPUT #endif */
#define DEBUG_OUTPUT std::cout << __LINE__ << std::endl; // 输出行号的简单示例
// 输出行号的简单示例
#define DEBUG_OUTPUT std::cout << __LINE__ << std::endl;
#define CONST_INT(num) ConstantInt::get(num, mod)
#define CONST_FP(num) \
ConstantFP::get(num, mod) // 得到常数值的表示,方便后面多次用到
// 得到常数值的表示,方便后面多次用到
#define CONST_FP(num) ConstantFP::get(num, mod)
int
main
()
{
...
...
@@ -71,9 +72,10 @@ int main()
mod
,
""
,
gcdFun
);
// return分支,提前create,以便true分支可以br
auto
br
=
builder
->
create_cond_br
(
icmp
,
trueBB
,
falseBB
);
// 条件BR
DEBUG_OUTPUT
// 调试的时候故意留下来的,以醒目地提醒你这个调试用的宏定义方法
builder
->
set_insert_point
(
trueBB
);
// if true; 分支的开始需要SetInsertPoint设置
DEBUG_OUTPUT
;
// 调试的时候故意留下来的,以醒目地提醒你这个调试用的宏定义方法
// if true; 分支的开始需要SetInsertPoint设置
builder
->
set_insert_point
(
trueBB
);
auto
uLoad
=
builder
->
create_load
(
uAlloca
);
builder
->
create_store
(
uLoad
,
retAlloca
);
builder
->
create_br
(
retBB
);
// br retBB
...
...
@@ -106,8 +108,8 @@ int main()
auto
bAlloca
=
builder
->
create_alloca
(
Int32Type
);
// b的存放
auto
tempAlloca
=
builder
->
create_alloca
(
Int32Type
);
// temp的存放
std
::
vector
<
Value
*>
args1
;
//获取funArrayFun函数的形参,通过Function中的iterator
//获取funArray函数的形参,通过Function中的iterator
std
::
vector
<
Value
*>
args1
;
for
(
auto
arg
=
funArrayFun
->
arg_begin
();
arg
!=
funArrayFun
->
arg_end
();
arg
++
)
{
args1
.
push_back
(
*
arg
);
// * 号运算符是从迭代器中取出迭代器当前指向的元素
...
...
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