Finish up the episode 8 slides

This commit is contained in:
Sameer Rahmani 2021-09-05 19:40:18 +01:00
parent 7410ca3d59
commit f980da8e4e
1 changed files with 208 additions and 2 deletions

View File

@ -1,7 +1,7 @@
#+TITLE: How to build a compiler with LLVM and MLIR
#+SEQ_TODO: TODO(t/!) NEXT(n/!) BLOCKED(b@/!) | DONE(d%) CANCELLED(c@/!) FAILED(f@/!)
#+TAGS: READER(r) MISC(m)
#+STARTUP: logdrawer logdone logreschedule indent content align constSI entitiespretty
#+STARTUP: logdrawer logdone logreschedule indent content align constSI entitiespretty overview
* DONE Episode 1 - Introduction
** What is it all about?
@ -159,7 +159,8 @@ We need to reform the AST to reflect the semantics of Serene closly.
Let's run the compiler to see the semantic analysis in action.
** Let's check out the code
* Episode 7 - The Context and Namespace
* DONE Episode 7 - The Context and Namespace
CLOSED: [2021-09-04 Sat 10:53]
** Namespaces
*** Unit of compilation
*** Usually maps to a file
@ -169,3 +170,208 @@ Let's run the compiler to see the semantic analysis in action.
*** The owner of LLVM/MLIR contexts
*** Holds the namespace table
*** Probably will contain the primitive types as well
* Episode 8 - MLIR Basics
** Serene Changes
- Introducing a SourceManager
- Reader changes
- *serenec* cli interface in changing
** Disclaimer
*I'm not an expert in MLIR*
** Why?
- A bit of history
- LLVM IR is to low level
- We need an IR to implement high level concepts and flows
*MLIR* is a framework to build a compiler with your own IR. kinda :P
- Reusability
- ...
** Language
*** Overview
- SSA Based (https://en.wikipedia.org/wiki/Static_single_assignment_form)
- Typed
- Context free(for lack of better words)
*** Dialects
- A collection of operations
- Custom types
- Meta data
- We can use a mixture of different dialects
**** builtin dialects:
- std
- llvm
- math
- async
- ...
*** Opetations
- Higher level of abstraction
- Not instructions
- SSA forms
- Tablegen backend
- Verifiers and printers
*** Attributes
*** Blocks & Regions
*** Types
- Extesible
** Pass Infrastructure
Analysis and transformation infrastructure
- We will implement most of our semantic analysis logic and type checker as passes
** Pattern Rewriting
- Tablegen backed
** Operation Definition Specification
** Examples
*Not*: You need =mlir-mode= and =llvm-mode= available to you for the code highlighting of
the following code blocks. Both of those are distributed with the LLVM.
*** General syntax
#+BEGIN_SRC mlir
%result:2 = "somedialect.blah"(%x#2) { some.attribute = true, other_attribute = 3 }
: (!somedialect<"example_type">) -> (!somedialect<"foo_s">, i8)
loc(callsite("main" at "main.srn":10:8))
#+END_SRC
*** Blocks and Regions
#+BEGIN_SRC mlir
func @simple(i64, i1) -> i64 {
^bb0(%a: i64, %cond: i1): // Code dominated by ^bb0 may refer to %a
cond_br %cond, ^bb1, ^bb2
^bb1:
br ^bb3(%a: i64) // Branch passes %a as the argument
^bb2:
%b = addi %a, %a : i64
br ^bb3(%b: i64) // Branch passes %b as the argument
// ^bb3 receives an argument, named %c, from predecessors
// and passes it on to bb4 along with %a. %a is referenced
// directly from its defining operation and is not passed through
// an argument of ^bb3.
^bb3(%c: i64):
//br ^bb4(%c, %a : i64, i64)
"serene.ifop"(%c) ({ // if %a is in-scope in the containing region...
// then %a is in-scope here too.
%new_value = "another_op"(%c) : (i64) -> (i64)
^someblock(%new_value):
%x = "some_other_op"() {value = 4 : i64} : () -> i64
}) : (i64) -> (i64)
^bb4(%d : i64, %e : i64):
%0 = addi %d, %e : i64
return %0 : i64 // Return is also a terminator.
}
#+END_SRC
*** SLIR example
Command line arguments to emir =slir=
#+BEGIN_SRC sh
./builder run --build-dir ./build -emit slir `pwd`/docs/examples/hello_world.srn
#+END_SRC
Output:
#+BEGIN_SRC mlir
module @user {
%0 = "serene.fn"() ( {
%2 = "serene.value"() {value = 0 : i64} : () -> i64
return %2 : i64
}) {args = {}, name = "main", sym_visibility = "public"} : () -> i64
%1 = "serene.fn"() ( {
%2 = "serene.value"() {value = 0 : i64} : () -> i64
return %2 : i64
}) {args = {n = i64, v = i64, y = i64}, name = "main1", sym_visibility = "public"} : () -> i64
}
#+END_SRC
*** Serene's MLIR (maybe we need a better name)
Command line arguments to emir =mlir=
#+BEGIN_SRC sh
./builder run --build-dir ./build -emit mlir `pwd`/docs/examples/hello_world.srn
#+END_SRC
Output:
#+BEGIN_SRC mlir
module @user {
func @main() -> i64 {
%c3_i64 = constant 3 : i64
return %c3_i64 : i64
}
func @main1(%arg0: i64, %arg1: i64, %arg2: i64) -> i64 {
%c3_i64 = constant 3 : i64
return %c3_i64 : i64
}
}
#+END_SRC
*** LIR
Command line arguments to emir =lir=
#+BEGIN_SRC sh
./builder run --build-dir ./build -emit lir `pwd`/docs/examples/hello_world.srn
#+END_SRC
Output:
#+BEGIN_SRC mlir
module @user {
llvm.func @main() -> i64 {
%0 = llvm.mlir.constant(3 : i64) : i64
llvm.return %0 : i64
}
llvm.func @main1(%arg0: i64, %arg1: i64, %arg2: i64) -> i64 {
%0 = llvm.mlir.constant(3 : i64) : i64
llvm.return %0 : i64
}
}
#+END_SRC
*** LLVMIR
Command line arguments to emir =llvmir=
#+BEGIN_SRC sh
./builder run --build-dir ./build -emit ir `pwd`/docs/examples/hello_world.srn
#+END_SRC
Output:
#+BEGIN_SRC llvm
target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux-gnu"
declare i8* @malloc(i64 %0)
declare void @free(i8* %0)
define i64 @main() !dbg !3 {
ret i64 3, !dbg !7
}
define i64 @main1(i64 %0, i64 %1, i64 %2) !dbg !9 {
ret i64 3, !dbg !10
}
!llvm.dbg.cu = !{!0}
!llvm.module.flags = !{!2}
!0 = distinct !DICompileUnit(language: DW_LANG_C, file: !1, producer: "mlir", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug)
!1 = !DIFile(filename: "LLVMDialectModule", directory: "/")
!2 = !{i32 2, !"Debug Info Version", i32 3}
!3 = distinct !DISubprogram(name: "main", linkageName: "main", scope: null, file: !4, type: !5, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !6)
!4 = !DIFile(filename: "REPL", directory: "/home/lxsameer/src/serene/serene/build")
!5 = !DISubroutineType(types: !6)
!6 = !{}
!7 = !DILocation(line: 0, column: 10, scope: !8)
!8 = !DILexicalBlockFile(scope: !3, file: !4, discriminator: 0)
!9 = distinct !DISubprogram(name: "main1", linkageName: "main1", scope: null, file: !4, line: 1, type: !5, scopeLine: 1, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !6)
!10 = !DILocation(line: 1, column: 11, scope: !11)
!11 = !DILexicalBlockFile(scope: !9, file: !4, discriminator: 0)
#+END_SRC
** Resources
- [[https://www.youtube.com/watch?v=Y4SvqTtOIDk][2020 LLVM Developers Meeting: M. Amini & R. Riddle “MLIR Tutorial”]]
- [[https://www.youtube.com/watch?v=qzljG6DKgic][2019 EuroLLVM Developers Meeting: T. Shpeisman & C. Lattner “MLIR: Multi-Level Intermediate Repr..”]]
- https://mlir.llvm.org/docs
- https://mlir.llvm.org/docs/LangRef
- https://en.wikipedia.org/wiki/Basic_block