eelco-visser-compiler-const.../lab/10.html

503 lines
18 KiB
HTML

<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta name="description" content="">
<meta name="author" content="Eelco Visser">
<meta name="generator" content="Jekyll v3.8.5">
<title>Lab 10: Instruction Selection</title>
<!-- <base href="/2021"> -->
<!--link rel="canonical" href="https://getbootstrap.com/docs/4.3/examples/starter-template/"-->
<link rel="icon" href="../img/logo/pl_ico2_2B3_icon.ico" type="image/x-icon">
<!-- Bootstrap core CSS -->
<!--link href="https://getbootstrap.com/docs/4.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous"-->
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
<style>
.bd-placeholder-img {
font-size: 1.125rem;
text-anchor: middle;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
@media (min-width: 768px) {
.bd-placeholder-img-lg {
font-size: 3.5rem;
}
}
</style>
<!-- Custom styles for this template -->
<link href="../css/main.css" rel="stylesheet">
<link href="../css/borders-responsive.css" rel="stylesheet">
<link rel="stylesheet" href="../css/pl.css">
</head>
<body>
<nav class="navbar navbar-expand-md navbar-dark bg-dark fixed-top">
<a class="navbar-brand" href="../index.html">
TU Delft | CS4200
</a>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarsExampleDefault" aria-controls="navbarsExampleDefault" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarsExampleDefault">
<ul class="navbar-nav mr-auto">
<li class="nav-item active">
<a class="nav-link" href="../lectures/index.html" tabindex="-1" aria-disabled="true">Lectures</a>
</li>
<li class="nav-item active">
<a class="nav-link" href="../homework/index.html" tabindex="-1" aria-disabled="true">Homework</a>
</li>
<li class="nav-item active">
<a class="nav-link" href="../project/index.html" tabindex="-1" aria-disabled="true">Project</a>
</li>
<li class="nav-item active">
<a class="nav-link" href="../news/index.html" tabindex="-1" aria-disabled="true">News</a>
</li>
<li class="nav-item active">
<a class="nav-link" href="../blog/index.html" tabindex="-1" aria-disabled="true">Blog</a>
</li>
</ul>
</div>
</nav>
<div class="container">
<div class="row">
<div class="col-sm-12 col-md-12 col-lg-12 col-xl-12">
<div class="mt-3 mb-3 pt-3 pb-3 text-dark border-top border-bottom border-grey">
<div class="text-dark font-weight-bold">
<h1>
Lab 10: Instruction Selection
</h1>
</div>
<div>
</div>
<div>
Project
</div>
<div>
November 26, 2021
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-sm-12 col-md-12 col-lg-9 border-lg-right border-grey">
<p>See the slides of <a href="../lecture/12.html">Lecture 12</a> on code generation for an approach to get started.</p>
<h3 id="objectives">Objectives</h3>
<ol>
<li>
<p>Develop tests for your compiler that explore the edge cases.</p>
</li>
<li>
<p>Define a transformation strategy that translates ChocoPy expressions to RISC-V code, including variable definitions, integer and boolean constants and operators.</p>
</li>
<li>
<p>Develop a simplification transformation that transforms expressions such that more concise code can be generated.</p>
</li>
</ol>
<h3 id="basic-compiler-pipeline">Basic Compiler Pipeline</h3>
<p>Follow the slides of <a href="../lecture/12.html">Lecture 12</a> to set up a basic compiler pipeline:</p>
<pre><code class="language-stratego:"> compile-to-rv32im-ast :: Program -&gt; RProgram
compile-to-rv32im-ast =
compile-cpy-to-cir
; compile-cir-to-rv32im
; compile-rv32im
</code></pre>
<h4 id="debugging">Debugging</h4>
<p>Use <code class="language-plaintext highlighter-rouge">debug(!msg)</code> or <code class="language-plaintext highlighter-rouge">dbg(|msg)</code> to print the current term to the console.</p>
<p>You can also debug your generated code, by creating a <code class="language-plaintext highlighter-rouge">.cpy</code> file, transforming it to an <code class="language-plaintext highlighter-rouge">.rv32im</code> file using the <code class="language-plaintext highlighter-rouge">Spoofax &gt; Generation</code> menu, and copying the generated output to the online Venus editor, where you can use the <code class="language-plaintext highlighter-rouge">Simulator</code> tab to run your code or step through each line, and inspect the memory and registers.</p>
<h3 id="from-chocopy-to-c-ir">From ChocoPy to C-IR</h3>
<p>Develop a first compilation phase to transform ChocoPy programs to an intermediate language that makes control flow explicit.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code> compile-cpy-to-cir :: Program -&gt; CProgram
compile-cpy-to-cir =
explicate-types
; desugar
; uniquify
; remove-complex-operands
; explicate-control
</code></pre></div></div>
<h4 id="explicate-types">Explicate Types</h4>
<p>A useful transformation is to type specialize the constructors of the AST, such that the analysis results are no longer needed.
That is useful when applying transformations, since preserving those annotations cannot be done for all transformations.
<strong>The following <code class="language-plaintext highlighter-rouge">explicate-types</code> transformation should be invoked on the AST before invoking the compiler transformation.</strong></p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>signature
constructors
AddInt : Exp * Exp -&gt; Exp
rules
explicate-types =
innermost(type-specialize)
type-specialize :
add@Add(e1, e2) -&gt; AddInt(e1, e2)
where &lt;get-type&gt; add =&gt; Int()
</code></pre></div></div>
<p>Note that the rules for translating integer additions should be adapted to reflect the change in constructors.</p>
<h4 id="desugar">Desugar</h4>
<p>To improve the result of code generation, it can be useful to transform the source language expression.
For example, left-associative additions may produce a better result.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code> desugar-exp :
AddInt(e1, AddInt(e2, e3)) -&gt; AddInt(AddInt(e1, e2), e3)
</code></pre></div></div>
<p>Define a transformation to <code class="language-plaintext highlighter-rouge">desugar</code> ChocoPy programs, making the task of downstream compilation easier.</p>
<p>This simplification can include constant folding, eventually.
However, do not yet include constant folding rules, since you want to test the translation of operators.
That is, your code generator should be able to translate arbitrary combinations of operators, so be prepared for the general case.</p>
<p>Think about (and try out in the online compiler!) the differences between adding integers and concatenating strings in RISC-V. In ChocoPy, they initially both use the <code class="language-plaintext highlighter-rouge">Add(...)</code> constructor, so make sure to disambiguate them into separate constructors you will later use for code generation. The same holds for other operations, but you have to think about those yourself.</p>
<h4 id="uniquify">Uniquify</h4>
<p>Define a transformation that eliminates shadowing. (See slides)</p>
<h4 id="remove-complex-operands">Remove Complex Operands</h4>
<p>To simplify instruction selection, simplify expressions to only use atomic expressions (constants or variables) creating new variables to store intermediate results.</p>
<h4 id="explicate-control-using-c-ir">Explicate Control using C-IR</h4>
<p>Use an intermediate language to explicate control.
That is, the <code class="language-plaintext highlighter-rouge">explicate-control</code> strategy translates from ChocoPy ASTs</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>signature
sorts CID CINT CProgram CBlock CLabel CTail CStmt
CType CExp CAtom CVar
constructors
: string -&gt; CID
: string -&gt; CINT
CProgram : List(CBlock) -&gt; CProgram
CBlock : CLabel * CTail -&gt; CBlock
CLabel : CID -&gt; CLabel
CReturn : CExp -&gt; CTail
CReturnNone : CTail
CSeq : CStmt * CTail -&gt; CTail
CVarDec : CVar * CType * CExp -&gt; CStmt
CAssign : CVar * CExp -&gt; CStmt
CIntT : CType
: CAtom -&gt; CExp
CMin : CAtom -&gt; CExp
CAdd : CAtom * CAtom -&gt; CExp
CMul : CAtom * CAtom -&gt; CExp
CDiv : CAtom * CAtom -&gt; CExp
CInt : CINT -&gt; CAtom
: CVar -&gt; CAtom
CVar : CID -&gt; CVar
</code></pre></div></div>
<h3 id="instruction-selection">Instruction Selection</h3>
<p>Define a transformation from C-IR to RISC-V instructions:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code> compile-cir-to-rv32im :: CProgram -&gt; RProgram
compile-cir-to-rv32im =
select-instructions-cprogram
</code></pre></div></div>
<p>The essence of this translation consists of instruction selection, i.e. mapping the high-level instructions of the intermediate language to concrete RISC-V instructions.
For example, register allocation for integer constants, variables, and addition may be defined as follows:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code> select-instrs-exp(|RArg) :: CExp -&gt; List(RLine)
select-instrs-exp(|x) :
CInt(i) -&gt; [RLi(x, &lt;cint-to-rint&gt;i)]
select-instrs-exp(|x) :
CVar(y) -&gt; [RMv(x, RVar(&lt;cid-to-string&gt;y))]
select-instrs-exp(|x) :
CAdd(y@CVar(_), z@CVar(_)) -&gt; [RAdd(x, &lt;cvar-to-rvar&gt;y, &lt;cvar-to-rvar&gt;z)]
</code></pre></div></div>
<p>Note that because expressions have been transformed to applications of operators to atomic expressions, this step does not need to invent names for intermediate results.
We use <code class="language-plaintext highlighter-rouge">RVar(x)</code> as symbolic registers in RISC-V code in order to postpone the mapping to concrete registers.</p>
<p>Define transformation rules for all operators of ChocoPy expressions.</p>
<h4 id="special-cases">Special Cases</h4>
<p>RISC-V provides specialized instructions for some operations.
For example, the <code class="language-plaintext highlighter-rouge">addi</code> instruction allows directly adding an integer constant (between -2048 and 2047) to a register.
A compiler can make use of such instructions, by detecting special patterns in the source language.
For example, the following rule, detects additions with an integer constant, and translates those to applications of <code class="language-plaintext highlighter-rouge">addi</code>, avoiding the use of an extra register.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>select-instrs-exp(|x) :
CAdd(z@CVar(_), CInt(i)) -&gt; [RAddi(x, &lt;cvar-to-rvar&gt;z, &lt;cint-to-rint&gt;i)]
with debug(!"select-instrs-exp: ")
</code></pre></div></div>
<p>Can you detect other specialized instructions and corresponding source language patterns that provide a more concise and/or faster target code?</p>
<h4 id="booleans">Booleans</h4>
<p>In ChocoPy we compile the Booleans <code class="language-plaintext highlighter-rouge">True</code> and <code class="language-plaintext highlighter-rouge">False</code> to integers in RISC-V (<code class="language-plaintext highlighter-rouge">1</code> and <code class="language-plaintext highlighter-rouge">0</code>, respectively).
Implement the Boolean operators <code class="language-plaintext highlighter-rouge">and</code>, <code class="language-plaintext highlighter-rouge">or</code> and <code class="language-plaintext highlighter-rouge">not</code>, and integer comparison operators <code class="language-plaintext highlighter-rouge">==</code>, <code class="language-plaintext highlighter-rouge">!=</code>, <code class="language-plaintext highlighter-rouge">&lt;</code>, <code class="language-plaintext highlighter-rouge">&gt;</code>, <code class="language-plaintext highlighter-rouge">&lt;=</code>, <code class="language-plaintext highlighter-rouge">&gt;=</code> (you can ignore <code class="language-plaintext highlighter-rouge">is</code> for now since it operates on objects).</p>
<p>You can make use of the online compiler, or the RISC-V instruction set to find the proper instructions in RISC-V.</p>
<!-- Also implement the ternary operator `... if ... else ...`. (See [Short-circuit Boolean operations](#shortcircuit) to get an idea on how to implement it.) -->
<h3 id="patching-risc-v-instructions">Patching RISC-V instructions</h3>
<p>Finally, we define a compiler stage that patches up the RISC-V code:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code> compile-rv32im :: RProgram -&gt; RProgram
compile-rv32im =
assign-homes
; patch-instructions
</code></pre></div></div>
<h4 id="assign-homes">Assign Homes</h4>
<p>Map symbolic registers to concrete registers.
Either by mapping variables to actual registers or by using a stack discipline.
We will look at register allocation next, so keep it simple.</p>
<h4 id="patch-instructions">Patch Instructions</h4>
<p>This is the place for any mopping up that needs to be done.</p>
</div>
<div class="col-sm-12 col-md-12 col-lg-3 col-xl-3 " >
<div class="sticky-top top70 d-none d-lg-block d-xl-block">
<div class="pb4 mb3 border-bottom border-grey ">
<nav>
<ul class="pagination justify-content-left">
<li class="page-item">
<a class="page-link" href="9.html">
&laquo;
</a>
</li>
<li class="page-item">
<a class="page-link" href="../project/index.html">
^
</a>
</li>
<li class="page-item">
<a class="page-link" href="11.html">&raquo;</a>
</li>
</ul>
</nav>
</div>
<ul id="my_toc" class="toc list-group list-group-flush d-none d-lg-block d-xl-block p-0 ml-0 mt-3">
<li class="list-group-item pl-0 ml-0 border-0 pl-0 pt-0 pb-1 pr-0 m-0 mr-3"><a href="10.html#objectives">Objectives</a></li>
<li class="list-group-item pl-0 ml-0 border-0 pl-0 pt-0 pb-1 pr-0 m-0 mr-3"><a href="10.html#basic-compiler-pipeline">Basic Compiler Pipeline</a>
<ul class="toc-sub pl-0">
<li class="list-group-item pl-0 ml-0 border-0 pl-0 pt-0 pb-1 pr-0 m-0 mr-3"><a href="10.html#debugging">Debugging</a></li>
</ul>
</li>
<li class="list-group-item pl-0 ml-0 border-0 pl-0 pt-0 pb-1 pr-0 m-0 mr-3"><a href="10.html#from-chocopy-to-c-ir">From ChocoPy to C-IR</a>
<ul class="toc-sub pl-0">
<li class="list-group-item pl-0 ml-0 border-0 pl-0 pt-0 pb-1 pr-0 m-0 mr-3"><a href="10.html#explicate-types">Explicate Types</a></li>
<li class="list-group-item pl-0 ml-0 border-0 pl-0 pt-0 pb-1 pr-0 m-0 mr-3"><a href="10.html#desugar">Desugar</a></li>
<li class="list-group-item pl-0 ml-0 border-0 pl-0 pt-0 pb-1 pr-0 m-0 mr-3"><a href="10.html#uniquify">Uniquify</a></li>
<li class="list-group-item pl-0 ml-0 border-0 pl-0 pt-0 pb-1 pr-0 m-0 mr-3"><a href="10.html#remove-complex-operands">Remove Complex Operands</a></li>
<li class="list-group-item pl-0 ml-0 border-0 pl-0 pt-0 pb-1 pr-0 m-0 mr-3"><a href="10.html#explicate-control-using-c-ir">Explicate Control using C-IR</a></li>
</ul>
</li>
<li class="list-group-item pl-0 ml-0 border-0 pl-0 pt-0 pb-1 pr-0 m-0 mr-3"><a href="10.html#instruction-selection">Instruction Selection</a>
<ul class="toc-sub pl-0">
<li class="list-group-item pl-0 ml-0 border-0 pl-0 pt-0 pb-1 pr-0 m-0 mr-3"><a href="10.html#special-cases">Special Cases</a></li>
<li class="list-group-item pl-0 ml-0 border-0 pl-0 pt-0 pb-1 pr-0 m-0 mr-3"><a href="10.html#booleans">Booleans</a></li>
</ul>
</li>
<li class="list-group-item pl-0 ml-0 border-0 pl-0 pt-0 pb-1 pr-0 m-0 mr-3"><a href="10.html#patching-risc-v-instructions">Patching RISC-V instructions</a>
<ul class="toc-sub pl-0">
<li class="list-group-item pl-0 ml-0 border-0 pl-0 pt-0 pb-1 pr-0 m-0 mr-3"><a href="10.html#assign-homes">Assign Homes</a></li>
<li class="list-group-item pl-0 ml-0 border-0 pl-0 pt-0 pb-1 pr-0 m-0 mr-3"><a href="10.html#patch-instructions">Patch Instructions</a></li>
</ul>
</li>
</ul>
</div>
</div>
</div>
<div class="row">
<div class="col-12">
<div class="border-top border-bottom border-grey mt-3 pt-3">
<nav>
<ul class="pagination justify-content-center">
<li class="page-item">
<a class="page-link" href="9.html">
Previous
</a>
</li>
<li class="page-item">
<a class="page-link" href="11.html">Next</a>
</li>
<li class="page-item">
<a class="page-link" href="../project/index.html">
Index
</a>
</li>
</ul>
</nav>
</div>
</div>
</div>
</div>
<!-- Optional JavaScript -->
<!-- jQuery first, then Popper.js, then Bootstrap JS -->
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js" integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script>
</body>
</html>