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 #+TITLE: How to build a compiler with LLVM and MLIR
#+SEQ_TODO: TODO(t/!) NEXT(n/!) BLOCKED(b@/!) | DONE(d%) CANCELLED(c@/!) FAILED(f@/!) #+SEQ_TODO: TODO(t/!) NEXT(n/!) BLOCKED(b@/!) | DONE(d%) CANCELLED(c@/!) FAILED(f@/!)
#+TAGS: READER(r) MISC(m) #+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 * DONE Episode 1 - Introduction
** What is it all about? ** 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 run the compiler to see the semantic analysis in action.
** Let's check out the code ** 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 ** Namespaces
*** Unit of compilation *** Unit of compilation
*** Usually maps to a file *** 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 *** The owner of LLVM/MLIR contexts
*** Holds the namespace table *** Holds the namespace table
*** Probably will contain the primitive types as well *** 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