Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Late Data Layout: Unifying Data Representation Transformations

456d1d6154efe50e950b65f966f63a50?s=47 Vlad Ureche
September 11, 2014

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

456d1d6154efe50e950b65f966f63a50?s=128

Vlad Ureche

September 11, 2014
Tweet

Transcript

  1. scala-miniboxing.org/ldl Late Data Layout: Unifying Data Representation Transformations 11th of

    September 2014 Virtual Machine Meetup ETH Zürich, Switzerland
  2. 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 vlad.ureche@epfl.ch
  3. scala-miniboxing.org/ldl Late Data Layout: Unifying Data Representation Transformations

  4. 4 scala-miniboxing.org/ldl

  5. 5 scala-miniboxing.org/ldl OOPSLA 2014, Portland, OR

  6. scala-miniboxing.org/ldl Late Data Layout: Unifying Data Representation Transformations

  7. scala-miniboxing.org/ldl Late Data Layout: Unifying Data Representation Transformations • compiler

    transformations • separate compilation • global scope
  8. scala-miniboxing.org/ldl Late Data Layout: Unifying Data Representation Transformations • unboxing,

    value classes • how data is represented
  9. scala-miniboxing.org/ldl Late Data Layout: Unifying Data Representation Transformations • what

    is there to unify? • why bother?
  10. scala-miniboxing.org/ldl Motivation Transformation Conclusion

  11. scala-miniboxing.org/ldl Representation Transformations

  12. scala-miniboxing.org/ldl Unboxing Primitive Types Representation Transformations

  13. scala-miniboxing.org/ldl Unboxing Primitive Types Specialization (Miniboxing) Representation Transformations

  14. scala-miniboxing.org/ldl Unboxing Primitive Types Specialization (Miniboxing) Value Classes Representation Transformations

  15. scala-miniboxing.org/ldl Unboxing Primitive Types Specialization (Miniboxing) Value Classes Representation Transformations

    motivated by erased generics
  16. scala-miniboxing.org/ldl Unboxing Primitive Types Specialization (Miniboxing) Value Classes Representation Transformations

    Staging (Multi-Stage Programming) motivated by erased generics
  17. scala-miniboxing.org/ldl Unboxing Primitive Types Specialization (Miniboxing) Value Classes Representation Transformations

    Staging (Multi-Stage Programming) Function Representation motivated by erased generics
  18. scala-miniboxing.org/ldl Unboxing Primitive Types Specialization (Miniboxing) Value Classes Representation Transformations

    Staging (Multi-Stage Programming) Function Representation motivated by erased generics
  19. 19 scala-miniboxing.org/ldl Unboxing Primitive Types Unboxing Primitive Types def identity[T](t:

    T): T = t
  20. 20 scala-miniboxing.org/ldl Unboxing Primitive Types Unboxing Primitive Types def identity[T](t:

    T): T = t scalac / javac
  21. 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
  22. 22 scala-miniboxing.org/ldl Unboxing Primitive Types Unboxing Primitive Types identity(5)

  23. 23 scala-miniboxing.org/ldl Unboxing Primitive Types Unboxing Primitive Types identity(5) scalac

    / javac
  24. 24 scala-miniboxing.org/ldl Unboxing Primitive Types Unboxing Primitive Types identity(5) identity(j.l.Integer.valueOf(5)).intValue

    scalac / javac
  25. 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. 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
  27. 27 scala-miniboxing.org/ldl Unboxing Primitive Types Unboxing Primitive Types val five:

    Int = 5
  28. 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. 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. 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. 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)
  32. 32 scala-miniboxing.org/ldl Unboxing Primitive Types Unboxing Primitive Types val five:

    Int = identity(5)
  33. 33 scala-miniboxing.org/ldl Unboxing Primitive Types Unboxing Primitive Types val five:

    Int = identity(5) scalac
  34. 34 scala-miniboxing.org/ldl Unboxing Primitive Types Unboxing Primitive Types val five:

    Int = identity(5) val five: int = scalac
  35. 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. 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. 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
  38. 38 scala-miniboxing.org/ldl Unboxing Primitive Types Unboxing Primitive Types scala.Int

  39. 39 scala-miniboxing.org/ldl Unboxing Primitive Types Unboxing Primitive Types scala.Int

  40. 40 scala-miniboxing.org/ldl Unboxing Primitive Types Unboxing Primitive Types scala.Int int

    • fast access • no garbage collection • locality
  41. 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. 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
  43. scala-miniboxing.org/ldl Unboxing Primitive Types Specialization (Miniboxing) Value Classes Representation Transformations

    Staging (Multi-Stage Programming) Function Representation
  44. 44 scala-miniboxing.org/ldl Specialization Specialization def identity[T](t: T): T = t

  45. 45 scala-miniboxing.org/ldl Specialization Specialization def identity[T](t: T): T = t

    specialization
  46. 46 scala-miniboxing.org/ldl Specialization Specialization def identity[T](t: T): T = t

    def identity(t: Object): Object = t specialization
  47. 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. 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. 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)
  50. 50 scala-miniboxing.org/ldl Specialization Specialization identity(5)

  51. 51 scala-miniboxing.org/ldl Specialization Specialization identity(5) specialization

  52. 52 scala-miniboxing.org/ldl Specialization Specialization identity(5) identity_I(5) specialization

  53. 53 scala-miniboxing.org/ldl Specialization Specialization identity(5) identity_I(5) specialization The variant of

    identity specialized for int
  54. 54 scala-miniboxing.org/ldl Specialization Specialization identity(5) identity_I(5) specialization The variant of

    identity specialized for int // no boxing!
  55. 55 scala-miniboxing.org/ldl Specialization Specialization def tupled[T1, T2](t1: T1, t2: T2)

    ...
  56. 56 scala-miniboxing.org/ldl Specialization Specialization def tupled[T1, T2](t1: T1, t2: T2)

    ... specialization
  57. 57 scala-miniboxing.org/ldl Specialization Specialization def tupled[T1, T2](t1: T1, t2: T2)

    ... // 100 methods (102) specialization
  58. 58 scala-miniboxing.org/ldl Specialization Specialization def tupled[T1, T2](t1: T1, t2: T2)

    ... // 100 methods (102) specialization
  59. 59 scala-miniboxing.org/ldl Specialization Specialization def tupled[T1, T2](t1: T1, t2: T2)

    ... // 100 methods (102) specialization Can we do better?
  60. 60 scala-miniboxing.org/ldl Specialization Specialization def tupled[T1, T2](t1: T1, t2: T2)

    ... // 100 methods (102) specialization Can we do better?
  61. 61 scala-miniboxing.org/ldl Miniboxing Miniboxing def identity[T](t: T): T = t

  62. 62 scala-miniboxing.org/ldl Miniboxing Miniboxing def identity[T](t: T): T = t

    miniboxing
  63. 63 scala-miniboxing.org/ldl Miniboxing Miniboxing def identity[T](t: T): T = t

    def identity(t: Object): Object = t miniboxing
  64. 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. 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. 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
  67. 67 scala-miniboxing.org/ldl Miniboxing Miniboxing identity(3)

  68. 68 scala-miniboxing.org/ldl Miniboxing Miniboxing identity(3) miniboxing

  69. 69 scala-miniboxing.org/ldl Miniboxing Miniboxing identity(3) identity_M(..., int2minibox(3)) miniboxing

  70. 70 scala-miniboxing.org/ldl Miniboxing Miniboxing identity(3) identity_M(..., int2minibox(3)) miniboxing The miniboxed

    variant of identity
  71. 71 scala-miniboxing.org/ldl Miniboxing Miniboxing identity(3) identity_M(..., int2minibox(3)) miniboxing Coercion The

    miniboxed variant of identity
  72. 72 scala-miniboxing.org/ldl Miniboxing Miniboxing T

  73. 73 scala-miniboxing.org/ldl Miniboxing Miniboxing T

  74. 74 scala-miniboxing.org/ldl Miniboxing Miniboxing T long • preferred encoding

  75. 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. 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
  77. scala-miniboxing.org/ldl Unboxing Primitive Types Specialization (Miniboxing) Value Classes Representation Transformations

    Staging (Multi-Stage Programming) Function Representation
  78. 78 scala-miniboxing.org/ldl Value Classes Value Classes def abs(c: Complex): Double

    = ...
  79. 79 scala-miniboxing.org/ldl Value Classes Value Classes def abs(c: Complex): Double

    = ... value class transformation
  80. 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. 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!
  82. 82 scala-miniboxing.org/ldl Value Classes Value Classes val c: Complex =

    Complex(2,1)
  83. 83 scala-miniboxing.org/ldl Value Classes Value Classes val c: Complex =

    Complex(2,1) value class transformation
  84. 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. 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!
  86. 86 scala-miniboxing.org/ldl Value Classes Value Classes val a: Any =

    c
  87. 87 scala-miniboxing.org/ldl Value Classes Value Classes val a: Any =

    c value class transformation
  88. 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. 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!
  90. 90 scala-miniboxing.org/ldl Value Classes Value Classes value class

  91. 91 scala-miniboxing.org/ldl Value Classes Value Classes value class

  92. 92 scala-miniboxing.org/ldl Value Classes Value Classes value class structure (by-val)

    • preferred encoding
  93. 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. 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
  95. scala-miniboxing.org/ldl Unboxing Primitive Types Specialization (Miniboxing) Value Classes Representation Transformations

    Staging (Multi-Stage Programming) Function Representation
  96. 96 scala-miniboxing.org/ldl Staging Staging T

  97. 97 scala-miniboxing.org/ldl Staging Staging T

  98. 98 scala-miniboxing.org/ldl Staging Staging T T (direct) • executed in

    this stage • stores a value
  99. 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. 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
  101. scala-miniboxing.org/ldl Unboxing Primitive Types Specialization (Miniboxing) Value Classes Representation Transformations

    Staging (Multi-Stage Programming) Function Representation
  102. 102 scala-miniboxing.org/ldl Function Representation Function Representation scala.FunctionX

  103. 103 scala-miniboxing.org/ldl Function Representation Function Representation scala.FunctionX

  104. 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. 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. 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
  107. scala-miniboxing.org/ldl Motivation Transformation Conclusion

  108. scala-miniboxing.org/ldl Motivation Transformation Conclusion

  109. 109 scala-miniboxing.org/ldl Late Data Layout (LDL) Late Data Layout (LDL)

  110. 110 scala-miniboxing.org/ldl Late Data Layout (LDL) Late Data Layout (LDL)

    concept
  111. 111 scala-miniboxing.org/ldl Late Data Layout (LDL) Late Data Layout (LDL)

    concept
  112. 112 scala-miniboxing.org/ldl Late Data Layout (LDL) Late Data Layout (LDL)

    concept repr. 1
  113. 113 scala-miniboxing.org/ldl Late Data Layout (LDL) Late Data Layout (LDL)

    concept repr. 1 repr. 2
  114. 114 scala-miniboxing.org/ldl Late Data Layout (LDL) Late Data Layout (LDL)

    concept repr. 1 … repr. n repr. 2
  115. 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. 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
  117. scala-miniboxing.org/ldl How to transform a program?

  118. scala-miniboxing.org/ldl How to transform a program? We'll use primitive unboxing

    as the running example, to keep things simple
  119. 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. 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
  121. scala-miniboxing.org/ldl Naive transformation Syntax-based transformation Type-based LDL transformation

  122. 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. 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. 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. 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. 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
  127. scala-miniboxing.org/ldl Naive transformation Syntax-based transformation Type-based LDL transformation

  128. 128 scala-miniboxing.org/ldl Syntax-based Syntax-based • when transforming a value –

    coerce the definition right-hand side – coerce all references to it
  129. 129 scala-miniboxing.org/ldl Syntax-based Syntax-based val x: Int = List[Int](1, 2,

    3).head
  130. 130 scala-miniboxing.org/ldl Syntax-based Syntax-based val x: Int = List[Int](1, 2,

    3).head syntax-based unboxing
  131. 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. 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. 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. 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. 135 scala-miniboxing.org/ldl Syntax-based Syntax-based val x: Int = List[Int](1, 2,

    3).head val z: Int = x
  136. 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. 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. 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. 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. 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. 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. 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. 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. 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
  145. 145 scala-miniboxing.org/ldl Peephole Optimization Peephole Optimization val z: int =

    unbox(box(x))
  146. 146 scala-miniboxing.org/ldl Peephole Optimization Peephole Optimization val z: int =

    unbox(box(x)) peephole
  147. 147 scala-miniboxing.org/ldl Peephole Optimization Peephole Optimization val z: int =

    unbox(box(x)) val z: int = x peephole
  148. 148 scala-miniboxing.org/ldl Peephole Optimization Peephole Optimization val z: int =

    unbox(box(x)) val z: int = x peephole
  149. 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. 150 scala-miniboxing.org/ldl Syntax-based Syntax-based def choice(t1: Int, t2: Int): Int

    = if (Random.nextBoolean()) t1 else t2
  151. 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. 152 scala-miniboxing.org/ldl Syntax-based Syntax-based def choice(t1: int, t2: Int): Int

    = if (Random.nextBoolean()) box(t1) else t2
  153. 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. 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. 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. 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. 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. 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. 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. 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. 161 scala-miniboxing.org/ldl Syntax-based Syntax-based def choice(t1: int, t2: int): int

    = if (Random.nextBoolean()) t1 else t2
  162. 162 scala-miniboxing.org/ldl Syntax-based Syntax-based def choice(t1: int, t2: int): int

    = if (Random.nextBoolean()) t1 else t2 complicated
  163. 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
  164. scala-miniboxing.org/ldl Naive transformation Syntax-based transformation Type-based LDL transformation

  165. 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. 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. 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. 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.
  169. 169 scala-miniboxing.org/ldl LDL Transformation LDL Transformation inject coerce commit

  170. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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
  194. scala-miniboxing.org/ldl Consistency Selectivity Optimality (not formally proven yet) Properties Type-based

    LDL transformation
  195. 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
  196. scala-miniboxing.org/ldl Consistency Selectivity Optimality (not formally proven yet) Properties Type-based

    LDL transformation
  197. 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. 198 scala-miniboxing.org/ldl Selectivity Selectivity def choice(t1: Int, t2: Int): Int

    = if (Random.nextBoolean()) t1 else t2 inject coerce commit
  199. 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. 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. 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. 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. 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. 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. 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. 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. 207 scala-miniboxing.org/ldl Selectivity Selectivity def choice(t1: Int, t2: int): int

    = if (Random.nextBoolean()) t1.intValue else t2 inject coerce commit
  208. scala-miniboxing.org/ldl Consistency Selectivity Optimality (not formally proven yet) Properties Type-based

    LDL transformation
  209. 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. 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. 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
  212. scala-miniboxing.org/ldl Motivation Transformation Conclusion

  213. scala-miniboxing.org/ldl Motivation Transformation Conclusion

  214. 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. 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. 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. 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. 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. 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. 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. 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.
  222. 222 scala-miniboxing.org/ldl

  223. 223 scala-miniboxing.org/ldl Conclusion Conclusion What's your use-case? What's your use-case?

    concept repr. 1 … repr. n repr. 2
  224. 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!)
  225. scala-miniboxing.org/ldl Thank you! concept repr. 1 … repr. n repr.

    2