Documentation

Lean.Compiler.LCNF.Basic

Lean Compiler Normal Form (LCNF) #

It is based on the A-normal form, and the approach described in the paper Compiling without continuations.

This type is used to index the fundamental LCNF IR data structures. Depending on its value different constructors are available for the different semantic phases of LCNF.

Notably in order to save memory we never index the IR types over Purity. Instead the type is parametrized by the phase and the individual constructors might carry a proof (that will be erased) that they are only allowed in a certain phase.

  • pure : Purity

    The code we are acting on is still pure, things like reordering up to value dependencies are acceptable.

  • impure : Purity

    The code we are acting on is to be considered generally impure, doing reorderings is potentially no longer legal.

Instances For
    @[inline]
    def Lean.Compiler.LCNF.Purity.withAssertPurity {α : Sort u_1} [Inhabited α] (is should : Purity) (k : is = shouldα) :
    α
    Instances For
      Instances For
        @[implicit_reducible]
        @[implicit_reducible]
        instance Lean.Compiler.LCNF.instBEqParam {pu✝ : Purity} :
        BEq (Param pu✝)
        def Lean.Compiler.LCNF.instBEqParam.beq {pu✝ : Purity} :
        Param pu✝Param pu✝Bool
        Instances For
          Instances For
            Instances For
              @[implicit_reducible]
              Instances For
                @[implicit_reducible]
                @[implicit_reducible]
                instance Lean.Compiler.LCNF.instBEqArg {pu✝ : Purity} :
                BEq (Arg pu✝)
                def Lean.Compiler.LCNF.instBEqArg.beq {pu✝ : Purity} :
                Arg pu✝Arg pu✝Bool
                Instances For
                  @[implicit_reducible]
                  Instances For
                    Instances For
                      Instances For
                        @[implemented_by _private.Lean.Compiler.LCNF.Basic.0.Lean.Compiler.LCNF.Arg.updateTypeImp]
                        opaque Lean.Compiler.LCNF.Arg.updateType! {pu : Purity} (arg : Arg pu) (type : Expr) :
                        Arg pu
                        @[implemented_by _private.Lean.Compiler.LCNF.Basic.0.Lean.Compiler.LCNF.Arg.updateFVarImp]
                        opaque Lean.Compiler.LCNF.Arg.updateFVar! {pu : Purity} (arg : Arg pu) (fvarId' : FVarId) :
                        Arg pu

                        Constructor information.

                        • name is the Name of the Constructor in Lean.
                        • cidx is the Constructor index (aka tag).
                        • size is the number of arguments of type object/tobject.
                        • usize is the number of arguments of type usize.
                        • ssize is the number of bytes used to store scalar values.

                        Recall that a Constructor object contains a header, then a sequence of pointers to other Lean objects, a sequence of USize (i.e., size_t) scalar values, and a sequence of other scalar values.

                        Instances For
                          @[implicit_reducible]
                          Instances For
                            @[implicit_reducible]
                            Instances For
                              @[implicit_reducible]
                              @[implicit_reducible]
                              Instances For
                                @[implemented_by _private.Lean.Compiler.LCNF.Basic.0.Lean.Compiler.LCNF.LetValue.updateProjImp]
                                @[implemented_by _private.Lean.Compiler.LCNF.Basic.0.Lean.Compiler.LCNF.LetValue.updateConstImp]
                                opaque Lean.Compiler.LCNF.LetValue.updateConst! {pu : Purity} (e : LetValue pu) (declName' : Name) (us' : List Level) (args' : Array (Arg pu)) :
                                @[implemented_by _private.Lean.Compiler.LCNF.Basic.0.Lean.Compiler.LCNF.LetValue.updateFVarImp]
                                opaque Lean.Compiler.LCNF.LetValue.updateFVar! {pu : Purity} (e : LetValue pu) (fvarId' : FVarId) (args' : Array (Arg pu)) :
                                @[implemented_by _private.Lean.Compiler.LCNF.Basic.0.Lean.Compiler.LCNF.LetValue.updateResetImp]
                                opaque Lean.Compiler.LCNF.LetValue.updateReset! {pu : Purity} (e : LetValue pu) (n' : Nat) (fvarId' : FVarId) :
                                @[implemented_by _private.Lean.Compiler.LCNF.Basic.0.Lean.Compiler.LCNF.LetValue.updateReuseImp]
                                opaque Lean.Compiler.LCNF.LetValue.updateReuse! {pu : Purity} (e : LetValue pu) (var' : FVarId) (i' : CtorInfo) (updateHeader' : Bool) (args' : Array (Arg pu)) :
                                @[implemented_by _private.Lean.Compiler.LCNF.Basic.0.Lean.Compiler.LCNF.LetValue.updateFapImp]
                                opaque Lean.Compiler.LCNF.LetValue.updateFap! {pu : Purity} (e : LetValue pu) (declName' : Name) (args' : Array (Arg pu)) :
                                @[implemented_by _private.Lean.Compiler.LCNF.Basic.0.Lean.Compiler.LCNF.LetValue.updatePapImp]
                                opaque Lean.Compiler.LCNF.LetValue.updatePap! {pu : Purity} (e : LetValue pu) (declName' : Name) (args' : Array (Arg pu)) :
                                @[implemented_by _private.Lean.Compiler.LCNF.Basic.0.Lean.Compiler.LCNF.LetValue.updateBoxImp]
                                opaque Lean.Compiler.LCNF.LetValue.updateBox! {pu : Purity} (e : LetValue pu) (ty' : Expr) (fvarId' : FVarId) :
                                @[implemented_by _private.Lean.Compiler.LCNF.Basic.0.Lean.Compiler.LCNF.LetValue.updateUnboxImp]
                                @[implemented_by _private.Lean.Compiler.LCNF.Basic.0.Lean.Compiler.LCNF.LetValue.updateArgsImp]
                                opaque Lean.Compiler.LCNF.LetValue.updateArgs! {pu : Purity} (e : LetValue pu) (args' : Array (Arg pu)) :
                                Instances For
                                  @[implicit_reducible]
                                  @[implicit_reducible]
                                  Instances For
                                    Instances For
                                      Instances For
                                        Instances For
                                          @[implicit_reducible]
                                          @[implicit_reducible]
                                          Instances For
                                            @[inline]
                                            Instances For
                                              @[inline]
                                              Instances For
                                                @[inline]
                                                Instances For
                                                  @[inline]
                                                  Instances For
                                                    @[inline]
                                                    Instances For
                                                      @[inline]
                                                      Instances For
                                                        @[inline]
                                                        def Lean.Compiler.LCNF.FunDecl.toParam {pu : Purity} (decl : FunDecl pu) (borrow : Bool) :
                                                        Instances For
                                                          @[inline]
                                                          Instances For
                                                            @[inline]
                                                            Instances For
                                                              @[inline]
                                                              Instances For
                                                                @[inline]
                                                                Instances For
                                                                  @[inline]
                                                                  Instances For
                                                                    @[implicit_reducible]
                                                                    @[implicit_reducible]
                                                                    Instances For

                                                                      Return the constructor names that have an explicit (non-default) alternative.

                                                                      Instances For
                                                                        Instances For
                                                                          @[implicit_reducible]
                                                                          def Lean.Compiler.LCNF.attachCodeDecls {pu : Purity} (decls : Array (CodeDecl pu)) (code : Code pu) :
                                                                          Code pu
                                                                          Instances For
                                                                            @[implemented_by _private.Lean.Compiler.LCNF.Basic.0.Lean.Compiler.LCNF.eqImp]
                                                                            opaque Lean.Compiler.LCNF.Code.beq {pu : Purity} :
                                                                            Code puCode puBool
                                                                            @[implicit_reducible]
                                                                            @[implemented_by _private.Lean.Compiler.LCNF.Basic.0.Lean.Compiler.LCNF.eqFunDecl]
                                                                            @[implicit_reducible]
                                                                            Instances For
                                                                              def Lean.Compiler.LCNF.Alt.forCodeM {m : TypeType u_1} {pu : Purity} [Monad m] (alt : Alt pu) (f : Code pum Unit) :
                                                                              Instances For
                                                                                @[implemented_by _private.Lean.Compiler.LCNF.Basic.0.Lean.Compiler.LCNF.updateAltCodeImp]
                                                                                opaque Lean.Compiler.LCNF.Alt.updateCode {pu : Purity} (alt : Alt pu) (c : Code pu) :
                                                                                Alt pu
                                                                                @[implemented_by _private.Lean.Compiler.LCNF.Basic.0.Lean.Compiler.LCNF.updateAltImp]
                                                                                opaque Lean.Compiler.LCNF.Alt.updateAlt! {pu : Purity} (alt : Alt pu) (ps' : Array (Param pu)) (k' : Code pu) :
                                                                                Alt pu
                                                                                @[implemented_by _private.Lean.Compiler.LCNF.Basic.0.Lean.Compiler.LCNF.updateAltsImp]
                                                                                opaque Lean.Compiler.LCNF.Code.updateAlts! {pu : Purity} (c : Code pu) (alts : Array (Alt pu)) :
                                                                                Code pu
                                                                                @[implemented_by _private.Lean.Compiler.LCNF.Basic.0.Lean.Compiler.LCNF.updateCasesImp]
                                                                                opaque Lean.Compiler.LCNF.Code.updateCases! {pu : Purity} (c : Code pu) (resultType : Expr) (discr : FVarId) (alts : Array (Alt pu)) :
                                                                                Code pu
                                                                                @[implemented_by _private.Lean.Compiler.LCNF.Basic.0.Lean.Compiler.LCNF.updateLetImp]
                                                                                opaque Lean.Compiler.LCNF.Code.updateLet! {pu : Purity} (c : Code pu) (decl' : LetDecl pu) (k' : Code pu) :
                                                                                Code pu
                                                                                @[implemented_by _private.Lean.Compiler.LCNF.Basic.0.Lean.Compiler.LCNF.updateContImp]
                                                                                opaque Lean.Compiler.LCNF.Code.updateCont! {pu : Purity} (c k' : Code pu) :
                                                                                Code pu
                                                                                @[implemented_by _private.Lean.Compiler.LCNF.Basic.0.Lean.Compiler.LCNF.updateFunImp]
                                                                                opaque Lean.Compiler.LCNF.Code.updateFun! {pu : Purity} (c : Code pu) (decl' : FunDecl pu) (k' : Code pu) :
                                                                                Code pu
                                                                                @[implemented_by _private.Lean.Compiler.LCNF.Basic.0.Lean.Compiler.LCNF.updateReturnImp]
                                                                                opaque Lean.Compiler.LCNF.Code.updateReturn! {pu : Purity} (c : Code pu) (fvarId' : FVarId) :
                                                                                Code pu
                                                                                @[implemented_by _private.Lean.Compiler.LCNF.Basic.0.Lean.Compiler.LCNF.updateJmpImp]
                                                                                opaque Lean.Compiler.LCNF.Code.updateJmp! {pu : Purity} (c : Code pu) (fvarId' : FVarId) (args' : Array (Arg pu)) :
                                                                                Code pu
                                                                                @[implemented_by _private.Lean.Compiler.LCNF.Basic.0.Lean.Compiler.LCNF.updateUnreachImp]
                                                                                opaque Lean.Compiler.LCNF.Code.updateUnreach! {pu : Purity} (c : Code pu) (type' : Expr) :
                                                                                Code pu
                                                                                @[implemented_by _private.Lean.Compiler.LCNF.Basic.0.Lean.Compiler.LCNF.updateSsetImp]
                                                                                opaque Lean.Compiler.LCNF.Code.updateSset! {pu : Purity} (c : Code pu) (fvarId' : FVarId) (i' offset' : Nat) (y' : FVarId) (ty' : Expr) (k' : Code pu) :
                                                                                Code pu
                                                                                @[implemented_by _private.Lean.Compiler.LCNF.Basic.0.Lean.Compiler.LCNF.updateUsetImp]
                                                                                opaque Lean.Compiler.LCNF.Code.updateUset! {pu : Purity} (c : Code pu) (fvarId' : FVarId) (i' : Nat) (y' : FVarId) (k' : Code pu) :
                                                                                Code pu
                                                                                @[implemented_by _private.Lean.Compiler.LCNF.Basic.0.Lean.Compiler.LCNF.updateIncImp]
                                                                                opaque Lean.Compiler.LCNF.Code.updateInc! {pu : Purity} (c : Code pu) (fvarId' : FVarId) (n' : Nat) (check' persistent' : Bool) (k' : Code pu) :
                                                                                Code pu
                                                                                @[implemented_by _private.Lean.Compiler.LCNF.Basic.0.Lean.Compiler.LCNF.updateDecImp]
                                                                                opaque Lean.Compiler.LCNF.Code.updateDec! {pu : Purity} (c : Code pu) (fvarId' : FVarId) (n' : Nat) (check' persistent' : Bool) (k' : Code pu) :
                                                                                Code pu
                                                                                @[implemented_by _private.Lean.Compiler.LCNF.Basic.0.Lean.Compiler.LCNF.updateParamCoreImp]
                                                                                opaque Lean.Compiler.LCNF.Param.updateCore {pu : Purity} (p : Param pu) (type : Expr) :

                                                                                Low-level update Param function. It does not update the local context. Consider using Param.update : Param → Expr → CompilerM Param if you want the local context to be updated.

                                                                                @[implemented_by _private.Lean.Compiler.LCNF.Basic.0.Lean.Compiler.LCNF.updateLetDeclCoreImp]
                                                                                opaque Lean.Compiler.LCNF.LetDecl.updateCore {pu : Purity} (decl : LetDecl pu) (type : Expr) (value : LetValue pu) :

                                                                                Low-level update LetDecl function. It does not update the local context. Consider using LetDecl.update : LetDecl → Expr → Expr → CompilerM LetDecl if you want the local context to be updated.

                                                                                @[implemented_by _private.Lean.Compiler.LCNF.Basic.0.Lean.Compiler.LCNF.updateFunDeclCoreImp]
                                                                                opaque Lean.Compiler.LCNF.FunDecl.updateCore {pu : Purity} (decl : FunDecl pu) (type : Expr) (params : Array (Param pu)) (value : Code pu) :

                                                                                Low-level update FunDecl function. It does not update the local context. Consider using FunDecl.update : LetDecl → Expr → Array ParamCode → CompilerM FunDecl if you want the local context to be updated.

                                                                                def Lean.Compiler.LCNF.Cases.extractAlt! {pu : Purity} (cases : Cases pu) (ctorName : Name) :
                                                                                Alt pu × Cases pu
                                                                                Instances For
                                                                                  def Lean.Compiler.LCNF.Alt.mapCodeM {m : TypeType u_1} {pu : Purity} [Monad m] (alt : Alt pu) (f : Code pum (Code pu)) :
                                                                                  m (Alt pu)
                                                                                  Instances For
                                                                                    Instances For
                                                                                      Instances For
                                                                                        Instances For
                                                                                          Instances For

                                                                                            Return true iff c.size ≤ n

                                                                                            Instances For
                                                                                              def Lean.Compiler.LCNF.Code.forM {m : TypeType u_1} {pu : Purity} [Monad m] (c : Code pu) (f : Code pum Unit) :
                                                                                              Instances For
                                                                                                Instances For
                                                                                                  @[implicit_reducible]
                                                                                                  @[implicit_reducible]
                                                                                                  Instances For
                                                                                                    Instances For
                                                                                                      def Lean.Compiler.LCNF.DeclValue.mapCodeM {m : TypeType u_1} {pu : Purity} [Monad m] (f : Code pum (Code pu)) :
                                                                                                      DeclValue pum (DeclValue pu)
                                                                                                      Instances For
                                                                                                        def Lean.Compiler.LCNF.DeclValue.forCodeM {m : TypeType u_1} {pu : Purity} [Monad m] (f : Code pum Unit) :
                                                                                                        DeclValue pum Unit
                                                                                                        Instances For
                                                                                                          def Lean.Compiler.LCNF.DeclValue.isCodeAndM {m : TypeType u_1} {pu : Purity} [Monad m] (v : DeclValue pu) (f : Code pum Bool) :
                                                                                                          Instances For

                                                                                                            The signature of a declaration being processed by the Lean to Lean compiler passes.

                                                                                                            • name : Name

                                                                                                              The name of the declaration from the Environment it came from

                                                                                                            • levelParams : List Name

                                                                                                              Universe level parameter names.

                                                                                                            • type : Expr

                                                                                                              The type of the declaration. Note that this is an erased LCNF type instead of the fully dependent one that might have been the original type of the declaration in the Environment. Furthermore, once in the impure staged of LCNF this type is only the return type.

                                                                                                            • params : Array (Param pu)

                                                                                                              Parameters.

                                                                                                            • safe : Bool

                                                                                                              We set this flag to false during LCNF conversion if the Lean function associated with this function was tagged as partial or unsafe. This information affects how static analyzers treat function applications of this kind. See DefinitionSafety. partial and unsafe functions may not be terminating, but Lean functions terminate, and some static analyzers exploit this fact. So, we use the following semantics. Suppose we have a (large) natural number C. We consider a nondeterministic model for computation of Lean expressions as follows: Each call to a partial/unsafe function uses up one "recursion token". Prior to consuming C recursion tokens all partial functions must be called as normal. Once the model has used up C recursion tokens, a subsequent call to a partial function has the following nondeterministic options: it can either call the function again, or return any value of the target type (even a noncomputable one). Larger values of C yield less nondeterminism in the model, but even the intersection of all choices of C yields nondeterminism where def loop : A := loop returns any value of type A. The compiler fixes a choice for C. This is a fixed constant greater than 2^2^64, which is allowed to be compiler and architecture dependent, and promises that it will produce an execution consistent with every possible nondeterministic outcome of the C-model. In the event that different nondeterministic executions disagree, the compiler is required to exhaust resources or output a looping computation.

                                                                                                            Instances For
                                                                                                              @[implicit_reducible]
                                                                                                              Instances For
                                                                                                                @[implicit_reducible]

                                                                                                                Declaration being processed by the Lean to Lean compiler passes.

                                                                                                                • value : DeclValue pu

                                                                                                                  The body of the declaration, usually changes as it progresses through compiler passes.

                                                                                                                • recursive : Bool

                                                                                                                  We set this flag to true during LCNF conversion. When we receive a block of functions to be compiled, we set this flag to true if there is an application to the function in the block containing it. This is an approximation, but it should be good enough because in the frontend, we invoke the compiler with blocks of strongly connected components only. We use this information to control inlining.

                                                                                                                • We store the inline attribute at LCNF declarations to make sure we can set them for auxiliary declarations created during compilation.

                                                                                                                Instances For
                                                                                                                  @[implicit_reducible]
                                                                                                                  def Lean.Compiler.LCNF.instBEqDecl.beq {pu✝ : Purity} :
                                                                                                                  Decl pu✝Decl pu✝Bool
                                                                                                                  Instances For
                                                                                                                    @[implicit_reducible]
                                                                                                                    instance Lean.Compiler.LCNF.instBEqDecl {pu✝ : Purity} :
                                                                                                                    BEq (Decl pu✝)
                                                                                                                    Instances For
                                                                                                                      Instances For
                                                                                                                        Instances For
                                                                                                                          Instances For
                                                                                                                            Instances For

                                                                                                                              Return true if the given declaration has been annotated with [inline], [inline_if_reduce], [macro_inline], or [always_inline]

                                                                                                                              Instances For
                                                                                                                                def Lean.Compiler.LCNF.Decl.castPurity! {pu1 : Purity} (decl : Decl pu1) (pu2 : Purity) :
                                                                                                                                Decl pu2
                                                                                                                                Instances For

                                                                                                                                  Return some i if decl is of the form

                                                                                                                                  def f (a_0 ... a_i ...) :=
                                                                                                                                    ...
                                                                                                                                    cases a_i
                                                                                                                                    | ...
                                                                                                                                    | ...
                                                                                                                                  

                                                                                                                                  That is, f is a sequence of declarations followed by a cases on the parameter i. We use this function to decide whether we should inline a declaration tagged with [inline_if_reduce] or not.

                                                                                                                                  Instances For

                                                                                                                                    Return true if the arrow type contains an instance implicit argument.

                                                                                                                                    Instances For

                                                                                                                                      Return true if decl is supposed to be inlined/specialized.

                                                                                                                                      Instances For
                                                                                                                                        def Lean.Compiler.LCNF.markRecDecls {pu : Purity} (decls : Array (Decl pu)) :
                                                                                                                                        Array (Decl pu)

                                                                                                                                        Traverse the given block of potentially mutually recursive functions and mark a declaration f as recursive if there is an application f ... in the block. This is an overapproximation, and relies on the fact that our frontend computes strongly connected components. See comment at recursive field.

                                                                                                                                        Instances For
                                                                                                                                          def Lean.Compiler.LCNF.instantiateRangeArgs {pu : Purity} (e : Expr) (beginIdx endIdx : Nat) (args : Array (Arg pu)) :
                                                                                                                                          Instances For
                                                                                                                                            def Lean.Compiler.LCNF.instantiateRevRangeArgs {pu : Purity} (e : Expr) (beginIdx endIdx : Nat) (args : Array (Arg pu)) :
                                                                                                                                            Instances For