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
7e736683
Commit
7e736683
authored
Jan 29, 2023
by
lxq
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
fix behaviour for PhiInst, now can pass functional test
parent
83f09476
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
49 additions
and
17 deletions
+49
-17
include/codegen.hpp
include/codegen.hpp
+17
-4
src/codegen/codegen.cpp
src/codegen/codegen.cpp
+26
-7
tests/5-bonus/test_time.py
tests/5-bonus/test_time.py
+6
-6
No files found.
include/codegen.hpp
View file @
7e736683
...
@@ -3,6 +3,7 @@
...
@@ -3,6 +3,7 @@
#include "BasicBlock.h"
#include "BasicBlock.h"
#include "Function.h"
#include "Function.h"
#include "IRprinter.h"
#include "Instruction.h"
#include "Instruction.h"
#include "Module.h"
#include "Module.h"
#include "Value.h"
#include "Value.h"
...
@@ -10,6 +11,7 @@
...
@@ -10,6 +11,7 @@
#include <map>
#include <map>
#include <ostream>
#include <ostream>
#include <vector>
#define ALIGN(x, align) (((x / align) + (x % align ? 1 : 0)) * align)
#define ALIGN(x, align) (((x / align) + (x % align ? 1 : 0)) * align)
// #define STACK_ALIGN(x) (((x / 16) + (x % 16 ? 1 : 0)) * 16)
// #define STACK_ALIGN(x) (((x / 16) + (x % 16 ? 1 : 0)) * 16)
...
@@ -36,16 +38,17 @@ class CodeGen {
...
@@ -36,16 +38,17 @@ class CodeGen {
void
run
();
void
run
();
private:
private:
void
IR2assem
(
Instruction
&
,
BasicBlock
&
);
void
IR2assem
(
LoadInst
*
);
void
IR2assem
(
LoadInst
*
);
void
IR2assem
(
StoreInst
*
);
void
IR2assem
(
StoreInst
*
);
void
IR2assem
(
ReturnInst
*
);
void
IR2assem
(
ReturnInst
*
);
void
IR2assem
(
Instruction
&
);
void
IR2assem
(
GetElementPtrInst
*
);
void
IR2assem
(
GetElementPtrInst
*
);
void
IR2assem
(
CallInst
*
);
void
IR2assem
(
CallInst
*
);
void
IR2assem
(
BranchInst
*
);
void
IR2assem
(
BranchInst
*
);
void
IR2assem
(
BinaryInst
*
);
void
IR2assem
(
BinaryInst
*
);
void
IR2assem
(
FpToSiInst
*
);
void
IR2assem
(
FpToSiInst
*
);
void
IR2assem
(
SiToFpInst
*
);
void
IR2assem
(
SiToFpInst
*
);
void
IR2assem
(
PhiInst
*
)
{}
// The Instructions below will do nothing
// The Instructions below will do nothing
void
IR2assem
(
AllocaInst
*
)
{}
void
IR2assem
(
AllocaInst
*
)
{}
// integration with BranchInst
// integration with BranchInst
...
@@ -53,8 +56,6 @@ class CodeGen {
...
@@ -53,8 +56,6 @@ class CodeGen {
void
IR2assem
(
FCmpInst
*
)
{}
void
IR2assem
(
FCmpInst
*
)
{}
void
IR2assem
(
ZextInst
*
)
{}
void
IR2assem
(
ZextInst
*
)
{}
void
IR2assem
(
PhiInst
*
)
{}
void
stackMemAlloc
();
void
stackMemAlloc
();
void
stackMemDealloc
();
void
stackMemDealloc
();
// load value `opk` to the specified register
// load value `opk` to the specified register
...
@@ -68,6 +69,17 @@ class CodeGen {
...
@@ -68,6 +69,17 @@ class CodeGen {
void
ptrContent2reg
(
Value
*
,
int
id
=
0
);
void
ptrContent2reg
(
Value
*
,
int
id
=
0
);
void
compute_arg_info
(
Function
*
);
void
compute_arg_info
(
Function
*
);
string
bool2branch
(
Instruction
*
);
string
bool2branch
(
Instruction
*
);
void
getPhiMap
();
void
copystmt
(
BasicBlock
*
bb
)
{
// all the phi instruction is transformed to copy-stmt
for
(
auto
&
copy
:
phi_map
[
bb
])
{
output
.
push_back
(
"# "
+
print_as_op
(
copy
.
first
,
false
)
+
" = "
+
print_as_op
(
copy
.
second
,
false
));
auto
lvalue
=
static_cast
<
Instruction
*>
(
copy
.
first
);
value2reg
(
copy
.
second
);
back2stack
(
lvalue
);
}
}
string
label_in_assem
(
BasicBlock
*
bb
)
{
string
label_in_assem
(
BasicBlock
*
bb
)
{
return
cur_func
->
get_name
()
+
bb
->
get_name
().
substr
(
5
);
return
cur_func
->
get_name
()
+
bb
->
get_name
().
substr
(
5
);
...
@@ -130,7 +142,8 @@ class CodeGen {
...
@@ -130,7 +142,8 @@ class CodeGen {
std
::
map
<
Value
*
,
unsigned
int
>
off
;
// stack offset to $fp
std
::
map
<
Value
*
,
unsigned
int
>
off
;
// stack offset to $fp
std
::
map
<
Function
*
,
std
::
map
<
int
,
int
>>
func_arg_off
;
// to $sp
std
::
map
<
Function
*
,
std
::
map
<
int
,
int
>>
func_arg_off
;
// to $sp
std
::
map
<
Function
*
,
int
>
func_arg_N
;
// total space for args
std
::
map
<
Function
*
,
int
>
func_arg_N
;
// total space for args
unsigned
int
stackN
;
// function local vars and so on
std
::
map
<
BasicBlock
*
,
std
::
vector
<
std
::
pair
<
Value
*
,
Value
*>>>
phi_map
;
unsigned
int
stackN
;
// function local vars and so on
Function
*
cur_func
;
Function
*
cur_func
;
...
...
src/codegen/codegen.cpp
View file @
7e736683
...
@@ -6,6 +6,7 @@
...
@@ -6,6 +6,7 @@
#include "codegen.hpp"
#include "codegen.hpp"
#include "BasicBlock.h"
#include "Constant.h"
#include "Constant.h"
#include "Function.h"
#include "Function.h"
#include "GlobalVariable.h"
#include "GlobalVariable.h"
...
@@ -16,6 +17,7 @@
...
@@ -16,6 +17,7 @@
#include <cstdint>
#include <cstdint>
#include <cstring>
#include <cstring>
#include <string>
#include <string>
#include <utility>
// $r0 $zero constant 0
// $r0 $zero constant 0
// $r1 $ra return address
// $r1 $ra return address
...
@@ -55,11 +57,29 @@ class Reg {
...
@@ -55,11 +57,29 @@ class Reg {
}
}
};
};
void
CodeGen
::
getPhiMap
()
{
phi_map
.
clear
();
for
(
auto
&
func
:
m
->
get_functions
())
for
(
auto
&
bb
:
func
.
get_basic_blocks
())
for
(
auto
&
instr
:
bb
.
get_instructions
())
{
if
(
not
instr
.
is_phi
())
continue
;
for
(
int
i
=
0
;
i
<
instr
.
get_num_operand
()
/
2
;
i
++
)
{
auto
key
=
static_cast
<
BasicBlock
*>
(
instr
.
get_operand
(
2
*
i
+
1
));
auto
value
=
std
::
make_pair
(
&
instr
,
instr
.
get_operand
(
2
*
i
));
phi_map
[
key
].
push_back
(
value
);
}
}
}
void
void
CodeGen
::
run
()
{
CodeGen
::
run
()
{
// TODO: implement
// TODO: implement
// 以下内容生成 int main() { return 0; } 的汇编代码
// 以下内容生成 int main() { return 0; } 的汇编代码
getPhiMap
();
output
.
push_back
(
".text"
);
output
.
push_back
(
".text"
);
// global variables
// global variables
for
(
auto
&
globl
:
m
->
get_global_variable
())
{
for
(
auto
&
globl
:
m
->
get_global_variable
())
{
...
@@ -86,14 +106,11 @@ CodeGen::run() {
...
@@ -86,14 +106,11 @@ CodeGen::run() {
for
(
auto
&
bb
:
func
.
get_basic_blocks
())
{
for
(
auto
&
bb
:
func
.
get_basic_blocks
())
{
output
.
push_back
(
label_in_assem
(
&
bb
)
+
":"
);
output
.
push_back
(
label_in_assem
(
&
bb
)
+
":"
);
for
(
auto
&
instr
:
bb
.
get_instructions
())
{
for
(
auto
&
instr
:
bb
.
get_instructions
())
{
IR2assem
(
instr
);
IR2assem
(
instr
,
bb
);
}
}
}
}
// restore the stack
// restore the stack
stackMemDealloc
();
stackMemDealloc
();
}
else
{
/* output.push_back(".globl " + func.get_name());
* output.push_back(".type " + func.get_name() + ", @function"); */
}
}
}
}
}
}
...
@@ -429,7 +446,9 @@ CodeGen::IR2assem(ReturnInst *instr) {
...
@@ -429,7 +446,9 @@ CodeGen::IR2assem(ReturnInst *instr) {
}
}
void
void
CodeGen
::
IR2assem
(
Instruction
&
instr
)
{
CodeGen
::
IR2assem
(
Instruction
&
instr
,
BasicBlock
&
bb
)
{
if
(
instr
.
is_br
()
or
instr
.
is_ret
())
copystmt
(
&
bb
);
output
.
push_back
(
"# "
+
instr
.
print
());
output
.
push_back
(
"# "
+
instr
.
print
());
switch
(
instr
.
get_instr_type
())
{
switch
(
instr
.
get_instr_type
())
{
case
Instruction
::
ret
:
case
Instruction
::
ret
:
...
@@ -488,6 +507,6 @@ CodeGen::IR2assem(Instruction &instr) {
...
@@ -488,6 +507,6 @@ CodeGen::IR2assem(Instruction &instr) {
}
}
// assert(false && "This ")
// assert(false && "This ")
if
(
not
instr
.
is_void
()
and
not
no_stack_alloca
(
&
instr
)
and
if
(
not
instr
.
is_void
()
and
not
no_stack_alloca
(
&
instr
)
and
not
instr
.
is_alloca
())
not
instr
.
is_alloca
()
and
not
instr
.
is_phi
()
)
back2stack
(
&
instr
);
back2stack
(
&
instr
);
}
}
tests/5-bonus/test_time.py
View file @
7e736683
...
@@ -40,7 +40,7 @@ def eval(console=False, test_dir=testfile_dir, use_clang=False):
...
@@ -40,7 +40,7 @@ def eval(console=False, test_dir=testfile_dir, use_clang=False):
single_begin
=
timeit
.
default_timer
()
single_begin
=
timeit
.
default_timer
()
testfiles
=
os
.
listdir
(
testfile_dir
)
testfiles
=
os
.
listdir
(
testfile_dir
)
testfiles
.
sort
()
#
testfiles.sort()
# 过滤出以.cminus结尾的file
# 过滤出以.cminus结尾的file
testfiles
=
filter
(
lambda
s
:
s
.
endswith
(
'.cminus'
),
testfiles
)
testfiles
=
filter
(
lambda
s
:
s
.
endswith
(
'.cminus'
),
testfiles
)
testfiles
=
list
(
testfiles
)
testfiles
=
list
(
testfiles
)
...
@@ -68,7 +68,7 @@ def eval(console=False, test_dir=testfile_dir, use_clang=False):
...
@@ -68,7 +68,7 @@ def eval(console=False, test_dir=testfile_dir, use_clang=False):
if
not
use_clang
:
if
not
use_clang
:
try
:
try
:
# ===可修改===
# ===可修改===
compile_res
=
subprocess
.
run
([
cminus
,
filepath
,
'-
mem2reg'
,
'-
S'
,
'a.s'
],
compile_res
=
subprocess
.
run
([
cminus
,
filepath
,
'-S'
,
'a.s'
],
stdout
=
subprocess
.
PIPE
,
stdout
=
subprocess
.
PIPE
,
stderr
=
subprocess
.
PIPE
,
stderr
=
subprocess
.
PIPE
,
timeout
=
300
)
timeout
=
300
)
...
@@ -126,7 +126,7 @@ def eval(console=False, test_dir=testfile_dir, use_clang=False):
...
@@ -126,7 +126,7 @@ def eval(console=False, test_dir=testfile_dir, use_clang=False):
# 记录运行时间
# 记录运行时间
start
=
timeit
.
default_timer
()
start
=
timeit
.
default_timer
()
for
i
in
range
(
10
):
for
_
in
range
(
10
):
exe_res
=
subprocess
.
run
([
'./a.out'
],
exe_res
=
subprocess
.
run
([
'./a.out'
],
input
=
input_option
,
input
=
input_option
,
stdout
=
subprocess
.
PIPE
,
stdout
=
subprocess
.
PIPE
,
...
@@ -140,7 +140,7 @@ def eval(console=False, test_dir=testfile_dir, use_clang=False):
...
@@ -140,7 +140,7 @@ def eval(console=False, test_dir=testfile_dir, use_clang=False):
continue
continue
except
Exception
as
e
:
except
Exception
as
e
:
output_file
.
write
(
'executable runtime error
\n
'
)
output_file
.
write
(
'executable runtime error
\n
'
)
output_file
.
write
(
str
(
e
))
output_file
.
write
(
str
(
e
)
+
'
\n
'
)
failed_count
+=
1
failed_count
+=
1
continue
continue
...
@@ -166,8 +166,8 @@ def eval(console=False, test_dir=testfile_dir, use_clang=False):
...
@@ -166,8 +166,8 @@ def eval(console=False, test_dir=testfile_dir, use_clang=False):
# 因为退出码也会作为输出的一部分,因此输出和答案不同可能是程序崩溃造成的
# 因为退出码也会作为输出的一部分,因此输出和答案不同可能是程序崩溃造成的
output_file
.
write
(
output_file
.
write
(
'output is different from standard answer, this may be caused by wrong return code
\n
'
)
'output is different from standard answer, this may be caused by wrong return code
\n
'
)
output_file
.
write
(
f"
\t
{
ref
=
}
"
)
output_file
.
write
(
"
\t
"
+
ref
+
"
\n
"
)
output_file
.
write
(
f"
\t
{
actual
=
}
"
)
output_file
.
write
(
"
\t
"
+
actual
+
"
\n
"
)
failed_count
+=
1
failed_count
+=
1
output_file
.
write
(
f"
{
failed_count
}
tests failed
\n
"
)
output_file
.
write
(
f"
{
failed_count
}
tests failed
\n
"
)
...
...
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