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
efe0d887
Commit
efe0d887
authored
Mar 03, 2023
by
lxq
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
start loop analysis code
parent
29b9788b
Changes
2
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
142 additions
and
49 deletions
+142
-49
include/optimization/LoopUnroll.hpp
include/optimization/LoopUnroll.hpp
+25
-1
src/optimization/LoopUnroll.cpp
src/optimization/LoopUnroll.cpp
+117
-48
No files found.
include/optimization/LoopUnroll.hpp
View file @
efe0d887
...
...
@@ -4,13 +4,16 @@
#include "BasicBlock.h"
#include "Module.h"
#include "PassManager.hpp"
#include "Type.h"
#include <map>
#include <ostream>
#include <string>
#include <vector>
using
std
::
cout
;
using
std
::
endl
;
using
std
::
map
;
using
std
::
string
;
using
std
::
to_string
;
using
std
::
vector
;
...
...
@@ -20,8 +23,29 @@ namespace Graph {
using
Edge
=
std
::
pair
<
BasicBlock
*
,
BasicBlock
*>
;
using
BackEdgeList
=
vector
<
Edge
>
;
using
SimpleLoop
=
vector
<
BasicBlock
*>
;
}
struct
BackEdgeSearcher
{
BackEdgeSearcher
(
BasicBlock
*
entry
)
{
dfsrun
(
entry
);
}
void
dfsrun
(
BasicBlock
*
bb
);
vector
<
BasicBlock
*>
path
;
map
<
BasicBlock
*
,
bool
>
vis
;
BackEdgeList
edges
;
};
}
// namespace Graph
namespace
Analysis
{
struct
LoopAnalysis
{
LoopAnalysis
(
const
Graph
::
SimpleLoop
&
);
LoopAnalysis
()
=
delete
;
enum
{
INT
,
FLOAT
,
UNDEF
}
Type
;
union
{
int
v
;
float
fv
;
}
initial
,
delta
,
threshold
;
};}
/* This is a class to unroll simple loops:
* - strict structure:
...
...
src/optimization/LoopUnroll.cpp
View file @
efe0d887
#include "LoopUnroll.hpp"
#include "BasicBlock.h"
#include "Constant.h"
#include "Function.h"
#include "Instruction.h"
#include "syntax_analyzer.h"
#include <map>
#include <vector>
using
std
::
find
;
using
std
::
map
;
using
namespace
Graph
;
using
namespace
Analysis
;
struct
BackEdgeSearcher
{
BackEdgeSearcher
(
BasicBlock
*
entry
)
{
dfsrun
(
entry
);
}
void
LoopUnroll
::
run
()
{
for
(
auto
&
_f
:
m_
->
get_functions
())
{
if
(
_f
.
is_declaration
())
continue
;
auto
func
=
&
_f
;
// cout << func->get_name() << endl;
auto
belist
=
detect_back
(
func
);
auto
sloops
=
check_sloops
(
belist
);
cout
<<
"get simple loops for function "
<<
func
->
get_name
()
<<
":
\n
"
;
for
(
auto
sl
:
sloops
)
{
cout
<<
"
\t
"
;
for
(
auto
p
:
sl
)
cout
<<
p
->
get_name
()
<<
" "
;
cout
<<
"
\n
"
;
}
}
}
void
dfsrun
(
BasicBlock
*
bb
)
{
vis
[
bb
]
=
true
;
path
.
push_back
(
bb
);
for
(
auto
succ
:
bb
->
get_succ_basic_blocks
())
{
if
(
vis
[
succ
])
{
string
type
;
Edge
edge
(
bb
,
succ
);
if
(
find
(
path
.
rbegin
(),
path
.
rend
(),
succ
)
==
path
.
rend
())
{
type
=
"cross-edge"
;
LoopAnalysis
::
LoopAnalysis
(
const
Graph
::
SimpleLoop
&
sl
)
{
auto
b
=
sl
.
front
();
auto
e
=
sl
.
back
();
// In `p`, get stop number(const)
Value
*
i
;
auto
rit
=
b
->
get_instructions
().
rbegin
();
assert
(
dynamic_cast
<
BranchInst
*>
(
&*
rit
)
&&
"The end instruction of a block should be branch"
);
i
=
(
rit
++
)
->
get_operand
(
0
);
assert
(
i
==
&*
rit
&&
dynamic_cast
<
CmpInst
*>
(
&*
rit
)
&&
static_cast
<
CmpInst
*>
(
&*
rit
)
->
get_cmp_op
()
==
CmpInst
::
NE
&&
"should be neq 0"
);
i
=
(
rit
++
)
->
get_operand
(
0
);
assert
(
i
==
&*
rit
&&
dynamic_cast
<
ZextInst
*>
(
&*
rit
)
&&
"neqz"
);
i
=
(
rit
++
)
->
get_operand
(
0
);
assert
(
i
==
&*
rit
&&
(
dynamic_cast
<
CmpInst
*>
(
&*
rit
)
or
dynamic_cast
<
FCmpInst
*>
(
&*
rit
))
&&
"cmp or fcmp"
);
if
(
dynamic_cast
<
Constant
*>
(
rit
->
get_operand
(
0
))
or
dynamic_cast
<
Constant
*>
(
rit
->
get_operand
(
1
)))
{
if
(
dynamic_cast
<
CmpInst
*>
(
&*
rit
))
{
Type
=
FLOAT
;
auto
constfloat
=
dynamic_cast
<
ConstantFP
*>
(
rit
->
get_operand
(
1
));
assert
(
constfloat
&&
"the case const at operand(0) not implemented"
);
threshold
.
fv
=
constfloat
->
get_value
();
}
else
{
type
=
"back-edge"
;
edges
.
push_back
(
edge
);
Type
=
INT
;
auto
constint
=
dynamic_cast
<
ConstantInt
*>
(
rit
->
get_operand
(
1
));
assert
(
constint
&&
"the case const at operand(0) not implemented"
);
threshold
.
v
=
constint
->
get_value
();
}
/* cout << "find " << type << ": " << LoopUnroll::str(edge)
* << "\n"; */
}
else
dfsrun
(
succ
);
}
else
{
Type
=
UNDEF
;
return
;
}
path
.
pop_back
();
// get control value and initial value
auto
control
=
rit
->
get_operand
(
0
);
auto
it
=
b
->
get_instructions
().
begin
();
for
(;
it
!=
b
->
get_instructions
().
end
();
++
it
)
{
auto
phi
=
dynamic_cast
<
PhiInst
*>
(
&*
it
);
assert
(
phi
&&
"unexpected structure for while block"
);
if
(
&*
it
!=
control
)
continue
;
assert
(
phi
->
get_operand
(
3
)
==
e
&&
"the orther case not implemented"
);
if
(
dynamic_cast
<
Constant
*>
(
phi
->
get_operand
(
0
)))
{
switch
(
Type
)
{
case
INT
:
initial
.
v
=
static_cast
<
ConstantInt
*>
(
phi
->
get_operand
(
0
))
->
get_value
();
break
;
case
FLOAT
:
initial
.
fv
=
static_cast
<
ConstantFP
*>
(
phi
->
get_operand
(
0
))
->
get_value
();
break
;
case
UNDEF
:
assert
(
false
);
break
;
}
}
else
{
Type
=
UNDEF
;
return
;
}
}
vector
<
BasicBlock
*>
path
;
map
<
BasicBlock
*
,
bool
>
vis
;
BackEdgeList
edges
;
};
// get delta
BackEdgeList
LoopUnroll
::
detect_back
(
Function
*
func
)
{
BackEdgeSearcher
search
(
func
->
get_entry_block
());
return
search
.
edges
;
// check correctness
// count loop
}
vector
<
SimpleLoop
>
...
...
@@ -91,21 +149,32 @@ LoopUnroll::check_sloops(const BackEdgeList &belist) const {
}
return
sloops
;
}
BackEdgeList
LoopUnroll
::
detect_back
(
Function
*
func
)
{
BackEdgeSearcher
search
(
func
->
get_entry_block
());
return
search
.
edges
;
}
void
LoopUnroll
::
run
()
{
for
(
auto
&
_f
:
m_
->
get_functions
())
{
if
(
_f
.
is_declaration
())
continue
;
auto
func
=
&
_f
;
// cout << func->get_name() << endl;
auto
belist
=
detect_back
(
func
);
auto
sloops
=
check_sloops
(
belist
);
cout
<<
"get simple loops for function "
<<
func
->
get_name
()
<<
":
\n
"
;
for
(
auto
sl
:
sloops
)
{
cout
<<
"
\t
"
;
for
(
auto
p
:
sl
)
cout
<<
p
->
get_name
()
<<
" "
;
cout
<<
"
\n
"
;
BackEdgeSearcher
::
dfsrun
(
BasicBlock
*
bb
)
{
vis
[
bb
]
=
true
;
path
.
push_back
(
bb
);
for
(
auto
succ
:
bb
->
get_succ_basic_blocks
())
{
if
(
vis
[
succ
])
{
string
type
;
Edge
edge
(
bb
,
succ
);
if
(
find
(
path
.
rbegin
(),
path
.
rend
(),
succ
)
==
path
.
rend
())
{
type
=
"cross-edge"
;
}
else
{
type
=
"back-edge"
;
edges
.
push_back
(
edge
);
}
/* cout << "find " << type << ": " << LoopUnroll::str(edge)
* << "\n"; */
}
else
dfsrun
(
succ
);
}
path
.
pop_back
();
}
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