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
Show 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
...
@@ -3,14 +3,14 @@ CCFLAGS=-g -W -Wall -O0 -std=c++2a -Wno-unused-parameter
.PHONY
:
clean distclean
.PHONY
:
clean distclean
all
:
latc
all
:
latc
_x86
clean
:
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
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..."
@
echo
"Linking latc
_x86
..."
${
CC
}
${
CCFLAGS
}
$^
-lstdc
++fs
-o
latc
${
CC
}
${
CCFLAGS
}
$^
-lstdc
++fs
-o
latc
_x86
Absyn.o
:
src/Absyn.cpp src/Absyn.h
Absyn.o
:
src/Absyn.cpp src/Absyn.h
${
CC
}
${
CCFLAGS
}
-c
src/Absyn.cpp
${
CC
}
${
CCFLAGS
}
-c
src/Absyn.cpp
...
@@ -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 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
${
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
...
...
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:
...
@@ -38,6 +38,13 @@ public:
void
generateQJump
(
QJump
&
q
);
void
generateQJump
(
QJump
&
q
);
void
generateQAssign
(
QAssign
&
q
);
void
generateQAssign
(
QAssign
&
q
);
void
generateQLabel
(
QLabel
&
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:
private:
std
::
filesystem
::
path
file
;
std
::
filesystem
::
path
file
;
std
::
stringstream
buf
;
std
::
stringstream
buf
;
...
@@ -52,7 +59,14 @@ private:
...
@@ -52,7 +59,14 @@ private:
class
Register
{
class
Register
{
public:
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
(
int
n
)
{
name
=
Compiler
::
regs
[
n
];
}
Register
(
const
VariablePtr
&
v
)
{
name
=
Compiler
::
regs
[
v
->
registerColor
+
1
];
}
Register
(
const
VariablePtr
&
v
)
{
name
=
Compiler
::
regs
[
v
->
registerColor
+
1
];
}
string
name
;
string
name
;
...
@@ -61,16 +75,12 @@ private:
...
@@ -61,16 +75,12 @@ private:
bool
operator
!=
(
const
Register
&
other
)
const
{
return
name
!=
other
.
name
;
}
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
);
string
getRef
(
VariablePtr
&
v
);
static
const
char
*
const
regs
[
6
];
static
const
char
*
const
regs
[
6
];
static
const
int
callerSavedRegisters
[
2
];
static
const
int
calleeSavedRegisters
[
3
];
static
string
getOpName
(
Quadruple
::
Op
op
)
{
static
string
getOpName
(
Quadruple
::
Op
op
)
{
switch
(
op
.
op
)
{
switch
(
op
.
op
)
{
...
@@ -79,10 +89,12 @@ private:
...
@@ -79,10 +89,12 @@ private:
case
Op
:
:
Mul
:
return
"IMULL"
;
case
Op
:
:
Mul
:
return
"IMULL"
;
case
Op
:
:
Div
:
case
Op
:
:
Div
:
case
Op
:
:
Mod
:
throw
runtime_error
(
"Impossible to handle division with default"
);
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
:
:
LT
:
return
"SETL"
;
case
Op
:
:
LE
:
return
"SETLE"
;
case
Op
:
:
LE
:
return
"SETLE"
;
case
Op
:
:
EQ
:
return
"SET
E
"
;
case
Op
:
:
EQ
:
return
"SET
Z
"
;
case
Op
:
:
NEQ
:
return
"SETN
E
"
;
case
Op
:
:
NEQ
:
return
"SETN
Z
"
;
case
Op
:
:
GE
:
return
"SETGE"
;
case
Op
:
:
GE
:
return
"SETGE"
;
case
Op
:
:
GT
:
return
"SETG"
;
case
Op
:
:
GT
:
return
"SETG"
;
default:
return
"Op"
+
to_string
(
op
.
op
)
+
"?"
;
default:
return
"Op"
+
to_string
(
op
.
op
)
+
"?"
;
...
@@ -121,7 +133,57 @@ private:
...
@@ -121,7 +133,57 @@ private:
}
}
void
append
(
string
cmd
,
string
op1
=
""
,
string
op2
=
""
,
string
op3
=
""
)
{
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:
...
@@ -50,7 +50,7 @@ public:
void
addPhi
(
const
BasicBlockPtr
&
blk
,
const
VariablePtr
&
local
,
VariablePtr
remote
)
{
void
addPhi
(
const
BasicBlockPtr
&
blk
,
const
VariablePtr
&
local
,
VariablePtr
remote
)
{
assert
(
blk
&&
local
&&
remote
);
assert
(
blk
&&
local
&&
remote
);
assert
(
local
->
info
&&
!
local
->
info
->
isInstanceVariable
());
assert
(
!
local
->
info
||
!
local
->
info
->
isInstanceVariable
());
auto
&
phiMap
=
findPhi
(
blk
);
auto
&
phiMap
=
findPhi
(
blk
);
phiMap
[
local
]
=
std
::
move
(
remote
);
phiMap
[
local
]
=
std
::
move
(
remote
);
}
}
...
...
src/codeGen/Quadruple.h
View file @
459ffddf
...
@@ -9,9 +9,9 @@
...
@@ -9,9 +9,9 @@
using
namespace
std
;
using
namespace
std
;
class
Compiler
;
class
Compiler
;
static
const
std
::
string
opNames
[]
=
{
"_U"
,
"
-"
,
"!"
,
"
"
,
"_UE"
,
static
const
std
::
string
opNames
[]
=
{
"_U"
,
"
!"
,
""
,
"-
"
,
"_UE"
,
"_B"
,
"+"
,
"-"
,
"*"
,
"/"
,
"%"
,
"&"
,
"|"
,
"^"
,
"_BE"
,
"_B"
,
"+"
,
"-"
,
"*"
,
"/"
,
"%"
,
"&"
,
"|"
,
"^"
,
"_BE"
,
"_C"
,
"<"
,
"
<="
,
"=="
,
"!="
,
">="
,
">
"
,
"_CE"
};
"_C"
,
"<"
,
"
>="
,
"<="
,
">"
,
"=="
,
"!=
"
,
"_CE"
};
class
Quadruple
:
public
enable_shared_from_this
<
Quadruple
>
{
class
Quadruple
:
public
enable_shared_from_this
<
Quadruple
>
{
public:
public:
...
@@ -19,22 +19,35 @@ public:
...
@@ -19,22 +19,35 @@ public:
public:
public:
enum
OpType
{
enum
OpType
{
UNARY
,
UNARY
,
N
eg
,
Not
,
Copy
,
UNARY_END
,
N
ot
,
Copy
,
Neg
,
UNARY_END
,
BINARY
,
BINARY
,
Plus
,
Minus
,
Mul
,
Div
,
Mod
,
And
,
Or
,
Xor
,
BINARY_END
,
Plus
,
Minus
,
Mul
,
Div
,
Mod
,
And
,
Or
,
Xor
,
BINARY_END
,
CMP
,
CMP
,
LT
,
LE
,
EQ
,
NEQ
,
GE
,
GT
,
CMP_END
LT
,
GE
,
LE
,
GT
,
EQ
,
NEQ
,
CMP_END
};
};
OpType
op
;
OpType
op
;
Op
(
OpType
op
=
UNARY
)
:
op
(
op
)
{};
Op
(
OpType
op
=
UNARY
)
:
op
(
op
)
{};
operator
OpType
()
const
{
return
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
)
{
static
OpType
kind
(
OpType
op
)
{
if
(
op
<=
UNARY_END
)
return
UNARY
;
if
(
op
<=
UNARY_END
)
return
UNARY
;
if
(
op
<=
BINARY_END
)
return
BINARY
;
if
(
op
<=
BINARY_END
)
return
BINARY
;
return
CMP
;
return
CMP
;
};
};
OpType
kind
()
const
{
return
Op
::
kind
(
*
this
);
};
static
const
std
::
string
&
name
(
OpType
op
)
{
static
const
std
::
string
&
name
(
OpType
op
)
{
return
opNames
[
op
];
return
opNames
[
op
];
}
}
...
@@ -71,7 +84,7 @@ public:
...
@@ -71,7 +84,7 @@ public:
std
::
string
toString
()
const
override
{
return
Quadruple
::
toString
()
+
"
\t
"
+
(
loc
?
(
loc
->
name
+
" := "
)
:
""
);
}
std
::
string
toString
()
const
override
{
return
Quadruple
::
toString
()
+
"
\t
"
+
(
loc
?
(
loc
->
name
+
" := "
)
:
""
);
}
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
&&
!
loc
->
constExpr
)
ret
.
emplace_back
(
loc
);
return
ret
;
return
ret
;
};
};
};
};
...
@@ -147,13 +160,16 @@ public:
...
@@ -147,13 +160,16 @@ public:
}
}
void
generateAsm
(
Compiler
&
c
)
override
;
void
generateAsm
(
Compiler
&
c
)
override
;
};
};
class
QCall
;
class
QParam
:
public
Quadruple
{
class
QParam
:
public
Quadruple
{
public:
public:
VariablePtr
param
;
VariablePtr
param
;
int
num
;
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
{
std
::
string
toString
()
const
override
{
if
(
num
<
0
)
{
if
(
num
<
0
)
{
...
...
src/codeGen/QuadrupleGenerator.cpp
View file @
459ffddf
...
@@ -46,10 +46,10 @@ QuadrupleGenerator::Result QuadrupleGenerator::compileFunction(FunctionInfoPtr f
...
@@ -46,10 +46,10 @@ QuadrupleGenerator::Result QuadrupleGenerator::compileFunction(FunctionInfoPtr f
for
(
const
auto
&
q
:
b
->
quads
)
{
for
(
const
auto
&
q
:
b
->
quads
)
{
q
->
index
=
index
++
;
q
->
index
=
index
++
;
if
(
auto
l
=
dynamic_pointer_cast
<
QLabel
>
(
q
))
{
if
(
auto
l
=
dynamic_pointer_cast
<
QLabel
>
(
q
))
{
if
(
!
l
->
label
.
empty
())
auto
old
=
l
->
label
;
l
->
label
=
to_string
(
label
++
)
+
"_"
+
l
->
label
;
l
->
label
=
"."
+
to_string
(
label
++
)
+
"_"
+
Compiler
::
mangleFunctionName
(
f
)
;
else
if
(
!
old
.
empty
())
l
->
label
=
to_string
(
label
++
)
;
l
->
label
+=
"_"
+
old
;
}
}
}
}
}
}
...
@@ -109,10 +109,12 @@ void QuadrupleGenerator::visitELitInt(ELitInt *p) {
...
@@ -109,10 +109,12 @@ void QuadrupleGenerator::visitELitInt(ELitInt *p) {
void
QuadrupleGenerator
::
visitELitTrue
(
ELitTrue
*
p
)
{
void
QuadrupleGenerator
::
visitELitTrue
(
ELitTrue
*
p
)
{
lastVar
=
alloc
(
1
);
lastVar
=
alloc
(
1
);
if
(
labelTrue
)
addQuad
<
QJump
>
(
labelTrue
);
}
}
void
QuadrupleGenerator
::
visitELitFalse
(
ELitFalse
*
p
)
{
void
QuadrupleGenerator
::
visitELitFalse
(
ELitFalse
*
p
)
{
lastVar
=
alloc
(
0
);
lastVar
=
alloc
(
0
);
if
(
labelFalse
)
addQuad
<
QJump
>
(
labelFalse
);
}
}
void
QuadrupleGenerator
::
visitEString
(
EString
*
p
)
{
void
QuadrupleGenerator
::
visitEString
(
EString
*
p
)
{
...
@@ -128,12 +130,20 @@ void QuadrupleGenerator::visitNeg(Neg *p) {
...
@@ -128,12 +130,20 @@ void QuadrupleGenerator::visitNeg(Neg *p) {
auto
var
=
evalExpr
(
p
->
expr_
);
auto
var
=
evalExpr
(
p
->
expr_
);
lastVar
=
alloc
();
lastVar
=
alloc
();
addQuad
<
QAssign
>
(
lastVar
,
Op
::
Neg
,
var
);
addQuad
<
QAssign
>
(
lastVar
,
Op
::
Neg
,
var
);
if
((
lastVar
->
constExpr
=
var
->
constExpr
))
{
lastVar
->
val
=
-
var
->
val
;
}
}
}
void
QuadrupleGenerator
::
visitNot
(
Not
*
p
)
{
void
QuadrupleGenerator
::
visitNot
(
Not
*
p
)
{
swap
(
labelTrue
,
labelFalse
);
auto
var
=
evalExpr
(
p
->
expr_
);
auto
var
=
evalExpr
(
p
->
expr_
);
swap
(
labelTrue
,
labelFalse
);
lastVar
=
alloc
();
lastVar
=
alloc
();
addQuad
<
QAssign
>
(
lastVar
,
Op
::
Not
,
var
);
addQuad
<
QAssign
>
(
lastVar
,
Op
::
Not
,
var
);
if
((
lastVar
->
constExpr
=
var
->
constExpr
))
{
lastVar
->
val
=
!
var
->
val
;
}
}
}
void
QuadrupleGenerator
::
visitEMul
(
EMul
*
p
)
{
void
QuadrupleGenerator
::
visitEMul
(
EMul
*
p
)
{
...
@@ -142,6 +152,16 @@ void QuadrupleGenerator::visitEMul(EMul *p) {
...
@@ -142,6 +152,16 @@ void QuadrupleGenerator::visitEMul(EMul *p) {
lastVar
=
alloc
();
lastVar
=
alloc
();
p
->
mulop_
->
accept
(
this
);
p
->
mulop_
->
accept
(
this
);
addQuad
<
QAssign
>
(
lastVar
,
l
,
op
,
r
);
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
)
{
void
QuadrupleGenerator
::
visitEAdd
(
EAdd
*
p
)
{
...
@@ -150,48 +170,120 @@ void QuadrupleGenerator::visitEAdd(EAdd *p) {
...
@@ -150,48 +170,120 @@ void QuadrupleGenerator::visitEAdd(EAdd *p) {
lastVar
=
alloc
();
lastVar
=
alloc
();
p
->
addop_
->
accept
(
this
);
p
->
addop_
->
accept
(
this
);
addQuad
<
QAssign
>
(
lastVar
,
l
,
op
,
r
);
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
)
{
void
QuadrupleGenerator
::
visitERel
(
ERel
*
p
)
{
auto
l
=
eval
Expr
(
p
->
expr_1
);
auto
l
=
eval
Jump
(
p
->
expr_1
,
nullptr
,
nullptr
);
auto
r
=
eval
Expr
(
p
->
expr_2
);
auto
r
=
eval
Jump
(
p
->
expr_2
,
nullptr
,
nullptr
);
lastVar
=
alloc
();
lastVar
=
alloc
();
p
->
relop_
->
accept
(
this
);
p
->
relop_
->
accept
(
this
);
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
);
addQuad
<
QAssign
>
(
lastVar
,
l
,
op
,
r
);
}
addLastVarCondJump
(
l
,
op
,
r
);
}
}
void
QuadrupleGenerator
::
visitEAnd
(
EAnd
*
p
)
{
void
QuadrupleGenerator
::
visitEAnd
(
EAnd
*
p
)
{
auto
l
=
evalExpr
(
p
->
expr_1
);
auto
labelAfter
=
make_shared
<
QLabel
>
(
"and_else"
);
auto
labelLeft
=
make_shared
<
QLabel
>
(
"use_left"
);
auto
l
=
evalJump
(
p
->
expr_1
,
nullptr
,
labelFalse
);
auto
labelAfter
=
make_shared
<
QLabel
>
(
"end_and"
);
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
);
addQuad
<
QJumpCond
>
(
labelLeft
,
Op
::
Not
,
l
);
auto
r
=
evalJump
(
p
->
expr_2
,
labelTrue
,
labelFalse
);
auto
r
=
evalExpr
(
p
->
expr_2
);
lastVar
=
alloc
();
addQuad
<
QAssign
>
(
lastVar
,
Op
::
Copy
,
r
);
if
(
!
r
||
r
->
constExpr
)
{
addQuad
<
QJump
>
(
labelAfter
);
assert
(
leftValBlock
->
quads
.
back
()
==
llq
);
addQuad
(
labelLeft
);
leftValBlock
->
quads
.
pop_back
();
addQuad
<
QAssign
>
(
lastVar
,
Op
::
Copy
,
alloc
(
0
));
// could merge basic blocks now, but why bother
if
(
r
)
{
lastVar
=
r
->
val
?
l
:
r
;
}
}
else
{
auto
rightValBlock
=
block
;
flushBasicBlock
();
addQuad
(
labelAfter
);
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
)
{
void
QuadrupleGenerator
::
visitEOr
(
EOr
*
p
)
{
auto
l
=
evalExpr
(
p
->
expr_1
);
auto
labelAfter
=
make_shared
<
QLabel
>
(
"or_else"
);
auto
labelLeft
=
make_shared
<
QLabel
>
(
"use_left"
);
auto
l
=
evalJump
(
p
->
expr_1
,
labelTrue
,
nullptr
);
auto
labelAfter
=
make_shared
<
QLabel
>
(
"end_or"
);
if
(
!
l
)
return
;
if
(
l
->
constExpr
)
{
addQuad
<
QJumpCond
>
(
labelLeft
,
Op
::
Copy
,
l
);
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
);
auto
r
=
evalExpr
(
p
->
expr_2
);
lastVar
=
alloc
()
;
if
(
!
r
)
return
;
addQuad
<
QAssign
>
(
lastVar
,
Op
::
Copy
,
r
);
if
(
r
->
constExpr
)
{
addQuad
<
QJump
>
(
labelAfter
);
assert
(
leftValBlock
->
quads
.
back
()
==
llq
);
addQuad
(
labelLeft
);
leftValBlock
->
quads
.
pop_back
();
addQuad
<
QAssign
>
(
lastVar
,
Op
::
Copy
,
alloc
(
1
));
// could merge basic blocks now, but why bother
lastVar
=
r
->
val
?
r
:
l
;
}
else
{
auto
rightValBlock
=
block
;
flushBasicBlock
();
addQuad
(
labelAfter
);
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
/// complex extensions
...
@@ -219,6 +311,10 @@ void QuadrupleGenerator::visitEIndexAcc(EIndexAcc *p) {
...
@@ -219,6 +311,10 @@ void QuadrupleGenerator::visitEIndexAcc(EIndexAcc *p) {
}
}
auto
quad
=
make_shared
<
QAccess
>
(
lastVar
,
lhs
,
index
,
4
,
0
);
auto
quad
=
make_shared
<
QAccess
>
(
lastVar
,
lhs
,
index
,
4
,
0
);
addQuad
(
quad
);
addQuad
(
quad
);
Bool
b
;
if
(
type
->
type_
->
isEqual
(
&
b
))
{
addLastVarCondJump
(
nullptr
,
Op
::
Copy
,
lastVar
);
}
}
}
void
QuadrupleGenerator
::
visitEClsMmbr
(
EClsMmbr
*
p
)
{
void
QuadrupleGenerator
::
visitEClsMmbr
(
EClsMmbr
*
p
)
{
...
@@ -240,6 +336,10 @@ void QuadrupleGenerator::visitEClsMmbr(EClsMmbr *p) {
...
@@ -240,6 +336,10 @@ void QuadrupleGenerator::visitEClsMmbr(EClsMmbr *p) {
auto
quad
=
make_shared
<
QAccess
>
(
lastVar
,
l
,
nullptr
,
0
,
offset
);
auto
quad
=
make_shared
<
QAccess
>
(
lastVar
,
l
,
nullptr
,
0
,
offset
);
addQuad
(
quad
);
addQuad
(
quad
);
}
}
Bool
b
;
if
(
var
->
type
->
isEqual
(
&
b
))
{
addLastVarCondJump
(
nullptr
,
Op
::
Copy
,
lastVar
);
}
}
}
void
QuadrupleGenerator
::
visitEApp
(
EApp
*
p
)
{
void
QuadrupleGenerator
::
visitEApp
(
EApp
*
p
)
{
...
@@ -270,18 +370,24 @@ void QuadrupleGenerator::visitEApp(EApp *p) {
...
@@ -270,18 +370,24 @@ void QuadrupleGenerator::visitEApp(EApp *p) {
throw
ParseError
(
"Unimplemented EApp instantiation (neither EClsMmbr nor EVar"
,
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_
)
{
for
(
auto
param
:
*
p
->
listexpr_
)
{
auto
var
=
evalExpr
(
param
);
auto
var
=
evalExpr
(
param
);
addQuad
<
QParam
>
(
var
,
i
++
);
addQuad
<
QParam
>
(
var
,
++
i
,
call
);
}
}
if
(
self
)
{
if
(
self
)
{
addQuad
<
QParam
>
(
self
,
0
);
addQuad
<
QParam
>
(
self
,
0
,
call
);
}
}
lastVar
=
alloc
();
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
)
{
void
QuadrupleGenerator
::
visitENewArray
(
ENewArray
*
p
)
{
...
@@ -387,17 +493,16 @@ void QuadrupleGenerator::visitCondElse(CondElse *p) {
...
@@ -387,17 +493,16 @@ 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
auto
elseBranch
=
make_shared
<
QLabel
>
(
"if_else"
);
auto
elseBranch
=
make_shared
<
QLabel
>
(
"if_else"
);
auto
after
=
make_shared
<
QLabel
>
(
"end_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
beforeBlock
=
flushBasicBlock
();
// possible jump -> else
auto
envIf
=
captureEnv
(),
envElse
=
envIf
;
auto
envIf
=
captureEnv
(),
envElse
=
envIf
;
auto
stmtIfFirstBlock
=
block
;
auto
stmtIfFirstBlock
=
block
;
addQuad
<
QLabel
>
(
"if_true"
);
addQuad
(
ifBranch
);
stmt_1
->
accept
(
this
);
stmt_1
->
accept
(
this
);
addQuad
<
QJump
>
(
after
);
addQuad
<
QJump
>
(
after
);
auto
stmtIfLastBlock
=
flushBasicBlock
();
// jump -> after
auto
stmtIfLastBlock
=
flushBasicBlock
();
// jump -> after
...
...
src/codeGen/QuadrupleGenerator.h
View file @
459ffddf
...
@@ -30,6 +30,7 @@ private:
...
@@ -30,6 +30,7 @@ private:
VariablePtr
lastVar
;
VariablePtr
lastVar
;
int
lineno
;
int
lineno
;
shared_ptr
<
Scope
>
scope
;
shared_ptr
<
Scope
>
scope
;
shared_ptr
<
QLabel
>
labelTrue
,
labelFalse
;
VariablePtr
evalLVal
(
Visitable
*
expr
)
{
VariablePtr
evalLVal
(
Visitable
*
expr
)
{
auto
info
=
evalExpr
(
expr
)
->
info
;
auto
info
=
evalExpr
(
expr
)
->
info
;
...
@@ -55,6 +56,17 @@ private:
...
@@ -55,6 +56,17 @@ private:
return
ret
;
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
)
{
VariablePtr
alloc
(
const
VarInfoPtr
&
info
)
{
if
(
info
->
loc
)
{
if
(
info
->
loc
)
{
return
info
->
loc
;
return
info
->
loc
;
...
@@ -84,6 +96,22 @@ private:
...
@@ -84,6 +96,22 @@ private:
return
quad
;
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
;
QuadruplePtr
lastQuad
;
BasicBlockPtr
newBlock
()
{
BasicBlockPtr
newBlock
()
{
...
...
src/codeGen/RegisterAllocator.cpp
View file @
459ffddf
...
@@ -104,7 +104,7 @@ void RegisterAllocator::buildGraph() {
...
@@ -104,7 +104,7 @@ void RegisterAllocator::buildGraph() {
if
(
v
.
second
==
-
1
)
{
if
(
v
.
second
==
-
1
)
{
gNumSpill
++
;
gNumSpill
++
;
}
else
{
}
else
{
v
.
first
->
name
+=
"-r"
+
to_string
(
v
.
second
);
v
.
first
->
name
+=
"-r"
+
to_string
(
v
.
second
+
2
);
}
}
}
}
for
(
auto
&
v
:
g2
.
getAllocation
())
{
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