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
43
Merge Requests
43
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
e547371b
Commit
e547371b
authored
Nov 26, 2025
by
Yang
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
add codegen summary
parent
c396901a
Changes
29
Hide whitespace changes
Inline
Side-by-side
Showing
29 changed files
with
413 additions
and
300 deletions
+413
-300
.vscode/launch.json
.vscode/launch.json
+63
-42
.vscode/tasks.json
.vscode/tasks.json
+8
-8
CMakeLists.txt
CMakeLists.txt
+11
-11
include/codegen/ASMInstruction.hpp
include/codegen/ASMInstruction.hpp
+5
-2
include/codegen/CodeGen.hpp
include/codegen/CodeGen.hpp
+6
-3
include/codegen/Register.hpp
include/codegen/Register.hpp
+12
-3
include/common/ast.hpp
include/common/ast.hpp
+36
-36
include/lightir/BasicBlock.hpp
include/lightir/BasicBlock.hpp
+8
-8
include/lightir/Constant.hpp
include/lightir/Constant.hpp
+1
-1
include/lightir/Function.hpp
include/lightir/Function.hpp
+16
-16
include/lightir/Instruction.hpp
include/lightir/Instruction.hpp
+1
-1
include/lightir/Module.hpp
include/lightir/Module.hpp
+1
-1
include/lightir/Names.hpp
include/lightir/Names.hpp
+13
-14
include/lightir/Type.hpp
include/lightir/Type.hpp
+30
-30
include/lightir/User.hpp
include/lightir/User.hpp
+5
-5
include/lightir/Value.hpp
include/lightir/Value.hpp
+5
-5
lldb_formatters.py
lldb_formatters.py
+9
-2
src/cminusfc/cminusf_builder.cpp
src/cminusfc/cminusf_builder.cpp
+3
-3
src/codegen/CodeGen.cpp
src/codegen/CodeGen.cpp
+37
-21
src/codegen/Register.cpp
src/codegen/Register.cpp
+46
-1
src/common/util.cpp
src/common/util.cpp
+7
-7
src/lightir/BasicBlock.cpp
src/lightir/BasicBlock.cpp
+5
-5
src/lightir/Constant.cpp
src/lightir/Constant.cpp
+1
-1
src/lightir/Function.cpp
src/lightir/Function.cpp
+13
-11
src/lightir/IRprinter.cpp
src/lightir/IRprinter.cpp
+21
-19
src/lightir/Instruction.cpp
src/lightir/Instruction.cpp
+4
-4
src/lightir/Module.cpp
src/lightir/Module.cpp
+1
-1
src/lightir/Names.cpp
src/lightir/Names.cpp
+23
-17
src/lightir/Type.cpp
src/lightir/Type.cpp
+22
-22
No files found.
.vscode/launch.json
View file @
e547371b
{
"configurations"
:
[
{
"type"
:
"lldb"
,
"request"
:
"launch"
,
"name"
:
"Compile & Debug 1.ll"
,
//
要调试的程序
"program"
:
"${workspaceFolder}/build/cminusfc"
,
//
命令行参数
"args"
:
[
"-o"
,
"./build/1.ll"
,
"-emit-llvm"
,
"./build/1.cminus"
],
//
程序运行的目录
"cwd"
:
"${workspaceFolder}"
,
//
程序运行前运行的命令(例如
build)
"preLaunchTask"
:
"make cminusfc"
,
"initCommands"
:
[
"command script import ${workspaceFolder}/lldb_formatters.py"
]
},
{
"type"
:
"lldb"
,
"request"
:
"launch"
,
"name"
:
"Debug 1.ll"
,
//
要调试的程序
"program"
:
"${workspaceFolder}/build/cminusfc"
,
//
命令行参数
"args"
:
[
"-o"
,
"./build/1.ll"
,
"-emit-llvm"
,
"./build/1.cminus"
],
//
程序运行的目录
"cwd"
:
"${workspaceFolder}"
,
"initCommands"
:
[
"command script import ${workspaceFolder}/lldb_formatters.py"
]
}
]
"configurations"
:
[
{
"type"
:
"lldb"
,
"request"
:
"launch"
,
"name"
:
"Compile & Gen 1.ll"
,
//
要调试的程序
"program"
:
"${workspaceFolder}/build/cminusfc"
,
//
命令行参数
"args"
:
[
"-emit-llvm"
,
"./build/1.cminus"
,
"-o"
,
"./build/1.ll"
],
//
程序运行的目录
"cwd"
:
"${workspaceFolder}"
,
//
程序运行前运行的命令(例如
build)
"preLaunchTask"
:
"make cminusfc"
,
"initCommands"
:
[
"command script import ${workspaceFolder}/lldb_formatters.py"
]
},
{
"type"
:
"lldb"
,
"request"
:
"launch"
,
"name"
:
"Gen 1.ll"
,
//
要调试的程序
"program"
:
"${workspaceFolder}/build/cminusfc"
,
//
命令行参数
"args"
:
[
"-emit-llvm"
,
"./build/1.cminus"
,
"-o"
,
"./build/1.ll"
],
//
程序运行的目录
"cwd"
:
"${workspaceFolder}"
,
"initCommands"
:
[
"command script import ${workspaceFolder}/lldb_formatters.py"
]
},
{
"type"
:
"lldb"
,
"request"
:
"launch"
,
"name"
:
"Compile & Gen 1.s"
,
//
要调试的程序
"program"
:
"${workspaceFolder}/build/cminusfc"
,
//
命令行参数
"args"
:
[
"-S"
,
"./build/1.cminus"
,
"-o"
,
"./build/1.s"
],
//
程序运行的目录
"cwd"
:
"${workspaceFolder}"
,
//
程序运行前运行的命令(例如
build)
"preLaunchTask"
:
"make cminusfc"
,
"initCommands"
:
[
"command script import ${workspaceFolder}/lldb_formatters.py"
]
}
]
}
\ No newline at end of file
.vscode/tasks.json
View file @
e547371b
{
"version"
:
"2.0.0"
,
"tasks"
:
[
{
"type"
:
"shell"
,
"label"
:
"make cminusfc"
,
"command"
:
"cd build && make"
}
]
"version"
:
"2.0.0"
,
"tasks"
:
[
{
"type"
:
"shell"
,
"label"
:
"make cminusfc"
,
"command"
:
"cd build && make"
}
]
}
\ No newline at end of file
CMakeLists.txt
View file @
e547371b
...
...
@@ -12,17 +12,17 @@ SET(CMAKE_CXX_FLAGS_ASAN "${CMAKE_CXX_FLAGS_DEBUG} -fsanitize=undefined -fsaniti
set
(
default_build_type
"Debug"
)
if
(
CMAKE_BUILD_TYPE STREQUAL
"Debug"
)
if
(
CMAKE_CXX_COMPILER_ID MATCHES
"Clang"
)
check_cxx_compiler_flag
(
"-fstandalone-debug"
CXX_SUPPORTS_STANDALONE_DEBUG
)
if
(
CXX_SUPPORTS_STANDALONE_DEBUG
)
message
(
STATUS
"Adding -fstandalone-debug for Clang"
)
set
(
CMAKE_CXX_FLAGS_DEBUG
"
${
CMAKE_CXX_FLAGS_DEBUG
}
-fstandalone-debug"
)
else
()
message
(
STATUS
"Clang does not support -fstandalone-debug, skipping"
)
endif
()
else
()
message
(
STATUS
"Use Gcc"
)
endif
()
if
(
CMAKE_CXX_COMPILER_ID MATCHES
"Clang"
)
check_cxx_compiler_flag
(
"-fstandalone-debug"
CXX_SUPPORTS_STANDALONE_DEBUG
)
if
(
CXX_SUPPORTS_STANDALONE_DEBUG
)
message
(
STATUS
"Adding -fstandalone-debug for Clang"
)
set
(
CMAKE_CXX_FLAGS_DEBUG
"
${
CMAKE_CXX_FLAGS_DEBUG
}
-fstandalone-debug"
)
else
()
message
(
STATUS
"Clang does not support -fstandalone-debug, skipping"
)
endif
()
else
()
message
(
STATUS
"Use Gcc"
)
endif
()
endif
()
if
(
CMAKE_BUILD_TYPE STREQUAL
"Debug"
)
...
...
include/codegen/ASMInstruction.hpp
View file @
e547371b
...
...
@@ -4,7 +4,7 @@
#include <string>
struct
ASMInstruction
{
enum
InstType
{
Instruction
,
At
r
ribute
,
Label
,
Comment
}
type
;
enum
InstType
{
Instruction
,
At
t
ribute
,
Label
,
Comment
}
type
;
std
::
string
content
;
explicit
ASMInstruction
(
std
::
string
s
,
InstType
ty
=
Instruction
)
...
...
@@ -13,7 +13,7 @@ struct ASMInstruction {
std
::
string
format
()
const
{
switch
(
type
)
{
case
ASMInstruction
::
Instruction
:
case
ASMInstruction
::
At
r
ribute
:
case
ASMInstruction
::
At
t
ribute
:
return
"
\t
"
+
content
+
"
\n
"
;
case
ASMInstruction
::
Label
:
return
content
+
":
\n
"
;
...
...
@@ -22,4 +22,7 @@ struct ASMInstruction {
}
assert
(
false
&&
"unreachable"
);
}
// 用于 lldb 调试生成 summary
std
::
string
safe_print
()
const
;
};
include/codegen/CodeGen.hpp
View file @
e547371b
...
...
@@ -8,13 +8,16 @@
class
CodeGen
{
public:
explicit
CodeGen
(
Module
*
module
)
:
m
(
module
)
{}
~
CodeGen
(){
for
(
auto
i
:
output
)
delete
i
;
}
std
::
string
print
()
const
;
void
run
();
template
<
class
...
Args
>
void
append_inst
(
Args
...
arg
)
{
output
.
emplace_back
(
arg
...
);
output
.
emplace_back
(
new
ASMInstruction
(
arg
...)
);
}
void
...
...
@@ -26,7 +29,7 @@ class CodeGen {
}
content
.
pop_back
();
content
.
pop_back
();
output
.
emplace_back
(
content
,
ty
);
output
.
emplace_back
(
new
ASMInstruction
(
content
,
ty
)
);
}
private:
...
...
@@ -98,5 +101,5 @@ class CodeGen {
}
context
;
Module
*
m
;
std
::
list
<
ASMInstruction
>
output
;
std
::
list
<
ASMInstruction
*
>
output
;
};
include/codegen/Register.hpp
View file @
e547371b
...
...
@@ -32,6 +32,9 @@ struct Reg {
std
::
string
print
()
const
;
// 用于 lldb 调试生成 summary
std
::
string
safe_print
()
const
;
static
Reg
zero
()
{
return
Reg
(
0
);
}
static
Reg
ra
()
{
return
Reg
(
1
);
}
static
Reg
sp
()
{
return
Reg
(
3
);
}
...
...
@@ -62,17 +65,20 @@ struct FReg {
std
::
string
print
()
const
;
static
FReg
fa
(
unsigned
i
)
{
assert
(
0
<=
i
and
i
<=
7
);
assert
(
i
<=
7
);
return
FReg
(
i
);
}
static
FReg
ft
(
unsigned
i
)
{
assert
(
0
<=
i
and
i
<=
15
);
assert
(
i
<=
15
);
return
FReg
(
i
+
8
);
}
static
FReg
fs
(
unsigned
i
)
{
assert
(
0
<=
i
and
i
<=
7
);
assert
(
i
<=
7
);
return
FReg
(
i
+
24
);
}
// 用于 lldb 调试生成 summary
std
::
string
safe_print
()
const
;
};
struct
CFReg
{
...
...
@@ -82,4 +88,7 @@ struct CFReg {
bool
operator
==
(
const
CFReg
&
other
)
{
return
id
==
other
.
id
;
}
std
::
string
print
()
const
{
return
"$fcc"
+
std
::
to_string
(
id
);
}
// 用于 lldb 调试生成 summary
std
::
string
safe_print
()
const
;
};
include/common/ast.hpp
View file @
e547371b
...
...
@@ -90,23 +90,23 @@ struct ASTNode {
};
struct
ASTProgram
:
ASTNode
{
Value
*
accept
(
ASTVisitor
&
)
final
;
~
ASTProgram
()
override
=
default
;
Value
*
accept
(
ASTVisitor
&
)
final
;
~
ASTProgram
()
override
=
default
;
std
::
vector
<
std
::
shared_ptr
<
ASTDeclaration
>>
declarations
;
};
struct
ASTDeclaration
:
ASTNode
{
~
ASTDeclaration
()
override
=
default
;
~
ASTDeclaration
()
override
=
default
;
CminusType
type
;
std
::
string
id
;
};
struct
ASTFactor
:
ASTNode
{
~
ASTFactor
()
override
=
default
;
~
ASTFactor
()
override
=
default
;
};
struct
ASTNum
:
ASTFactor
{
Value
*
accept
(
ASTVisitor
&
)
final
;
Value
*
accept
(
ASTVisitor
&
)
final
;
CminusType
type
;
union
{
int
i_val
;
...
...
@@ -115,18 +115,18 @@ struct ASTNum : ASTFactor {
};
struct
ASTVarDeclaration
:
ASTDeclaration
{
Value
*
accept
(
ASTVisitor
&
)
final
;
Value
*
accept
(
ASTVisitor
&
)
final
;
std
::
shared_ptr
<
ASTNum
>
num
;
};
struct
ASTFunDeclaration
:
ASTDeclaration
{
Value
*
accept
(
ASTVisitor
&
)
final
;
Value
*
accept
(
ASTVisitor
&
)
final
;
std
::
vector
<
std
::
shared_ptr
<
ASTParam
>>
params
;
std
::
shared_ptr
<
ASTCompoundStmt
>
compound_stmt
;
};
struct
ASTParam
:
ASTNode
{
Value
*
accept
(
ASTVisitor
&
)
final
;
Value
*
accept
(
ASTVisitor
&
)
final
;
CminusType
type
;
std
::
string
id
;
// true if it is array param
...
...
@@ -134,22 +134,22 @@ struct ASTParam : ASTNode {
};
struct
ASTStatement
:
ASTNode
{
~
ASTStatement
()
override
=
default
;
~
ASTStatement
()
override
=
default
;
};
struct
ASTCompoundStmt
:
ASTStatement
{
Value
*
accept
(
ASTVisitor
&
)
final
;
Value
*
accept
(
ASTVisitor
&
)
final
;
std
::
vector
<
std
::
shared_ptr
<
ASTVarDeclaration
>>
local_declarations
;
std
::
vector
<
std
::
shared_ptr
<
ASTStatement
>>
statement_list
;
};
struct
ASTExpressionStmt
:
ASTStatement
{
Value
*
accept
(
ASTVisitor
&
)
final
;
Value
*
accept
(
ASTVisitor
&
)
final
;
std
::
shared_ptr
<
ASTExpression
>
expression
;
};
struct
ASTSelectionStmt
:
ASTStatement
{
Value
*
accept
(
ASTVisitor
&
)
final
;
Value
*
accept
(
ASTVisitor
&
)
final
;
std
::
shared_ptr
<
ASTExpression
>
expression
;
std
::
shared_ptr
<
ASTStatement
>
if_statement
;
// should be nullptr if no else structure exists
...
...
@@ -157,13 +157,13 @@ struct ASTSelectionStmt : ASTStatement {
};
struct
ASTIterationStmt
:
ASTStatement
{
Value
*
accept
(
ASTVisitor
&
)
final
;
Value
*
accept
(
ASTVisitor
&
)
final
;
std
::
shared_ptr
<
ASTExpression
>
expression
;
std
::
shared_ptr
<
ASTStatement
>
statement
;
};
struct
ASTReturnStmt
:
ASTStatement
{
Value
*
accept
(
ASTVisitor
&
)
final
;
Value
*
accept
(
ASTVisitor
&
)
final
;
// should be nullptr if return void
std
::
shared_ptr
<
ASTExpression
>
expression
;
};
...
...
@@ -171,41 +171,41 @@ struct ASTReturnStmt : ASTStatement {
struct
ASTExpression
:
ASTFactor
{};
struct
ASTAssignExpression
:
ASTExpression
{
Value
*
accept
(
ASTVisitor
&
)
final
;
Value
*
accept
(
ASTVisitor
&
)
final
;
std
::
shared_ptr
<
ASTVar
>
var
;
std
::
shared_ptr
<
ASTExpression
>
expression
;
};
struct
ASTSimpleExpression
:
ASTExpression
{
Value
*
accept
(
ASTVisitor
&
)
final
;
Value
*
accept
(
ASTVisitor
&
)
final
;
std
::
shared_ptr
<
ASTAdditiveExpression
>
additive_expression_l
;
std
::
shared_ptr
<
ASTAdditiveExpression
>
additive_expression_r
;
RelOp
op
;
};
struct
ASTVar
:
ASTFactor
{
Value
*
accept
(
ASTVisitor
&
)
final
;
Value
*
accept
(
ASTVisitor
&
)
final
;
std
::
string
id
;
// nullptr if var is of int type
std
::
shared_ptr
<
ASTExpression
>
expression
;
};
struct
ASTAdditiveExpression
:
ASTNode
{
Value
*
accept
(
ASTVisitor
&
)
final
;
Value
*
accept
(
ASTVisitor
&
)
final
;
std
::
shared_ptr
<
ASTAdditiveExpression
>
additive_expression
;
AddOp
op
;
std
::
shared_ptr
<
ASTTerm
>
term
;
};
struct
ASTTerm
:
ASTNode
{
Value
*
accept
(
ASTVisitor
&
)
final
;
Value
*
accept
(
ASTVisitor
&
)
final
;
std
::
shared_ptr
<
ASTTerm
>
term
;
MulOp
op
;
std
::
shared_ptr
<
ASTFactor
>
factor
;
};
struct
ASTCall
:
ASTFactor
{
Value
*
accept
(
ASTVisitor
&
)
final
;
Value
*
accept
(
ASTVisitor
&
)
final
;
std
::
string
id
;
std
::
vector
<
std
::
shared_ptr
<
ASTExpression
>>
args
;
};
...
...
@@ -233,22 +233,22 @@ class ASTVisitor {
class
ASTPrinter
:
public
ASTVisitor
{
public:
Value
*
visit
(
ASTProgram
&
)
final
;
Value
*
visit
(
ASTNum
&
)
final
;
Value
*
visit
(
ASTVarDeclaration
&
)
final
;
Value
*
visit
(
ASTFunDeclaration
&
)
final
;
Value
*
visit
(
ASTParam
&
)
final
;
Value
*
visit
(
ASTCompoundStmt
&
)
final
;
Value
*
visit
(
ASTExpressionStmt
&
)
final
;
Value
*
visit
(
ASTSelectionStmt
&
)
final
;
Value
*
visit
(
ASTIterationStmt
&
)
final
;
Value
*
visit
(
ASTReturnStmt
&
)
final
;
Value
*
visit
(
ASTAssignExpression
&
)
final
;
Value
*
visit
(
ASTSimpleExpression
&
)
final
;
Value
*
visit
(
ASTAdditiveExpression
&
)
final
;
Value
*
visit
(
ASTVar
&
)
final
;
Value
*
visit
(
ASTTerm
&
)
final
;
Value
*
visit
(
ASTCall
&
)
final
;
Value
*
visit
(
ASTProgram
&
)
final
;
Value
*
visit
(
ASTNum
&
)
final
;
Value
*
visit
(
ASTVarDeclaration
&
)
final
;
Value
*
visit
(
ASTFunDeclaration
&
)
final
;
Value
*
visit
(
ASTParam
&
)
final
;
Value
*
visit
(
ASTCompoundStmt
&
)
final
;
Value
*
visit
(
ASTExpressionStmt
&
)
final
;
Value
*
visit
(
ASTSelectionStmt
&
)
final
;
Value
*
visit
(
ASTIterationStmt
&
)
final
;
Value
*
visit
(
ASTReturnStmt
&
)
final
;
Value
*
visit
(
ASTAssignExpression
&
)
final
;
Value
*
visit
(
ASTSimpleExpression
&
)
final
;
Value
*
visit
(
ASTAdditiveExpression
&
)
final
;
Value
*
visit
(
ASTVar
&
)
final
;
Value
*
visit
(
ASTTerm
&
)
final
;
Value
*
visit
(
ASTCall
&
)
final
;
void
add_depth
()
{
depth
+=
2
;
}
void
remove_depth
()
{
depth
-=
2
;
}
...
...
include/lightir/BasicBlock.hpp
View file @
e547371b
...
...
@@ -12,10 +12,10 @@ class Module;
class
BasicBlock
:
public
Value
{
public:
BasicBlock
(
const
BasicBlock
&
other
)
=
delete
;
BasicBlock
(
BasicBlock
&&
other
)
noexcept
=
delete
;
BasicBlock
&
operator
=
(
const
BasicBlock
&
other
)
=
delete
;
BasicBlock
&
operator
=
(
BasicBlock
&&
other
)
noexcept
=
delete
;
BasicBlock
(
const
BasicBlock
&
other
)
=
delete
;
BasicBlock
(
BasicBlock
&&
other
)
noexcept
=
delete
;
BasicBlock
&
operator
=
(
const
BasicBlock
&
other
)
=
delete
;
BasicBlock
&
operator
=
(
BasicBlock
&&
other
)
noexcept
=
delete
;
~
BasicBlock
()
override
;
static
BasicBlock
*
create
(
Module
*
m
,
const
std
::
string
&
name
,
Function
*
parent
)
{
...
...
@@ -31,18 +31,18 @@ class BasicBlock : public Value {
void
add_pre_basic_block
(
BasicBlock
*
bb
)
{
for
(
auto
i
:
pre_bbs_
)
if
(
i
==
bb
)
return
;
pre_bbs_
.
push_back
(
bb
);
pre_bbs_
.
push_back
(
bb
);
}
// 自动去重
void
add_succ_basic_block
(
BasicBlock
*
bb
)
{
for
(
auto
i
:
succ_bbs_
)
if
(
i
==
bb
)
return
;
succ_bbs_
.
push_back
(
bb
);
succ_bbs_
.
push_back
(
bb
);
}
void
remove_pre_basic_block
(
BasicBlock
*
bb
)
{
pre_bbs_
.
remove
(
bb
);
}
// 若你将 br label0, label0 的其中一个 label0 改为 label1,并且调用 remove_suc label0,那 suc 集合中也将不再包含 label0
void
remove_succ_basic_block
(
BasicBlock
*
bb
)
{
succ_bbs_
.
remove
(
bb
);
}
BasicBlock
*
get_entry_block_of_same_function
()
const
;
BasicBlock
*
get_entry_block_of_same_function
()
const
;
// If the Block is terminated by ret/br
bool
is_terminated
()
const
;
...
...
@@ -77,7 +77,7 @@ class BasicBlock : public Value {
Module
*
get_module
()
const
;
void
erase_from_parent
();
std
::
string
print
()
override
;
std
::
string
print
()
override
;
// 用于 lldb 调试生成 summary
std
::
string
safe_print
()
const
;
...
...
include/lightir/Constant.hpp
View file @
e547371b
...
...
@@ -56,7 +56,7 @@ class ConstantArray : public Constant {
static
ConstantArray
*
get
(
ArrayType
*
ty
,
const
std
::
vector
<
Constant
*>
&
val
);
std
::
string
print
()
override
;
std
::
string
print
()
override
;
};
class
ConstantZero
:
public
Constant
{
...
...
include/lightir/Function.hpp
View file @
e547371b
...
...
@@ -16,10 +16,10 @@ class FunctionType;
class
Function
:
public
Value
{
public:
Function
(
const
Function
&
other
)
=
delete
;
Function
(
Function
&&
other
)
noexcept
=
delete
;
Function
&
operator
=
(
const
Function
&
other
)
=
delete
;
Function
&
operator
=
(
Function
&&
other
)
noexcept
=
delete
;
Function
(
const
Function
&
other
)
=
delete
;
Function
(
Function
&&
other
)
noexcept
=
delete
;
Function
&
operator
=
(
const
Function
&
other
)
=
delete
;
Function
&
operator
=
(
Function
&&
other
)
noexcept
=
delete
;
Function
(
FunctionType
*
ty
,
const
std
::
string
&
name
,
Module
*
parent
);
~
Function
()
override
;
static
Function
*
create
(
FunctionType
*
ty
,
const
std
::
string
&
name
,
...
...
@@ -35,18 +35,18 @@ class Function : public Value {
Module
*
get_parent
()
const
;
// 此处 remove 的 BasicBlock, 需要手动 delete
// 此处 remove 的 BasicBlock, 需要手动 delete
void
remove
(
BasicBlock
*
bb
);
BasicBlock
*
get_entry_block
()
const
{
return
basic_blocks_
.
front
();
}
std
::
list
<
BasicBlock
*>
&
get_basic_blocks
()
{
return
basic_blocks_
;
}
std
::
list
<
Argument
>
&
get_args
()
{
return
arguments_
;
}
std
::
list
<
Argument
*
>
&
get_args
()
{
return
arguments_
;
}
bool
is_declaration
()
const
{
return
basic_blocks_
.
empty
();
}
void
set_instr_name
();
std
::
string
print
()
override
;
// 用于检查函数的基本块是否存在问题
// 用于检查函数的基本块是否存在问题
void
check_for_block_relation_error
()
const
;
// 用于 lldb 调试生成 summary
...
...
@@ -58,7 +58,7 @@ class Function : public Value {
private:
std
::
list
<
BasicBlock
*>
basic_blocks_
;
std
::
list
<
Argument
>
arguments_
;
std
::
list
<
Argument
*
>
arguments_
;
Module
*
parent_
;
unsigned
seq_cnt_
;
// print use
};
...
...
@@ -66,17 +66,17 @@ class Function : public Value {
// Argument of Function, does not contain actual value
class
Argument
:
public
Value
{
public:
Argument
(
const
Argument
&
other
)
=
delete
;
Argument
(
Argument
&&
other
)
noexcept
=
delete
;
Argument
&
operator
=
(
const
Argument
&
other
)
=
delete
;
Argument
&
operator
=
(
Argument
&&
other
)
noexcept
=
delete
;
Argument
(
const
Argument
&
other
)
=
delete
;
Argument
(
Argument
&&
other
)
noexcept
=
delete
;
Argument
&
operator
=
(
const
Argument
&
other
)
=
delete
;
Argument
&
operator
=
(
Argument
&&
other
)
noexcept
=
delete
;
explicit
Argument
(
Type
*
ty
,
const
std
::
string
&
name
=
""
,
Function
*
f
=
nullptr
,
unsigned
arg_no
=
0
)
:
Value
(
ty
,
name
),
parent_
(
f
),
arg_no_
(
arg_no
)
{}
~
Argument
()
override
=
default
;
~
Argument
()
override
=
default
;
const
Function
*
get_parent
()
const
{
return
parent_
;
}
Function
*
get_parent
()
{
return
parent_
;
}
const
Function
*
get_parent
()
const
{
return
parent_
;
}
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
{
...
...
@@ -84,7 +84,7 @@ class Argument : public Value {
return
arg_no_
;
}
std
::
string
print
()
override
;
std
::
string
print
()
override
;
// 用于 lldb 调试生成 summary
std
::
string
safe_print
()
const
;
...
...
include/lightir/Instruction.hpp
View file @
e547371b
...
...
@@ -277,7 +277,7 @@ class AllocaInst : public Instruction {
public:
// 新特性:指令表分为 {alloca, phi | other inst} 两段,创建和向基本块插入 alloca 和 phi,都只会插在第一段,它们在常规指令前面
static
AllocaInst
*
create_alloca
(
Type
*
ty
,
BasicBlock
*
bb
,
const
std
::
string
&
name
=
""
);
Type
*
get_alloca_type
()
const
{
return
get_type
()
->
get_pointer_element_type
();
}
...
...
include/lightir/Module.hpp
View file @
e547371b
...
...
@@ -42,7 +42,7 @@ class Module {
private:
// The global variables in the module
std
::
list
<
GlobalVariable
*>
global_list_
;
std
::
list
<
GlobalVariable
*>
global_list_
;
// The functions in the module
std
::
list
<
Function
*>
function_list_
;
...
...
include/lightir/Names.hpp
View file @
e547371b
...
...
@@ -6,22 +6,21 @@
class
Names
{
public:
explicit
Names
(
bool
use_underline
,
std
::
string
prefix
,
std
::
string
append
)
:
use_underline_
(
use_underline
),
default_prefix_used_count_
(
0
),
default_prefix_
(
std
::
move
(
prefix
)),
appended_prefix_
(
std
::
move
(
append
))
{
}
explicit
Names
(
std
::
string
prefix
,
std
::
string
append
)
:
default_prefix_used_count_
(
0
),
default_prefix_
(
std
::
move
(
prefix
)),
appended_prefix_
(
std
::
move
(
append
))
{
}
// 获得一个 Names 内唯一的名称,会保持唯一的同时尽可能的与 names 类似
std
::
string
get_name
(
std
::
string
name
);
// 获得一个 Names 内唯一的名称
std
::
string
get_name
();
// 获得一个 Names 内唯一的名称,会保持唯一的同时尽可能的与 names 类似
std
::
string
get_name
(
std
::
string
name
);
// 获得一个 Names 内唯一的名称
std
::
string
get_name
();
private:
bool
use_underline_
;
int
default_prefix_used_count_
;
std
::
string
default_prefix_
;
std
::
string
appended_prefix_
;
std
::
unordered_map
<
std
::
string
,
int
>
allocated_
;
int
default_prefix_used_count_
;
std
::
string
default_prefix_
;
std
::
string
appended_prefix_
;
std
::
unordered_map
<
std
::
string
,
int
>
allocated_
;
};
#endif // !NAMES_HPP
include/lightir/Type.hpp
View file @
e547371b
...
...
@@ -12,12 +12,12 @@ class FloatType;
class
Type
{
public:
Type
(
const
Type
&
other
)
=
delete
;
Type
(
Type
&&
other
)
noexcept
=
delete
;
Type
&
operator
=
(
const
Type
&
other
)
=
delete
;
Type
&
operator
=
(
Type
&&
other
)
noexcept
=
delete
;
Type
(
const
Type
&
other
)
=
delete
;
Type
(
Type
&&
other
)
noexcept
=
delete
;
Type
&
operator
=
(
const
Type
&
other
)
=
delete
;
Type
&
operator
=
(
Type
&&
other
)
noexcept
=
delete
;
enum
TypeID
:
uint8_t
{
enum
TypeID
:
uint8_t
{
VoidTyID
,
// Void
LabelTyID
,
// Labels, e.g., BasicBlock
IntegerTyID
,
// Integers, include 32 bits and 1 bit
...
...
@@ -63,12 +63,12 @@ class Type {
class
IntegerType
:
public
Type
{
public:
IntegerType
(
const
IntegerType
&
other
)
=
delete
;
IntegerType
(
IntegerType
&&
other
)
noexcept
=
delete
;
IntegerType
&
operator
=
(
const
IntegerType
&
other
)
=
delete
;
IntegerType
&
operator
=
(
IntegerType
&&
other
)
noexcept
=
delete
;
IntegerType
(
const
IntegerType
&
other
)
=
delete
;
IntegerType
(
IntegerType
&&
other
)
noexcept
=
delete
;
IntegerType
&
operator
=
(
const
IntegerType
&
other
)
=
delete
;
IntegerType
&
operator
=
(
IntegerType
&&
other
)
noexcept
=
delete
;
explicit
IntegerType
(
unsigned
num_bits
,
Module
*
m
);
explicit
IntegerType
(
unsigned
num_bits
,
Module
*
m
);
~
IntegerType
()
override
;
unsigned
get_num_bits
()
const
;
...
...
@@ -79,12 +79,12 @@ class IntegerType : public Type {
class
FunctionType
:
public
Type
{
public:
FunctionType
(
const
FunctionType
&
other
)
=
delete
;
FunctionType
(
FunctionType
&&
other
)
noexcept
=
delete
;
FunctionType
&
operator
=
(
const
FunctionType
&
other
)
=
delete
;
FunctionType
&
operator
=
(
FunctionType
&&
other
)
noexcept
=
delete
;
FunctionType
(
const
FunctionType
&
other
)
=
delete
;
FunctionType
(
FunctionType
&&
other
)
noexcept
=
delete
;
FunctionType
&
operator
=
(
const
FunctionType
&
other
)
=
delete
;
FunctionType
&
operator
=
(
FunctionType
&&
other
)
noexcept
=
delete
;
FunctionType
(
Type
*
result
,
const
std
::
vector
<
Type
*>&
params
);
FunctionType
(
Type
*
result
,
const
std
::
vector
<
Type
*>&
params
);
~
FunctionType
()
override
;
static
bool
is_valid_return_type
(
const
Type
*
ty
);
...
...
@@ -106,12 +106,12 @@ class FunctionType : public Type {
class
ArrayType
:
public
Type
{
public:
ArrayType
(
const
ArrayType
&
other
)
=
delete
;
ArrayType
(
ArrayType
&&
other
)
noexcept
=
delete
;
ArrayType
&
operator
=
(
const
ArrayType
&
other
)
=
delete
;
ArrayType
&
operator
=
(
ArrayType
&&
other
)
noexcept
=
delete
;
ArrayType
(
const
ArrayType
&
other
)
=
delete
;
ArrayType
(
ArrayType
&&
other
)
noexcept
=
delete
;
ArrayType
&
operator
=
(
const
ArrayType
&
other
)
=
delete
;
ArrayType
&
operator
=
(
ArrayType
&&
other
)
noexcept
=
delete
;
ArrayType
(
Type
*
contained
,
unsigned
num_elements
);
ArrayType
(
Type
*
contained
,
unsigned
num_elements
);
~
ArrayType
()
override
;
static
bool
is_valid_element_type
(
const
Type
*
ty
);
...
...
@@ -128,12 +128,12 @@ class ArrayType : public Type {
class
PointerType
:
public
Type
{
public:
PointerType
(
const
PointerType
&
other
)
=
delete
;
PointerType
(
PointerType
&&
other
)
noexcept
=
delete
;
PointerType
&
operator
=
(
const
PointerType
&
other
)
=
delete
;
PointerType
&
operator
=
(
PointerType
&&
other
)
noexcept
=
delete
;
PointerType
(
const
PointerType
&
other
)
=
delete
;
PointerType
(
PointerType
&&
other
)
noexcept
=
delete
;
PointerType
&
operator
=
(
const
PointerType
&
other
)
=
delete
;
PointerType
&
operator
=
(
PointerType
&&
other
)
noexcept
=
delete
;
PointerType
(
Type
*
contained
);
PointerType
(
Type
*
contained
);
~
PointerType
()
override
;
Type
*
get_element_type
()
const
{
return
contained_
;
}
...
...
@@ -145,12 +145,12 @@ class PointerType : public Type {
class
FloatType
:
public
Type
{
public:
FloatType
(
const
FloatType
&
other
)
=
delete
;
FloatType
(
FloatType
&&
other
)
noexcept
=
delete
;
FloatType
&
operator
=
(
const
FloatType
&
other
)
=
delete
;
FloatType
&
operator
=
(
FloatType
&&
other
)
noexcept
=
delete
;
FloatType
(
const
FloatType
&
other
)
=
delete
;
FloatType
(
FloatType
&&
other
)
noexcept
=
delete
;
FloatType
&
operator
=
(
const
FloatType
&
other
)
=
delete
;
FloatType
&
operator
=
(
FloatType
&&
other
)
noexcept
=
delete
;
FloatType
(
Module
*
m
);
FloatType
(
Module
*
m
);
~
FloatType
()
override
;
static
FloatType
*
get
(
Module
*
m
);
};
include/lightir/User.hpp
View file @
e547371b
...
...
@@ -6,11 +6,11 @@
class
User
:
public
Value
{
public:
User
(
const
User
&
other
)
=
delete
;
User
(
User
&&
other
)
noexcept
=
delete
;
User
&
operator
=
(
const
User
&
other
)
=
delete
;
User
&
operator
=
(
User
&&
other
)
noexcept
=
delete
;
User
(
Type
*
ty
,
const
std
::
string
&
name
=
""
)
:
Value
(
ty
,
name
){}
User
(
const
User
&
other
)
=
delete
;
User
(
User
&&
other
)
noexcept
=
delete
;
User
&
operator
=
(
const
User
&
other
)
=
delete
;
User
&
operator
=
(
User
&&
other
)
noexcept
=
delete
;
User
(
Type
*
ty
,
const
std
::
string
&
name
=
""
)
:
Value
(
ty
,
name
){}
~
User
()
override
;
const
std
::
vector
<
Value
*>
&
get_operands
()
const
{
return
operands_
;
}
...
...
include/lightir/Value.hpp
View file @
e547371b
...
...
@@ -12,12 +12,12 @@ struct Use;
class
Value
{
public:
Value
(
const
Value
&
other
)
=
delete
;
Value
(
Value
&&
other
)
noexcept
=
delete
;
Value
&
operator
=
(
const
Value
&
other
)
=
delete
;
Value
&
operator
=
(
Value
&&
other
)
noexcept
=
delete
;
Value
(
const
Value
&
other
)
=
delete
;
Value
(
Value
&&
other
)
noexcept
=
delete
;
Value
&
operator
=
(
const
Value
&
other
)
=
delete
;
Value
&
operator
=
(
Value
&&
other
)
noexcept
=
delete
;
explicit
Value
(
Type
*
ty
,
std
::
string
name
=
""
)
explicit
Value
(
Type
*
ty
,
std
::
string
name
=
""
)
:
type_
(
ty
),
name_
(
std
::
move
(
name
)){}
virtual
~
Value
();
...
...
lldb_formatters.py
View file @
e547371b
...
...
@@ -9,7 +9,13 @@ def parseString(val : lldb.SBValue):
return
""
def
SafePrintSummary
(
valobj
:
lldb
.
SBValue
,
internal_dict
):
name
:
lldb
.
SBValue
=
valobj
.
EvaluateExpression
(
"this->safe_print()"
)
if
valobj
.
GetType
().
IsPointerType
():
deref
:
lldb
.
SBValue
=
valobj
.
Dereference
()
if
deref
.
IsValid
():
valobj
=
deref
else
:
return
""
name
:
lldb
.
SBValue
=
valobj
.
EvaluateExpression
(
"safe_print()"
)
return
parseString
(
name
)
def
__lldb_init_module
(
debugger
:
lldb
.
SBDebugger
,
internal_dict
):
...
...
@@ -18,7 +24,8 @@ def __lldb_init_module(debugger: lldb.SBDebugger, internal_dict):
,
"Function"
,
"Argument"
,
"BasicBlock"
,
"GlobalVariable"
,
"Instruction"
,
"IBinaryInst"
,
"FBinaryInst"
,
"ICmpInst"
,
"FCmpInst"
,
"CallInst"
,
"BranchInst"
,
"ReturnInst"
,
"GetElementPtrInst"
,
"StoreInst"
,
"LoadInst"
,
"AllocaInst"
,
"ZextInst"
,
"FpToSiInst"
,
"SiToFpInst"
,
"PhiInst"
]
,
"Instruction"
,
"IBinaryInst"
,
"FBinaryInst"
,
"ICmpInst"
,
"FCmpInst"
,
"CallInst"
,
"BranchInst"
,
"ReturnInst"
,
"GetElementPtrInst"
,
"StoreInst"
,
"LoadInst"
,
"AllocaInst"
,
"ZextInst"
,
"FpToSiInst"
,
"SiToFpInst"
,
"PhiInst"
,
"ASMInstruction"
,
"Reg"
,
"FReg"
,
"CFReg"
]
for
i
in
types
:
debugger
.
HandleCommand
(
f"type summary add -F lldb_formatters.SafePrintSummary
{
i
}
-w my"
...
...
src/cminusfc/cminusf_builder.cpp
View file @
e547371b
...
...
@@ -108,7 +108,7 @@ Value* CminusfBuilder::visit(ASTVarDeclaration &node) {
}
Value
*
CminusfBuilder
::
visit
(
ASTFunDeclaration
&
node
)
{
Type
*
ret_type
;
Type
*
ret_type
;
std
::
vector
<
Type
*>
param_types
;
if
(
node
.
type
==
TYPE_INT
)
ret_type
=
INT32_T
;
...
...
@@ -142,8 +142,8 @@ Value* CminusfBuilder::visit(ASTFunDeclaration &node) {
scope
.
enter
();
context
.
pre_enter_scope
=
true
;
std
::
vector
<
Value
*>
args
;
for
(
auto
&
arg
:
func
->
get_args
())
{
args
.
push_back
(
&
arg
);
for
(
auto
arg
:
func
->
get_args
())
{
args
.
push_back
(
arg
);
}
for
(
unsigned
int
i
=
0
;
i
<
node
.
params
.
size
();
++
i
)
{
if
(
node
.
params
[
i
]
->
isarray
)
{
...
...
src/codegen/CodeGen.cpp
View file @
e547371b
#include "CodeGen.hpp"
#include "ASMInstruction.hpp"
#include "CodeGenUtil.hpp"
#include "Register.hpp"
std
::
string
ASMInstruction
::
safe_print
()
const
{
switch
(
type
)
{
case
Instruction
:
case
Attribute
:
return
content
;
case
Label
:
return
content
+
":"
;
case
Comment
:
return
"# "
+
content
;
}
return
"<error>"
;
}
void
CodeGen
::
allocate
()
{
// 备份 $ra $fp
...
...
@@ -8,9 +24,9 @@ void CodeGen::allocate() {
// 为每个参数分配栈空间
for
(
auto
&
arg
:
context
.
func
->
get_args
())
{
auto
size
=
arg
.
get_type
()
->
get_size
();
auto
size
=
arg
->
get_type
()
->
get_size
();
offset
=
offset
+
size
;
context
.
offset_map
[
&
arg
]
=
-
static_cast
<
int
>
(
offset
);
context
.
offset_map
[
arg
]
=
-
static_cast
<
int
>
(
offset
);
}
// 为指令结果分配栈空间
...
...
@@ -205,11 +221,11 @@ void CodeGen::gen_prologue() {
int
garg_cnt
=
0
;
int
farg_cnt
=
0
;
for
(
auto
&
arg
:
context
.
func
->
get_args
())
{
if
(
arg
.
get_type
()
->
is_float_type
())
{
store_from_freg
(
&
arg
,
FReg
::
fa
(
farg_cnt
++
));
for
(
auto
arg
:
context
.
func
->
get_args
())
{
if
(
arg
->
get_type
()
->
is_float_type
())
{
store_from_freg
(
arg
,
FReg
::
fa
(
farg_cnt
++
));
}
else
{
// int or pointer
store_from_greg
(
&
arg
,
Reg
::
a
(
garg_cnt
++
));
store_from_greg
(
arg
,
Reg
::
a
(
garg_cnt
++
));
}
}
}
...
...
@@ -241,16 +257,16 @@ void CodeGen::gen_binary() {
load_to_greg
(
context
.
inst
->
get_operand
(
1
),
Reg
::
t
(
1
));
switch
(
context
.
inst
->
get_instr_type
())
{
case
Instruction
::
add
:
output
.
emplace_back
(
"add.w $t2, $t0, $t1"
);
append_inst
(
"add.w $t2, $t0, $t1"
);
break
;
case
Instruction
::
sub
:
output
.
emplace_back
(
"sub.w $t2, $t0, $t1"
);
append_inst
(
"sub.w $t2, $t0, $t1"
);
break
;
case
Instruction
::
mul
:
output
.
emplace_back
(
"mul.w $t2, $t0, $t1"
);
append_inst
(
"mul.w $t2, $t0, $t1"
);
break
;
case
Instruction
::
sdiv
:
output
.
emplace_back
(
"div.w $t2, $t0, $t1"
);
append_inst
(
"div.w $t2, $t0, $t1"
);
break
;
default:
assert
(
false
);
...
...
@@ -370,26 +386,26 @@ void CodeGen::run() {
* - 支持更旧版本的 GNU 汇编器, 因为 `.bss` 伪指令是应该相对较新的指令,
* GNU 汇编器在 2023 年 2 月的 2.37 版本才将其引入
*/
append_inst
(
".text"
,
ASMInstruction
::
At
r
ribute
);
append_inst
(
".text"
,
ASMInstruction
::
At
t
ribute
);
append_inst
(
".section"
,
{
".bss"
,
"
\"
aw
\"
"
,
"@nobits"
},
ASMInstruction
::
At
r
ribute
);
ASMInstruction
::
At
t
ribute
);
for
(
auto
global
:
m
->
get_global_variable
())
{
auto
size
=
global
->
get_type
()
->
get_pointer_element_type
()
->
get_size
();
append_inst
(
".globl"
,
{
global
->
get_name
()},
ASMInstruction
::
At
r
ribute
);
ASMInstruction
::
At
t
ribute
);
append_inst
(
".type"
,
{
global
->
get_name
(),
"@object"
},
ASMInstruction
::
At
r
ribute
);
ASMInstruction
::
At
t
ribute
);
append_inst
(
".size"
,
{
global
->
get_name
(),
std
::
to_string
(
size
)},
ASMInstruction
::
At
r
ribute
);
ASMInstruction
::
At
t
ribute
);
append_inst
(
global
->
get_name
(),
ASMInstruction
::
Label
);
append_inst
(
".space"
,
{
std
::
to_string
(
size
)},
ASMInstruction
::
At
r
ribute
);
ASMInstruction
::
At
t
ribute
);
}
}
// 函数代码段
output
.
emplace_back
(
".text"
,
ASMInstruction
::
Atrribute
);
output
.
emplace_back
(
new
ASMInstruction
(
".text"
,
ASMInstruction
::
Attribute
)
);
for
(
auto
func
:
m
->
get_functions
())
{
if
(
not
func
->
is_declaration
())
{
// 更新 context
...
...
@@ -397,9 +413,9 @@ void CodeGen::run() {
context
.
func
=
func
;
// 函数信息
append_inst
(
".globl"
,
{
func
->
get_name
()},
ASMInstruction
::
At
r
ribute
);
append_inst
(
".globl"
,
{
func
->
get_name
()},
ASMInstruction
::
At
t
ribute
);
append_inst
(
".type"
,
{
func
->
get_name
(),
"@function"
},
ASMInstruction
::
At
r
ribute
);
ASMInstruction
::
At
t
ribute
);
append_inst
(
func
->
get_name
(),
ASMInstruction
::
Label
);
// 分配函数栈帧
...
...
@@ -495,8 +511,8 @@ void CodeGen::run() {
std
::
string
CodeGen
::
print
()
const
{
std
::
string
result
;
for
(
const
auto
&
inst
:
output
)
{
result
+=
inst
.
format
();
for
(
const
auto
inst
:
output
)
{
result
+=
inst
->
format
();
}
return
result
;
}
src/codegen/Register.cpp
View file @
e547371b
...
...
@@ -26,9 +26,35 @@ std::string Reg::print() const {
assert
(
false
);
}
std
::
string
Reg
::
safe_print
()
const
{
if
(
id
==
0
)
{
return
"$zero"
;
}
if
(
id
==
1
)
{
return
"$ra"
;
}
if
(
id
==
2
)
{
return
"$tp"
;
}
if
(
id
==
3
)
{
return
"$sp"
;
}
if
(
4
<=
id
and
id
<=
11
)
{
return
"$a"
+
std
::
to_string
(
id
-
4
);
}
if
(
12
<=
id
and
id
<=
20
)
{
return
"$t"
+
std
::
to_string
(
id
-
12
);
}
if
(
id
==
22
)
{
return
"$fp"
;
}
return
"<error id "
+
std
::
to_string
(
id
)
+
">"
;
}
std
::
string
FReg
::
print
()
const
{
if
(
0
<=
id
and
id
<=
7
)
{
if
(
id
<=
7
)
{
return
"$fa"
+
std
::
to_string
(
id
);
}
if
(
8
<=
id
and
id
<=
23
)
{
...
...
@@ -39,3 +65,22 @@ std::string FReg::print() const {
}
assert
(
false
);
}
std
::
string
FReg
::
safe_print
()
const
{
if
(
id
<=
7
)
{
return
"$fa"
+
std
::
to_string
(
id
);
}
if
(
8
<=
id
and
id
<=
23
)
{
return
"$ft"
+
std
::
to_string
(
id
-
8
);
}
if
(
24
<=
id
and
id
<=
31
)
{
return
"$fs"
+
std
::
to_string
(
id
-
24
);
}
return
"<error id "
+
std
::
to_string
(
id
)
+
">"
;
}
std
::
string
CFReg
::
safe_print
()
const
{
return
"$fcc"
+
std
::
to_string
(
id
);
}
src/common/util.cpp
View file @
e547371b
...
...
@@ -2,14 +2,14 @@
std
::
string
ptr_to_str
(
const
void
*
ptr
)
{
const
char
*
translate
=
"0123456789abcdef"
;
const
char
*
translate
=
"0123456789abcdef"
;
uintptr_t
addr
=
reinterpret_cast
<
uintptr_t
>
(
ptr
);
uintptr_t
addr
=
reinterpret_cast
<
uintptr_t
>
(
ptr
);
uintptr_t
a
=
addr
&
0xF
;
uintptr_t
b
=
(
addr
>>
4
)
&
0xF
;
uintptr_t
c
=
(
addr
>>
8
)
&
0xF
;
uintptr_t
d
=
(
addr
>>
12
)
&
0xF
;
uintptr_t
a
=
addr
&
0xF
;
uintptr_t
b
=
(
addr
>>
4
)
&
0xF
;
uintptr_t
c
=
(
addr
>>
8
)
&
0xF
;
uintptr_t
d
=
(
addr
>>
12
)
&
0xF
;
return
{
'<'
,
translate
[
d
],
translate
[
c
],
translate
[
b
],
translate
[
a
],
'>'
};
return
{
'<'
,
translate
[
d
],
translate
[
c
],
translate
[
b
],
translate
[
a
],
'>'
};
}
src/lightir/BasicBlock.cpp
View file @
e547371b
...
...
@@ -47,7 +47,7 @@ void BasicBlock::add_instruction(Instruction *instr) {
auto
it
=
instr_list_
.
begin
();
for
(;
it
!=
instr_list_
.
end
()
&&
((
*
it
)
->
is_alloca
()
||
(
*
it
)
->
is_phi
());
++
it
){}
instr_list_
.
emplace
(
it
,
instr
);
return
;
return
;
}
assert
(
not
is_terminated
()
&&
"Inserting instruction to terminated bb"
);
instr_list_
.
push_back
(
instr
);
...
...
@@ -56,7 +56,7 @@ void BasicBlock::add_instruction(Instruction *instr) {
void
BasicBlock
::
add_instr_begin
(
Instruction
*
instr
)
{
if
(
instr
->
is_alloca
()
||
instr
->
is_phi
())
instr_list_
.
push_front
(
instr
);
instr_list_
.
push_front
(
instr
);
else
{
auto
it
=
instr_list_
.
begin
();
...
...
@@ -121,8 +121,8 @@ BasicBlock::~BasicBlock()
BasicBlock
*
BasicBlock
::
get_entry_block_of_same_function
()
const
{
assert
(
parent_
!=
nullptr
&&
"bb have no parent function"
);
return
parent_
->
get_entry_block
();
assert
(
parent_
!=
nullptr
&&
"bb have no parent function"
);
return
parent_
->
get_entry_block
();
}
Names
GLOBAL_BASICBLOCK_NAMES_
{
false
,
"label"
,
""
};
\ No newline at end of file
Names
GLOBAL_BASICBLOCK_NAMES_
{
"label"
,
"_"
};
\ No newline at end of file
src/lightir/Constant.cpp
View file @
e547371b
...
...
@@ -168,7 +168,7 @@ std::string ConstantFP::print() {
ConstantZero
*
ConstantZero
::
get
(
Type
*
ty
,
Module
*
m
)
{
if
(
not
cached_zero
[
ty
])
{
cached_zero
[
ty
]
=
std
::
unique_ptr
<
ConstantZero
>
(
new
ConstantZero
(
ty
));
cached_zero
[
ty
]
=
std
::
unique_ptr
<
ConstantZero
>
(
new
ConstantZero
(
ty
));
}
return
cached_zero
[
ty
].
get
();
}
...
...
src/lightir/Function.cpp
View file @
e547371b
...
...
@@ -3,31 +3,33 @@
#include "Module.hpp"
#include "Instruction.hpp"
#include <cassert>
#include <string>
#include <unordered_set>
#include <queue>
namespace
{
std
::
string
chopName
(
std
::
string
name
)
{
if
(
name
.
size
()
>
4
)
return
{
name
.
begin
(),
name
.
begin
()
+
4
};
std
::
string
chopName
(
std
::
string
name
)
{
if
(
name
.
size
()
>
3
)
return
{
name
.
begin
(),
name
.
begin
()
+
3
};
return
name
;
}
}
}
Function
::
Function
(
FunctionType
*
ty
,
const
std
::
string
&
name
,
Module
*
parent
)
:
Value
(
ty
,
name
),
names4blocks_
(
false
,
"label"
,
chopName
(
name
)),
names4insts_
(
true
,
"op"
,
""
),
parent_
(
parent
),
seq_cnt_
(
0
)
{
:
Value
(
ty
,
name
),
names4blocks_
(
"label"
,
chopName
(
name
)
+
"_"
),
names4insts_
(
"op"
,
""
),
parent_
(
parent
),
seq_cnt_
(
0
)
{
// num_args_ = ty->getNumParams();
parent
->
add_function
(
this
);
// build args
for
(
unsigned
i
=
0
;
i
<
get_num_of_args
();
i
++
)
{
arguments_
.
emplace_back
(
ty
->
get_param_type
(
i
),
""
,
this
,
i
);
arguments_
.
emplace_back
(
new
Argument
(
ty
->
get_param_type
(
i
),
"arg"
+
std
::
to_string
(
i
),
this
,
i
)
);
}
}
Function
::~
Function
()
{
for
(
auto
bb
:
basic_blocks_
)
delete
bb
;
for
(
auto
arg
:
arguments_
)
delete
arg
;
}
Function
*
Function
::
create
(
FunctionType
*
ty
,
const
std
::
string
&
name
,
...
...
@@ -66,10 +68,10 @@ void Function::add_basic_block(BasicBlock* bb) { basic_blocks_.push_back(bb); }
void
Function
::
set_instr_name
()
{
std
::
map
<
Value
*
,
int
>
seq
;
for
(
auto
&
arg
:
this
->
get_args
())
{
if
(
seq
.
find
(
&
arg
)
==
seq
.
end
())
{
if
(
seq
.
find
(
arg
)
==
seq
.
end
())
{
auto
seq_num
=
seq
.
size
()
+
seq_cnt_
;
if
(
arg
.
set_name
(
"arg"
+
std
::
to_string
(
seq_num
)))
{
seq
.
insert
({
&
arg
,
seq_num
});
if
(
arg
->
set_name
(
"arg"
+
std
::
to_string
(
seq_num
)))
{
seq
.
insert
({
arg
,
seq_num
});
}
}
}
...
...
@@ -121,7 +123,7 @@ std::string Function::print() {
for
(
auto
&
arg
:
get_args
())
{
if
(
&
arg
!=
&*
get_args
().
begin
())
func_ir
+=
", "
;
func_ir
+=
arg
.
print
();
func_ir
+=
arg
->
print
();
}
}
func_ir
+=
")"
;
...
...
@@ -160,7 +162,7 @@ std::string Argument::safe_print() const
auto
ty
=
parent
->
get_function_type
();
if
(
ty
==
nullptr
||
ty
->
get_num_of_args
()
<=
arg_no_
)
return
"@"
+
parent
->
get_name
()
+
" arg"
+
std
::
to_string
(
arg_no_
)
+
" <unknow type>"
;
auto
ty2
=
ty
->
get_param_type
(
arg_no_
);
return
"@"
+
parent
->
get_name
()
+
" arg"
+
std
::
to_string
(
arg_no_
)
+
" "
+
(
ty2
==
nullptr
?
"<null>"
:
ty2
->
safe_print
()
);
return
(
ty2
==
nullptr
?
"<null>"
:
ty2
->
safe_print
())
+
" @"
+
parent
->
get_name
()
+
" arg"
+
std
::
to_string
(
arg_no_
);
}
...
...
src/lightir/IRprinter.cpp
View file @
e547371b
...
...
@@ -217,7 +217,7 @@ std::string Instruction::safe_print() const
switch
(
op_id_
)
{
case
ret
:
{
{
std
::
string
instr_ir
;
instr_ir
+=
get_instr_op_name
();
instr_ir
+=
" "
;
...
...
@@ -230,9 +230,9 @@ std::string Instruction::safe_print() const
instr_ir
+=
"void"
;
}
return
instr_ir
;
}
}
case
br
:
{
{
std
::
string
instr_ir
;
instr_ir
+=
safe_print_instr_op_name
(
get_instr_type
());
instr_ir
+=
" "
;
...
...
@@ -244,7 +244,7 @@ std::string Instruction::safe_print() const
instr_ir
+=
safe_print_op_as_op
(
this
,
2
,
true
);
}
return
instr_ir
;
}
}
case
add
:
case
sub
:
case
mul
:
...
...
@@ -265,7 +265,7 @@ std::string Instruction::safe_print() const
return
instr_ir
;
}
case
alloca
:
{
{
std
::
string
instr_ir
;
instr_ir
+=
safe_print_as_op
(
this
,
true
);
instr_ir
+=
" = "
;
...
...
@@ -284,9 +284,9 @@ std::string Instruction::safe_print() const
else
instr_ir
+=
ty2
->
safe_print
();
}
return
instr_ir
;
}
}
case
load
:
{
{
std
::
string
instr_ir
;
instr_ir
+=
safe_print_as_op
(
this
,
true
);
instr_ir
+=
" = "
;
...
...
@@ -294,9 +294,9 @@ std::string Instruction::safe_print() const
instr_ir
+=
" "
;
instr_ir
+=
safe_print_op_as_op
(
this
,
0
,
true
);
return
instr_ir
;
}
}
case
store
:
{
{
std
::
string
instr_ir
;
instr_ir
+=
safe_print_instr_op_name
(
get_instr_type
());
instr_ir
+=
" "
;
...
...
@@ -304,7 +304,7 @@ std::string Instruction::safe_print() const
instr_ir
+=
", "
;
instr_ir
+=
safe_print_op_as_op
(
this
,
1
,
true
);
return
instr_ir
;
}
}
case
ge
:
case
gt
:
case
le
:
...
...
@@ -340,8 +340,8 @@ std::string Instruction::safe_print() const
return
instr_ir
;
}
case
phi
:
{
std
::
string
instr_ir
;
{
std
::
string
instr_ir
;
instr_ir
+=
safe_print_as_op
(
this
,
true
);
instr_ir
+=
" = "
;
instr_ir
+=
safe_print_instr_op_name
(
get_instr_type
());
...
...
@@ -356,7 +356,7 @@ std::string Instruction::safe_print() const
instr_ir
+=
" ]"
;
}
return
instr_ir
;
}
}
case
call
:
{
std
::
string
instr_ir
;
...
...
@@ -410,7 +410,7 @@ std::string Instruction::safe_print() const
return
instr_ir
;
}
case
getelementptr
:
{
{
std
::
string
instr_ir
;
instr_ir
+=
safe_print_as_op
(
this
,
true
);
instr_ir
+=
" = "
;
...
...
@@ -422,11 +422,11 @@ std::string Instruction::safe_print() const
instr_ir
+=
safe_print_op_as_op
(
this
,
i
,
true
);
}
return
instr_ir
;
}
}
case
zext
:
case
fptosi
:
case
sitofp
:
{
{
std
::
string
instr_ir
;
instr_ir
+=
safe_print_as_op
(
this
,
true
);
instr_ir
+=
" = "
;
...
...
@@ -434,7 +434,7 @@ std::string Instruction::safe_print() const
instr_ir
+=
" "
;
instr_ir
+=
safe_print_op_as_op
(
this
,
0
,
true
);
return
instr_ir
;
}
}
}
std
::
string
str
;
str
+=
safe_print_as_op
(
this
,
true
);
...
...
@@ -538,10 +538,12 @@ std::string BranchInst::print() {
std
::
string
ReturnInst
::
print
()
{
std
::
string
instr_ir
;
instr_ir
+=
safe_print_instr_op_name
(
get_instr_type
()
);
instr_ir
+=
get_instr_op_name
(
);
instr_ir
+=
" "
;
if
(
!
is_void_ret
())
{
instr_ir
+=
safe_print_op_as_op
(
this
,
0
,
true
);
instr_ir
+=
this
->
get_operand
(
0
)
->
get_type
()
->
print
();
instr_ir
+=
" "
;
instr_ir
+=
print_as_op
(
this
->
get_operand
(
0
),
false
);
}
else
{
instr_ir
+=
"void"
;
}
...
...
src/lightir/Instruction.cpp
View file @
e547371b
...
...
@@ -15,7 +15,7 @@ Instruction::Instruction(Type *ty, OpID id, const std::string& name, BasicBlock
assert
(
ty
!=
nullptr
&&
"Instruction have null type"
);
assert
(((
!
ty
->
is_void_type
())
||
name
.
empty
())
&&
"Void Type Instruction should not have name"
);
if
(
parent
)
parent
->
add_instruction
(
this
);
parent
->
add_instruction
(
this
);
if
(
!
ty
->
is_void_type
()
&&
parent
&&
parent
->
get_parent
())
set_name
(
parent_
->
get_parent
()
->
names4insts_
.
get_name
(
name
));
}
...
...
@@ -226,7 +226,7 @@ GetElementPtrInst::GetElementPtrInst(Value *ptr, const std::vector<Value *>& idx
add_operand
(
ptr
);
for
(
auto
idx
:
idxs
)
{
assert
(
idx
->
get_type
()
->
is_integer_type
()
&&
"Index is not integer"
);
assert
(
idx
->
get_type
()
->
is_integer_type
()
&&
"Index is not integer"
);
add_operand
(
idx
);
}
}
...
...
@@ -309,7 +309,7 @@ ZextInst::ZextInst(Value *val, Type *ty, BasicBlock *bb, const std::string& name
"ZextInst operand is not integer"
);
assert
(
ty
->
is_integer_type
()
&&
"ZextInst destination type is not integer"
);
assert
((
dynamic_cast
<
IntegerType
*>
(
val
->
get_type
())
->
get_num_bits
()
<
dynamic_cast
<
IntegerType
*>
(
ty
)
->
get_num_bits
())
&&
dynamic_cast
<
IntegerType
*>
(
ty
)
->
get_num_bits
())
&&
"ZextInst operand bit size is not smaller than destination type bit "
"size"
);
add_operand
(
val
);
...
...
@@ -368,4 +368,4 @@ PhiInst *PhiInst::create_phi(Type *ty, BasicBlock *bb,
return
new
PhiInst
(
ty
,
vals
,
val_bbs
,
bb
,
name
);
}
Names
GLOBAL_INSTRUCTION_NAMES_
{
true
,
"op"
,
""
};
\ No newline at end of file
Names
GLOBAL_INSTRUCTION_NAMES_
{
"op"
,
"_"
};
\ No newline at end of file
src/lightir/Module.cpp
View file @
e547371b
...
...
@@ -23,7 +23,7 @@ Module::~Module()
for
(
auto
&
i
:
pointer_map_
)
delete
i
.
second
;
for
(
auto
&
i
:
array_map_
)
delete
i
.
second
;
for
(
auto
&
i
:
function_map_
)
delete
i
.
second
;
for
(
auto
i
:
function_list_
)
delete
i
;
for
(
auto
i
:
function_list_
)
delete
i
;
for
(
auto
i
:
global_list_
)
delete
i
;
}
...
...
src/lightir/Names.cpp
View file @
e547371b
...
...
@@ -2,25 +2,31 @@
std
::
string
Names
::
get_name
(
std
::
string
name
)
{
int
ed
=
static_cast
<
int
>
(
name
.
size
());
while
(
ed
>
0
)
{
char
ch
=
name
[
ed
-
1
];
if
((
use_underline_
&&
ch
==
'_'
)
||
(
ch
>=
'0'
&&
ch
<=
'9'
))
ed
--
;
else
break
;
}
if
(
ed
==
0
)
return
get_name
();
std
::
string
name1
=
{
name
.
begin
(),
name
.
begin
()
+
ed
};
if
(
name1
==
default_prefix_
)
return
get_name
();
auto
get
=
appended_prefix_
+
name1
;
auto
idx
=
allocated_
[
name1
]
++
;
if
(
idx
==
0
)
return
get
;
if
(
use_underline_
)
get
+=
"_"
;
return
get
+
std
::
to_string
(
idx
);
int
ed
=
static_cast
<
int
>
(
name
.
size
());
int
bg
=
0
;
while
(
bg
<
ed
)
{
char
ch
=
name
[
bg
];
if
(
ch
==
'_'
||
(
ch
>=
'0'
&&
ch
<=
'9'
))
bg
++
;
else
break
;
}
while
(
ed
>
bg
)
{
char
ch
=
name
[
ed
-
1
];
if
(
ch
==
'_'
||
(
ch
>=
'0'
&&
ch
<=
'9'
))
ed
--
;
else
break
;
}
if
(
bg
==
ed
)
return
get_name
();
std
::
string
name1
=
{
name
.
begin
()
+
bg
,
name
.
begin
()
+
ed
};
if
(
name1
==
default_prefix_
)
return
get_name
();
auto
get
=
appended_prefix_
+
name1
;
auto
idx
=
allocated_
[
name1
]
++
;
if
(
idx
==
0
)
return
get
;
return
get
+
std
::
to_string
(
idx
);
}
std
::
string
Names
::
get_name
()
{
auto
get
=
appended_prefix_
+
default_prefix_
;
return
get
+
std
::
to_string
(
++
default_prefix_used_count_
);
auto
get
=
appended_prefix_
+
default_prefix_
;
return
get
+
std
::
to_string
(
++
default_prefix_used_count_
);
}
src/lightir/Type.cpp
View file @
e547371b
...
...
@@ -72,11 +72,11 @@ std::string Type::print() const {
case
IntegerTyID
:
type_ir
+=
"i"
;
type_ir
+=
std
::
to_string
(
dynamic_cast
<
const
IntegerType
*>
(
this
)
->
get_num_bits
());
dynamic_cast
<
const
IntegerType
*>
(
this
)
->
get_num_bits
());
break
;
case
FunctionTyID
:
type_ir
+=
dynamic_cast
<
const
FunctionType
*>
(
this
)
->
get_return_type
()
->
print
();
dynamic_cast
<
const
FunctionType
*>
(
this
)
->
get_return_type
()
->
print
();
type_ir
+=
" ("
;
for
(
unsigned
i
=
0
;
i
<
dynamic_cast
<
const
FunctionType
*>
(
this
)
->
get_num_of_args
();
...
...
@@ -96,10 +96,10 @@ std::string Type::print() const {
case
ArrayTyID
:
type_ir
+=
"["
;
type_ir
+=
std
::
to_string
(
dynamic_cast
<
const
ArrayType
*>
(
this
)
->
get_num_of_elements
());
dynamic_cast
<
const
ArrayType
*>
(
this
)
->
get_num_of_elements
());
type_ir
+=
" x "
;
type_ir
+=
dynamic_cast
<
const
ArrayType
*>
(
this
)
->
get_element_type
()
->
print
();
dynamic_cast
<
const
ArrayType
*>
(
this
)
->
get_element_type
()
->
print
();
type_ir
+=
"]"
;
break
;
case
FloatTyID
:
...
...
@@ -119,38 +119,38 @@ std::string Type::safe_print() const
case
LabelTyID
:
return
"label"
;
case
IntegerTyID
:
{
auto
ty
=
dynamic_cast
<
const
IntegerType
*>
(
this
);
{
auto
ty
=
dynamic_cast
<
const
IntegerType
*>
(
this
);
if
(
ty
==
nullptr
)
return
"<not IntegerType>"
;
return
"i"
+
std
::
to_string
(
ty
->
get_num_bits
());
}
return
"i"
+
std
::
to_string
(
ty
->
get_num_bits
());
}
case
FunctionTyID
:
{
auto
ty
=
dynamic_cast
<
const
FunctionType
*>
(
this
);
if
(
ty
==
nullptr
)
return
"<not FunctionType>"
;
{
auto
ty
=
dynamic_cast
<
const
FunctionType
*>
(
this
);
if
(
ty
==
nullptr
)
return
"<not FunctionType>"
;
auto
ty2
=
ty
->
get_return_type
();
std
::
string
type_ir
=
(
ty2
==
nullptr
?
"<null>"
:
ty2
->
safe_print
())
+
" ("
;
for
(
unsigned
i
=
0
;
i
<
ty
->
get_num_of_args
();
i
++
)
{
if
(
i
)
type_ir
+=
", "
;
for
(
unsigned
i
=
0
;
i
<
ty
->
get_num_of_args
();
i
++
)
{
if
(
i
)
type_ir
+=
", "
;
ty2
=
ty
->
get_param_type
(
i
);
type_ir
+=
(
ty2
==
nullptr
?
"<null>"
:
ty2
->
safe_print
());
}
type_ir
+=
(
ty2
==
nullptr
?
"<null>"
:
ty2
->
safe_print
());
}
return
type_ir
+
")"
;
}
}
case
PointerTyID
:
{
auto
ty
=
dynamic_cast
<
const
PointerType
*>
(
this
);
{
auto
ty
=
dynamic_cast
<
const
PointerType
*>
(
this
);
if
(
ty
==
nullptr
)
return
"<not PointerType>"
;
auto
ty2
=
ty
->
get_element_type
();
return
(
ty2
==
nullptr
?
"<null>"
:
ty2
->
safe_print
())
+
"*"
;
}
}
case
ArrayTyID
:
{
auto
ty
=
dynamic_cast
<
const
ArrayType
*>
(
this
);
{
auto
ty
=
dynamic_cast
<
const
ArrayType
*>
(
this
);
if
(
ty
==
nullptr
)
return
"<not ArrayType>"
;
auto
ty2
=
ty
->
get_element_type
();
return
"["
+
std
::
to_string
(
ty
->
get_num_of_elements
())
+
"x"
+
(
ty2
==
nullptr
?
"<null>"
:
ty2
->
safe_print
())
+
"]"
;
}
}
case
FloatTyID
:
return
"float"
;
}
...
...
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