220 likes | 328 Views
LX: A Language for Flexible Type Analysis. Stephanie Weirich Cornell University joint work with Karl Crary (CMU). Typed Compilation. Terms. Types. Source. IL. Machine.
E N D
LX: A Language for Flexible Type Analysis Stephanie Weirich Cornell University joint work with Karl Crary (CMU)
Typed Compilation Terms Types Source IL Machine A series of translations between typed languages, propagating a set of invariants throughout the entire compilation process. Types are used for a variety of optimizations and provide safety assurances about the output of compiler.
Polymorphic Subscript Because any array may be passed to a polymorphic function, all arrays must look the same, no matter the type of their elements. A:array int B:array bool ICFP '98 sub = Fn a:Type => fn (A:array a,i:int) => wordsub(A,i) 06/08/99
Monomorphic subscript In languages such as C, the type of an array is always known at compilation. We can pack boolean values into integer arrays. int A[4] bool B[4] A[2] intsub(A,2) B[2] intsub(B,0)&(1<<2) <> 0 06/08/99
Type Analysis ( liML ) A:array int B:array bool type packedarray(a:Type) = typecase a of int => array int | bool => array int sub = Fn a:Type => fn (A:packedarray a,i:int) => typecase a of int => wordsub(A,i) | bool => (wordsub(A,i div 32) & (1<<(i mod 32))) <> 0 06/08/99
A Problem What if, during typed compilation, two source types map to the same target type? Source Language false true int bool term compilation type compilation Target Language 0 1 int
An initial attempt Target language contains both source language and target language types, and has a built-in type constructor interp to translate between them. sub = Fn a:S => fn (A:array (interp a),i:int) => typecase a of [int]S=> wordsub(A,i) | [bool]S => (wordsub(A,i div 32) & (1<<(i mod 32))) <> 0
Issues in Compilation How do we preserve the meaning of typecase when the types themselves change? • type translation may not be injective • in TALx86,intint may be compiled into a variety of types depending on the calling convention, register allocation, etc • In closure conversion, a b converted to c. (a * c b) * c • larger type takes longer to analyze • typecase is no longer exhaustive
Goal • Need a facility to describe the types of another language, and describe a translation of those types into the types of the current language. • Need a way to examine those representations the term level
Example datakind S=SInt|SBool interp :S -> Type interp = fn a:S => case a of SInt => int | SBool => int sub = Fn a:S => fn (A:array (interp a),i:int) => ccasea of SInt=> wordsub(A,i) | SBool => (wordsub(A,i div 32) & (1<<(i mod 32))) <> 0
LX Language • Type analysis is just a programming idiom • System F augmented with building blocks for datakinds • tuples • sums • primitive recursion • Strongly Normalizing so that type checking is decidable • Term-level ccase
Another Example datakind M =Int |Prodof M * M |ArrowofM * M interp : M -> Type fun interp ( a:M) = case a of Int => int | Prod (c1,c2)) => interp(c1) * interp(c2) | Arrow (c1,c2)) => interp(c1) interp(c2)
Example fun printf [a:M] (x:interp a) => ccase a of Int=> (* x is of type int *) print_int x Prod(b,c)=> print “<“; printf [b](fst x); print “,”; printf [c] (snd x); print “>” Arrow(b,c) => (* x is of type interp(b)interp(c) *) print “fun” (* x is of typeinterp(Prod(b,c))*) (* x is of typeinterp(b) * interp(c)*)
Type-Analyzing Languages analyze native types analyze constructed types type-passing semantics liML LX type-erasure semantics lR LXvcase
Type-Passing Semantics Types are necessary at run time Requires sophisticated machinery to describe low level languages Abstract kinds and translucent sums for polymorphic typed closure conversion [MMH 96] Type-Erasure Semantics Types may be erased prior to run time Standard type theory constructs suffice Simpler typed closure conversion [ MWCG 97][CWM 98]
Type Passing Example ( liML ) type packedarray(a:Type) = typecase a of int => array int | bool => array int sub = Fn a:Type => fn (A:packedarray a,i:int) => typecase a of int => wordsub(A,i) | bool => (wordsub(A,i div 32) & (1<<(i mod 32))) <> 0
Type Erasure Example ( lR ) type packedarray(a:Type) = typecase a of int => array int | bool => array int sub = Fn a:Type => fn (A:packedarray a, i:int, rx:R(a)) => typecase rxof Rint => wordsub(A,i) | Rbool => (wordsub(A,i div 32) & (1<<(i mod 32))) <> 0
Example datakind S=SInt|SBool interp :S Type interp = fn a:S => case a of SInt => int | SBool => int datatype SRep = RInt | RBool
Example sub = Fn a:S => fn (A:array (interp a),i:int, rx:SRep) => case rxof RInt => ccase a of SInt => wordsub(A,i) | SBool => impossible | RBool => ccase a of SInt => impossible | SBool => (wordsub(A,i div 32) & (1<<(i mod 32))) <> 0
Second Try datatype SRep [a:S ] = RInt of (case a of SInt => unit | SBool => void) | RBool of (case a of SInt => void | SBool => unit)
Second Try sub = Fn a:S => fn (A:array (interp a),i:int, rx:SRep(a)) => case rxof RInt y => vcasea of SInt => wordsub(A,i) | SBool => dead y | RBool y => vcasea of Sint => dead y | SBool => (wordsub(A,i div 32) & (1<<(i mod 32))) <> 0
Related Work Inductive Types Mendler 87, Werner 94, Howard 92, 96, Gordon 94 Type Analysis Harper/Morrisett 95, Duggan 98, etc… Type Erasure Crary/Weirich/Morrisett 98 Typed Compilation TIL - FLINT - TAL - Church