Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
latte
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
zygzagZ
latte
Commits
ec3a8925
Commit
ec3a8925
authored
Jan 08, 2021
by
zygzagZ
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Fixed quad BB generation, start implementation of optimal graph-coloring
register allocation
parent
bc58b2c2
Changes
9
Show whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
243 additions
and
50 deletions
+243
-50
Makefile
Makefile
+3
-3
Compiler.cpp
src/Compiler.cpp
+18
-6
Compiler.h
src/Compiler.h
+1
-0
BasicBlock.cpp
src/codeGen/BasicBlock.cpp
+10
-9
Graph.h
src/codeGen/Graph.h
+152
-0
Quadruple.h
src/codeGen/Quadruple.h
+4
-9
QuadrupleGenerator.cpp
src/codeGen/QuadrupleGenerator.cpp
+19
-16
RegisterAllocator.cpp
src/codeGen/RegisterAllocator.cpp
+32
-5
RegisterAllocator.h
src/codeGen/RegisterAllocator.h
+4
-2
No files found.
Makefile
View file @
ec3a8925
...
@@ -30,7 +30,7 @@ Skeleton.o : src/Skeleton.cpp src/Skeleton.h src/Absyn.h
...
@@ -30,7 +30,7 @@ Skeleton.o : src/Skeleton.cpp src/Skeleton.h src/Absyn.h
TypeCheck.o
:
src/TypeCheck.cpp src/TypeCheck.h src/Info.h src/InfoList.h src/Absyn.h src/ParseError.h
TypeCheck.o
:
src/TypeCheck.cpp src/TypeCheck.h src/Info.h src/InfoList.h src/Absyn.h src/ParseError.h
${
CC
}
${
CCFLAGS
}
-c
src/TypeCheck.cpp
${
CC
}
${
CCFLAGS
}
-c
src/TypeCheck.cpp
Compiler.o
:
src/Compiler.cpp src/Compiler.h src/TypeCheck.h src/Info.h src/InfoList.h src/Absyn.h src/ParseError.h src/codeGen/Quadruple.h src/codeGen/Variable.h src/codeGen/QuadrupleGenerator.h
Compiler.o
:
src/Compiler.cpp src/Compiler.h src/TypeCheck.h src/Info.h src/InfoList.h src/Absyn.h src/ParseError.h src/codeGen/Quadruple.h src/codeGen/Variable.h src/codeGen/QuadrupleGenerator.h
src/codeGen/RegisterAllocator.h src/codeGen/Graph.h
${
CC
}
${
CCFLAGS
}
-c
src/Compiler.cpp
${
CC
}
${
CCFLAGS
}
-c
src/Compiler.cpp
Info.o
:
src/Info.cpp src/Info.h src/InfoList.h src/Absyn.h
Info.o
:
src/Info.cpp src/Info.h src/InfoList.h src/Absyn.h
...
@@ -51,10 +51,10 @@ BasicBlock.o : src/codeGen/BasicBlock.cpp src/codeGen/Quadruple.h src/codeGen/Ba
...
@@ -51,10 +51,10 @@ BasicBlock.o : src/codeGen/BasicBlock.cpp src/codeGen/Quadruple.h src/codeGen/Ba
QuadrupleGenerator.o
:
src/codeGen/QuadrupleGenerator.cpp src/codeGen/Quadruple.h src/codeGen/BasicBlock.h src/Info.h src/InfoList.h src/Absyn.h src/codeGen/Variable.h src/Compiler.h src/codeGen/QuadrupleGenerator.h
QuadrupleGenerator.o
:
src/codeGen/QuadrupleGenerator.cpp src/codeGen/Quadruple.h src/codeGen/BasicBlock.h src/Info.h src/InfoList.h src/Absyn.h src/codeGen/Variable.h src/Compiler.h src/codeGen/QuadrupleGenerator.h
${
CC
}
${
CCFLAGS
}
-c
src/codeGen/QuadrupleGenerator.cpp
${
CC
}
${
CCFLAGS
}
-c
src/codeGen/QuadrupleGenerator.cpp
RegisterAllocator.o
:
src/codeGen/RegisterAllocator.cpp src/codeGen/Quadruple.h src/codeGen/BasicBlock.h src/Info.h src/InfoList.h src/Absyn.h src/codeGen/Variable.h src/codeGen/RegisterAllocator.h
RegisterAllocator.o
:
src/codeGen/RegisterAllocator.cpp src/codeGen/Quadruple.h src/codeGen/BasicBlock.h src/Info.h src/InfoList.h src/Absyn.h src/codeGen/Variable.h src/codeGen/RegisterAllocator.h
src/codeGen/Graph.h
${
CC
}
${
CCFLAGS
}
-c
src/codeGen/RegisterAllocator.cpp
${
CC
}
${
CCFLAGS
}
-c
src/codeGen/RegisterAllocator.cpp
Latte.o
:
src/Latte.cpp src/Parser.h src/Printer.h src/Absyn.h src/ParseError.h src/TypeCheck.h src/Compiler.h src/Info.h src/InfoList.h src/codeGen/QuadrupleGenerator.h
Latte.o
:
src/Latte.cpp src/Parser.h src/Printer.h src/Absyn.h src/ParseError.h src/TypeCheck.h src/Compiler.h src/Info.h src/InfoList.h src/codeGen/QuadrupleGenerator.h
src/codeGen/RegisterAllocator.h src/codeGen/Graph.h
${
CC
}
${
CCFLAGS
}
-c
src/Latte.cpp
${
CC
}
${
CCFLAGS
}
-c
src/Latte.cpp
lib/runtime.o
:
lib/runtime.c Makefile
lib/runtime.o
:
lib/runtime.c Makefile
...
...
src/Compiler.cpp
View file @
ec3a8925
...
@@ -54,16 +54,22 @@ void Compiler::compileFunction(const FunctionInfoPtr& f) {
...
@@ -54,16 +54,22 @@ void Compiler::compileFunction(const FunctionInfoPtr& f) {
// c++ thiscall ecx, stack right-to-left (push c, push b, push a)
// c++ thiscall ecx, stack right-to-left (push c, push b, push a)
buf
<<
"
\"
"
<<
name
<<
"
\"
:
\n
"
;
buf
<<
"
\"
"
<<
name
<<
"
\"
:
\n
"
;
QuadrupleGenerator
::
Result
quadEnv
=
quadGen
.
compileFunction
(
f
);
auto
quadEnv
=
quadGen
.
compileFunction
(
f
);
try
{
RegisterAllocator
regGen
((
quadEnv
));
RegisterAllocator
regGen
=
RegisterAllocator
(
quadEnv
);
regGen
.
allocate
();
regGen
.
allocate
();
}
catch
(
const
ParseError
&
e
)
{
printFunction
(
quadEnv
);
throw
ParseError
(
buf
.
str
()
+
e
.
what
());
}
printFunction
(
quadEnv
);
}
void
Compiler
::
printFunction
(
QuadrupleGenerator
::
Result
quadEnv
)
{
int
blkNo
=
0
;
int
blkNo
=
0
;
for
(
const
auto
&
b
:
quadEnv
.
blocks
)
{
for
(
const
auto
&
b
:
quadEnv
.
blocks
)
{
buf
<<
"------------------------------
\n
"
;
buf
<<
"------------------------------
----------------------------------------------
\n
"
;
buf
<<
"blok "
<<
blkNo
<<
" "
<<
b
->
getName
()
<<
endl
;
buf
<<
"blok "
<<
blkNo
<<
" "
<<
b
->
getName
()
<<
endl
;
/*buf << "in: ";
/*buf << "in: ";
for (auto in : b->in) {
for (auto in : b->in) {
...
@@ -91,6 +97,12 @@ void Compiler::compileFunction(const FunctionInfoPtr& f) {
...
@@ -91,6 +97,12 @@ void Compiler::compileFunction(const FunctionInfoPtr& f) {
for
(
const
auto
&
q
:
b
->
quads
)
{
for
(
const
auto
&
q
:
b
->
quads
)
{
auto
ret
=
q
->
toString
();
auto
ret
=
q
->
toString
();
if
(
!
ret
.
empty
())
{
if
(
!
ret
.
empty
())
{
auto
len
=
0
;
for
(
const
auto
&
c
:
ret
)
{
len
++
;
if
(
c
==
'\t'
)
len
+=
8
-
(
len
%
8
);
}
for
(;
len
<
70
;
len
++
)
ret
+=
' '
;
buf
<<
ret
<<
" alive: "
;
buf
<<
ret
<<
" alive: "
;
for
(
auto
var
:
q
->
aliveAfter
)
for
(
auto
var
:
q
->
aliveAfter
)
buf
<<
var
->
name
<<
" "
;
buf
<<
var
->
name
<<
" "
;
...
...
src/Compiler.h
View file @
ec3a8925
...
@@ -33,6 +33,7 @@ private:
...
@@ -33,6 +33,7 @@ private:
QuadrupleGenerator
quadGen
;
QuadrupleGenerator
quadGen
;
void
compileFunction
(
const
FunctionInfoPtr
&
f
);
void
compileFunction
(
const
FunctionInfoPtr
&
f
);
void
printFunction
(
QuadrupleGenerator
::
Result
quadEnv
);
static
std
::
string
mangleFunctionName
(
const
FunctionInfoPtr
&
f
)
{
static
std
::
string
mangleFunctionName
(
const
FunctionInfoPtr
&
f
)
{
if
(
auto
c
=
f
->
klass
.
lock
())
{
if
(
auto
c
=
f
->
klass
.
lock
())
{
...
...
src/codeGen/BasicBlock.cpp
View file @
ec3a8925
...
@@ -2,6 +2,7 @@
...
@@ -2,6 +2,7 @@
#include "Quadruple.h"
#include "Quadruple.h"
void
BasicBlock
::
finishQuads
()
{
void
BasicBlock
::
finishQuads
()
{
if
(
!
afterInit
.
empty
())
{
while
(
!
quads
.
empty
()
&&
quads
.
back
()
->
isFinal
())
{
while
(
!
quads
.
empty
()
&&
quads
.
back
()
->
isFinal
())
{
auto
final
=
quads
.
back
();
auto
final
=
quads
.
back
();
quads
.
pop_back
();
quads
.
pop_back
();
...
@@ -11,8 +12,8 @@ void BasicBlock::finishQuads() {
...
@@ -11,8 +12,8 @@ void BasicBlock::finishQuads() {
for
(
const
auto
&
q
:
afterInit
)
{
for
(
const
auto
&
q
:
afterInit
)
{
quads
.
push_back
(
q
);
quads
.
push_back
(
q
);
}
}
afterInit
.
clear
();
afterInit
.
clear
();
}
auto
self
=
this
->
shared_from_this
();
auto
self
=
this
->
shared_from_this
();
for
(
const
auto
&
q
:
quads
)
{
for
(
const
auto
&
q
:
quads
)
{
...
...
src/codeGen/Graph.h
0 → 100644
View file @
ec3a8925
#ifndef ZAD2_GRAPH_H
#define ZAD2_GRAPH_H
#include <unordered_set>
template
<
typename
T
>
class
Graph
{
public:
Graph
()
{
};
void
add
(
T
&
i
,
T
&
j
)
{
vertices
[
i
];
vertices
[
j
];
edgesSet
.
emplace
(
i
,
j
);
edgesSet
.
emplace
(
j
,
i
);
}
set
<
pair
<
T
,
T
>>
edgesSet
;
map
<
T
,
int
>
vertices
;
vector
<
T
>
reverseVertices
;
vector
<
unordered_set
<
int
>>
edges
;
vector
<
int
>
order
;
vector
<
int
>
color
;
bool
chordal
=
false
;
auto
getEdges
()
const
{
return
edgesSet
;
}
vector
<
T
>
getOrder
()
const
{
vector
<
T
>
ret
;
for
(
auto
i
:
order
)
ret
.
emplace_back
(
reverseVertices
[
i
]);
return
ret
;
}
void
buildGraph
()
{
int
n
=
0
;
reverseVertices
.
reserve
(
vertices
.
size
());
for
(
auto
&
i
:
vertices
)
{
i
.
second
=
n
++
;
reverseVertices
.
emplace_back
(
i
.
first
);
}
edges
.
resize
(
vertices
.
size
());
for
(
auto
e
:
edgesSet
)
{
auto
a
=
vertices
[
e
.
first
],
b
=
vertices
[
e
.
second
];
edges
[
a
].
emplace
(
b
);
}
}
void
initOrder
()
{
if
(
vertices
.
empty
())
return
;
vector
<
int
>
card
;
vector
<
unordered_set
<
int
>>
lambda
;
int
n
=
vertices
.
size
();
card
.
resize
(
n
);
lambda
.
resize
(
n
);
for
(
int
i
=
0
;
i
<
n
;
i
++
)
{
lambda
[
0
].
emplace
(
i
);
}
while
(
!
lambda
.
empty
())
{
if
(
lambda
.
back
().
empty
())
{
lambda
.
pop_back
();
continue
;
}
auto
v
=
*
lambda
.
back
().
begin
();
order
.
push_back
(
v
);
for
(
auto
x
:
edges
[
v
])
{
auto
&
c
=
card
[
x
];
if
(
c
>=
0
)
{
lambda
[
c
].
erase
(
x
);
c
++
;
if
(
lambda
.
size
()
<=
c
)
lambda
.
emplace_back
();
lambda
[
c
].
emplace
(
x
);
}
}
lambda
[
card
[
v
]].
erase
(
v
);
card
[
v
]
=
-
1
;
}
}
void
initChordal
()
{
unordered_set
<
int
>
visited
;
for
(
auto
i
:
order
)
{
unordered_set
<
int
>
neighbors
;
for
(
auto
x
:
edges
[
i
])
{
if
(
visited
.
count
(
x
))
{
neighbors
.
emplace
(
x
);
}
}
for
(
auto
x
:
neighbors
)
{
for
(
auto
y
:
neighbors
)
{
if
(
x
==
y
)
continue
;
if
(
!
edges
[
x
].
count
(
y
)
||
!
edges
[
y
].
count
(
x
))
{
chordal
=
false
;
return
;
}
}
}
visited
.
emplace
(
i
);
}
chordal
=
true
;
}
vector
<
int
>
spilledVertices
;
int
highestColor
;
map
<
int
,
int
>
colorUses
;
vector
<
int
>
colorCount
;
void
initColoring
(
int
maxC
)
{
highestColor
=
-
1
;
color
.
resize
(
vertices
.
size
());
for
(
auto
&
i
:
color
)
i
=
-
1
;
for
(
auto
c
:
order
)
{
bool
used
[
maxC
];
for
(
auto
x
:
edges
[
c
])
{
if
(
color
[
x
]
==
-
1
)
continue
;
used
[
color
[
x
]]
=
true
;
}
for
(
int
col
=
0
;
col
<
maxC
;
col
++
)
{
if
(
!
used
[
col
])
{
color
[
c
]
=
col
;
break
;
}
}
if
(
color
[
c
]
==
-
1
)
{
disconnectNode
(
c
);
spilledVertices
.
emplace_back
(
c
);
}
else
{
highestColor
=
max
(
highestColor
,
color
[
c
]);
}
}
chordal
=
true
;
}
void
disconnectNode
(
int
node
)
{
for
(
auto
x
:
edges
[
node
])
{
edges
[
x
].
erase
(
node
);
}
}
void
setup
()
{
if
(
vertices
.
empty
())
{
throw
std
::
runtime_error
(
"ayy lmao empty vertices"
);
}
buildGraph
();
initOrder
();
initChordal
();
}
};
#endif //ZAD2_GRAPH_H
src/codeGen/Quadruple.h
View file @
ec3a8925
...
@@ -5,6 +5,7 @@
...
@@ -5,6 +5,7 @@
#include "../Info.h"
#include "../Info.h"
#include "Variable.h"
#include "Variable.h"
#include "setOverloads.h"
using
namespace
std
;
using
namespace
std
;
static
const
std
::
string
opNames
[]
=
{
"_U"
,
"-"
,
"!"
,
""
,
"_UE"
,
static
const
std
::
string
opNames
[]
=
{
"_U"
,
"-"
,
"!"
,
""
,
"_UE"
,
...
@@ -52,6 +53,9 @@ public:
...
@@ -52,6 +53,9 @@ public:
for
(
const
auto
&
v
:
vars
())
{
for
(
const
auto
&
v
:
vars
())
{
if
(
v
)
v
->
uses
.
emplace_back
(
self
);
if
(
v
)
v
->
uses
.
emplace_back
(
self
);
}
}
for
(
const
auto
&
v
:
definitions
())
{
if
(
v
)
v
->
writes
.
emplace_back
(
self
);
}
};
};
virtual
vector
<
VariablePtr
>
vars
()
const
{
return
{};
};
virtual
vector
<
VariablePtr
>
vars
()
const
{
return
{};
};
virtual
vector
<
VariablePtr
>
definitions
()
const
{
return
{};
};
virtual
vector
<
VariablePtr
>
definitions
()
const
{
return
{};
};
...
@@ -63,10 +67,6 @@ public:
...
@@ -63,10 +67,6 @@ public:
explicit
QWriteVar
(
VariablePtr
loc
)
:
Quadruple
(),
loc
(
std
::
move
(
loc
))
{};
explicit
QWriteVar
(
VariablePtr
loc
)
:
Quadruple
(),
loc
(
std
::
move
(
loc
))
{};
std
::
string
toString
()
const
override
{
return
Quadruple
::
toString
()
+
"
\t
"
+
(
loc
?
(
loc
->
name
+
" := "
)
:
""
);
}
std
::
string
toString
()
const
override
{
return
Quadruple
::
toString
()
+
"
\t
"
+
(
loc
?
(
loc
->
name
+
" := "
)
:
""
);
}
void
useVariables
()
override
{
Quadruple
::
useVariables
();
if
(
loc
)
loc
->
writes
.
emplace_back
(
shared_from_this
());
}
vector
<
VariablePtr
>
definitions
()
const
override
{
vector
<
VariablePtr
>
definitions
()
const
override
{
auto
ret
=
Quadruple
::
definitions
();
auto
ret
=
Quadruple
::
definitions
();
if
(
loc
)
ret
.
emplace_back
(
loc
);
if
(
loc
)
ret
.
emplace_back
(
loc
);
...
@@ -165,11 +165,6 @@ public:
...
@@ -165,11 +165,6 @@ public:
return
ret
;
return
ret
;
}
}
void
useVariables
()
override
{
Quadruple
::
useVariables
();
if
(
param
&&
num
<
0
)
param
->
writes
.
emplace_back
(
shared_from_this
());
}
vector
<
VariablePtr
>
definitions
()
const
override
{
vector
<
VariablePtr
>
definitions
()
const
override
{
auto
ret
=
Quadruple
::
definitions
();
auto
ret
=
Quadruple
::
definitions
();
if
(
param
&&
num
<
0
)
ret
.
emplace_back
(
param
);
if
(
param
&&
num
<
0
)
ret
.
emplace_back
(
param
);
...
...
src/codeGen/QuadrupleGenerator.cpp
View file @
ec3a8925
...
@@ -382,36 +382,38 @@ void QuadrupleGenerator::visitCondElse(CondElse *p) {
...
@@ -382,36 +382,38 @@ void QuadrupleGenerator::visitCondElse(CondElse *p) {
void
QuadrupleGenerator
::
compileCond
(
Expr
*
expr_
,
Stmt
*
stmt_1
,
Stmt
*
stmt_2
)
{
void
QuadrupleGenerator
::
compileCond
(
Expr
*
expr_
,
Stmt
*
stmt_1
,
Stmt
*
stmt_2
)
{
// TODO: stmty nie składają się z jednego bloku tylko z wielu
// TODO: stmty nie składają się z jednego bloku tylko z wielu
auto
elseBranch
=
make_shared
<
QLabel
>
(
"else"
);
auto
elseBranch
=
make_shared
<
QLabel
>
(
"
if_
else"
);
auto
after
=
make_shared
<
QLabel
>
(
"end_else"
);
auto
after
=
make_shared
<
QLabel
>
(
"end_else"
);
auto
var
=
evalExpr
(
expr_
);
auto
var
=
evalExpr
(
expr_
);
addQuad
<
QJumpCond
>
(
elseBranch
,
Op
::
Not
,
var
);
addQuad
<
QJumpCond
>
(
elseBranch
,
Op
::
Not
,
var
);
auto
beforeBlock
=
flushBasicBlock
();
// possible jump -> else
auto
beforeBlock
=
flushBasicBlock
();
// possible jump -> else
auto
env1
=
captureEnv
(),
env2
=
env1
;
auto
envIf
=
captureEnv
(),
envElse
=
envIf
;
auto
stmtIfFirstBlock
=
block
;
addQuad
<
QLabel
>
(
"if_true"
);
stmt_1
->
accept
(
this
);
stmt_1
->
accept
(
this
);
addQuad
<
QJump
>
(
after
);
addQuad
<
QJump
>
(
after
);
auto
stmt
1
Block
=
flushBasicBlock
();
// jump -> after
auto
stmt
IfLast
Block
=
flushBasicBlock
();
// jump -> after
env
1
.
capture
();
env
If
.
capture
();
env
1
.
revert
();
env
If
.
revert
();
addQuad
(
elseBranch
);
addQuad
(
elseBranch
);
auto
stmtElseFirstBlock
=
block
;
if
(
stmt_2
)
{
if
(
stmt_2
)
{
stmt_2
->
accept
(
this
);
stmt_2
->
accept
(
this
);
}
}
auto
stmt
2
Block
=
flushBasicBlock
();
// jump <- cond
auto
stmt
ElseLast
Block
=
flushBasicBlock
();
// jump <- cond
env
2
.
capture
();
env
Else
.
capture
();
addQuad
(
after
);
addQuad
(
after
);
beforeBlock
->
append
(
stmt
1
Block
);
beforeBlock
->
append
(
stmt
IfFirst
Block
);
beforeBlock
->
append
(
stmt
2
Block
);
beforeBlock
->
append
(
stmt
ElseFirst
Block
);
stmt
1
Block
->
append
(
block
);
stmt
IfLast
Block
->
append
(
block
);
stmt
2
Block
->
append
(
block
);
stmt
ElseLast
Block
->
append
(
block
);
merge2Envs
(
&
env
1
,
stmt1Block
,
&
env2
,
stmt2
Block
);
merge2Envs
(
&
env
If
,
stmtIfLastBlock
,
&
envElse
,
stmtElseLast
Block
);
}
}
void
QuadrupleGenerator
::
merge2Envs
(
VariableLayout
*
env1
,
const
BasicBlockPtr
&
b1
,
VariableLayout
*
env2
,
const
BasicBlockPtr
&
b2
)
{
void
QuadrupleGenerator
::
merge2Envs
(
VariableLayout
*
env1
,
const
BasicBlockPtr
&
b1
,
VariableLayout
*
env2
,
const
BasicBlockPtr
&
b2
)
{
...
@@ -473,12 +475,13 @@ void QuadrupleGenerator::visitWhile(While *expr) {
...
@@ -473,12 +475,13 @@ void QuadrupleGenerator::visitWhile(While *expr) {
auto
info
=
p
.
first
;
auto
info
=
p
.
first
;
auto
hooked
=
p
.
second
.
first
;
auto
hooked
=
p
.
second
.
first
;
auto
looped
=
p
.
second
.
second
;
auto
looped
=
p
.
second
.
second
;
if
(
!
hooked
||
hooked
==
looped
)
continue
;
if
(
!
hooked
)
continue
;
auto
orig
=
env1
.
changes
[
info
].
first
;
// save hooks if used
// save hooks if used
info
->
loc
=
hooked
;
info
->
loc
=
hooked
;
// transition from pre-hook to hooked var [before -> cond]
// transition from pre-hook to hooked var [before -> cond]
auto
orig
=
env1
.
changes
[
info
].
first
;
condBlock
->
addPhi
(
beforeBlock
,
hooked
,
orig
);
condBlock
->
addPhi
(
beforeBlock
,
hooked
,
orig
);
// transition from hooked var
condBlock
->
addPhi
(
loopLastBlock
,
hooked
,
looped
);
condBlock
->
addPhi
(
loopLastBlock
,
hooked
,
looped
);
// loopLastBlock doesn't need phi, it has only one incoming block
// loopLastBlock doesn't need phi, it has only one incoming block
...
@@ -501,6 +504,6 @@ void QuadrupleGenerator::visitSExp(SExp *p) {
...
@@ -501,6 +504,6 @@ void QuadrupleGenerator::visitSExp(SExp *p) {
void
QuadrupleGenerator
::
visitForEach
(
ForEach
*
p
)
{
void
QuadrupleGenerator
::
visitForEach
(
ForEach
*
p
)
{
auto
tab
=
evalExpr
(
p
->
expr_
);
auto
tab
=
evalExpr
(
p
->
expr_
);
throw
ParseError
(
"ForEach is yet unimplemented!"
,
p
);
//
throw ParseError("ForEach is yet unimplemented!", p);
// TODO: implement
// TODO: implement
}
}
\ No newline at end of file
src/codeGen/RegisterAllocator.cpp
View file @
ec3a8925
#include "RegisterAllocator.h"
#include "RegisterAllocator.h"
#include "BasicBlock.h"
#include "BasicBlock.h"
#include "setOverloads.h"
#include "setOverloads.h"
#include <fstream>
void
RegisterAllocator
::
analyseLive
()
{
void
RegisterAllocator
::
analyseLive
()
{
for
(
const
auto
&
v
:
vars
)
{
for
(
const
auto
&
v
:
vars
)
{
...
@@ -37,7 +38,8 @@ void RegisterAllocator::analyseLive() {
...
@@ -37,7 +38,8 @@ void RegisterAllocator::analyseLive() {
if
(
!
changed
)
break
;
if
(
!
changed
)
break
;
}
}
assert
(
blocks
.
empty
()
||
blocks
[
0
]
->
flow
.
in
.
empty
());
if
(
!
blocks
.
empty
()
&&
!
blocks
[
0
]
->
flow
.
in
.
empty
())
throw
ParseError
(
"Variable definition not found - first block expects input"
);
}
}
void
RegisterAllocator
::
allocate
()
{
void
RegisterAllocator
::
allocate
()
{
...
@@ -45,7 +47,24 @@ void RegisterAllocator::allocate() {
...
@@ -45,7 +47,24 @@ void RegisterAllocator::allocate() {
buildGraph
();
buildGraph
();
}
}
void
printGraph
(
const
Graph
<
VariablePtr
>
&
graph
,
const
std
::
string
&
filename
)
{
ofstream
f
(
filename
);
for
(
const
auto
&
v
:
graph
.
getEdges
())
{
f
<<
v
.
first
->
name
<<
" "
<<
v
.
second
->
name
<<
endl
;
}
f
.
close
();
}
void
printGraph
(
const
Graph
<
std
::
string
>
&
graph
,
const
std
::
string
&
filename
)
{
ofstream
f
(
filename
);
for
(
const
auto
&
v
:
graph
.
getEdges
())
{
f
<<
v
.
first
<<
" "
<<
v
.
second
<<
endl
;
}
f
.
close
();
}
void
RegisterAllocator
::
buildGraph
()
{
void
RegisterAllocator
::
buildGraph
()
{
bool
anyAlive
=
false
;
for
(
const
auto
&
b
:
blocks
)
{
for
(
const
auto
&
b
:
blocks
)
{
set
<
VariablePtr
>
alive
=
b
->
flow
.
in
;
set
<
VariablePtr
>
alive
=
b
->
flow
.
in
;
for
(
const
auto
&
q
:
b
->
quads
)
{
for
(
const
auto
&
q
:
b
->
quads
)
{
...
@@ -59,17 +78,25 @@ void RegisterAllocator::buildGraph() {
...
@@ -59,17 +78,25 @@ void RegisterAllocator::buildGraph() {
}
}
alive
-=
to_set
(
dead
);
alive
-=
to_set
(
dead
);
q
->
aliveAfter
=
alive
;
q
->
aliveAfter
=
alive
;
anyAlive
|=
alive
.
size
()
>=
2
;
for
(
auto
i
:
alive
)
{
for
(
auto
i
:
alive
)
{
for
(
auto
j
:
alive
)
{
for
(
auto
j
:
alive
)
{
if
(
i
!=
j
)
{
if
(
i
!=
j
)
{
if
(
i
.
get
()
>
j
.
get
())
{
graph
.
add
(
i
,
j
);
swap
(
i
,
j
);
g2
.
add
(
i
->
name
,
j
->
name
);
}
}
graphEdges
.
insert
(
make_pair
(
i
,
j
));
}
}
}
}
}
}
}
}
if
(
!
anyAlive
)
return
;
graph
.
setup
();
g2
.
setup
();
assert
(
graph
.
chordal
==
g2
.
chordal
);
if
(
!
g2
.
chordal
)
{
printGraph
(
graph
,
"./mygraph"
);
printGraph
(
g2
,
"./myg2"
);
throw
ParseError
(
"graph not chordal!"
);
}
}
}
}
...
...
src/codeGen/RegisterAllocator.h
View file @
ec3a8925
...
@@ -5,6 +5,7 @@
...
@@ -5,6 +5,7 @@
#include "Quadruple.h"
#include "Quadruple.h"
#include "QuadrupleGenerator.h"
#include "QuadrupleGenerator.h"
#include "Graph.h"
class
Register
:
public
std
::
enable_shared_from_this
<
Register
>
{
class
Register
:
public
std
::
enable_shared_from_this
<
Register
>
{
bool
available
;
bool
available
;
...
@@ -14,7 +15,7 @@ class Register : public std::enable_shared_from_this<Register> {
...
@@ -14,7 +15,7 @@ class Register : public std::enable_shared_from_this<Register> {
class
RegisterAllocator
{
class
RegisterAllocator
{
public:
public:
explicit
RegisterAllocator
(
const
QuadrupleGenerator
::
Result
&
r
)
:
blocks
(
r
.
blocks
),
vars
(
r
.
vars
)
{}
RegisterAllocator
(
const
QuadrupleGenerator
::
Result
&
r
)
:
blocks
(
r
.
blocks
),
vars
(
r
.
vars
)
{}
void
processQJump
(
shared_ptr
<
QJump
>
q
);
void
processQJump
(
shared_ptr
<
QJump
>
q
);
void
processQJumpCond
(
shared_ptr
<
QJumpCond
>
q
);
void
processQJumpCond
(
shared_ptr
<
QJumpCond
>
q
);
void
processQLabel
(
shared_ptr
<
QLabel
>
q
);
void
processQLabel
(
shared_ptr
<
QLabel
>
q
);
...
@@ -29,10 +30,11 @@ public:
...
@@ -29,10 +30,11 @@ public:
void
allocate
();
void
allocate
();
void
buildGraph
();
void
buildGraph
();
private:
private:
Graph
<
VariablePtr
>
graph
;
Graph
<
std
::
string
>
g2
;
void
analyseLive
();
void
analyseLive
();
vector
<
BasicBlockPtr
>
blocks
;
vector
<
BasicBlockPtr
>
blocks
;
vector
<
VariablePtr
>
vars
;
vector
<
VariablePtr
>
vars
;
set
<
pair
<
VariablePtr
,
VariablePtr
>>
graphEdges
;
};
};
...
...
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