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
158a82bc
Commit
158a82bc
authored
Mar 04, 2023
by
lxq
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
loop unroll finished
parent
efe0d887
Changes
11
Expand all
Show whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
680 additions
and
76 deletions
+680
-76
include/optimization/BrMerge.hpp
include/optimization/BrMerge.hpp
+15
-0
include/optimization/LoopUnroll.hpp
include/optimization/LoopUnroll.hpp
+58
-9
src/cminusfc/cminusfc.cpp
src/cminusfc/cminusfc.cpp
+9
-3
src/codegen/codegen.cpp
src/codegen/codegen.cpp
+0
-1
src/codegen/liverange.cpp
src/codegen/liverange.cpp
+4
-0
src/codegen/regalloc.cpp
src/codegen/regalloc.cpp
+3
-3
src/optimization/BrMerge.cpp
src/optimization/BrMerge.cpp
+67
-0
src/optimization/CMakeLists.txt
src/optimization/CMakeLists.txt
+1
-0
src/optimization/ExceptCallMerge.cpp
src/optimization/ExceptCallMerge.cpp
+15
-2
src/optimization/GVN.cpp
src/optimization/GVN.cpp
+4
-4
src/optimization/LoopUnroll.cpp
src/optimization/LoopUnroll.cpp
+504
-54
No files found.
include/optimization/BrMerge.hpp
0 → 100644
View file @
158a82bc
#ifndef BRMERGE_HPP
#define BRMERGE_HPP
#include "Module.h"
#include "PassManager.hpp"
class
BrMerge
:
public
Pass
{
public:
BrMerge
(
Module
*
m
)
:
Pass
(
m
)
{}
void
run
()
override
;
private:
};
#endif
include/optimization/LoopUnroll.hpp
View file @
158a82bc
...
...
@@ -2,9 +2,11 @@
#ifndef LOOPUNROLL_HPP
#define LOOPUNROLL_HPP
#include "BasicBlock.h"
#include "Instruction.h"
#include "Module.h"
#include "PassManager.hpp"
#include "Type.h"
#include "Value.h"
#include <map>
#include <ostream>
...
...
@@ -35,17 +37,42 @@ struct BackEdgeSearcher {
};
}
// namespace Graph
namespace
Analysis
{
struct
LoopAnalysis
{
LoopAnalysis
(
const
Graph
::
SimpleLoop
&
);
LoopAnalysis
()
=
delete
;
enum
{
INT
,
FLOAT
,
UNDEF
}
Type
;
union
{
namespace
Analysis
{
#define Threshold 100
struct
CountedLoop
{
typedef
union
{
int
v
;
float
fv
;
}
initial
,
delta
,
threshold
;
};}
}
I_F
;
CountedLoop
(
const
Graph
::
SimpleLoop
&
);
CountedLoop
()
=
delete
;
void
new_emulate
()
{
switch
(
Type
)
{
case
INT
:
emulate
.
v
=
initial
.
v
;
break
;
case
FLOAT
:
emulate
.
fv
=
initial
.
fv
;
break
;
case
UNDEF
:
assert
(
false
);
break
;
}
};
// whether cur emulate shuold continue loop
bool
judge
();
// emulate the delta part
void
next
();
enum
{
INT
,
FLOAT
,
UNDEF
}
Type
;
I_F
initial
,
stop
,
emulate
;
int
count
;
// determined in construct function
bool
reverse
;
// for delta emulate part
BinaryInst
*
delta
;
Instruction
*
control
;
};
}
// namespace Analysis
/* This is a class to unroll simple loops:
* - strict structure:
...
...
@@ -56,6 +83,7 @@ struct LoopAnalysis {
class
LoopUnroll
:
public
Pass
{
public:
LoopUnroll
(
Module
*
_m
)
:
Pass
(
_m
)
{
m_
->
set_print_name
();
for
(
auto
&
f
:
m_
->
get_functions
())
if
(
f
.
get_name
()
==
"neg_idx_except"
)
{
neg_func
=
&
f
;
...
...
@@ -75,7 +103,28 @@ class LoopUnroll : public Pass {
private:
Function
*
neg_func
;
map
<
Value
*
,
Value
*>
old2new
;
Graph
::
BackEdgeList
detect_back
(
Function
*
);
vector
<
Graph
::
SimpleLoop
>
check_sloops
(
const
Graph
::
BackEdgeList
&
)
const
;
void
unroll_loop
(
Graph
::
SimpleLoop
&
);
Value
*
right_v
(
Value
*
v
)
const
{
if
(
old2new
.
find
(
v
)
!=
old2new
.
end
())
{
return
old2new
.
at
(
v
);
}
else
return
v
;
}
BasicBlock
*
copy_instruction
(
Instruction
&
instr
,
BasicBlock
*
bb
,
// old block
BasicBlock
*
BB
,
// new block
BasicBlock
*
pre
,
// previous of whole loop
BasicBlock
*
succ
,
// successor of whole loop
Graph
::
SimpleLoop
&
sl
,
// the whole loop
Analysis
::
CountedLoop
&
cl
,
// analysis info
bool
init
);
bool
is_neg_block
(
BasicBlock
*
bb
)
const
{
auto
instr
=
&*
bb
->
get_instructions
().
begin
();
return
(
instr
->
is_call
()
and
instr
->
get_operand
(
0
)
==
neg_func
);
}
};
#endif
src/cminusfc/cminusfc.cpp
View file @
158a82bc
...
...
@@ -5,6 +5,7 @@
#include "GVN.h"
// #include "LoopInvHoist.hpp"
// #include "LoopSearch.hpp"
#include "BrMerge.hpp"
#include "ExceptCallMerge.hpp"
#include "LoopUnroll.hpp"
#include "Mem2Reg.hpp"
...
...
@@ -22,7 +23,8 @@ using namespace std::literals::string_literals;
void
print_help
(
std
::
string
exe_name
)
{
std
::
cout
<<
"Usage: "
<<
exe_name
<<
" [ -h | --help ] [ -o <target-file> ] [ -emit-llvm ] "
<<
" [-h | --help] [-o <target-file>] [-S <assembly-file>] "
"[-emit-llvm] [-loopunroll] "
"[-mem2reg] [-gvn] [-dump-json] <input-file>"
<<
std
::
endl
;
}
...
...
@@ -62,7 +64,7 @@ main(int argc, char **argv) {
}
else
if
(
argv
[
i
]
==
"-gvn"
s
)
{
gvn
=
true
;
}
else
if
(
argv
[
i
]
==
"-loopunroll"
s
)
{
loopunroll
=
true
;
gvn
=
loopunroll
=
true
;
}
else
if
(
argv
[
i
]
==
"-dump-json"
s
)
{
dump_json
=
true
;
}
else
{
...
...
@@ -125,11 +127,15 @@ main(int argc, char **argv) {
if
(
loopunroll
)
{
PM
.
add_pass
<
NegCallMerge
>
(
false
);
PM
.
add_pass
<
LoopUnroll
>
(
false
);
PM
.
add_pass
<
DeadCode
>
(
false
);
PM
.
add_pass
<
GVN
>
(
false
,
dump_json
);
PM
.
add_pass
<
DeadCode
>
(
false
);
PM
.
add_pass
<
BrMerge
>
(
false
);
}
m
->
set_print_name
();
PM
.
run
();
m
->
set_print_name
();
auto
IR
=
m
->
print
();
if
(
assembly
)
{
...
...
src/codegen/codegen.cpp
View file @
158a82bc
...
...
@@ -9,7 +9,6 @@
#include "Value.h"
#include "ast.hpp"
#include "regalloc.hpp"
#include "syntax_analyzer.h"
#include <algorithm>
#include <cstdint>
...
...
src/codegen/liverange.cpp
View file @
158a82bc
...
...
@@ -82,6 +82,10 @@ LiveRangeAnalyzer::get_dfs_order(Function *func) {
for
(
auto
succ
:
bb
->
get_succ_basic_blocks
())
Q
.
push_front
(
succ
);
}
cout
<<
"DFS order for function "
<<
func
->
get_name
()
<<
":
\n
"
;
for
(
auto
bb
:
BB_DFS_Order
)
cout
<<
bb
->
get_name
()
<<
" "
;
cout
<<
endl
;
}
void
...
...
src/codegen/regalloc.cpp
View file @
158a82bc
...
...
@@ -11,7 +11,7 @@ using std::for_each;
using
namespace
RA
;
#define ASSERT_CMPINST_USED_ONCE(cmpinst) \
(assert(cmpinst->get_use_list().size()
=
= 1))
(assert(cmpinst->get_use_list().size()
<
= 1))
int
get_arg_id
(
Argument
*
arg
)
{
...
...
@@ -47,6 +47,8 @@ RegAllocator::no_reg_alloca(Value *v) {
// %op2 = icmp ne i32 %op1, 0 # <- if judges to here
// br i1 %op2, label %label3, label %label5
ASSERT_CMPINST_USED_ONCE
(
use_ins
);
if
(
use_ins
->
get_use_list
().
size
()
==
0
)
return
false
;
auto
use2_ins
=
dynamic_cast
<
Instruction
*>
(
use_ins
->
get_use_list
().
begin
()
->
val_
);
alloc
=
not
(
use2_ins
->
is_br
());
...
...
@@ -128,12 +130,10 @@ RegAllocator::LinearScan(const LVITS &liveints, Function *func) {
void
RegAllocator
::
ExpireOldIntervals
(
LiveInterval
liveint
)
{
auto
it
=
active
.
begin
();
for
(;
it
!=
active
.
end
()
and
it
->
first
.
j
<
liveint
.
first
.
i
;
++
it
)
used
[
regmap
.
at
(
it
->
second
)]
=
false
;
active
.
erase
(
active
.
begin
(),
it
);
}
void
...
...
src/optimization/BrMerge.cpp
0 → 100644
View file @
158a82bc
#include "BrMerge.hpp"
#include "BasicBlock.h"
#include "Constant.h"
#include "Instruction.h"
void
BrMerge
::
run
()
{
BranchInst
*
br
;
ReturnInst
*
ret
;
for
(
auto
&
func
:
m_
->
get_functions
())
{
bool
cont
=
true
;
while
(
cont
)
{
cont
=
false
;
for
(
auto
&
bb
:
func
.
get_basic_blocks
())
{
if
(
&
bb
==
func
.
get_entry_block
())
continue
;
auto
&
instructions
=
bb
.
get_instructions
();
br
=
dynamic_cast
<
BranchInst
*>
(
&*
instructions
.
rbegin
());
ret
=
dynamic_cast
<
ReturnInst
*>
(
&*
instructions
.
rbegin
());
assert
((
br
or
ret
)
&&
"final Instruction"
);
if
(
instructions
.
size
()
==
1
)
{
if
(
br
)
{
// change: br or cond-br with constant jump
BasicBlock
*
succ
;
if
(
not
br
->
is_cond_br
())
{
assert
(
bb
.
get_succ_basic_blocks
().
size
()
==
1
);
succ
=
*
bb
.
get_succ_basic_blocks
().
begin
();
}
else
if
(
dynamic_cast
<
Constant
*>
(
br
->
get_operand
(
0
)))
{
assert
(
bb
.
get_succ_basic_blocks
().
size
()
==
2
);
succ
=
static_cast
<
BasicBlock
*>
(
dynamic_cast
<
ConstantInt
*>
(
br
->
get_operand
(
0
))
->
get_value
()
?
br
->
get_operand
(
1
)
:
br
->
get_operand
(
2
));
}
else
continue
;
for
(
auto
pre
:
bb
.
get_pre_basic_blocks
())
{
// change br's op
auto
ins
=
&*
pre
->
get_instructions
().
rbegin
();
bool
set
=
false
;
for
(
int
i
=
0
;
i
<
ins
->
get_num_operand
();
++
i
)
if
(
ins
->
get_operand
(
i
)
==
&
bb
)
{
ins
->
set_operand
(
i
,
succ
);
set
=
true
;
break
;
}
assert
(
set
);
// change pre's succ
pre
->
remove_succ_basic_block
(
&
bb
);
pre
->
add_succ_basic_block
(
&
bb
);
// change succ's pre
succ
->
add_pre_basic_block
(
pre
);
}
// change succ's pre
succ
->
remove_pre_basic_block
(
&
bb
);
// remove useless block
func
.
get_basic_blocks
().
remove
(
&
bb
);
cont
=
true
;
}
else
{
// ret: do not change
}
}
else
{
}
}
}
}
}
src/optimization/CMakeLists.txt
View file @
158a82bc
...
...
@@ -5,4 +5,5 @@ add_library(
Dominators.cpp
Mem2Reg.cpp
GVN.cpp
BrMerge.cpp
)
src/optimization/ExceptCallMerge.cpp
View file @
158a82bc
...
...
@@ -46,15 +46,28 @@ NegCallMerge::run(Function *func) {
idx
=
{
0
};
}
for
(
auto
i
:
idx
)
if
(
calls
.
find
(
br
->
get_operand
(
i
))
!=
calls
.
end
())
if
(
calls
.
find
(
br
->
get_operand
(
i
))
!=
calls
.
end
())
{
auto
remove
=
static_cast
<
BasicBlock
*>
(
br
->
get_operand
(
i
));
if
(
remove
==
reserved
)
continue
;
br
->
get_operands
()[
i
]
=
reserved
;
// correct pre/succ blocks
bb
.
add_succ_basic_block
(
reserved
);
reserved
->
add_pre_basic_block
(
&
bb
);
// remove wrong graph links
bb
.
remove_succ_basic_block
(
remove
);
remove
->
remove_pre_basic_block
(
&
bb
);
blocks
.
remove
(
remove
);
}
}
}
return
;
// remove useless BasicBlocks
for
(
auto
_bb
:
calls
)
{
auto
bb
=
static_cast
<
BasicBlock
*>
(
_bb
);
if
(
bb
!=
reserved
)
{
cout
<<
"remove block "
<<
bb
->
get_name
()
<<
" in function "
<<
func
->
get_name
()
<<
endl
;
/* cout << "remove block " << bb->get_name() << " in function "
* << func->get_name() << endl; */
auto
it
=
blocks
.
begin
();
for
(;
&*
it
!=
bb
;
++
it
)
;
...
...
src/optimization/GVN.cpp
View file @
158a82bc
...
...
@@ -411,10 +411,10 @@ GVN::detectEquivalences() {
break
;
}
default:
{
std
::
cerr
<<
"In function "
<<
func_
->
get_name
()
<<
", "
<<
" block "
<<
bb
->
get_name
()
<<
" has count of predecessors: "
<<
pre_bbs_
.
size
();
/*
std::cerr << "In function " << func_->get_name() << ", "
*
<< " block " << bb->get_name()
*
<< " has count of predecessors: "
* << pre_bbs_.size(); */
continue
;
}
}
...
...
src/optimization/LoopUnroll.cpp
View file @
158a82bc
This diff is collapsed.
Click to expand it.
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