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
f1600373
Commit
f1600373
authored
Dec 08, 2022
by
李晓奇
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
move script back
parent
9d5c5e1f
Changes
1
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
350 additions
and
0 deletions
+350
-0
tests/4-ir-opt/lab4_evals.py
tests/4-ir-opt/lab4_evals.py
+350
-0
No files found.
tests/4-ir-opt/lab4_evals.py
0 → 100644
View file @
f1600373
#!/usr/bin/env python3
import
subprocess
import
os
import
argparse
import
re
import
time
import
glob
import
json5
from
pathlib
import
Path
# you can run the script from anywhere!
cminusfc_path
=
Path
(
__file__
).
absolute
().
parents
[
2
]
/
"build/cminusfc"
cminusfc
=
str
(
cminusfc_path
)
try
:
from
tqdm
import
tqdm
except
Exception
as
_
:
os
.
system
(
"apt install -y python3-tqdm || python3 -m pip install tqdm"
)
from
tqdm
import
tqdm
repeated_time
=
3
def
init_args
():
parser
=
argparse
.
ArgumentParser
()
parser
.
add_argument
(
"--GlobalValueNumber"
,
"-gvn"
,
action
=
"store_true"
)
parser
.
add_argument
(
"--GlobalValueNumberAnalysis"
,
"-gvn-analysis"
,
action
=
"store_true"
)
args
=
parser
.
parse_args
()
return
args
def
get_raw_testcases
(
root_path
):
file_names
=
glob
.
glob
(
root_path
+
"/*.cminus"
)
# pattern=r'[0-9]+'
# file_names.sort(key= lambda item:int(re.findall(pattern, os.path.basename(item))[0]))
return
file_names
def
get_baseline_files
(
root_path
):
file_names
=
glob
.
glob
(
root_path
+
"/*.ll"
)
# pattern=r'[0-9]+'
# file_names.sort(key= lambda item:int(re.findall(pattern, os.path.basename(item))[0]))
return
file_names
def
compile_baseline_files
(
file_lists
):
print
(
"Compiling baseline files"
)
progess_bar
=
tqdm
(
total
=
len
(
file_lists
),
ncols
=
50
)
exec_files
=
list
()
for
each
in
file_lists
:
exec_file
,
_
=
os
.
path
.
splitext
(
each
)
COMMAND
=
"clang -O0 -w "
+
each
+
" -o "
+
exec_file
+
" -L. -lcminus_io"
try
:
result
=
subprocess
.
run
(
COMMAND
,
stdout
=
subprocess
.
PIPE
,
stderr
=
subprocess
.
PIPE
,
shell
=
True
,
timeout
=
1
,
)
if
result
.
returncode
==
0
:
exec_files
.
append
(
exec_file
)
else
:
exec_files
.
append
(
None
)
print
(
f"
\n
Compile
{
each
.
split
(
'/'
)[
-
1
]
}
\033
[31;1m failed
\033
[0m"
)
except
Exception
as
_
:
exec_files
.
append
(
None
)
print
(
f"Compile
{
each
.
split
(
'/'
)[
-
1
]
}
\033
[31;1m failed
\033
[0m"
)
progess_bar
.
update
(
1
)
progess_bar
.
close
()
return
exec_files
def
compile_testcases
(
file_lists
,
option
):
COMMAND
=
cminusfc
+
" "
+
option
+
" "
exec_files
=
list
()
print
(
"Compiling "
,
option
)
progess_bar
=
tqdm
(
total
=
len
(
file_lists
),
ncols
=
50
)
for
each
in
file_lists
:
try
:
result
=
subprocess
.
run
(
COMMAND
+
each
,
stdout
=
subprocess
.
PIPE
,
stderr
=
subprocess
.
PIPE
,
shell
=
True
,
timeout
=
1
,
)
if
result
.
returncode
==
0
:
exec_file
,
_
=
os
.
path
.
splitext
(
each
)
exec_files
.
append
(
exec_file
)
else
:
exec_files
.
append
(
None
)
print
(
f"
\n
Compile
{
each
.
split
(
'/'
)[
-
1
]
}
\033
[31;1m failed
\033
[0m"
)
except
Exception
as
_
:
exec_files
.
append
(
None
)
print
(
f"Compile
{
each
.
split
(
'/'
)[
-
1
]
}
\033
[31;1m failed
\033
[0m"
)
progess_bar
.
update
(
1
)
progess_bar
.
close
()
return
exec_files
def
gvn_evaluate
(
file_lists
,
metric_func
,
check_mode
=
True
):
result
=
list
()
print
(
"Evalution "
)
progess_bar
=
tqdm
(
total
=
len
(
file_lists
),
ncols
=
50
)
for
each
in
file_lists
:
if
each
==
None
:
result
.
append
(
None
)
continue
if
check_if_correct
(
each
,
check_mode
):
base
=
0
for
_
in
range
(
repeated_time
):
re_value
=
metric_func
(
each
)
if
re_value
!=
None
:
base
+=
re_value
/
repeated_time
else
:
base
=
None
break
result
.
append
(
base
)
else
:
result
.
append
(
None
)
subprocess
.
call
([
"rm"
,
"-rf"
,
each
])
progess_bar
.
update
(
1
)
progess_bar
.
close
()
return
result
def
check_if_correct
(
exec_file
,
check_mode
=
True
):
if
check_mode
:
input_option
=
None
if
os
.
path
.
exists
(
exec_file
+
".in"
):
with
open
(
exec_file
+
".in"
,
"rb"
)
as
fin
:
input_option
=
fin
.
read
()
try
:
result
=
subprocess
.
run
(
[
exec_file
],
input
=
input_option
,
stdout
=
subprocess
.
PIPE
,
stderr
=
subprocess
.
PIPE
,
timeout
=
10
,
)
with
open
(
exec_file
+
".out"
,
"rb"
)
as
fout
:
answer
=
fout
.
read
()
if
result
.
stdout
==
answer
:
return
True
else
:
print
(
f"Execute
{
exec_file
.
split
(
'/'
)[
-
1
]
}
result is not correct! your output:
{
result
.
stdout
}
, but the answer is:
{
answer
}
"
)
return
False
except
Exception
as
e
:
print
(
f"Execute
{
exec_file
.
split
(
'/'
)[
-
1
]
}
\033
[31;1m failed
\033
[0m"
)
return
False
else
:
return
True
def
get_execute_time
(
exec_file
):
try
:
cmdline
=
"taskset -c 0 "
+
exec_file
+
" < "
+
exec_file
+
".in"
+
" 2>&1"
input_option
=
None
start
=
time
.
time
()
result
=
subprocess
.
run
(
[
cmdline
],
shell
=
True
,
stdout
=
subprocess
.
PIPE
,
stderr
=
subprocess
.
PIPE
,
universal_newlines
=
True
,
timeout
=
10
,
)
elapsed
=
time
.
time
()
-
start
return
elapsed
except
Exception
as
e
:
print
(
f"Execute
{
exec_file
.
split
(
'/'
)[
-
1
]
}
\033
[31;1m failed
\033
[0m"
)
return
None
def
table_print
(
testcase
,
before_optimization
,
after_optimization
,
baseline
):
if
len
(
before_optimization
)
==
len
(
baseline
)
and
len
(
before_optimization
)
==
len
(
after_optimization
):
pass
else
:
max_len
=
max
(
[
len
(
before_optimization
),
len
(
after_optimization
),
len
(
baseline
)]
)
if
len
(
before_optimization
)
<
max_len
:
before_optimization
+=
[
None
]
*
\
(
max_len
-
len
(
before_optimization
))
if
len
(
after_optimization
)
<
max_len
:
after_optimization
+=
[
None
]
*
(
max_len
-
len
(
after_optimization
))
if
len
(
baseline
)
<
max_len
:
baseline
+=
[
None
]
*
(
max_len
-
len
(
baseline
))
print
(
"
\033
[33;1mtestcase"
,
"
\t
"
,
"
\033
[31;1mbefore optimization
\033
[0m"
,
"
\t
"
,
"
\033
[32;1mafter optimization
\033
[0m"
,
"
\t
"
,
"
\033
[35;1mbaseline
\033
[0m"
,
)
for
index
,
(
result1
,
result2
,
result3
)
in
enumerate
(
zip
(
before_optimization
,
after_optimization
,
baseline
)
):
print
(
testcase
[
index
].
split
(
"/"
)[
-
1
],
"
\t\t
%.2f"
%
result1
if
result1
!=
None
else
"
\t\t
None"
,
"
\t\t\t
%.2f"
%
result2
if
result2
!=
None
else
"
\t\t\t
None"
,
"
\t\t
%.2f"
%
result3
if
result3
!=
None
else
"
\t\t
None"
,
)
def
calculate_gvn_bb_score
(
input_partition
,
answer_partition
):
# score of every bb is either 0 or 1
if
len
(
input_partition
)
!=
len
(
answer_partition
):
return
0
score_cnt
=
0
for
in_cc
in
input_partition
:
for
ans_cc
in
answer_partition
:
if
set
(
in_cc
)
==
set
(
ans_cc
):
score_cnt
+=
1
break
if
score_cnt
==
len
(
answer_partition
):
return
1
return
0
def
calculate_gvn_score
(
input_functions
,
answer_functions
):
# input & answer is dict from json
# calculate score use sum(score of every bb)/total_bb
# score of every bb is either 1 or 0
# total_bb is count of pout
total_bb
=
0
for
ans_func
in
answer_functions
:
total_bb
+=
len
(
ans_func
[
"pout"
])
cal_score
=
0
for
ans_func
in
answer_functions
:
for
in_func
in
input_functions
:
if
ans_func
[
"function"
]
==
in_func
[
"function"
]:
for
ans_bb
,
ans_partition
in
ans_func
[
"pout"
].
items
():
for
in_bb
,
in_partition
in
in_func
[
"pout"
].
items
():
if
ans_bb
==
in_bb
:
cal_score
+=
calculate_gvn_bb_score
(
in_partition
,
ans_partition
)
else
:
continue
else
:
continue
return
cal_score
/
total_bb
if
__name__
==
"__main__"
:
script_path
=
os
.
path
.
join
(
os
.
getcwd
(),
__file__
)
usr_args
=
init_args
()
if
usr_args
.
GlobalValueNumber
:
print
(
"="
*
10
,
"GlobalValueNumber"
,
"="
*
10
)
root_path
=
os
.
path
.
join
(
os
.
path
.
dirname
(
script_path
),
"testcases/GVN/performance"
)
testcases
=
get_raw_testcases
(
root_path
=
root_path
)
exec_files1
=
compile_testcases
(
file_lists
=
testcases
,
option
=
"-mem2reg"
)
results1
=
gvn_evaluate
(
file_lists
=
exec_files1
,
metric_func
=
get_execute_time
)
exec_files2
=
compile_testcases
(
file_lists
=
testcases
,
option
=
"-mem2reg -gvn"
)
results2
=
gvn_evaluate
(
file_lists
=
exec_files2
,
metric_func
=
get_execute_time
)
baseline_files
=
get_baseline_files
(
os
.
path
.
join
(
root_path
,
"baseline"
))
exec_files3
=
compile_baseline_files
(
baseline_files
)
results3
=
gvn_evaluate
(
file_lists
=
exec_files3
,
metric_func
=
get_execute_time
,
check_mode
=
False
)
table_print
(
testcase
=
testcases
,
before_optimization
=
results1
,
after_optimization
=
results2
,
baseline
=
results3
,
)
if
usr_args
.
GlobalValueNumberAnalysis
:
print
(
"="
*
10
,
"GlobalValueNumberAnalysis"
,
"="
*
10
)
root_path
=
os
.
path
.
join
(
os
.
path
.
dirname
(
script_path
),
"testcases/GVN/functional"
)
testcases
=
get_raw_testcases
(
root_path
=
root_path
)
option
=
"-mem2reg -emit-llvm -gvn -dump-json"
COMMAND
=
cminusfc
+
" "
+
option
+
" "
print
(
"Compiling "
,
option
)
progess_bar
=
tqdm
(
total
=
len
(
testcases
),
ncols
=
50
)
score_list
=
[]
i
=
0
for
each
in
testcases
:
i
+=
1
try
:
result
=
subprocess
.
run
(
COMMAND
+
each
,
stdout
=
subprocess
.
PIPE
,
stderr
=
subprocess
.
PIPE
,
shell
=
True
,
timeout
=
1
,
)
if
result
.
returncode
==
0
:
exec_file
,
_
=
os
.
path
.
splitext
(
each
)
each_base
=
each
.
split
(
"/"
)[
-
1
]
print
(
f"
\n
Compile
{
each_base
}
\033
[32;1m success
\033
[0m"
)
with
open
(
"gvn.json"
,
"r"
)
as
load_input
:
with
open
(
exec_file
+
".json"
,
"r"
)
as
load_answer
:
print
(
f"generate json
{
each_base
}
\033
[32;1m success
\033
[0m"
)
# here, input is a list of dict
input_functions
=
json5
.
load
(
load_input
)
answer_functions
=
json5
.
load
(
load_answer
)
score
=
calculate_gvn_score
(
input_functions
,
answer_functions
)
score_list
.
append
((
each_base
,
score
))
subprocess
.
call
([
"rm"
,
"-rf"
,
exec_file
+
".ll"
])
else
:
print
(
f"
\n
nCompile
{
each
.
split
(
'/'
)[
-
1
]
}
\033
[31;1m failed
\033
[0m"
)
except
Exception
as
_
:
print
(
f"Analyze
{
each
.
split
(
'/'
)[
-
1
]
}
\033
[31;1m failed
\033
[0m"
)
progess_bar
.
update
(
1
)
progess_bar
.
close
()
i
=
0
for
file
,
score
in
score_list
:
i
+=
1
print
(
file
+
":"
,
score
)
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