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 @@
#include "BasicBlock.h"
#include "Function.h"
#include "IRprinter.h"
#include "Instruction.h"
#include "Module.h"
#include "Value.h"
...
...
@@ -10,6 +11,7 @@
#include <map>
#include <ostream>
#include <vector>
#define ALIGN(x, align) (((x / align) + (x % align ? 1 : 0)) * align)
// #define STACK_ALIGN(x) (((x / 16) + (x % 16 ? 1 : 0)) * 16)
...
...
@@ -36,16 +38,17 @@ class CodeGen {
void
run
();
private:
void
IR2assem
(
Instruction
&
,
BasicBlock
&
);
void
IR2assem
(
LoadInst
*
);
void
IR2assem
(
StoreInst
*
);
void
IR2assem
(
ReturnInst
*
);
void
IR2assem
(
Instruction
&
);
void
IR2assem
(
GetElementPtrInst
*
);
void
IR2assem
(
CallInst
*
);
void
IR2assem
(
BranchInst
*
);
void
IR2assem
(
BinaryInst
*
);
void
IR2assem
(
FpToSiInst
*
);
void
IR2assem
(
SiToFpInst
*
);
void
IR2assem
(
PhiInst
*
)
{}
// The Instructions below will do nothing
void
IR2assem
(
AllocaInst
*
)
{}
// integration with BranchInst
...
...
@@ -53,8 +56,6 @@ class CodeGen {
void
IR2assem
(
FCmpInst
*
)
{}
void
IR2assem
(
ZextInst
*
)
{}
void
IR2assem
(
PhiInst
*
)
{}
void
stackMemAlloc
();
void
stackMemDealloc
();
// load value `opk` to the specified register
...
...
@@ -68,6 +69,17 @@ class CodeGen {
void
ptrContent2reg
(
Value
*
,
int
id
=
0
);
void
compute_arg_info
(
Function
*
);
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
)
{
return
cur_func
->
get_name
()
+
bb
->
get_name
().
substr
(
5
);
...
...
@@ -130,7 +142,8 @@ class CodeGen {
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
*
,
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
;
...
...
src/codegen/codegen.cpp
View file @
7e736683
...
...
@@ -6,6 +6,7 @@
#include "codegen.hpp"
#include "BasicBlock.h"
#include "Constant.h"
#include "Function.h"
#include "GlobalVariable.h"
...
...
@@ -16,6 +17,7 @@
#include <cstdint>
#include <cstring>
#include <string>
#include <utility>
// $r0 $zero constant 0
// $r1 $ra return address
...
...
@@ -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
CodeGen
::
run
()
{
// TODO: implement
// 以下内容生成 int main() { return 0; } 的汇编代码
getPhiMap
();
output
.
push_back
(
".text"
);
// global variables
for
(
auto
&
globl
:
m
->
get_global_variable
())
{
...
...
@@ -86,14 +106,11 @@ CodeGen::run() {
for
(
auto
&
bb
:
func
.
get_basic_blocks
())
{
output
.
push_back
(
label_in_assem
(
&
bb
)
+
":"
);
for
(
auto
&
instr
:
bb
.
get_instructions
())
{
IR2assem
(
instr
);
IR2assem
(
instr
,
bb
);
}
}
// restore the stack
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) {
}
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
());
switch
(
instr
.
get_instr_type
())
{
case
Instruction
::
ret
:
...
...
@@ -488,6 +507,6 @@ CodeGen::IR2assem(Instruction &instr) {
}
// assert(false && "This ")
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
);
}
tests/5-bonus/test_time.py
View file @
7e736683
...
...
@@ -40,7 +40,7 @@ def eval(console=False, test_dir=testfile_dir, use_clang=False):
single_begin
=
timeit
.
default_timer
()
testfiles
=
os
.
listdir
(
testfile_dir
)
testfiles
.
sort
()
#
testfiles.sort()
# 过滤出以.cminus结尾的file
testfiles
=
filter
(
lambda
s
:
s
.
endswith
(
'.cminus'
),
testfiles
)
testfiles
=
list
(
testfiles
)
...
...
@@ -68,7 +68,7 @@ def eval(console=False, test_dir=testfile_dir, use_clang=False):
if
not
use_clang
:
try
:
# ===可修改===
compile_res
=
subprocess
.
run
([
cminus
,
filepath
,
'-
mem2reg'
,
'-
S'
,
'a.s'
],
compile_res
=
subprocess
.
run
([
cminus
,
filepath
,
'-S'
,
'a.s'
],
stdout
=
subprocess
.
PIPE
,
stderr
=
subprocess
.
PIPE
,
timeout
=
300
)
...
...
@@ -126,7 +126,7 @@ def eval(console=False, test_dir=testfile_dir, use_clang=False):
# 记录运行时间
start
=
timeit
.
default_timer
()
for
i
in
range
(
10
):
for
_
in
range
(
10
):
exe_res
=
subprocess
.
run
([
'./a.out'
],
input
=
input_option
,
stdout
=
subprocess
.
PIPE
,
...
...
@@ -140,7 +140,7 @@ def eval(console=False, test_dir=testfile_dir, use_clang=False):
continue
except
Exception
as
e
:
output_file
.
write
(
'executable runtime error
\n
'
)
output_file
.
write
(
str
(
e
))
output_file
.
write
(
str
(
e
)
+
'
\n
'
)
failed_count
+=
1
continue
...
...
@@ -166,8 +166,8 @@ def eval(console=False, test_dir=testfile_dir, use_clang=False):
# 因为退出码也会作为输出的一部分,因此输出和答案不同可能是程序崩溃造成的
output_file
.
write
(
'output is different from standard answer, this may be caused by wrong return code
\n
'
)
output_file
.
write
(
f"
\t
{
ref
=
}
"
)
output_file
.
write
(
f"
\t
{
actual
=
}
"
)
output_file
.
write
(
"
\t
"
+
ref
+
"
\n
"
)
output_file
.
write
(
"
\t
"
+
actual
+
"
\n
"
)
failed_count
+=
1
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