Finish up the episode 8 slides
This commit is contained in:
parent
7410ca3d59
commit
f980da8e4e
210
docs/videos.org
210
docs/videos.org
|
@ -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
|
||||||
|
|
Loading…
Reference in New Issue