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
459ffddf
Commit
459ffddf
authored
Jan 09, 2021
by
zygzagZ
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Dopychanie kolanem
parent
e694f348
Changes
8
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
437 additions
and
121 deletions
+437
-121
Makefile
Makefile
+6
-6
Compiler.cpp
src/Compiler.cpp
+159
-54
Compiler.h
src/Compiler.h
+72
-10
BasicBlock.h
src/codeGen/BasicBlock.h
+1
-1
Quadruple.h
src/codeGen/Quadruple.h
+22
-6
QuadrupleGenerator.cpp
src/codeGen/QuadrupleGenerator.cpp
+148
-43
QuadrupleGenerator.h
src/codeGen/QuadrupleGenerator.h
+28
-0
RegisterAllocator.cpp
src/codeGen/RegisterAllocator.cpp
+1
-1
No files found.
Makefile
View file @
459ffddf
...
...
@@ -3,14 +3,14 @@ CCFLAGS=-g -W -Wall -O0 -std=c++2a -Wno-unused-parameter
.PHONY
:
clean distclean
all
:
latc
all
:
latc
_x86
clean
:
rm
-f
*
.o latc Grammar.aux Grammar.log Grammar.pdf Grammar.dvi Grammar.ps Grammar
rm
-f
*
.o latc
_x86
Grammar.aux Grammar.log Grammar.pdf Grammar.dvi Grammar.ps Grammar
latc
:
Absyn.o Lexer.o Parser.o Printer.o TypeCheck.o Info.o Skeleton.o ParseError.o Compiler.o Quadruple.o BasicBlock.o QuadrupleGenerator.o RegisterAllocator.o Latte.o
@
echo
"Linking latc..."
${
CC
}
${
CCFLAGS
}
$^
-lstdc
++fs
-o
latc
latc
_x86
:
Absyn.o Lexer.o Parser.o Printer.o TypeCheck.o Info.o Skeleton.o ParseError.o Compiler.o Quadruple.o BasicBlock.o QuadrupleGenerator.o RegisterAllocator.o Latte.o
@
echo
"Linking latc
_x86
..."
${
CC
}
${
CCFLAGS
}
$^
-lstdc
++fs
-o
latc
_x86
Absyn.o
:
src/Absyn.cpp src/Absyn.h
${
CC
}
${
CCFLAGS
}
-c
src/Absyn.cpp
...
...
@@ -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
${
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 src/codeGen/RegisterAllocator.h src/codeGen/Graph.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
src/codeGen/BasicBlock.h
${
CC
}
${
CCFLAGS
}
-c
src/Compiler.cpp
Info.o
:
src/Info.cpp src/Info.h src/InfoList.h src/Absyn.h
...
...
src/Compiler.cpp
View file @
459ffddf
This diff is collapsed.
Click to expand it.
src/Compiler.h
View file @
459ffddf
...
...
@@ -38,6 +38,13 @@ public:
void
generateQJump
(
QJump
&
q
);
void
generateQAssign
(
QAssign
&
q
);
void
generateQLabel
(
QLabel
&
q
);
static
std
::
string
mangleFunctionName
(
const
FunctionInfoPtr
&
f
)
{
if
(
auto
c
=
f
->
klass
.
lock
())
{
return
c
->
name
+
"::"
+
f
->
name
;
}
return
f
->
name
;
}
private:
std
::
filesystem
::
path
file
;
std
::
stringstream
buf
;
...
...
@@ -52,7 +59,14 @@ private:
class
Register
{
public:
Register
(
string
n
)
:
name
(
std
::
move
(
n
))
{};
Register
(
string
n
)
:
name
(
n
)
{
for
(
auto
reg
:
Compiler
::
regs
)
{
if
(
name
==
reg
)
{
return
;
}
}
throw
runtime_error
(
"Invalid register name"
);
};
Register
(
int
n
)
{
name
=
Compiler
::
regs
[
n
];
}
Register
(
const
VariablePtr
&
v
)
{
name
=
Compiler
::
regs
[
v
->
registerColor
+
1
];
}
string
name
;
...
...
@@ -61,16 +75,12 @@ private:
bool
operator
!=
(
const
Register
&
other
)
const
{
return
name
!=
other
.
name
;
}
};
static
std
::
string
mangleFunctionName
(
const
FunctionInfoPtr
&
f
)
{
if
(
auto
c
=
f
->
klass
.
lock
())
{
return
c
->
name
+
"::"
+
f
->
name
;
}
return
f
->
name
;
}
string
getRef
(
VariablePtr
&
v
);
static
const
char
*
const
regs
[
6
];
static
const
int
callerSavedRegisters
[
2
];
static
const
int
calleeSavedRegisters
[
3
];
static
string
getOpName
(
Quadruple
::
Op
op
)
{
switch
(
op
.
op
)
{
...
...
@@ -79,10 +89,12 @@ private:
case
Op
:
:
Mul
:
return
"IMULL"
;
case
Op
:
:
Div
:
case
Op
:
:
Mod
:
throw
runtime_error
(
"Impossible to handle division with default"
);
case
Op
:
:
Not
:
return
"SETZ"
;
case
Op
:
:
Copy
:
return
"SETNZ"
;
case
Op
:
:
LT
:
return
"SETL"
;
case
Op
:
:
LE
:
return
"SETLE"
;
case
Op
:
:
EQ
:
return
"SET
E
"
;
case
Op
:
:
NEQ
:
return
"SETN
E
"
;
case
Op
:
:
EQ
:
return
"SET
Z
"
;
case
Op
:
:
NEQ
:
return
"SETN
Z
"
;
case
Op
:
:
GE
:
return
"SETGE"
;
case
Op
:
:
GT
:
return
"SETG"
;
default:
return
"Op"
+
to_string
(
op
.
op
)
+
"?"
;
...
...
@@ -121,7 +133,57 @@ private:
}
void
append
(
string
cmd
,
string
op1
=
""
,
string
op2
=
""
,
string
op3
=
""
)
{
buf
<<
"
\t
"
<<
cmd
<<
" "
<<
op1
<<
" "
<<
op2
<<
" "
<<
op3
<<
endl
;
append
({
cmd
,
op1
,
op2
,
op3
});
}
void
append
(
vector
<
string
>
ops
)
{
static
const
char
*
const
delimiters
=
"
\t
,,,,"
;
assert
(
ops
.
size
()
<
6
);
while
(
ops
.
size
()
&&
ops
.
back
().
empty
())
ops
.
pop_back
();
buf
<<
"
\t
"
;
for
(
uint
i
=
0
;
i
<
ops
.
size
();
i
++
)
{
buf
<<
delimiters
[
i
]
<<
ops
[
i
];
}
buf
<<
endl
;
}
string
getBlockLabelText
(
const
QuadruplePtr
&
q
)
{
return
getBlockLabelText
(
q
->
block
);
}
string
getBlockLabelText
(
BasicBlockPtr
&
b
)
{
auto
n
=
b
->
getName
();
if
(
n
.
empty
())
throw
runtime_error
(
"Attempt to get label text of unlabeled block"
);
return
"
\"
"
+
n
+
"
\"
"
;
}
shared_ptr
<
QLabel
>
exitLabel
;
void
generateStandardReturn
()
{
append
(
"JMP"
,
"
\"
"
+
exitLabel
->
label
+
"
\"
"
);
}
vector
<
Register
>
registersToSave
(
QCall
&
q
)
{
const
int
noRegs
=
sizeof
(
callerSavedRegisters
)
/
sizeof
(
*
callerSavedRegisters
);
bool
saved
[
noRegs
];
int
notSaved
=
noRegs
;
for
(
auto
&
i
:
saved
)
i
=
false
;
for
(
auto
&
live
:
q
.
aliveAfter
)
{
for
(
int
i
=
0
;
i
<
noRegs
;
i
++
)
{
int
r
=
callerSavedRegisters
[
i
];
if
(
!
saved
[
i
]
&&
Register
(
live
)
==
Register
(
r
))
{
saved
[
i
]
=
true
;
--
notSaved
;
}
}
if
(
notSaved
==
0
)
break
;
}
vector
<
Register
>
ret
;
for
(
int
i
=
0
;
i
<
noRegs
;
i
++
)
{
if
(
saved
[
i
])
ret
.
emplace_back
(
callerSavedRegisters
[
i
]);
}
return
ret
;
}
};
...
...
src/codeGen/BasicBlock.h
View file @
459ffddf
...
...
@@ -50,7 +50,7 @@ public:
void
addPhi
(
const
BasicBlockPtr
&
blk
,
const
VariablePtr
&
local
,
VariablePtr
remote
)
{
assert
(
blk
&&
local
&&
remote
);
assert
(
local
->
info
&&
!
local
->
info
->
isInstanceVariable
());
assert
(
!
local
->
info
||
!
local
->
info
->
isInstanceVariable
());
auto
&
phiMap
=
findPhi
(
blk
);
phiMap
[
local
]
=
std
::
move
(
remote
);
}
...
...
src/codeGen/Quadruple.h
View file @
459ffddf
...
...
@@ -9,9 +9,9 @@
using
namespace
std
;
class
Compiler
;
static
const
std
::
string
opNames
[]
=
{
"_U"
,
"
-"
,
"!"
,
"
"
,
"_UE"
,
static
const
std
::
string
opNames
[]
=
{
"_U"
,
"
!"
,
""
,
"-
"
,
"_UE"
,
"_B"
,
"+"
,
"-"
,
"*"
,
"/"
,
"%"
,
"&"
,
"|"
,
"^"
,
"_BE"
,
"_C"
,
"<"
,
"
<="
,
"=="
,
"!="
,
">="
,
">
"
,
"_CE"
};
"_C"
,
"<"
,
"
>="
,
"<="
,
">"
,
"=="
,
"!=
"
,
"_CE"
};
class
Quadruple
:
public
enable_shared_from_this
<
Quadruple
>
{
public:
...
...
@@ -19,22 +19,35 @@ public:
public:
enum
OpType
{
UNARY
,
N
eg
,
Not
,
Copy
,
UNARY_END
,
N
ot
,
Copy
,
Neg
,
UNARY_END
,
BINARY
,
Plus
,
Minus
,
Mul
,
Div
,
Mod
,
And
,
Or
,
Xor
,
BINARY_END
,
CMP
,
LT
,
LE
,
EQ
,
NEQ
,
GE
,
GT
,
CMP_END
LT
,
GE
,
LE
,
GT
,
EQ
,
NEQ
,
CMP_END
};
OpType
op
;
Op
(
OpType
op
=
UNARY
)
:
op
(
op
)
{};
operator
OpType
()
const
{
return
op
;
};
Op
neg
()
const
{
if
(
op
<=
Op
::
Copy
)
return
OpType
(
UNARY
+
1
+
((
int
)(
op
-
UNARY
-
1
)
^
1
));
if
(
op
>
Op
::
CMP
)
return
OpType
(
CMP
+
1
+
((
int
)(
op
-
CMP
-
1
)
^
1
));
throw
runtime_error
(
"Invalid argument to Op::neg()"
);
};
static
OpType
kind
(
OpType
op
)
{
if
(
op
<=
UNARY_END
)
return
UNARY
;
if
(
op
<=
BINARY_END
)
return
BINARY
;
return
CMP
;
};
OpType
kind
()
const
{
return
Op
::
kind
(
*
this
);
};
static
const
std
::
string
&
name
(
OpType
op
)
{
return
opNames
[
op
];
}
...
...
@@ -71,7 +84,7 @@ public:
std
::
string
toString
()
const
override
{
return
Quadruple
::
toString
()
+
"
\t
"
+
(
loc
?
(
loc
->
name
+
" := "
)
:
""
);
}
vector
<
VariablePtr
>
definitions
()
const
override
{
auto
ret
=
Quadruple
::
definitions
();
if
(
loc
)
ret
.
emplace_back
(
loc
);
if
(
loc
&&
!
loc
->
constExpr
)
ret
.
emplace_back
(
loc
);
return
ret
;
};
};
...
...
@@ -147,13 +160,16 @@ public:
}
void
generateAsm
(
Compiler
&
c
)
override
;
};
class
QCall
;
class
QParam
:
public
Quadruple
{
public:
VariablePtr
param
;
int
num
;
QParam
(
VariablePtr
param
,
int
num
)
:
param
(
std
::
move
(
param
)),
num
(
num
)
{};
shared_ptr
<
QCall
>
call
;
QParam
(
VariablePtr
param
,
int
num
,
shared_ptr
<
QCall
>
call
=
nullptr
)
:
param
(
std
::
move
(
param
)),
num
(
num
),
call
(
std
::
move
(
call
))
{};
std
::
string
toString
()
const
override
{
if
(
num
<
0
)
{
...
...
src/codeGen/QuadrupleGenerator.cpp
View file @
459ffddf
...
...
@@ -46,10 +46,10 @@ QuadrupleGenerator::Result QuadrupleGenerator::compileFunction(FunctionInfoPtr f
for
(
const
auto
&
q
:
b
->
quads
)
{
q
->
index
=
index
++
;
if
(
auto
l
=
dynamic_pointer_cast
<
QLabel
>
(
q
))
{
if
(
!
l
->
label
.
empty
())
l
->
label
=
to_string
(
label
++
)
+
"_"
+
l
->
label
;
else
l
->
label
=
to_string
(
label
++
)
;
auto
old
=
l
->
label
;
l
->
label
=
"."
+
to_string
(
label
++
)
+
"_"
+
Compiler
::
mangleFunctionName
(
f
)
;
if
(
!
old
.
empty
())
l
->
label
+=
"_"
+
old
;
}
}
}
...
...
@@ -109,10 +109,12 @@ void QuadrupleGenerator::visitELitInt(ELitInt *p) {
void
QuadrupleGenerator
::
visitELitTrue
(
ELitTrue
*
p
)
{
lastVar
=
alloc
(
1
);
if
(
labelTrue
)
addQuad
<
QJump
>
(
labelTrue
);
}
void
QuadrupleGenerator
::
visitELitFalse
(
ELitFalse
*
p
)
{
lastVar
=
alloc
(
0
);
if
(
labelFalse
)
addQuad
<
QJump
>
(
labelFalse
);
}
void
QuadrupleGenerator
::
visitEString
(
EString
*
p
)
{
...
...
@@ -128,12 +130,20 @@ void QuadrupleGenerator::visitNeg(Neg *p) {
auto
var
=
evalExpr
(
p
->
expr_
);
lastVar
=
alloc
();
addQuad
<
QAssign
>
(
lastVar
,
Op
::
Neg
,
var
);
if
((
lastVar
->
constExpr
=
var
->
constExpr
))
{
lastVar
->
val
=
-
var
->
val
;
}
}
void
QuadrupleGenerator
::
visitNot
(
Not
*
p
)
{
swap
(
labelTrue
,
labelFalse
);
auto
var
=
evalExpr
(
p
->
expr_
);
swap
(
labelTrue
,
labelFalse
);
lastVar
=
alloc
();
addQuad
<
QAssign
>
(
lastVar
,
Op
::
Not
,
var
);
if
((
lastVar
->
constExpr
=
var
->
constExpr
))
{
lastVar
->
val
=
!
var
->
val
;
}
}
void
QuadrupleGenerator
::
visitEMul
(
EMul
*
p
)
{
...
...
@@ -142,6 +152,16 @@ void QuadrupleGenerator::visitEMul(EMul *p) {
lastVar
=
alloc
();
p
->
mulop_
->
accept
(
this
);
addQuad
<
QAssign
>
(
lastVar
,
l
,
op
,
r
);
if
((
lastVar
->
constExpr
=
l
->
constExpr
&&
r
->
constExpr
))
{
if
(
op
==
Op
::
Mul
)
lastVar
->
val
=
l
->
val
*
r
->
val
;
else
if
(
r
->
val
==
0
)
throw
ParseError
(
"Division by 0"
,
p
);
else
if
(
op
==
Op
::
Div
)
lastVar
->
val
=
l
->
val
/
r
->
val
;
else
if
(
op
==
Op
::
Mod
)
lastVar
->
val
=
l
->
val
%
r
->
val
;
}
}
void
QuadrupleGenerator
::
visitEAdd
(
EAdd
*
p
)
{
...
...
@@ -150,48 +170,120 @@ void QuadrupleGenerator::visitEAdd(EAdd *p) {
lastVar
=
alloc
();
p
->
addop_
->
accept
(
this
);
addQuad
<
QAssign
>
(
lastVar
,
l
,
op
,
r
);
if
((
lastVar
->
constExpr
=
l
->
constExpr
&&
r
->
constExpr
))
{
if
(
op
==
Op
::
Minus
)
lastVar
->
val
=
l
->
val
-
r
->
val
;
else
if
(
op
==
Op
::
Plus
)
lastVar
->
val
=
l
->
val
+
r
->
val
;
}
}
void
QuadrupleGenerator
::
visitERel
(
ERel
*
p
)
{
auto
l
=
eval
Expr
(
p
->
expr_1
);
auto
r
=
eval
Expr
(
p
->
expr_2
);
auto
l
=
eval
Jump
(
p
->
expr_1
,
nullptr
,
nullptr
);
auto
r
=
eval
Jump
(
p
->
expr_2
,
nullptr
,
nullptr
);
lastVar
=
alloc
();
p
->
relop_
->
accept
(
this
);
addQuad
<
QAssign
>
(
lastVar
,
l
,
op
,
r
);
if
((
lastVar
->
constExpr
=
l
->
constExpr
&&
r
->
constExpr
))
{
if
(
op
==
Op
::
LT
)
lastVar
->
val
=
l
->
val
<
r
->
val
;
else
if
(
op
==
Op
::
LE
)
lastVar
->
val
=
l
->
val
<=
r
->
val
;
else
if
(
op
==
Op
::
EQ
)
lastVar
->
val
=
l
->
val
==
r
->
val
;
else
if
(
op
==
Op
::
NEQ
)
lastVar
->
val
=
l
->
val
!=
r
->
val
;
else
if
(
op
==
Op
::
GE
)
lastVar
->
val
=
l
->
val
>=
r
->
val
;
else
if
(
op
==
Op
::
GT
)
lastVar
->
val
=
l
->
val
>
r
->
val
;
addQuad
<
QAssign
>
(
lastVar
,
l
,
op
,
r
);
}
addLastVarCondJump
(
l
,
op
,
r
);
}
void
QuadrupleGenerator
::
visitEAnd
(
EAnd
*
p
)
{
auto
l
=
evalExpr
(
p
->
expr_1
);
auto
labelLeft
=
make_shared
<
QLabel
>
(
"use_left"
);
auto
labelAfter
=
make_shared
<
QLabel
>
(
"end_and"
);
addQuad
<
QJumpCond
>
(
labelLeft
,
Op
::
Not
,
l
);
auto
r
=
evalExpr
(
p
->
expr_2
);
lastVar
=
alloc
();
addQuad
<
QAssign
>
(
lastVar
,
Op
::
Copy
,
r
);
addQuad
<
QJump
>
(
labelAfter
);
addQuad
(
labelLeft
);
addQuad
<
QAssign
>
(
lastVar
,
Op
::
Copy
,
alloc
(
0
));
addQuad
(
labelAfter
);
auto
labelAfter
=
make_shared
<
QLabel
>
(
"and_else"
);
auto
l
=
evalJump
(
p
->
expr_1
,
nullptr
,
labelFalse
);
if
(
!
l
)
return
;
if
(
l
->
constExpr
)
{
lastVar
=
l
->
val
?
evalJump
(
p
->
expr_2
,
labelTrue
,
labelFalse
)
:
l
;
// jest git skoczymy pozniej bo to constexpr
return
;
}
else
{
auto
leftValBlock
=
block
;
auto
llq
=
make_shared
<
QJumpCond
>
(
labelFalse
?
labelFalse
:
labelAfter
,
Op
::
Not
,
l
);
addQuad
(
llq
);
flushBasicBlock
();
leftValBlock
->
append
(
block
);
auto
r
=
evalJump
(
p
->
expr_2
,
labelTrue
,
labelFalse
);
if
(
!
r
||
r
->
constExpr
)
{
assert
(
leftValBlock
->
quads
.
back
()
==
llq
);
leftValBlock
->
quads
.
pop_back
();
// could merge basic blocks now, but why bother
if
(
r
)
{
lastVar
=
r
->
val
?
l
:
r
;
}
}
else
{
auto
rightValBlock
=
block
;
flushBasicBlock
();
addQuad
(
labelAfter
);
rightValBlock
->
append
(
block
);
leftValBlock
->
append
(
block
);
if
(
!
labelTrue
||
!
labelFalse
)
{
lastVar
=
alloc
();
block
->
addPhi
(
rightValBlock
,
lastVar
,
r
);
block
->
addPhi
(
leftValBlock
,
lastVar
,
l
);
}
else
{
lastVar
=
nullptr
;
}
}
}
}
void
QuadrupleGenerator
::
visitEOr
(
EOr
*
p
)
{
auto
l
=
evalExpr
(
p
->
expr_1
);
auto
labelLeft
=
make_shared
<
QLabel
>
(
"use_left"
);
auto
labelAfter
=
make_shared
<
QLabel
>
(
"end_or"
);
addQuad
<
QJumpCond
>
(
labelLeft
,
Op
::
Copy
,
l
);
auto
r
=
evalExpr
(
p
->
expr_2
);
lastVar
=
alloc
();
addQuad
<
QAssign
>
(
lastVar
,
Op
::
Copy
,
r
);
addQuad
<
QJump
>
(
labelAfter
);
addQuad
(
labelLeft
);
addQuad
<
QAssign
>
(
lastVar
,
Op
::
Copy
,
alloc
(
1
));
addQuad
(
labelAfter
);
auto
labelAfter
=
make_shared
<
QLabel
>
(
"or_else"
);
auto
l
=
evalJump
(
p
->
expr_1
,
labelTrue
,
nullptr
);
if
(
!
l
)
return
;
if
(
l
->
constExpr
)
{
lastVar
=
l
->
val
?
l
:
evalJump
(
p
->
expr_2
,
labelTrue
,
labelFalse
);
// jest git skoczymy pozniej bo to constexpr
return
;
}
else
{
auto
leftValBlock
=
block
;
auto
llq
=
make_shared
<
QJumpCond
>
(
labelTrue
?
labelTrue
:
labelAfter
,
Op
::
Copy
,
l
);
addQuad
(
llq
);
flushBasicBlock
();
leftValBlock
->
append
(
block
);
auto
r
=
evalExpr
(
p
->
expr_2
);
if
(
!
r
)
return
;
if
(
r
->
constExpr
)
{
assert
(
leftValBlock
->
quads
.
back
()
==
llq
);
leftValBlock
->
quads
.
pop_back
();
// could merge basic blocks now, but why bother
lastVar
=
r
->
val
?
r
:
l
;
}
else
{
auto
rightValBlock
=
block
;
flushBasicBlock
();
addQuad
(
labelAfter
);
rightValBlock
->
append
(
block
);
leftValBlock
->
append
(
block
);
if
(
!
labelTrue
||
!
labelFalse
)
{
lastVar
=
alloc
();
block
->
addPhi
(
rightValBlock
,
lastVar
,
r
);
block
->
addPhi
(
leftValBlock
,
lastVar
,
l
);
}
else
{
lastVar
=
nullptr
;
}
}
}
}
/// complex extensions
...
...
@@ -219,6 +311,10 @@ void QuadrupleGenerator::visitEIndexAcc(EIndexAcc *p) {
}
auto
quad
=
make_shared
<
QAccess
>
(
lastVar
,
lhs
,
index
,
4
,
0
);
addQuad
(
quad
);
Bool
b
;
if
(
type
->
type_
->
isEqual
(
&
b
))
{
addLastVarCondJump
(
nullptr
,
Op
::
Copy
,
lastVar
);
}
}
void
QuadrupleGenerator
::
visitEClsMmbr
(
EClsMmbr
*
p
)
{
...
...
@@ -240,6 +336,10 @@ void QuadrupleGenerator::visitEClsMmbr(EClsMmbr *p) {
auto
quad
=
make_shared
<
QAccess
>
(
lastVar
,
l
,
nullptr
,
0
,
offset
);
addQuad
(
quad
);
}
Bool
b
;
if
(
var
->
type
->
isEqual
(
&
b
))
{
addLastVarCondJump
(
nullptr
,
Op
::
Copy
,
lastVar
);
}
}
void
QuadrupleGenerator
::
visitEApp
(
EApp
*
p
)
{
...
...
@@ -270,18 +370,24 @@ void QuadrupleGenerator::visitEApp(EApp *p) {
throw
ParseError
(
"Unimplemented EApp instantiation (neither EClsMmbr nor EVar"
,
p
);
}
int
i
=
1
;
auto
call
=
make_shared
<
QCall
>
(
lastVar
,
info
,
p
->
listexpr_
->
size
(),
self
);
int
i
=
0
;
for
(
auto
param
:
*
p
->
listexpr_
)
{
auto
var
=
evalExpr
(
param
);
addQuad
<
QParam
>
(
var
,
i
++
);
addQuad
<
QParam
>
(
var
,
++
i
,
call
);
}
if
(
self
)
{
addQuad
<
QParam
>
(
self
,
0
);
addQuad
<
QParam
>
(
self
,
0
,
call
);
}
lastVar
=
alloc
();
addQuad
<
QCall
>
(
lastVar
,
info
,
i
,
self
);
addQuad
(
call
);
Bool
b
;
if
(
info
->
type
->
isEqual
(
&
b
))
{
addLastVarCondJump
(
nullptr
,
Op
::
Copy
,
lastVar
);
}
}
void
QuadrupleGenerator
::
visitENewArray
(
ENewArray
*
p
)
{
...
...
@@ -387,17 +493,16 @@ void QuadrupleGenerator::visitCondElse(CondElse *p) {
}
void
QuadrupleGenerator
::
compileCond
(
Expr
*
expr_
,
Stmt
*
stmt_1
,
Stmt
*
stmt_2
)
{
// TODO: stmty nie składają się z jednego bloku tylko z wielu
auto
elseBranch
=
make_shared
<
QLabel
>
(
"if_else"
);
auto
after
=
make_shared
<
QLabel
>
(
"end_else"
);
auto
ifBranch
=
make_shared
<
QLabel
>
(
"if_true"
);
auto
var
=
evalExpr
(
expr_
);
evalJump
(
expr_
,
ifBranch
,
elseBranch
);
addQuad
<
QJumpCond
>
(
elseBranch
,
Op
::
Not
,
var
);
auto
beforeBlock
=
flushBasicBlock
();
// possible jump -> else
auto
envIf
=
captureEnv
(),
envElse
=
envIf
;
auto
stmtIfFirstBlock
=
block
;
addQuad
<
QLabel
>
(
"if_true"
);
addQuad
(
ifBranch
);
stmt_1
->
accept
(
this
);
addQuad
<
QJump
>
(
after
);
auto
stmtIfLastBlock
=
flushBasicBlock
();
// jump -> after
...
...
src/codeGen/QuadrupleGenerator.h
View file @
459ffddf
...
...
@@ -30,6 +30,7 @@ private:
VariablePtr
lastVar
;
int
lineno
;
shared_ptr
<
Scope
>
scope
;
shared_ptr
<
QLabel
>
labelTrue
,
labelFalse
;
VariablePtr
evalLVal
(
Visitable
*
expr
)
{
auto
info
=
evalExpr
(
expr
)
->
info
;
...
...
@@ -55,6 +56,17 @@ private:
return
ret
;
}
VariablePtr
evalJump
(
Visitable
*
expr
,
shared_ptr
<
QLabel
>
tLabel
,
shared_ptr
<
QLabel
>
fLabel
)
{
if
(
!
expr
)
throw
runtime_error
(
"No expr to eval"
);
lineno
=
expr
->
lineno
;
swap
(
labelTrue
,
tLabel
);
swap
(
labelFalse
,
fLabel
);
auto
ret
=
evalExpr
(
expr
);
swap
(
labelTrue
,
tLabel
);
swap
(
labelFalse
,
fLabel
);
return
ret
;
}
VariablePtr
alloc
(
const
VarInfoPtr
&
info
)
{
if
(
info
->
loc
)
{
return
info
->
loc
;
...
...
@@ -84,6 +96,22 @@ private:
return
quad
;
}
void
addLastVarCondJump
(
const
VariablePtr
&
l
,
Quadruple
::
Op
op
,
const
VariablePtr
&
r
)
{
if
(
labelTrue
&&
labelFalse
)
{
addQuad
<
QJumpCond
>
(
labelTrue
,
l
,
op
,
r
);
addQuad
<
QAssign
>
(
lastVar
,
l
,
op
,
r
);
addQuad
<
QJump
>
(
labelFalse
);
return
;
}
else
if
(
labelTrue
)
{
addQuad
<
QJumpCond
>
(
labelTrue
,
l
,
op
,
r
);
lastVar
=
alloc
(
0
);
}
else
if
(
labelFalse
)
{
addQuad
<
QJumpCond
>
(
labelFalse
,
l
,
op
.
neg
(),
r
);
lastVar
=
alloc
(
1
);
}
else
return
;
addQuad
<
QAssign
>
(
lastVar
,
l
,
op
,
r
);
}
QuadruplePtr
lastQuad
;
BasicBlockPtr
newBlock
()
{
...
...
src/codeGen/RegisterAllocator.cpp
View file @
459ffddf
...
...
@@ -104,7 +104,7 @@ void RegisterAllocator::buildGraph() {
if
(
v
.
second
==
-
1
)
{
gNumSpill
++
;
}
else
{
v
.
first
->
name
+=
"-r"
+
to_string
(
v
.
second
);
v
.
first
->
name
+=
"-r"
+
to_string
(
v
.
second
+
2
);
}
}
for
(
auto
&
v
:
g2
.
getAllocation
())
{
...
...
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