Share
Embed
Late Data Layout: Unifying Data Representation Transformations
Late Data Layout presentation given at the Virtual Machines Meetup at ETH Zürich, Switzerland. Website: http://vmmeetup.github.io/2014/
Project website: http://scala-ldl.org
Vlad Ureche
September 11, 2014
Transcript
225 slides
-
scala-miniboxing.org/ldl Late Data Layout: Unifying Data Representation Transformations 11th of
September 2014 Virtual Machine Meetup ETH Zürich, Switzerland -
scala-miniboxing.org/ldl Vlad URECHE PhD student in the Scala Team @
EPFL Miniboxing guy. Also worked on specialization, the backend and scaladoc. @ @VladUreche @VladUreche [email protected] -
scala-miniboxing.org/ldl Late Data Layout: Unifying Data Representation Transformations • compiler
transformations • separate compilation • global scope -
scala-miniboxing.org/ldl Late Data Layout: Unifying Data Representation Transformations • unboxing,
value classes • how data is represented -
scala-miniboxing.org/ldl Late Data Layout: Unifying Data Representation Transformations • what
is there to unify? • why bother? -
scala-miniboxing.org/ldl Unboxing Primitive Types Specialization (Miniboxing) Value Classes Representation Transformations
Staging (Multi-Stage Programming) motivated by erased generics -
scala-miniboxing.org/ldl Unboxing Primitive Types Specialization (Miniboxing) Value Classes Representation Transformations
Staging (Multi-Stage Programming) Function Representation motivated by erased generics -
scala-miniboxing.org/ldl Unboxing Primitive Types Specialization (Miniboxing) Value Classes Representation Transformations
Staging (Multi-Stage Programming) Function Representation motivated by erased generics -
20 scala-miniboxing.org/ldl Unboxing Primitive Types Unboxing Primitive Types def identity[T](t:
T): T = t scalac / javac -
21 scala-miniboxing.org/ldl Unboxing Primitive Types Unboxing Primitive Types def identity[T](t:
T): T = t def identity(t: Object): Object = t scalac / javac -
25 scala-miniboxing.org/ldl Unboxing Primitive Types Unboxing Primitive Types identity(5) identity(j.l.Integer.valueOf(5)).intValue
scalac / javac Object representation -
26 scala-miniboxing.org/ldl Unboxing Primitive Types Unboxing Primitive Types identity(5) identity(j.l.Integer.valueOf(5)).intValue
scalac / javac produces garbage breaks locality guarantees inflates heap requirements indirect (slow) access to the value Object representation -
28 scala-miniboxing.org/ldl Unboxing Primitive Types Unboxing Primitive Types val five:
Int = 5 scala.Int behaves like an object (has methods, can be used with generics) -
29 scala-miniboxing.org/ldl Unboxing Primitive Types Unboxing Primitive Types val five:
Int = 5 scalac scala.Int behaves like an object (has methods, can be used with generics) -
30 scala-miniboxing.org/ldl Unboxing Primitive Types Unboxing Primitive Types val five:
Int = 5 val five: int = 5 scalac scala.Int behaves like an object (has methods, can be used with generics) -
31 scala-miniboxing.org/ldl Unboxing Primitive Types Unboxing Primitive Types val five:
Int = 5 val five: int = 5 scalac Unboxed integer scala.Int behaves like an object (has methods, can be used with generics) -
33 scala-miniboxing.org/ldl Unboxing Primitive Types Unboxing Primitive Types val five:
Int = identity(5) scalac -
34 scala-miniboxing.org/ldl Unboxing Primitive Types Unboxing Primitive Types val five:
Int = identity(5) val five: int = scalac -
35 scala-miniboxing.org/ldl Unboxing Primitive Types Unboxing Primitive Types val five:
Int = identity(5) val five: int = identity(I.valueOf(5)).intValue scalac -
36 scala-miniboxing.org/ldl Unboxing Primitive Types Unboxing Primitive Types val five:
Int = identity(5) val five: int = identity(I.valueOf(5)).intValue scalac Boxing coercion -
37 scala-miniboxing.org/ldl Unboxing Primitive Types Unboxing Primitive Types val five:
Int = identity(5) val five: int = identity(I.valueOf(5)).intValue scalac Boxing coercion Unboxing coercion -
40 scala-miniboxing.org/ldl Unboxing Primitive Types Unboxing Primitive Types scala.Int int
• fast access • no garbage collection • locality -
41 scala-miniboxing.org/ldl Unboxing Primitive Types Unboxing Primitive Types scala.Int int
• fast access • no garbage collection • locality • indirect access • object allocation • and thus garbage collection • no locality guarantees • compatible with erased generics java.lang.Integer -
42 scala-miniboxing.org/ldl Unboxing Primitive Types Unboxing Primitive Types scala.Int int
• fast access • no garbage collection • locality • indirect access • object allocation • and thus garbage collection • no locality guarantees • compatible with erased generics java.lang.Integer incompatible → coercions -
scala-miniboxing.org/ldl Unboxing Primitive Types Specialization (Miniboxing) Value Classes Representation Transformations
Staging (Multi-Stage Programming) Function Representation -
46 scala-miniboxing.org/ldl Specialization Specialization def identity[T](t: T): T = t
def identity(t: Object): Object = t specialization -
47 scala-miniboxing.org/ldl Specialization Specialization def identity[T](t: T): T = t
def identity(t: Object): Object = t specialization def identity_Z(t: bool): bool = t -
48 scala-miniboxing.org/ldl Specialization Specialization def identity[T](t: T): T = t
def identity(t: Object): Object = t specialization def identity_Z(t: bool): bool = t def identity_C(t: char): char = t -
49 scala-miniboxing.org/ldl Specialization Specialization def identity[T](t: T): T = t
def identity(t: Object): Object = t specialization def identity_Z(t: bool): bool = t def identity_C(t: char): char = t … (7 other variants) -
53 scala-miniboxing.org/ldl Specialization Specialization identity(5) identity_I(5) specialization The variant of
identity specialized for int -
54 scala-miniboxing.org/ldl Specialization Specialization identity(5) identity_I(5) specialization The variant of
identity specialized for int // no boxing! -
57 scala-miniboxing.org/ldl Specialization Specialization def tupled[T1, T2](t1: T1, t2: T2)
... // 100 methods (102) specialization -
58 scala-miniboxing.org/ldl Specialization Specialization def tupled[T1, T2](t1: T1, t2: T2)
... // 100 methods (102) specialization -
59 scala-miniboxing.org/ldl Specialization Specialization def tupled[T1, T2](t1: T1, t2: T2)
... // 100 methods (102) specialization Can we do better? -
60 scala-miniboxing.org/ldl Specialization Specialization def tupled[T1, T2](t1: T1, t2: T2)
... // 100 methods (102) specialization Can we do better? -
63 scala-miniboxing.org/ldl Miniboxing Miniboxing def identity[T](t: T): T = t
def identity(t: Object): Object = t miniboxing -
64 scala-miniboxing.org/ldl Miniboxing Miniboxing def identity[T](t: T): T = t
def identity(t: Object): Object = t miniboxing def identity_M(..., t: long): long = t -
65 scala-miniboxing.org/ldl Miniboxing Miniboxing def identity[T](t: T): T = t
def identity(t: Object): Object = t miniboxing def identity_M(..., t: long): long = t long encodes all primitive types -
66 scala-miniboxing.org/ldl Miniboxing Miniboxing def identity[T](t: T): T = t
def identity(t: Object): Object = t miniboxing def identity_M(..., t: long): long = t Only 2n variants long encodes all primitive types -
71 scala-miniboxing.org/ldl Miniboxing Miniboxing identity(3) identity_M(..., int2minibox(3)) miniboxing Coercion The
miniboxed variant of identity -
75 scala-miniboxing.org/ldl Miniboxing Miniboxing T long • preferred encoding •
fallback encoding • compatible with • virtual dispatch • subtyping • erased generics T (erased to Object) -
76 scala-miniboxing.org/ldl Miniboxing Miniboxing T long • preferred encoding •
fallback encoding • compatible with • virtual dispatch • subtyping • erased generics T (erased to Object) incompatible → coercions -
scala-miniboxing.org/ldl Unboxing Primitive Types Specialization (Miniboxing) Value Classes Representation Transformations
Staging (Multi-Stage Programming) Function Representation -
79 scala-miniboxing.org/ldl Value Classes Value Classes def abs(c: Complex): Double
= ... value class transformation -
80 scala-miniboxing.org/ldl Value Classes Value Classes def abs(c: Complex): Double
= ... def abs(c_re: Double, c_im: Double): Double = ... value class transformation -
81 scala-miniboxing.org/ldl Value Classes Value Classes def abs(c: Complex): Double
= ... def abs(c_re: Double, c_im: Double): Double = ... value class transformation No object created! -
83 scala-miniboxing.org/ldl Value Classes Value Classes val c: Complex =
Complex(2,1) value class transformation -
84 scala-miniboxing.org/ldl Value Classes Value Classes val c: Complex =
Complex(2,1) val c_re: Double = 2 val c_im: Double = 1 value class transformation -
85 scala-miniboxing.org/ldl Value Classes Value Classes val c: Complex =
Complex(2,1) val c_re: Double = 2 val c_im: Double = 1 value class transformation No object created! -
87 scala-miniboxing.org/ldl Value Classes Value Classes val a: Any =
c value class transformation -
88 scala-miniboxing.org/ldl Value Classes Value Classes val a: Any =
c val a: Any = new Complex(c_re, c_im) value class transformation -
89 scala-miniboxing.org/ldl Value Classes Value Classes val a: Any =
c val a: Any = new Complex(c_re, c_im) value class transformation Coercion! -
93 scala-miniboxing.org/ldl Value Classes Value Classes value class structure (by-val)
• preferred encoding • fallback encoding • compatible with • subtyping • erased generics class (by-ref) -
94 scala-miniboxing.org/ldl Value Classes Value Classes value class structure (by-val)
• preferred encoding • fallback encoding • compatible with • subtyping • erased generics class (by-ref) incompatible → coercions -
scala-miniboxing.org/ldl Unboxing Primitive Types Specialization (Miniboxing) Value Classes Representation Transformations
Staging (Multi-Stage Programming) Function Representation -
98 scala-miniboxing.org/ldl Staging Staging T T (direct) • executed in
this stage • stores a value -
99 scala-miniboxing.org/ldl Staging Staging T T (direct) • executed in
this stage • stores a value • executed in the next stage • stores the expression that produces the value Rep[T] (lifted) -
100 scala-miniboxing.org/ldl Staging Staging T T (direct) • executed in
this stage • stores a value • executed in the next stage • stores the expression that produces the value Rep[T] (lifted) incompatible → coercions -
scala-miniboxing.org/ldl Unboxing Primitive Types Specialization (Miniboxing) Value Classes Representation Transformations
Staging (Multi-Stage Programming) Function Representation -
104 scala-miniboxing.org/ldl Function Representation Function Representation scala.FunctionX FunctionX • compatible
with the library • does not have all specializations • slow when used by miniboxed code -
105 scala-miniboxing.org/ldl Function Representation Function Representation scala.FunctionX FunctionX • compatible
with the library • does not have all specializations • slow when used by miniboxed code • fast calling from miniboxed code • all specializations are there MbFunctionX -
106 scala-miniboxing.org/ldl Function Representation Function Representation scala.FunctionX FunctionX • compatible
with the library • does not have all specializations • slow when used by miniboxed code • fast calling from miniboxed code • all specializations are there MbFunctionX incompatible → coercions -
113 scala-miniboxing.org/ldl Late Data Layout (LDL) Late Data Layout (LDL)
concept repr. 1 repr. 2 -
114 scala-miniboxing.org/ldl Late Data Layout (LDL) Late Data Layout (LDL)
concept repr. 1 … repr. n repr. 2 -
115 scala-miniboxing.org/ldl Late Data Layout (LDL) Late Data Layout (LDL)
concept repr. 1 … repr. n repr. 2 Constraints from the interaction with other language features: • generics • subtyping • virtual dispatch • DSL semantics (staging) -
116 scala-miniboxing.org/ldl Late Data Layout (LDL) Late Data Layout (LDL)
concept repr. 1 … repr. n repr. 2 Constraints from the interaction with other language features: • generics • subtyping • virtual dispatch • DSL semantics (staging) incompatible → coercions -
scala-miniboxing.org/ldl How to transform a program? We'll use primitive unboxing
as the running example, to keep things simple -
119 scala-miniboxing.org/ldl Unboxing Primitive Types Unboxing Primitive Types scala.Int int
• fast access • no garbage collection • locality • indirect access • object allocation • and thus garbage collection • no locality guarantees • compatible with erased generics java.lang.Integer -
120 scala-miniboxing.org/ldl Unboxing Primitive Types Unboxing Primitive Types scala.Int int
• fast access • no garbage collection • locality • indirect access • object allocation • and thus garbage collection • no locality guarantees • compatible with erased generics java.lang.Integer incompatible → coercions -
122 scala-miniboxing.org/ldl Naive transformation Naive transformation val x: Int =
List[Int](1, 2, 3).head val y: List[Int] = List[Int](x) naive unboxing -
123 scala-miniboxing.org/ldl Naive transformation Naive transformation val x: Int =
List[Int](1, 2, 3).head val y: List[Int] = List[Int](x) val x: int = List[Int](1, 2, 3).head val y: List[Int] = List[Int](x) naive unboxing -
124 scala-miniboxing.org/ldl Naive transformation Naive transformation val x: Int =
List[Int](1, 2, 3).head val y: List[Int] = List[Int](x) val x: int = List[Int](1, 2, 3).head val y: List[Int] = List[Int](x) naive unboxing representation mismatch: expected: int (unboxed) found: Int (boxed) -
125 scala-miniboxing.org/ldl Naive transformation Naive transformation val x: Int =
List[Int](1, 2, 3).head val y: List[Int] = List[Int](x) val x: int = List[Int](1, 2, 3).head val y: List[Int] = List[Int](x) naive unboxing representation mismatch: expected: int (unboxed) found: Int (boxed) representation mismatch: expected: Int (boxed) found: int (unboxed) -
126 scala-miniboxing.org/ldl Naive transformation Naive transformation • naively replacing representations
– leads to mismatches – which are hard to recover (impossible for value classes and miniboxing) • we need coercions between representations -
128 scala-miniboxing.org/ldl Syntax-based Syntax-based • when transforming a value –
coerce the definition right-hand side – coerce all references to it -
130 scala-miniboxing.org/ldl Syntax-based Syntax-based val x: Int = List[Int](1, 2,
3).head syntax-based unboxing -
131 scala-miniboxing.org/ldl Syntax-based Syntax-based val x: Int = List[Int](1, 2,
3).head val x: int = syntax-based unboxing -
132 scala-miniboxing.org/ldl Syntax-based Syntax-based val x: Int = List[Int](1, 2,
3).head val x: int = unbox(List[Int](1, 2, 3).head) syntax-based unboxing -
133 scala-miniboxing.org/ldl Syntax-based Syntax-based val x: Int = List[Int](1, 2,
3).head val x: int = unbox(List[Int](1, 2, 3).head) syntax-based unboxing There are no references to x, so there's nothing else to do. -
134 scala-miniboxing.org/ldl Syntax-based Syntax-based val x: Int = List[Int](1, 2,
3).head val x: int = unbox(List[Int](1, 2, 3).head) syntax-based unboxing There are no references to x, so there's nothing else to do. -
135 scala-miniboxing.org/ldl Syntax-based Syntax-based val x: Int = List[Int](1, 2,
3).head val z: Int = x -
136 scala-miniboxing.org/ldl Syntax-based Syntax-based val x: Int = List[Int](1, 2,
3).head val z: Int = x Transform one by one -
137 scala-miniboxing.org/ldl Syntax-based Syntax-based val x: Int = List[Int](1, 2,
3).head val z: Int = x syntax-based unboxing Transform one by one -
138 scala-miniboxing.org/ldl Syntax-based Syntax-based val x: Int = List[Int](1, 2,
3).head val z: Int = x val x: int = unbox(List[Int](1, 2, 3).head) syntax-based unboxing Transform one by one -
139 scala-miniboxing.org/ldl Syntax-based Syntax-based val x: Int = List[Int](1, 2,
3).head val z: Int = x val x: int = unbox(List[Int](1, 2, 3).head) val z: Int = box(x) syntax-based unboxing Transform one by one -
140 scala-miniboxing.org/ldl Syntax-based Syntax-based val x: int = unbox(List[Int](1, 2,
3).head) val z: Int = box(x) -
141 scala-miniboxing.org/ldl Syntax-based Syntax-based val x: int = unbox(List[Int](1, 2,
3).head) val z: Int = box(x) syntax-based unboxing -
142 scala-miniboxing.org/ldl Syntax-based Syntax-based val x: int = unbox(List[Int](1, 2,
3).head) val z: Int = box(x) val x: int = unbox(List[Int](1, 2, 3).head) val z: int = syntax-based unboxing -
143 scala-miniboxing.org/ldl Syntax-based Syntax-based val x: int = unbox(List[Int](1, 2,
3).head) val z: Int = box(x) val x: int = unbox(List[Int](1, 2, 3).head) val z: int = unbox(box(x)) syntax-based unboxing -
144 scala-miniboxing.org/ldl Syntax-based Syntax-based val x: int = unbox(List[Int](1, 2,
3).head) val z: Int = box(x) val x: int = unbox(List[Int](1, 2, 3).head) val z: int = unbox(box(x)) syntax-based unboxing suboptimal -
146 scala-miniboxing.org/ldl Peephole Optimization Peephole Optimization val z: int =
unbox(box(x)) peephole -
147 scala-miniboxing.org/ldl Peephole Optimization Peephole Optimization val z: int =
unbox(box(x)) val z: int = x peephole -
148 scala-miniboxing.org/ldl Peephole Optimization Peephole Optimization val z: int =
unbox(box(x)) val z: int = x peephole -
149 scala-miniboxing.org/ldl Peephole Optimization Peephole Optimization val z: int =
unbox(box(x)) val z: int = x peephole Okay, let's add the peephole transformation in the pipeline. -
150 scala-miniboxing.org/ldl Syntax-based Syntax-based def choice(t1: Int, t2: Int): Int
= if (Random.nextBoolean()) t1 else t2 -
151 scala-miniboxing.org/ldl Syntax-based Syntax-based def choice(t1: Int, t2: Int): Int
= if (Random.nextBoolean()) t1 else t2 Transform one by one -
152 scala-miniboxing.org/ldl Syntax-based Syntax-based def choice(t1: int, t2: Int): Int
= if (Random.nextBoolean()) box(t1) else t2 -
153 scala-miniboxing.org/ldl Syntax-based Syntax-based def choice(t1: int, t2: int): Int
= if (Random.nextBoolean()) box(t1) else box(t2) -
154 scala-miniboxing.org/ldl Syntax-based Syntax-based def choice(t1: int, t2: int): Int
= if (Random.nextBoolean()) box(t1) else box(t2) Anything missing? -
155 scala-miniboxing.org/ldl Syntax-based Syntax-based def choice(t1: int, t2: int): int
= unbox(if (Random.nextBoolean()) box(t1) else box(t2)) -
156 scala-miniboxing.org/ldl Syntax-based Syntax-based def choice(t1: int, t2: int): int
= unbox(if (Random.nextBoolean()) box(t1) else box(t2)) -
157 scala-miniboxing.org/ldl Syntax-based Syntax-based def choice(t1: int, t2: int): int
= unbox(if (Random.nextBoolean()) box(t1) else box(t2)) new peephole rule -
158 scala-miniboxing.org/ldl Syntax-based Syntax-based def choice(t1: int, t2: int): int
= unbox(if (Random.nextBoolean()) box(t1) else box(t2)) new peephole rule sink outside coercions into the if branches -
159 scala-miniboxing.org/ldl Syntax-based Syntax-based def choice(t1: int, t2: int): int
= if (Random.nextBoolean()) unbox(box(t1)) else unbox(box(t2)) -
160 scala-miniboxing.org/ldl Syntax-based Syntax-based def choice(t1: int, t2: int): int
= if (Random.nextBoolean()) unbox(box(t1)) else unbox(box(t2)) -
161 scala-miniboxing.org/ldl Syntax-based Syntax-based def choice(t1: int, t2: int): int
= if (Random.nextBoolean()) t1 else t2 -
162 scala-miniboxing.org/ldl Syntax-based Syntax-based def choice(t1: int, t2: int): int
= if (Random.nextBoolean()) t1 else t2 complicated -
163 scala-miniboxing.org/ldl Syntax-based Syntax-based • peephole transformation does not scale
– needs multiple rules for each node – needs stateful rewrites – leads to an explosion of rules x states Details in the paper -
165 scala-miniboxing.org/ldl LDL Transformation LDL Transformation • propagate representation information
– into the type system (based on annotated types) – allows selective marking of values to be unboxed -
166 scala-miniboxing.org/ldl LDL Transformation LDL Transformation • re-typecheck the tree
– exposes inconsistencies in the representation • based on backward type propagation • from local type inference – so we introduce coercions • optimally, only when representations don't match -
167 scala-miniboxing.org/ldl LDL Transformation LDL Transformation • three-stage mechanism –
inject annotate the values to be unboxed → – coerce introduce coercion markers → – commit commit to the alternative representations → -
168 scala-miniboxing.org/ldl LDL Transformation LDL Transformation Warning! Throughout the presentation
we'll be writing annotations written before types (e.g. “@unboxed Int”), although in the Scala syntax they are written after the type (e.g.“Int @unboxed”). This makes it easier to read the types aloud. -
170 scala-miniboxing.org/ldl LDL Transformation LDL Transformation def choice(t1: Int, t2:
Int): Int = if (Random.nextBoolean()) t1 else t2 inject coerce commit -
171 scala-miniboxing.org/ldl LDL Transformation LDL Transformation def choice(t1: Int, t2:
Int): Int = if (Random.nextBoolean()) t1 else t2 inject coerce commit -
172 scala-miniboxing.org/ldl LDL Transformation LDL Transformation def choice(t1: @unboxed Int,
t2: @unboxed Int): @unboxed Int = if (Random.nextBoolean()) t1 else t2 inject coerce commit configurable introduction of annotations based on external constraints -
173 scala-miniboxing.org/ldl LDL Transformation LDL Transformation def choice(t1: @unboxed Int,
t2: @unboxed Int): @unboxed Int = if (Random.nextBoolean()) t1 else t2 inject coerce commit -
174 scala-miniboxing.org/ldl LDL Transformation LDL Transformation def choice(t1: @unboxed Int,
t2: @unboxed Int): @unboxed Int = if (Random.nextBoolean()) t1 else t2 inject coerce commit -
175 scala-miniboxing.org/ldl LDL Transformation LDL Transformation def choice(t1: @unboxed Int,
t2: @unboxed Int): @unboxed Int = if (Random.nextBoolean()) t1 else t2 inject coerce commit the return type of choice is @unboxed Int -
176 scala-miniboxing.org/ldl LDL Transformation LDL Transformation def choice(t1: @unboxed Int,
t2: @unboxed Int): @unboxed Int = if (Random.nextBoolean()) t1 else t2 inject coerce commit the return type of choice is @unboxed Int -
177 scala-miniboxing.org/ldl LDL Transformation LDL Transformation def choice(t1: @unboxed Int,
t2: @unboxed Int): @unboxed Int = if (Random.nextBoolean()) t1 else t2 inject coerce commit : @unboxed Int the return type of choice is @unboxed Int -
178 scala-miniboxing.org/ldl LDL Transformation LDL Transformation def choice(t1: @unboxed Int,
t2: @unboxed Int): @unboxed Int = if (Random.nextBoolean()) t1 else t2 inject coerce commit : @unboxed Int expected type (part of local type inference) the return type of choice is @unboxed Int -
179 scala-miniboxing.org/ldl LDL Transformation LDL Transformation def choice(t1: @unboxed Int,
t2: @unboxed Int): @unboxed Int = if (Random.nextBoolean()) t1 else t2 inject coerce commit : @unboxed Int -
180 scala-miniboxing.org/ldl LDL Transformation LDL Transformation def choice(t1: @unboxed Int,
t2: @unboxed Int): @unboxed Int = if (Random.nextBoolean()) t1 else t2 inject coerce commit : Boolean -
181 scala-miniboxing.org/ldl LDL Transformation LDL Transformation def choice(t1: @unboxed Int,
t2: @unboxed Int): @unboxed Int = if (Random.nextBoolean()) t1 else t2 inject coerce commit : Boolean matches: expected: Boolean found: Boolean -
182 scala-miniboxing.org/ldl LDL Transformation LDL Transformation def choice(t1: @unboxed Int,
t2: @unboxed Int): @unboxed Int = if (Random.nextBoolean()) t1 else t2 inject coerce commit : @unboxed Int -
183 scala-miniboxing.org/ldl LDL Transformation LDL Transformation def choice(t1: @unboxed Int,
t2: @unboxed Int): @unboxed Int = if (Random.nextBoolean()) t1 else t2 inject coerce commit : @unboxed Int matches: expected: @unboxed Int found: @unboxed Int -
184 scala-miniboxing.org/ldl LDL Transformation LDL Transformation def choice(t1: @unboxed Int,
t2: @unboxed Int): @unboxed Int = if (Random.nextBoolean()) t1 else t2 inject coerce commit : @unboxed Int -
185 scala-miniboxing.org/ldl LDL Transformation LDL Transformation def choice(t1: @unboxed Int,
t2: @unboxed Int): @unboxed Int = if (Random.nextBoolean()) t1 else t2 inject coerce commit matches: ... : @unboxed Int -
186 scala-miniboxing.org/ldl LDL Transformation LDL Transformation def choice(t1: @unboxed Int,
t2: @unboxed Int): @unboxed Int = if (Random.nextBoolean()) t1 else t2 inject coerce commit -
187 scala-miniboxing.org/ldl LDL Transformation LDL Transformation def choice(t1: @unboxed Int,
t2: @unboxed Int): @unboxed Int = if (Random.nextBoolean()) t1 else t2 inject coerce commit all okay, next phase -
188 scala-miniboxing.org/ldl LDL Transformation LDL Transformation def choice(t1: @unboxed Int,
t2: @unboxed Int): @unboxed Int = if (Random.nextBoolean()) t1 else t2 inject coerce commit -
189 scala-miniboxing.org/ldl LDL Transformation LDL Transformation def choice(t1: @unboxed Int,
t2: @unboxed Int): @unboxed Int = if (Random.nextBoolean()) t1 else t2 inject coerce commit Replace: @unboxed Int → int (not showing Int → j.l.Integer) -
190 scala-miniboxing.org/ldl LDL Transformation LDL Transformation def choice(t1: int, t2:
int): int = if (Random.nextBoolean()) t1 else t2 inject coerce commit -
191 scala-miniboxing.org/ldl LDL Transformation LDL Transformation def choice(t1: int, t2:
int): int = if (Random.nextBoolean()) t1 else t2 inject coerce commit that's it! -
192 scala-miniboxing.org/ldl LDL Transformation LDL Transformation • three-stage mechanism –
inject: add annotations – coerce: add coercions (based on the annotations) – commit: final representation semantics -
193 scala-miniboxing.org/ldl LDL Transformation LDL Transformation • Scalac's erasure –
similar transformation – less flexible (no annotations) – entangled with other transformations • we took what's good – and allowed the transformation to work on other use cases as well -
195 scala-miniboxing.org/ldl Consistency Consistency inject coerce commit • representations become
explicit in types – representation mismatches • become type mismatches • are exposed by the type system – mismatches lead to coercions • explicit bridges between representations • are introduced automatically – regardless of the representations • at a meta-level -
197 scala-miniboxing.org/ldl Selectivity Selectivity inject coerce commit • annotations allow
selectively picking the values to be transformed – value classes • cannot unbox multi-param values in return position (not supported by the JVM platform) • bridge methods – staging • annotations signal domain-specific knowledge – can occur inside generics (List[@staged Int]) -
198 scala-miniboxing.org/ldl Selectivity Selectivity def choice(t1: Int, t2: Int): Int
= if (Random.nextBoolean()) t1 else t2 inject coerce commit -
199 scala-miniboxing.org/ldl Selectivity Selectivity def choice(t1: Int, t2: Int): Int
= if (Random.nextBoolean()) t1 else t2 inject coerce commit what if we did not annotate t1? -
200 scala-miniboxing.org/ldl Selectivity Selectivity def choice(t1: Int, t2: @unboxed Int):
@unboxed Int = if (Random.nextBoolean()) t1 else t2 inject coerce commit what if we did not annotate t1? -
201 scala-miniboxing.org/ldl Selectivity Selectivity def choice(t1: Int, t2: @unboxed Int):
@unboxed Int = if (Random.nextBoolean()) t1 else t2 inject coerce commit : @unboxed Int -
202 scala-miniboxing.org/ldl Selectivity Selectivity def choice(t1: Int, t2: @unboxed Int):
@unboxed Int = if (Random.nextBoolean()) t1 else t2 inject coerce commit : @unboxed Int -
203 scala-miniboxing.org/ldl Selectivity Selectivity def choice(t1: Int, t2: @unboxed Int):
@unboxed Int = if (Random.nextBoolean()) t1 else t2 inject coerce commit : @unboxed Int mismatch: expected: @unboxed Int found: Int -
204 scala-miniboxing.org/ldl Selectivity Selectivity def choice(t1: Int, t2: @unboxed Int):
@unboxed Int = if (Random.nextBoolean()) t1 else t2 inject coerce commit : @unboxed Int mismatch: expected: @unboxed Int found: Int coercion -
205 scala-miniboxing.org/ldl Selectivity Selectivity def choice(t1: Int, t2: @unboxed Int):
@unboxed Int = if (Random.nextBoolean()) unbox(t1) else t2 inject coerce commit -
206 scala-miniboxing.org/ldl Selectivity Selectivity def choice(t1: Int, t2: @unboxed Int):
@unboxed Int = if (Random.nextBoolean()) unbox(t1) else t2 inject coerce commit -
207 scala-miniboxing.org/ldl Selectivity Selectivity def choice(t1: Int, t2: int): int
= if (Random.nextBoolean()) t1.intValue else t2 inject coerce commit -
209 scala-miniboxing.org/ldl Optimality Optimality def choice(t1: Int, t2: @unboxed Int):
@unboxed Int = if (Random.nextBoolean()) unbox(t1) else t2 inject coerce commit -
210 scala-miniboxing.org/ldl Optimality Optimality def choice(t1: Int, t2: @unboxed Int):
@unboxed Int = if (Random.nextBoolean()) unbox(t1) else t2 inject coerce commit -
211 scala-miniboxing.org/ldl Optimality Optimality def choice(t1: Int, t2: @unboxed Int):
@unboxed Int = if (Random.nextBoolean()) unbox(t1) else t2 inject coerce commit Coercions are sunk in the tree → excute only if necessary -
214 scala-miniboxing.org/ldl Conclusion Conclusion LDL is a LDL is a
• compile-time transformation – compatible with separate compilation – compatible with partial transformation -
215 scala-miniboxing.org/ldl Conclusion Conclusion LDL is a LDL is a
• compile-time transformation – compatible with separate compilation – compatible with partial transformation – global scope (Graal/Truffle: local scope) • optimizes all data in a program -
216 scala-miniboxing.org/ldl Conclusion Conclusion LDL is a LDL is a
• compile-time transformation – compatible with separate compilation – compatible with partial transformation – global scope (Graal/Truffle: local scope) • optimizes all data in a program / containers – conservative (Graal/Truffle: speculative) -
217 scala-miniboxing.org/ldl Conclusion Conclusion LDL is a LDL is a
• compile-time transformation – compatible with separate compilation – compatible with partial transformation – global scope (Graal/Truffle: local scope) • optimizes all data in a program / containers – conservative (Graal/Truffle: speculative) Complementary optimizations -
218 scala-miniboxing.org/ldl Conclusion Conclusion LDL allows LDL allows • splitting
a high-level concept – into multiple representations – in a consistent way (through coercions) – in a selective way (through annotations) – in an optimal way (coerce only if necessary) -
219 scala-miniboxing.org/ldl Conclusion Conclusion LDL is used in LDL is
used in • the miniboxing plugin – for specialization – for function representation • other prototypes – value classes – staging -
220 scala-miniboxing.org/ldl Conclusion Conclusion LDL is used in LDL is
used in • the miniboxing plugin – for specialization – for function representation • other prototypes – value classes – staging Don't take my word for it -
221 scala-miniboxing.org/ldl Conclusion Conclusion LDL is used in LDL is
used in • the miniboxing plugin – for specialization – for function representation • other prototypes – value classes – staging Don't take my word for it Sources on github, artifact online. -
223 scala-miniboxing.org/ldl Conclusion Conclusion What's your use-case? What's your use-case?
concept repr. 1 … repr. n repr. 2 -
scala-miniboxing.org/ldl Credits and Thank you-s • Cristian Talau - developed
the initial prototype, as a semester project • Eugene Burmako - the value class plugin based on the LDL transformation • Aymeric Genet - developing collection-like benchmarks for the miniboxing plugin • Martin Odersky, for his patient guidance • Eugene Burmako, for trusting the idea enough to develop the value-plugin based on the LDL transformation • Iulian Dragos, for his work on specialization and many explanations • Miguel Garcia, for his original insights that spawned the miniboxing idea • Michel Schinz, for his wonderful comments and enlightening ACC course • Andrew Myers and Roland Ducournau for the discussions we had and the feedback provided • Heather Miller for the eye-opening discussions we had • Vojin Jovanovic, Sandro Stucki, Manohar Jonalagedda and the whole LAMP laboratory in EPFL for the extraordinary atmosphere • Adriaan Moors, for the miniboxing name which stuck :)) • Thierry Coppey, Vera Salvisberg and George Nithin, who patiently listened to many presentations and provided valuable feedback • Grzegorz Kossakowski, for the many brainstorming sessions on specialization • Erik Osheim, Tom Switzer and Rex Kerr for their guidance on the Scala community side • OOPSLA paper and artifact reviewers, who reshaped the paper with their feedback • Sandro, Vojin, Nada, Heather, Manohar - reviews and discussions on the LDL paper • Hubert Plociniczak for the type notation in the LDL paper • Denys Shabalin, Dmitry Petrashko for their patient reviews of the LDL paper Special thanks to the Scala Community for their support! (@StuHood, @vpatryshev and everyone else!)