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
bb0ba170
Commit
bb0ba170
authored
Jan 08, 2021
by
zygzagZ
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Register Allocation fixed & working
parent
ec3a8925
Changes
11
Hide whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
466 additions
and
52 deletions
+466
-52
Makefile
Makefile
+1
-1
Compiler.cpp
src/Compiler.cpp
+77
-0
Compiler.h
src/Compiler.h
+37
-0
Info.h
src/Info.h
+1
-1
Graph.h
src/codeGen/Graph.h
+250
-29
Quadruple.cpp
src/codeGen/Quadruple.cpp
+41
-0
Quadruple.h
src/codeGen/Quadruple.h
+16
-4
QuadrupleGenerator.cpp
src/codeGen/QuadrupleGenerator.cpp
+6
-0
QuadrupleGenerator.h
src/codeGen/QuadrupleGenerator.h
+2
-0
RegisterAllocator.cpp
src/codeGen/RegisterAllocator.cpp
+32
-6
Variable.h
src/codeGen/Variable.h
+3
-11
No files found.
Makefile
View file @
bb0ba170
...
...
@@ -39,7 +39,7 @@ Info.o : src/Info.cpp src/Info.h src/InfoList.h src/Absyn.h
ParseError.o
:
src/ParseError.cpp src/Info.h src/InfoList.h src/Absyn.h src/ParseError.h
${
CC
}
${
CCFLAGS
}
-c
src/ParseError.cpp
Quadruple.o
:
src/codeGen/Quadruple.cpp src/Info.h src/InfoList.h src/Absyn.h src/codeGen/Variable.h
Quadruple.o
:
src/codeGen/Quadruple.cpp src/
codeGen/Quadruple.h src/
Info.h src/InfoList.h src/Absyn.h src/codeGen/Variable.h
${
CC
}
${
CCFLAGS
}
-c
src/codeGen/Quadruple.cpp
Variable.o
:
src/codeGen/Variable.cpp src/codeGen/Quadruple.h src/Info.h src/InfoList.h src/Absyn.h
...
...
src/Compiler.cpp
View file @
bb0ba170
...
...
@@ -8,6 +8,7 @@
extern
std
::
filesystem
::
path
binaryPath
;
const
std
::
string
Compiler
::
extension
=
"s"
;
void
Compiler
::
externalCommand
(
std
::
filesystem
::
path
lat
)
{
return
;
auto
obj
=
lat
;
obj
.
replace_extension
(
"o"
);
auto
cmd
=
std
::
string
(
"as --32 '"
)
+
lat
.
string
()
+
"' -o '"
+
obj
.
string
()
+
"'"
;
...
...
@@ -126,3 +127,79 @@ void Compiler::printFunction(QuadrupleGenerator::Result quadEnv) {
blkNo
++
;
}
}
Compiler
::
regs
=
{
"eax"
,
"ebx"
,
"ecx"
,
"edx"
,
"esi"
,
"edi"
};
string
Compiler
::
getRef
(
VariablePtr
&
v
)
{
if
(
v
->
registerColor
==
-
1
)
{
if
(
!
v
->
localOffset
)
{
temps
.
emplace
(
v
);
v
->
localOffset
=
4
*
temps
.
size
();
}
return
to_string
(
v
->
localOffset
)
+
"(ebp)"
;
}
else
{
return
regs
[
v
->
registerColor
+
1
];
}
}
void
Compiler
::
generateQJumpCond
(
QJumpCond
&
q
)
{
// return QJump::generateAsm();
}
void
Compiler
::
generateQAlloc
(
QAlloc
&
q
)
{
}
void
Compiler
::
generateQWrite
(
QWrite
&
q
)
{
// return Quadruple::generateAsm();
}
void
Compiler
::
generateQAccess
(
QAccess
&
q
)
{
// return Quadruple::generateAsm();
}
void
Compiler
::
generateQReturn
(
QReturn
&
q
)
{
// return Quadruple::generateAsm();
}
void
Compiler
::
generateQCall
(
QCall
&
q
)
{
// return Quadruple::generateAsm();
}
void
Compiler
::
generateQParam
(
QParam
&
q
)
{
// return Quadruple::generateAsm();
}
void
Compiler
::
generateQJump
(
QJump
&
q
)
{
// return Quadruple::generateAsm();
}
void
Compiler
::
generateQAssign
(
QAssign
&
q
)
{
string
tg
=
regs
[
q
.
loc
->
registerColor
+
1
];
if
(
q
.
args
.
size
()
==
1
)
{
switch
(
q
.
op
.
op
)
{
case
Op
:
:
Not
:
{
buf
<<
""
return
;
}
}
}
else
{
buf
<<
"movl %"
<<
tg
<<
" "
;
auto
&
i
=
q
.
args
[
0
],
&
j
=
q
.
args
[
1
];
buf
<<
getRef
(
i
)
<<
endl
;
buf
<<
getOpName
(
q
.
op
)
<<
" %"
<<
tg
<<
" "
<<
getRef
(
i
)
<<
endl
;
}
}
void
Compiler
::
generateQLabel
(
QLabel
&
q
)
{
// return Quadruple::generateAsm();
}
\ No newline at end of file
src/Compiler.h
View file @
bb0ba170
...
...
@@ -12,6 +12,7 @@
#include "codeGen/Quadruple.h"
#include "codeGen/BasicBlock.h"
#include "codeGen/QuadrupleGenerator.h"
#include <unordered_set>
using
Op
=
Quadruple
::
Op
;
class
Compiler
{
...
...
@@ -26,12 +27,26 @@ public:
static
std
::
string
getVirtName
(
const
ClassInfoPtr
&
c
)
{
return
c
->
name
+
":virt_table"
;
}
void
generateQJumpCond
(
QJumpCond
&
q
);
void
generateQAlloc
(
QAlloc
&
q
);
void
generateQWrite
(
QWrite
&
q
);
void
generateQAccess
(
QAccess
&
q
);
void
generateQReturn
(
QReturn
&
q
);
void
generateQCall
(
QCall
&
q
);
void
generateQParam
(
QParam
&
q
);
void
generateQJump
(
QJump
&
q
);
void
generateQAssign
(
QAssign
&
q
);
void
generateQLabel
(
QLabel
&
q
);
private:
std
::
filesystem
::
path
file
;
std
::
stringstream
buf
;
shared_ptr
<
Scope
>
scope
;
QuadrupleGenerator
quadGen
;
unordered_set
<
VariablePtr
>
temps
;
unordered_set
<
VarInfoPtr
>
localInfos
;
void
compileFunction
(
const
FunctionInfoPtr
&
f
);
void
printFunction
(
QuadrupleGenerator
::
Result
quadEnv
);
...
...
@@ -41,6 +56,28 @@ private:
}
return
f
->
name
;
}
string
getRef
(
VariablePtr
&
v
);
static
const
char
**
regs
;
static
string
getOpName
(
Quadruple
::
Op
op
)
{
switch
(
op
.
op
)
{
case
Op
:
:
Plus
:
return
"addl"
;
case
Op
:
:
Minus
:
return
"subl"
;
case
Op
:
:
Mul
:
return
"mull"
;
case
Op
:
:
Div
:
return
"divl"
;
case
Op
:
:
Mod
:
return
"divl"
;
default:
return
""
;
}
}
string
moveToAnyRegister
(
VariablePtr
&
v
)
{
if
(
v
->
registerColor
==
-
1
)
{
buf
<<
"movl %eax "
<<
getRef
(
v
)
<<
endl
;
return
"eax"
;
}
else
return
regs
[
v
->
registerColor
+
1
];
}
};
#endif
src/Info.h
View file @
bb0ba170
...
...
@@ -26,7 +26,7 @@ public:
string
name
;
TypePtr
type
;
int
lineLocation
;
size_t
offset
=
0
;
size_t
offset
=
0
,
localOffset
=
0
;
bool
isInstanceVariable
()
const
{
return
offset
;
};
VariablePtr
loc
;
...
...
src/codeGen/Graph.h
View file @
bb0ba170
#ifndef ZAD2_GRAPH_H
#define ZAD2_GRAPH_H
#include <unordered_set>
#include <queue>
using
namespace
std
;
class
FindUnion
{
uint
n
{
0
};
vector
<
uint
>
t
;
public:
void
resize
(
uint
num
)
{
n
=
num
;
t
.
resize
(
n
);
for
(
uint
i
=
0
;
i
<
n
;
i
++
)
t
[
i
]
=
i
;
}
uint
get
(
uint
c
)
{
if
(
t
[
c
]
==
c
)
return
c
;
return
t
[
c
]
=
get
(
t
[
c
]);
}
void
add
(
uint
a
,
uint
b
)
{
t
[
get
(
a
)]
=
get
(
b
);
}
};
template
<
typename
T
>
class
Graph
{
public:
Graph
()
{
};
struct
Result
{
int
color
;
bool
spilled
;
};
void
add
(
T
&
i
,
T
&
j
)
{
if
(
evaluated
)
throw
runtime_error
(
"Add to evaluated graph"
);
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
;
void
addAssign
(
T
&
i
,
T
&
j
)
{
if
(
evaluated
)
throw
runtime_error
(
"Add to evaluated graph"
);
assignsSet
.
emplace
(
i
,
j
);
vertices
[
i
];
vertices
[
j
];
}
auto
getEdges
()
const
{
const
auto
&
getEdges
()
const
{
return
edgesSet
;
}
vector
<
T
>
getOrder
()
const
{
vector
<
T
>
ret
;
for
(
auto
i
:
order
)
ret
.
emplace_back
(
reverseVertices
[
i
]);
const
auto
&
getAssigns
()
const
{
return
assignsSet
;
}
map
<
T
,
int
>
getAllocation
()
const
{
if
(
!
evaluated
)
throw
runtime_error
(
"Query of unevaluated graph"
);
map
<
T
,
int
>
ret
;
for
(
const
auto
&
i
:
vertices
)
ret
[
i
.
first
]
=
color
[
i
.
second
];
return
ret
;
}
int
getColor
(
T
x
)
{
if
(
!
evaluated
)
throw
runtime_error
(
"Query of unevaluated graph"
);
if
(
!
vertices
.
count
(
x
))
throw
runtime_error
(
"Query of non-graph vertex"
);
int
c
=
vertices
[
x
];
return
color
[
c
];
}
Result
get
(
T
x
)
{
if
(
!
evaluated
)
throw
runtime_error
(
"Query of unevaluated graph"
);
if
(
!
vertices
.
count
(
x
))
throw
runtime_error
(
"Query of non-graph vertex"
);
int
c
=
vertices
[
x
];
return
Result
(
color
[
c
],
spilled
(
c
));
}
void
eval
(
int
colors
)
{
if
(
evaluated
)
throw
runtime_error
(
"Try of re-evaluating graph"
);
evaluated
=
true
;
if
(
vertices
.
empty
())
return
;
maxColors
=
colors
;
buildGraph
();
initOrder
();
initChordal
();
initColoring
(
vertices
.
size
());
if
(
!
chordal
)
return
;
if
(
maxColors
<
1
)
{
throw
std
::
runtime_error
(
"Spill to no colors!"
);
}
spillToColors
(
maxColors
);
coalesce
();
remapColors
();
checkAllocation
();
}
bool
isChordal
()
const
{
if
(
!
evaluated
)
throw
runtime_error
(
"Query of unevaluated graph"
);
return
chordal
;
}
private:
bool
evaluated
=
false
;
set
<
pair
<
T
,
T
>>
edgesSet
;
map
<
T
,
int
>
vertices
;
vector
<
T
>
reverseVertices
;
vector
<
unordered_set
<
int
>>
edges
;
FindUnion
alias
;
vector
<
int
>
order
;
vector
<
int
>
color
;
bool
chordal
=
true
;
int
maxColors
=
0
;
set
<
pair
<
T
,
T
>>
assignsSet
;
void
buildGraph
()
{
int
n
=
0
;
reverseVertices
.
reserve
(
vertices
.
size
());
...
...
@@ -39,6 +121,7 @@ public:
reverseVertices
.
emplace_back
(
i
.
first
);
}
alias
.
resize
(
vertices
.
size
());
edges
.
resize
(
vertices
.
size
());
for
(
auto
e
:
edgesSet
)
{
auto
a
=
vertices
[
e
.
first
],
b
=
vertices
[
e
.
second
];
...
...
@@ -69,7 +152,7 @@ public:
if
(
c
>=
0
)
{
lambda
[
c
].
erase
(
x
);
c
++
;
if
(
lambda
.
size
()
<=
c
)
if
(
(
int
)
lambda
.
size
()
<=
c
)
lambda
.
emplace_back
();
lambda
[
c
].
emplace
(
x
);
}
...
...
@@ -103,49 +186,187 @@ public:
}
vector
<
int
>
spilledVertices
;
int
highestColor
;
map
<
int
,
int
>
colorUses
;
int
highestColor
=
-
1
;
vector
<
unordered_set
<
int
>
>
colorUses
;
vector
<
int
>
colorCount
;
vector
<
int
>
spilledColor
;
vector
<
uint
>
nonSpilledColors
;
vector
<
int
>
coalescedNodes
;
void
initColoring
(
int
maxC
)
{
highestColor
=
-
1
;
color
.
resize
(
vertices
.
size
());
colorUses
.
resize
(
vertices
.
size
());
colorCount
.
resize
(
vertices
.
size
());
vector
<
char
>
used
;
used
.
resize
(
maxC
);
for
(
auto
&
i
:
color
)
i
=
-
1
;
for
(
auto
c
:
order
)
{
bool
used
[
maxC
];
// calc used
for
(
auto
x
:
edges
[
c
])
{
if
(
color
[
x
]
==
-
1
)
continue
;
used
[
color
[
x
]]
=
true
;
}
// calc self color
for
(
int
col
=
0
;
col
<
maxC
;
col
++
)
{
if
(
!
used
[
col
])
{
color
[
c
]
=
col
;
break
;
}
}
// clear used table for next use
for
(
auto
x
:
edges
[
c
])
{
if
(
color
[
x
]
==
-
1
)
continue
;
used
[
color
[
x
]]
=
false
;
}
// spill or apply color
if
(
color
[
c
]
==
-
1
)
{
disconnectNode
(
c
);
spilledVertices
.
emplace_back
(
c
);
markSpilled
(
c
);
}
else
{
highestColor
=
max
(
highestColor
,
color
[
c
]);
colorUses
[
color
[
c
]].
emplace
(
c
);
colorCount
[
color
[
c
]]
++
;
}
}
chordal
=
true
;
while
(
!
colorCount
.
empty
()
&&
colorCount
.
back
()
==
0
)
{
colorUses
.
pop_back
();
colorCount
.
pop_back
();
}
}
bool
spilled
(
int
c
)
const
{
return
color
[
c
]
==
-
1
;
}
void
disconnectNode
(
int
node
)
{
for
(
auto
x
:
edges
[
node
])
{
edges
[
x
].
erase
(
node
);
void
markSpilled
(
int
c
)
{
spilledVertices
.
emplace_back
(
c
);
color
[
c
]
=
-
1
;
// edges won't contain already spilled nodes
for
(
auto
x
:
edges
[
c
])
{
edges
[
x
].
erase
(
c
);
}
}
void
setup
()
{
if
(
vertices
.
empty
())
{
throw
std
::
runtime_error
(
"ayy lmao empty vertices"
);
void
spillToColors
(
uint
maxC
)
{
// heuristic: least used
priority_queue
<
pair
<
uint
,
uint
>>
Q
;
// { number of uses, color id }
spilledColor
.
resize
(
colorCount
.
size
());
nonSpilledColors
.
clear
();
for
(
uint
i
=
0
;
i
<
colorCount
.
size
();
i
++
)
{
Q
.
emplace
(
colorCount
[
i
],
i
);
}
for
(
uint
i
=
0
;
i
<
maxC
&&
!
Q
.
empty
();
i
++
)
{
// pop first most used maxC colors
auto
col
=
Q
.
top
().
second
;
spilledColor
[
col
]
=
false
;
nonSpilledColors
.
emplace_back
(
col
);
Q
.
pop
();
}
while
(
!
Q
.
empty
())
{
auto
col
=
Q
.
top
().
second
;
spilledColor
[
col
]
=
true
;
Q
.
pop
();
for
(
auto
i
:
colorUses
[
col
])
{
if
(
!
spilled
(
i
))
{
markSpilled
(
i
);
}
}
colorUses
[
col
].
clear
();
}
// reconnect spilled nodes;
for
(
auto
c
:
spilledVertices
)
{
for
(
auto
it
=
edges
[
c
].
begin
();
it
!=
edges
[
c
].
end
();)
{
auto
n
=
*
it
;
if
(
spilled
(
n
))
{
edges
[
n
].
emplace
(
c
);
++
it
;
}
else
{
it
=
edges
[
c
].
erase
(
it
);
}
}
}
}
void
setColor
(
int
x
,
int
col
)
{
if
(
color
[
x
]
==
col
)
return
;
if
(
color
[
x
]
!=
-
1
)
{
colorUses
[
color
[
x
]].
erase
(
x
);
colorCount
[
color
[
x
]]
--
;
}
color
[
x
]
=
col
;
if
(
col
!=
-
1
)
{
colorCount
[
col
]
++
;
colorUses
[
col
].
emplace
(
x
);
}
}
void
coalesceNode
(
int
x
,
int
y
,
int
col
)
{
for
(
auto
e
:
edges
[
y
])
{
edges
[
x
].
emplace
(
e
);
edges
[
e
].
emplace
(
x
);
edges
[
e
].
erase
(
y
);
}
edges
[
y
].
clear
();
setColor
(
x
,
col
);
coalescedNodes
.
emplace_back
(
y
);
alias
.
add
(
y
,
x
);
}
void
coalesce
()
{
vector
<
char
>
used
;
used
.
resize
(
highestColor
+
1
);
for
(
auto
it
:
assignsSet
)
{
for
(
auto
&
c
:
used
)
c
=
false
;
auto
x
=
vertices
[
it
.
first
],
y
=
vertices
[
it
.
second
];
x
=
alias
.
get
(
x
);
y
=
alias
.
get
(
y
);
if
(
x
==
y
)
continue
;
if
(
spilled
(
x
)
||
spilled
(
y
))
continue
;
if
(
edges
[
x
].
count
(
y
)
||
edges
[
y
].
count
(
x
))
continue
;
for
(
auto
z
:
edges
[
x
])
if
(
color
[
z
]
>=
0
)
used
[
color
[
z
]]
=
true
;
for
(
auto
z
:
edges
[
y
])
if
(
color
[
z
]
>=
0
)
used
[
color
[
z
]]
=
true
;
for
(
int
c
:
nonSpilledColors
)
{
if
(
used
[
c
])
continue
;
coalesceNode
(
x
,
y
,
c
);
break
;
}
}
for
(
uint
i
=
0
;
i
<
color
.
size
();
i
++
)
{
setColor
(
i
,
color
[
alias
.
get
(
i
)]);
}
}
void
remapColors
()
{
sort
(
nonSpilledColors
.
begin
(),
nonSpilledColors
.
end
());
for
(
uint
i
=
0
;
i
<
nonSpilledColors
.
size
();
i
++
)
{
if
(
nonSpilledColors
[
i
]
!=
i
)
{
auto
&
col
=
nonSpilledColors
[
i
];
for
(
auto
v
:
colorUses
[
col
])
color
[
v
]
=
i
;
swap
(
colorCount
[
i
],
colorCount
[
col
]);
swap
(
colorUses
[
i
],
colorUses
[
col
]);
}
}
}
void
checkAllocation
()
{
if
(
vertices
.
size
()
!=
color
.
size
())
throw
runtime_error
(
"Invalid allocation, vertices size mismatches color size"
);
uint
size
=
spilledVertices
.
size
()
+
coalescedNodes
.
size
();
for
(
uint
i
=
0
;
i
<
vertices
.
size
();
i
++
)
if
(
!
spilled
(
i
))
if
(
alias
.
get
(
i
)
==
i
)
size
++
;
if
(
size
!=
vertices
.
size
())
throw
runtime_error
(
"Invalid allocation, original size mismatches current size"
);
for
(
auto
v
:
edgesSet
)
{
int
x
=
alias
.
get
(
vertices
[
v
.
first
]);
int
y
=
alias
.
get
(
vertices
[
v
.
second
]);
if
(
!
spilled
(
x
)
&&
color
[
x
]
==
color
[
y
])
throw
runtime_error
(
"Invalid allocation, same color assigned to colliding variables"
);
if
(
color
[
x
]
>=
maxColors
||
color
[
y
]
>=
maxColors
)
throw
runtime_error
(
"Invalid allocation, more colors used than allowed"
);
}
buildGraph
();
initOrder
();
initChordal
();
}
};
...
...
src/codeGen/Quadruple.cpp
View file @
bb0ba170
#include "Quadruple.h"
#include "../Compiler.h"
void
QJumpCond
::
generateAsm
(
Compiler
&
c
)
{
c
.
generateQJumpCond
(
*
this
);
}
void
QAlloc
::
generateAsm
(
Compiler
&
c
)
{
c
.
generateQAlloc
(
*
this
);
}
void
QWrite
::
generateAsm
(
Compiler
&
c
)
{
c
.
generateQWrite
(
*
this
);
}
void
QAccess
::
generateAsm
(
Compiler
&
c
)
{
c
.
generateQAccess
(
*
this
);
}
void
QReturn
::
generateAsm
(
Compiler
&
c
)
{
c
.
generateQReturn
(
*
this
);
}
void
QCall
::
generateAsm
(
Compiler
&
c
)
{
c
.
generateQCall
(
*
this
);
}
void
QParam
::
generateAsm
(
Compiler
&
c
)
{
c
.
generateQParam
(
*
this
);
}
void
QJump
::
generateAsm
(
Compiler
&
c
)
{
c
.
generateQJump
(
*
this
);
}
void
QAssign
::
generateAsm
(
Compiler
&
c
)
{
c
.
generateQAssign
(
*
this
);
}
void
QLabel
::
generateAsm
(
Compiler
&
c
)
{
c
.
generateQLabel
(
*
this
);
}
src/codeGen/Quadruple.h
View file @
bb0ba170
...
...
@@ -7,6 +7,7 @@
#include "Variable.h"
#include "setOverloads.h"
using
namespace
std
;
class
Compiler
;
static
const
std
::
string
opNames
[]
=
{
"_U"
,
"-"
,
"!"
,
""
,
"_UE"
,
"_B"
,
"+"
,
"-"
,
"*"
,
"/"
,
"%"
,
"&"
,
"|"
,
"^"
,
"_BE"
,
...
...
@@ -59,6 +60,7 @@ public:
};
virtual
vector
<
VariablePtr
>
vars
()
const
{
return
{};
};
virtual
vector
<
VariablePtr
>
definitions
()
const
{
return
{};
};
virtual
void
generateAsm
(
Compiler
&
c
)
{
};
};
class
QWriteVar
:
public
Quadruple
{
...
...
@@ -79,6 +81,7 @@ public:
string
label
;
std
::
string
toString
()
const
override
{
return
Quadruple
::
toString
()
+
"
\"
"
+
label
+
"
\"
:"
;
}
explicit
QLabel
(
std
::
string
comment
)
:
label
(
std
::
move
(
comment
))
{}
void
generateAsm
(
Compiler
&
c
)
override
;
};
class
QAssign
:
public
QWriteVar
{
...
...
@@ -100,6 +103,7 @@ public:
vector
<
VariablePtr
>
vars
()
const
override
{
return
args
;
}
void
generateAsm
(
Compiler
&
c
)
override
;
};
class
QJump
:
public
Quadruple
{
...
...
@@ -108,10 +112,11 @@ public:
explicit
QJump
(
shared_ptr
<
QLabel
>
target
)
:
target
(
std
::
move
(
target
))
{};
std
::
string
toString
()
const
override
{
return
Quadruple
::
toString
()
+
"jump
"
+
target
->
label
;
return
Quadruple
::
toString
()
+
"jump
\"
"
+
target
->
label
+
"
\"
"
;
}
virtual
bool
isFinal
()
const
{
return
true
;
}
bool
isFinal
()
const
override
{
return
true
;
}
void
generateAsm
(
Compiler
&
c
)
override
;
};
class
QJumpCond
:
public
QJump
{
...
...
@@ -127,9 +132,9 @@ public:
std
::
string
toString
()
const
override
{
if
(
!
left
)
return
Q
uadruple
::
toString
()
+
"jump
\"
"
+
target
->
label
+
"
\
"
if "
+
Op
::
name
(
op
)
+
" "
+
right
->
name
;
return
Q
Jump
::
toString
()
+
" if "
+
Op
::
name
(
op
)
+
" "
+
right
->
name
;
else
return
Q
uadruple
::
toString
()
+
"jump
\"
"
+
target
->
label
+
"
\
"
if "
+
left
->
name
+
" "
+
Op
::
name
(
op
)
+
" "
+
right
->
name
;
return
Q
Jump
::
toString
()
+
" if "
+
left
->
name
+
" "
+
Op
::
name
(
op
)
+
" "
+
right
->
name
;
}
bool
isFinal
()
const
override
{
return
true
;
}
...
...
@@ -140,6 +145,7 @@ public:
if
(
right
)
ret
.
emplace_back
(
right
);
return
ret
;
}
void
generateAsm
(
Compiler
&
c
)
override
;
};
class
QParam
:
public
Quadruple
{
...
...
@@ -170,6 +176,7 @@ public:
if
(
param
&&
num
<
0
)
ret
.
emplace_back
(
param
);
return
ret
;
};
void
generateAsm
(
Compiler
&
c
)
override
;
};
class
QCall
:
public
QWriteVar
{
...
...
@@ -193,6 +200,7 @@ public:
if
(
self
)
ret
.
emplace_back
(
self
);
return
ret
;
}
void
generateAsm
(
Compiler
&
c
)
override
;
};
class
QReturn
:
public
Quadruple
{
...
...
@@ -215,6 +223,7 @@ public:
if
(
val
)
ret
.
emplace_back
(
val
);
return
ret
;
}
void
generateAsm
(
Compiler
&
c
)
override
;
};
class
QAccess
:
public
QWriteVar
{
...
...
@@ -237,6 +246,7 @@ public:
if
(
access
.
index
)
ret
.
emplace_back
(
access
.
index
);
return
ret
;
}
void
generateAsm
(
Compiler
&
c
)
override
;
};
class
QWrite
:
public
Quadruple
{
...
...
@@ -256,6 +266,7 @@ public:
if
(
val
)
ret
.
emplace_back
(
val
);
return
ret
;
}
void
generateAsm
(
Compiler
&
c
)
override
;
};
class
QAlloc
:
public
QWriteVar
{
...
...
@@ -278,6 +289,7 @@ public:
if
(
count
)
ret
.
emplace_back
(
count
);
return
ret
;
}
void
generateAsm
(
Compiler
&
c
)
override
;
};
class
QPhi
:
public
Quadruple
{
...
...
src/codeGen/QuadrupleGenerator.cpp
View file @
bb0ba170
...
...
@@ -317,6 +317,12 @@ void QuadrupleGenerator::visitInit(Init *p) {
addQuad
<
QAssign
>
(
alloc
(
info
),
Op
::
Copy
,
var
);
}
void
QuadrupleGenerator
::
visitNoInit
(
Init
*
p
)
{
auto
info
=
p
->
pident_
->
var
.
lock
();
assert
(
info
);
addQuad
<
QAssign
>
(
alloc
(
info
),
Op
::
Copy
,
alloc
(
0
));
}
void
QuadrupleGenerator
::
assign
(
Expr
*
lval
,
VariablePtr
val
)
{
auto
dest
=
evalLVal
(
lval
);
if
(
dest
->
info
&&
dest
->
info
->
isInstanceVariable
())
{
...
...
src/codeGen/QuadrupleGenerator.h
View file @
bb0ba170
...
...
@@ -161,6 +161,8 @@ private:
void
visitInit
(
Init
*
p
)
override
;
void
visitNoInit
(
Init
*
p
)
override
;
void
assign
(
Expr
*
lval
,
VariablePtr
val
);
void
visitAss
(
Ass
*
p
)
override
;
...
...
src/codeGen/RegisterAllocator.cpp
View file @
bb0ba170
...
...
@@ -68,6 +68,12 @@ void RegisterAllocator::buildGraph() {
for
(
const
auto
&
b
:
blocks
)
{
set
<
VariablePtr
>
alive
=
b
->
flow
.
in
;
for
(
const
auto
&
q
:
b
->
quads
)
{
if
(
auto
assign
=
dynamic_pointer_cast
<
QAssign
>
(
q
))
{
if
(
assign
->
op
==
Quadruple
::
Op
::
Copy
)
{
graph
.
addAssign
(
assign
->
loc
,
assign
->
args
[
0
]);
g2
.
addAssign
(
assign
->
loc
->
name
,
assign
->
args
[
0
]
->
name
);
}
}
alive
+=
to_set
(
q
->
definitions
());
vector
<
VariablePtr
>
dead
;
for
(
const
auto
&
var
:
alive
)
{
...
...
@@ -78,7 +84,7 @@ void RegisterAllocator::buildGraph() {
}
alive
-=
to_set
(
dead
);
q
->
aliveAfter
=
alive
;
anyAlive
|=
alive
.
size
()
>=
2
;
anyAlive
|=
alive
.
size
()
>=
1
;
for
(
auto
i
:
alive
)
{
for
(
auto
j
:
alive
)
{
if
(
i
!=
j
)
{
...
...
@@ -90,13 +96,33 @@ void RegisterAllocator::buildGraph() {
}
}
if
(
!
anyAlive
)
return
;
graph
.
setup
();
g2
.
setup
();
assert
(
graph
.
chordal
==
g2
.
chordal
);
if
(
!
g2
.
chordal
)
{
graph
.
eval
(
5
);
g2
.
eval
(
5
);
int
gNumSpill
=
0
,
g2NumSpill
=
0
;
for
(
auto
&
v
:
graph
.
getAllocation
())
{
v
.
first
->
registerColor
=
v
.
second
;
if
(
v
.
second
==
-
1
)
{
gNumSpill
++
;
}
else
{
v
.
first
->
name
+=
"-r"
+
to_string
(
v
.
second
);
}
}
for
(
auto
&
v
:
g2
.
getAllocation
())
{
if
(
v
.
second
==
-
1
)
g2NumSpill
++
;
}
cout
<<
"allocation: VPtr eval spills: "
<<
gNumSpill
<<
" vs strings spills: "
<<
g2NumSpill
<<
endl
;
if
(
!
g2
.
isChordal
())
{
printGraph
(
graph
,
"./mygraph"
);
printGraph
(
g2
,
"./myg2"
);
throw
ParseError
(
"graph not chordal!"
);
if
(
graph
.
isChordal
())
{
throw
ParseError
(
"allocation: g2 not chordal, tho g1 is chordal!"
);
}
throw
ParseError
(
"allocation: none graph chordal!"
);
}
else
{
if
(
!
graph
.
isChordal
())
{
throw
ParseError
(
"allocation: g1 not chordal, tho g2 is chordal!"
);
}
}
}
...
...
src/codeGen/Variable.h
View file @
bb0ba170
...
...
@@ -18,24 +18,16 @@ public:
bool
constExpr
{
false
};
int
val
{
0
};
std
::
string
name
;
int
registerColor
=
-
1
;
vector
<
QuadruplePtr
>
uses
;
vector
<
QuadruplePtr
>
writes
;
int
localOffset
=
0
;
void
clear
(
const
QuadruplePtr
&
q
)
{
uses
.
erase
(
std
::
remove
(
uses
.
begin
(),
uses
.
end
(),
q
),
uses
.
end
());
writes
.
erase
(
std
::
remove
(
writes
.
begin
(),
writes
.
end
(),
q
),
writes
.
end
());
//
// for (auto it = uses.begin(); it != uses.end();) {
// if (*it == q)
// it = uses.erase(it);
// else it++;
// }
// for (auto it = writes.begin(); it != writes.end();) {
// if (*it == q)
// it = writes.erase(it);
// else 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