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
18fa0178
Commit
18fa0178
authored
Nov 16, 2022
by
陈清源
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
lab4 publish
parent
720f0a57
Changes
10
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
866 additions
and
16 deletions
+866
-16
Documentations/4.1-ssa/README.md
Documentations/4.1-ssa/README.md
+305
-0
Documentations/4.1-ssa/ssa.pdf
Documentations/4.1-ssa/ssa.pdf
+0
-0
include/optimization/Dominators.h
include/optimization/Dominators.h
+67
-0
include/optimization/Mem2Reg.hpp
include/optimization/Mem2Reg.hpp
+28
-0
include/optimization/PassManager.hpp
include/optimization/PassManager.hpp
+42
-0
src/CMakeLists.txt
src/CMakeLists.txt
+2
-1
src/cminusfc/cminusfc.cpp
src/cminusfc/cminusfc.cpp
+15
-15
src/optimization/CMakeLists.txt
src/optimization/CMakeLists.txt
+5
-0
src/optimization/Dominators.cpp
src/optimization/Dominators.cpp
+223
-0
src/optimization/Mem2Reg.cpp
src/optimization/Mem2Reg.cpp
+179
-0
No files found.
Documentations/4.1-ssa/README.md
0 → 100644
View file @
18fa0178
This diff is collapsed.
Click to expand it.
Documentations/4.1-ssa/ssa.pdf
0 → 100644
View file @
18fa0178
File added
include/optimization/Dominators.h
0 → 100644
View file @
18fa0178
#ifndef SYSYC_DOMINATORS_HPP
#define SYSYC_DOMINATORS_HPP
#include "BasicBlock.h"
#include "PassManager.hpp"
#include <list>
#include <map>
#include <set>
class
Dominators
:
public
Pass
{
public:
explicit
Dominators
(
Module
*
m
)
:
Pass
(
m
)
{}
~
Dominators
()
=
default
;
void
run
()
override
;
void
create_doms
(
Function
*
f
);
void
create_reverse_post_order
(
Function
*
f
);
void
create_idom
(
Function
*
f
);
void
create_dominance_frontier
(
Function
*
f
);
void
create_dom_tree_succ
(
Function
*
f
);
// for debug
void
print_idom
(
Function
*
f
);
void
print_dominance_frontier
(
Function
*
f
);
/****************api about Dominator****************/
void
add_dom
(
BasicBlock
*
bb
,
BasicBlock
*
dom_bb
)
{
doms_
[
bb
].
insert
(
dom_bb
);
}
std
::
set
<
BasicBlock
*>
&
get_doms
(
BasicBlock
*
bb
)
{
return
doms_
[
bb
];
}
void
set_doms
(
BasicBlock
*
bb
,
std
::
set
<
BasicBlock
*>
&
doms
)
{
doms_
[
bb
].
clear
();
doms_
[
bb
].
insert
(
doms
.
begin
(),
doms
.
end
());
}
BasicBlock
*
get_idom
(
BasicBlock
*
bb
)
{
return
idom_
[
bb
];
}
void
set_idom
(
BasicBlock
*
bb
,
BasicBlock
*
idom
)
{
idom_
[
bb
]
=
idom
;
}
void
add_dominance_frontier
(
BasicBlock
*
bb
,
BasicBlock
*
dom_frontier_bb
)
{
dom_frontier_
[
bb
].
insert
(
dom_frontier_bb
);
}
std
::
set
<
BasicBlock
*>
&
get_dominance_frontier
(
BasicBlock
*
bb
)
{
return
dom_frontier_
[
bb
];
}
void
set_dominance_frontier
(
BasicBlock
*
bb
,
std
::
set
<
BasicBlock
*>
&
df
)
{
dom_frontier_
[
bb
].
clear
();
dom_frontier_
[
bb
].
insert
(
df
.
begin
(),
df
.
end
());
}
// successor blocks of this node in dominance tree
std
::
set
<
BasicBlock
*>
get_dom_tree_succ_blocks
(
BasicBlock
*
bb
)
{
return
dom_tree_succ_blocks_
[
bb
];
}
void
add_dom_tree_succ_block
(
BasicBlock
*
bb
,
BasicBlock
*
dom_tree_succ_bb
)
{
dom_tree_succ_blocks_
[
bb
].
insert
(
dom_tree_succ_bb
);
}
/****************api about Dominator****************/
private:
void
post_order_visit
(
BasicBlock
*
bb
,
std
::
set
<
BasicBlock
*>
&
visited
);
BasicBlock
*
intersect
(
BasicBlock
*
b1
,
BasicBlock
*
b2
);
std
::
list
<
BasicBlock
*>
reverse_post_order_
{};
std
::
map
<
BasicBlock
*
,
int
>
post_order_id_
{};
// the root has highest ID
std
::
map
<
BasicBlock
*
,
std
::
set
<
BasicBlock
*>>
doms_
{};
// dominance set
std
::
map
<
BasicBlock
*
,
BasicBlock
*>
idom_
{};
// immediate dominance
std
::
map
<
BasicBlock
*
,
std
::
set
<
BasicBlock
*>>
dom_frontier_
{};
// dominance frontier set
std
::
map
<
BasicBlock
*
,
std
::
set
<
BasicBlock
*>>
dom_tree_succ_blocks_
{};
};
#endif
include/optimization/Mem2Reg.hpp
0 → 100644
View file @
18fa0178
#ifndef SYSYC_MEM2REG_HPP
#define SYSYC_MEM2REG_HPP
#include "BasicBlock.h"
#include "Dominators.h"
#include "Function.h"
#include "IRBuilder.h"
#include "Instruction.h"
#include "Module.h"
#include "PassManager.hpp"
#include <memory>
class
Mem2Reg
:
public
Pass
{
private:
Function
*
func_
;
std
::
unique_ptr
<
Dominators
>
dominators_
;
public:
Mem2Reg
(
Module
*
m
)
:
Pass
(
m
)
{}
~
Mem2Reg
(){};
void
run
()
override
;
void
generate_phi
();
void
re_name
(
BasicBlock
*
bb
);
void
remove_alloca
();
};
#endif
\ No newline at end of file
include/optimization/PassManager.hpp
0 → 100644
View file @
18fa0178
#ifndef PASSMANAGER_HPP
#define PASSMANAGER_HPP
#include "Module.h"
#include <memory>
#include <vector>
class
Pass
{
public:
Pass
(
Module
*
m
)
:
m_
(
m
)
{}
virtual
~
Pass
()
=
default
;
virtual
void
run
()
=
0
;
protected:
Module
*
m_
;
};
class
PassManager
{
public:
PassManager
(
Module
*
m
)
:
m_
(
m
)
{}
template
<
typename
PassType
,
typename
...
Args
>
void
add_pass
(
bool
print_ir
,
Args
&&
...
args
)
{
passes_
.
push_back
(
std
::
pair
<
std
::
unique_ptr
<
Pass
>
,
bool
>
(
new
PassType
(
m_
,
std
::
forward
<
Args
>
(
args
)...),
print_ir
));
}
void
run
()
{
for
(
auto
&
pass
:
passes_
)
{
pass
.
first
->
run
();
if
(
pass
.
second
)
{
m_
->
set_print_name
();
std
::
cout
<<
m_
->
print
();
}
}
}
private:
std
::
vector
<
std
::
pair
<
std
::
unique_ptr
<
Pass
>
,
bool
>>
passes_
;
Module
*
m_
;
};
#endif
\ No newline at end of file
src/CMakeLists.txt
View file @
18fa0178
...
...
@@ -2,4 +2,5 @@ add_subdirectory(parser)
add_subdirectory
(
common
)
add_subdirectory
(
io
)
add_subdirectory
(
lightir
)
add_subdirectory
(
cminusfc
)
\ No newline at end of file
add_subdirectory
(
cminusfc
)
add_subdirectory
(
optimization
)
\ No newline at end of file
src/cminusfc/cminusfc.cpp
View file @
18fa0178
#include "Dominators.h"
#include "Mem2Reg.hpp"
#include "PassManager.hpp"
#include "cminusf_builder.hpp"
#include "logging.hpp"
#include <fstream>
#include <iostream>
#include <memory>
...
...
@@ -6,20 +11,15 @@
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 ] <input-file>"
<<
std
::
endl
;
std
::
cout
<<
"Usage: "
<<
exe_name
<<
" [ -h | --help ] [ -o <target-file> ] [ -emit-llvm ] [-mem2reg] <input-file>"
<<
std
::
endl
;
}
int
main
(
int
argc
,
char
**
argv
)
{
std
::
string
target_path
;
std
::
string
input_path
;
bool
mem2reg
=
false
;
bool
const_propagation
=
false
;
bool
activevars
=
false
;
bool
loop_inv_hoist
=
false
;
bool
loop_search
=
false
;
bool
emit
=
false
;
for
(
int
i
=
1
;
i
<
argc
;
++
i
)
{
...
...
@@ -38,14 +38,6 @@ int main(int argc, char **argv) {
emit
=
true
;
}
else
if
(
argv
[
i
]
==
"-mem2reg"
s
)
{
mem2reg
=
true
;
}
else
if
(
argv
[
i
]
==
"-loop-search"
s
)
{
loop_search
=
true
;
}
else
if
(
argv
[
i
]
==
"-loop-inv-hoist"
s
)
{
loop_inv_hoist
=
true
;
}
else
if
(
argv
[
i
]
==
"-const-propagation"
s
)
{
const_propagation
=
true
;
}
else
if
(
argv
[
i
]
==
"-active-vars"
s
)
{
activevars
=
true
;
}
else
{
if
(
input_path
.
empty
())
{
input_path
=
argv
[
i
];
...
...
@@ -85,6 +77,14 @@ int main(int argc, char **argv) {
auto
m
=
builder
.
getModule
();
m
->
set_print_name
();
PassManager
PM
(
m
.
get
());
if
(
mem2reg
)
{
PM
.
add_pass
<
Mem2Reg
>
(
emit
);
}
PM
.
run
();
auto
IR
=
m
->
print
();
std
::
ofstream
output_stream
;
...
...
src/optimization/CMakeLists.txt
0 → 100644
View file @
18fa0178
add_library
(
OP_lib STATIC
Dominators.cpp
Mem2Reg.cpp
)
src/optimization/Dominators.cpp
0 → 100644
View file @
18fa0178
#include "Dominators.h"
#include <algorithm>
#include <string>
void
Dominators
::
run
()
{
for
(
auto
&
f1
:
m_
->
get_functions
())
{
auto
f
=
&
f1
;
if
(
f
->
get_basic_blocks
().
size
()
==
0
)
continue
;
for
(
auto
&
bb1
:
f
->
get_basic_blocks
())
{
auto
bb
=
&
bb1
;
doms_
.
insert
({
bb
,
{}});
idom_
.
insert
({
bb
,
{}});
dom_frontier_
.
insert
({
bb
,
{}});
dom_tree_succ_blocks_
.
insert
({
bb
,
{}});
}
create_reverse_post_order
(
f
);
create_idom
(
f
);
create_dominance_frontier
(
f
);
create_dom_tree_succ
(
f
);
// for debug
// print_idom(f);
// print_dominance_frontier(f);
}
}
void
Dominators
::
create_doms
(
Function
*
f
)
{
// init
for
(
auto
&
bb1
:
f
->
get_basic_blocks
())
{
auto
bb
=
&
bb1
;
add_dom
(
bb
,
bb
);
}
// iterate
bool
changed
=
true
;
std
::
vector
<
BasicBlock
*>
ret
(
f
->
get_num_basic_blocks
());
std
::
vector
<
BasicBlock
*>
pre
(
f
->
get_num_basic_blocks
());
while
(
changed
)
{
changed
=
false
;
for
(
auto
&
bb1
:
f
->
get_basic_blocks
())
{
auto
bb
=
&
bb1
;
auto
&
bbs
=
bb
->
get_pre_basic_blocks
();
auto
&
first
=
get_doms
((
*
bbs
.
begin
()));
pre
.
insert
(
pre
.
begin
(),
first
.
begin
(),
first
.
end
());
pre
.
resize
(
first
.
size
());
ret
.
resize
(
f
->
get_num_basic_blocks
());
for
(
auto
iter
=
++
bbs
.
begin
();
iter
!=
bbs
.
end
();
++
iter
)
{
auto
&
now
=
get_doms
((
*
iter
));
auto
it
=
std
::
set_intersection
(
pre
.
begin
(),
pre
.
end
(),
now
.
begin
(),
now
.
end
(),
ret
.
begin
());
ret
.
resize
(
it
-
ret
.
begin
());
pre
.
resize
(
ret
.
size
());
pre
.
insert
(
pre
.
begin
(),
ret
.
begin
(),
ret
.
end
());
}
std
::
set
<
BasicBlock
*>
doms
;
doms
.
insert
(
bb
);
doms
.
insert
(
pre
.
begin
(),
pre
.
end
());
if
(
get_doms
(
bb
)
!=
doms
)
{
set_doms
(
bb
,
doms
);
changed
=
true
;
}
}
}
}
void
Dominators
::
create_reverse_post_order
(
Function
*
f
)
{
reverse_post_order_
.
clear
();
post_order_id_
.
clear
();
std
::
set
<
BasicBlock
*>
visited
;
post_order_visit
(
f
->
get_entry_block
(),
visited
);
reverse_post_order_
.
reverse
();
}
void
Dominators
::
post_order_visit
(
BasicBlock
*
bb
,
std
::
set
<
BasicBlock
*>
&
visited
)
{
visited
.
insert
(
bb
);
for
(
auto
b
:
bb
->
get_succ_basic_blocks
())
{
if
(
visited
.
find
(
b
)
==
visited
.
end
())
post_order_visit
(
b
,
visited
);
}
post_order_id_
[
bb
]
=
reverse_post_order_
.
size
();
reverse_post_order_
.
push_back
(
bb
);
}
void
Dominators
::
create_idom
(
Function
*
f
)
{
// init
for
(
auto
&
bb
:
f
->
get_basic_blocks
())
set_idom
(
&
bb
,
nullptr
);
auto
root
=
f
->
get_entry_block
();
set_idom
(
root
,
root
);
// iterate
bool
changed
=
true
;
while
(
changed
)
{
changed
=
false
;
for
(
auto
bb
:
this
->
reverse_post_order_
)
{
if
(
bb
==
root
)
{
continue
;
}
// find one pred which has idom
BasicBlock
*
pred
=
nullptr
;
for
(
auto
p
:
bb
->
get_pre_basic_blocks
())
{
if
(
get_idom
(
p
))
{
pred
=
p
;
break
;
}
}
assert
(
pred
);
BasicBlock
*
new_idom
=
pred
;
for
(
auto
p
:
bb
->
get_pre_basic_blocks
())
{
if
(
p
==
pred
)
continue
;
if
(
get_idom
(
p
))
{
new_idom
=
intersect
(
p
,
new_idom
);
}
}
if
(
get_idom
(
bb
)
!=
new_idom
)
{
set_idom
(
bb
,
new_idom
);
changed
=
true
;
}
}
}
}
// find closest parent of b1 and b2
BasicBlock
*
Dominators
::
intersect
(
BasicBlock
*
b1
,
BasicBlock
*
b2
)
{
while
(
b1
!=
b2
)
{
while
(
post_order_id_
[
b1
]
<
post_order_id_
[
b2
])
{
assert
(
get_idom
(
b1
));
b1
=
get_idom
(
b1
);
}
while
(
post_order_id_
[
b2
]
<
post_order_id_
[
b1
])
{
assert
(
get_idom
(
b2
));
b2
=
get_idom
(
b2
);
}
}
return
b1
;
}
void
Dominators
::
create_dominance_frontier
(
Function
*
f
)
{
for
(
auto
&
bb1
:
f
->
get_basic_blocks
())
{
auto
bb
=
&
bb1
;
if
(
bb
->
get_pre_basic_blocks
().
size
()
>=
2
)
{
for
(
auto
p
:
bb
->
get_pre_basic_blocks
())
{
auto
runner
=
p
;
while
(
runner
!=
get_idom
(
bb
))
{
add_dominance_frontier
(
runner
,
bb
);
runner
=
get_idom
(
runner
);
}
}
}
}
}
void
Dominators
::
create_dom_tree_succ
(
Function
*
f
)
{
for
(
auto
&
bb1
:
f
->
get_basic_blocks
())
{
auto
bb
=
&
bb1
;
auto
idom
=
get_idom
(
bb
);
// e.g, entry bb
if
(
idom
!=
bb
)
{
add_dom_tree_succ_block
(
idom
,
bb
);
}
}
}
void
Dominators
::
print_idom
(
Function
*
f
)
{
int
counter
=
0
;
std
::
map
<
BasicBlock
*
,
std
::
string
>
bb_id
;
for
(
auto
&
bb1
:
f
->
get_basic_blocks
())
{
auto
bb
=
&
bb1
;
if
(
bb
->
get_name
().
empty
())
bb_id
[
bb
]
=
"bb"
+
std
::
to_string
(
counter
);
else
bb_id
[
bb
]
=
bb
->
get_name
();
counter
++
;
}
printf
(
"Immediate dominance of function %s:
\n
"
,
f
->
get_name
().
c_str
());
for
(
auto
&
bb1
:
f
->
get_basic_blocks
())
{
auto
bb
=
&
bb1
;
std
::
string
output
;
output
=
bb_id
[
bb
]
+
": "
;
if
(
get_idom
(
bb
))
{
output
+=
bb_id
[
get_idom
(
bb
)];
}
else
{
output
+=
"null"
;
}
printf
(
"%s
\n
"
,
output
.
c_str
());
}
}
void
Dominators
::
print_dominance_frontier
(
Function
*
f
)
{
int
counter
=
0
;
std
::
map
<
BasicBlock
*
,
std
::
string
>
bb_id
;
for
(
auto
&
bb1
:
f
->
get_basic_blocks
())
{
auto
bb
=
&
bb1
;
if
(
bb
->
get_name
().
empty
())
bb_id
[
bb
]
=
"bb"
+
std
::
to_string
(
counter
);
else
bb_id
[
bb
]
=
bb
->
get_name
();
counter
++
;
}
printf
(
"Dominance Frontier of function %s:
\n
"
,
f
->
get_name
().
c_str
());
for
(
auto
&
bb1
:
f
->
get_basic_blocks
())
{
auto
bb
=
&
bb1
;
std
::
string
output
;
output
=
bb_id
[
bb
]
+
": "
;
if
(
get_dominance_frontier
(
bb
).
empty
())
{
output
+=
"null"
;
}
else
{
bool
first
=
true
;
for
(
auto
df
:
get_dominance_frontier
(
bb
))
{
if
(
first
)
{
first
=
false
;
}
else
{
output
+=
", "
;
}
output
+=
bb_id
[
df
];
}
}
printf
(
"%s
\n
"
,
output
.
c_str
());
}
}
src/optimization/Mem2Reg.cpp
0 → 100644
View file @
18fa0178
#include "Mem2Reg.hpp"
#include "IRBuilder.h"
#include <memory>
// 判断是否是全局变量地址
#define IS_GLOBAL_VARIABLE(l_val) dynamic_cast<GlobalVariable *>(l_val)
// 判断是否是 getelementptr 指令
#define IS_GEP_INSTR(l_val) dynamic_cast<GetElementPtrInst *>(l_val)
std
::
map
<
Value
*
,
std
::
vector
<
Value
*>>
var_val_stack
;
// 全局变量初值提前存入栈中
void
Mem2Reg
::
run
()
{
// 创建支配树分析 Pass 的实例
dominators_
=
std
::
make_unique
<
Dominators
>
(
m_
);
// 建立支配树
dominators_
->
run
();
// 以函数为单元遍历实现 Mem2Reg 算法
for
(
auto
&
f
:
m_
->
get_functions
())
{
func_
=
&
f
;
if
(
func_
->
get_basic_blocks
().
size
()
>=
1
)
{
// 对应伪代码中 phi 指令插入的阶段
generate_phi
();
// 对应伪代码中重命名阶段
re_name
(
func_
->
get_entry_block
());
}
// 移除冗余的局部变量的分配空间
remove_alloca
();
}
}
void
Mem2Reg
::
generate_phi
()
{
// global_live_var_name 是全局名字集合,以 alloca 出的局部变量来统计。
// 步骤一:找到活跃在多个 block 的全局名字集合,以及它们所属的 bb 块
std
::
set
<
Value
*>
global_live_var_name
;
std
::
map
<
Value
*
,
std
::
set
<
BasicBlock
*>>
live_var_2blocks
;
for
(
auto
&
bb1
:
func_
->
get_basic_blocks
())
{
auto
bb
=
&
bb1
;
std
::
set
<
Value
*>
var_is_killed
;
for
(
auto
&
instr1
:
bb
->
get_instructions
())
{
auto
instr
=
&
instr1
;
if
(
instr
->
is_store
())
{
// store i32 a, i32 *b
// a is r_val, b is l_val
auto
r_val
=
static_cast
<
StoreInst
*>
(
instr
)
->
get_rval
();
auto
l_val
=
static_cast
<
StoreInst
*>
(
instr
)
->
get_lval
();
if
(
!
IS_GLOBAL_VARIABLE
(
l_val
)
&&
!
IS_GEP_INSTR
(
l_val
))
{
global_live_var_name
.
insert
(
l_val
);
live_var_2blocks
[
l_val
].
insert
(
bb
);
}
}
}
}
// 步骤二:从支配树获取支配边界信息,并在对应位置插入 phi 指令
std
::
map
<
std
::
pair
<
BasicBlock
*
,
Value
*>
,
bool
>
bb_has_var_phi
;
// bb has phi for var
for
(
auto
var
:
global_live_var_name
)
{
std
::
vector
<
BasicBlock
*>
work_list
;
work_list
.
assign
(
live_var_2blocks
[
var
].
begin
(),
live_var_2blocks
[
var
].
end
());
for
(
int
i
=
0
;
i
<
work_list
.
size
();
i
++
)
{
auto
bb
=
work_list
[
i
];
for
(
auto
bb_dominance_frontier_bb
:
dominators_
->
get_dominance_frontier
(
bb
))
{
if
(
bb_has_var_phi
.
find
({
bb_dominance_frontier_bb
,
var
})
==
bb_has_var_phi
.
end
())
{
// generate phi for bb_dominance_frontier_bb & add bb_dominance_frontier_bb to work list
auto
phi
=
PhiInst
::
create_phi
(
var
->
get_type
()
->
get_pointer_element_type
(),
bb_dominance_frontier_bb
);
phi
->
set_lval
(
var
);
bb_dominance_frontier_bb
->
add_instr_begin
(
phi
);
work_list
.
push_back
(
bb_dominance_frontier_bb
);
bb_has_var_phi
[{
bb_dominance_frontier_bb
,
var
}]
=
true
;
}
}
}
}
}
void
Mem2Reg
::
re_name
(
BasicBlock
*
bb
)
{
std
::
vector
<
Instruction
*>
wait_delete
;
// 步骤三:将 phi 指令作为 lval 的最新定值,lval 即是为局部变量 alloca 出的地址空间
for
(
auto
&
instr1
:
bb
->
get_instructions
())
{
auto
instr
=
&
instr1
;
if
(
instr
->
is_phi
())
{
auto
l_val
=
static_cast
<
PhiInst
*>
(
instr
)
->
get_lval
();
var_val_stack
[
l_val
].
push_back
(
instr
);
}
}
for
(
auto
&
instr1
:
bb
->
get_instructions
())
{
auto
instr
=
&
instr1
;
// 步骤四:用 lval 最新的定值替代对应的load指令
if
(
instr
->
is_load
())
{
auto
l_val
=
static_cast
<
LoadInst
*>
(
instr
)
->
get_lval
();
if
(
!
IS_GLOBAL_VARIABLE
(
l_val
)
&&
!
IS_GEP_INSTR
(
l_val
))
{
if
(
var_val_stack
.
find
(
l_val
)
!=
var_val_stack
.
end
())
{
// 此处指令替换会维护 UD 链与 DU 链
instr
->
replace_all_use_with
(
var_val_stack
[
l_val
].
back
());
wait_delete
.
push_back
(
instr
);
}
}
}
// 步骤五:将 store 指令的 rval,也即被存入内存的值,作为 lval 的最新定值
if
(
instr
->
is_store
())
{
auto
l_val
=
static_cast
<
StoreInst
*>
(
instr
)
->
get_lval
();
auto
r_val
=
static_cast
<
StoreInst
*>
(
instr
)
->
get_rval
();
if
(
!
IS_GLOBAL_VARIABLE
(
l_val
)
&&
!
IS_GEP_INSTR
(
l_val
))
{
var_val_stack
[
l_val
].
push_back
(
r_val
);
wait_delete
.
push_back
(
instr
);
}
}
}
// 步骤六:为 lval 对应的 phi 指令参数补充完整
for
(
auto
succ_bb
:
bb
->
get_succ_basic_blocks
())
{
for
(
auto
&
instr1
:
succ_bb
->
get_instructions
())
{
auto
instr
=
&
instr1
;
if
(
instr
->
is_phi
())
{
auto
l_val
=
static_cast
<
PhiInst
*>
(
instr
)
->
get_lval
();
if
(
var_val_stack
.
find
(
l_val
)
!=
var_val_stack
.
end
())
{
assert
(
var_val_stack
[
l_val
].
size
()
!=
0
);
static_cast
<
PhiInst
*>
(
instr
)
->
add_phi_pair_operand
(
var_val_stack
[
l_val
].
back
(),
bb
);
}
// 对于 phi 参数只有一个前驱定值的情况,将会输出 [ undef, bb ] 的参数格式
}
}
}
// 步骤七:对 bb 在支配树上的所有后继节点,递归执行 re_name 操作
for
(
auto
dom_succ_bb
:
dominators_
->
get_dom_tree_succ_blocks
(
bb
))
{
re_name
(
dom_succ_bb
);
}
// 步骤八:pop出 lval 的最新定值
for
(
auto
&
instr1
:
bb
->
get_instructions
())
{
auto
instr
=
&
instr1
;
if
(
instr
->
is_store
())
{
auto
l_val
=
static_cast
<
StoreInst
*>
(
instr
)
->
get_lval
();
if
(
!
IS_GLOBAL_VARIABLE
(
l_val
)
&&
!
IS_GEP_INSTR
(
l_val
))
{
var_val_stack
[
l_val
].
pop_back
();
}
}
else
if
(
instr
->
is_phi
())
{
auto
l_val
=
static_cast
<
PhiInst
*>
(
instr
)
->
get_lval
();
if
(
var_val_stack
.
find
(
l_val
)
!=
var_val_stack
.
end
())
{
var_val_stack
[
l_val
].
pop_back
();
}
}
}
// 清除冗余的指令
for
(
auto
instr
:
wait_delete
)
{
bb
->
erase_instr
(
instr
);
}
}
void
Mem2Reg
::
remove_alloca
()
{
for
(
auto
&
bb1
:
func_
->
get_basic_blocks
())
{
auto
bb
=
&
bb1
;
std
::
vector
<
Instruction
*>
wait_delete
;
for
(
auto
&
instr1
:
bb
->
get_instructions
())
{
auto
instr
=
&
instr1
;
auto
is_alloca
=
dynamic_cast
<
AllocaInst
*>
(
instr
);
if
(
is_alloca
)
{
bool
is_int
=
is_alloca
->
get_type
()
->
get_pointer_element_type
()
->
is_integer_type
();
bool
is_float
=
is_alloca
->
get_type
()
->
get_pointer_element_type
()
->
is_float_type
();
if
(
is_int
||
is_float
)
{
wait_delete
.
push_back
(
instr
);
}
}
}
for
(
auto
instr
:
wait_delete
)
{
bb
->
erase_instr
(
instr
);
}
}
}
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