File: .lake/packages/lean4/src/lean/Lean/Compiler/LCNF/Simp/JpCases.lean

full_name: Lean.Compiler.LCNF.Simp.isJpCases?.go
code: /--
Given the function declaration `decl`, return `some idx` if it is of the form
```
f y :=
  ... /- This part is not bigger than smallThreshold. -/
  cases y
  | ... => ...
  ...
```
`idx` is the index of the parameter used in the `cases` statement.
-/
def isJpCases? (decl : FunDecl) : CompilerM (Option Nat) 
goal: Option Nat

full_name: Lean.Compiler.LCNF.Simp.isJpCases?
code: /--
Given the function declaration `decl`, return `some idx` if it is of the form
```
f y :=
  ... /- This part is not bigger than smallThreshold. -/
  cases y
  | ... => ...
  ...
```
`idx` is the index of the parameter used in the `cases` statement.
-/
def isJpCases? (decl : FunDecl) : CompilerM (Option Nat) 
goal: Lean.Compiler.LCNF.CompilerM (Option Nat)

full_name: Lean.Compiler.LCNF.Simp.JpCasesInfo.ctorNames
code: /--
Information for join points that satisfy `isJpCases?`
-/
structure JpCasesInfo where
  /-- Parameter index returned by `isJpCases?`. This parameter is the one the join point is performing the case-split. -/
  paramIdx  : Nat
  /--
  Set of constructor names s.t. `ctorName` is in the set if there is a jump to the join point where the parameter
  `paramIdx` is a constructor application.
  -/
  ctorNames : NameSet := {}
  deriving Inhabited
goal: Lean.NameSet

full_name: Lean.Compiler.LCNF.Simp.JpCasesInfo
code: /--
Information for join points that satisfy `isJpCases?`
-/
structure JpCasesInfo where
  /-- Parameter index returned by `isJpCases?`. This parameter is the one the join point is performing the case-split. -/
  paramIdx  : Nat
  /--
  Set of constructor names s.t. `ctorName` is in the set if there is a jump to the join point where the parameter
  `paramIdx` is a constructor application.
  -/
  ctorNames : NameSet := {}
  deriving Inhabited
goal: Type

full_name: Lean.Compiler.LCNF.Simp.JpCasesInfo.paramIdx
code: /--
Information for join points that satisfy `isJpCases?`
-/
structure JpCasesInfo where
  /-- Parameter index returned by `isJpCases?`. This parameter is the one the join point is performing the case-split. -/
  paramIdx  : Nat
  /--
  Set of constructor names s.t. `ctorName` is in the set if there is a jump to the join point where the parameter
  `paramIdx` is a constructor application.
  -/
  ctorNames : NameSet := {}
  deriving Inhabited
goal: Nat

full_name: Lean.Compiler.LCNF.Simp.instInhabitedJpCasesInfo
code: /--
Information for join points that satisfy `isJpCases?`
-/
structure JpCasesInfo where
  /-- Parameter index returned by `isJpCases?`. This parameter is the one the join point is performing the case-split. -/
  paramIdx  : Nat
  /--
  Set of constructor names s.t. `ctorName` is in the set if there is a jump to the join point where the parameter
  `paramIdx` is a constructor application.
  -/
  ctorNames : NameSet := {}
  deriving Inhabited
goal: Inhabited Lean.Compiler.LCNF.Simp.JpCasesInfo

full_name: Lean.Compiler.LCNF.Simp.JpCasesInfoMap
code: abbrev JpCasesInfoMap 
goal: Type

full_name: Lean.Compiler.LCNF.Simp.JpCasesInfoMap.isCandidate
code: /-- Return `true` if the collected information suggests opportunities for the `JpCases` optimization. -/
def JpCasesInfoMap.isCandidate (info : JpCasesInfoMap) : Bool 
goal: Bool

full_name: Lean.Compiler.LCNF.Simp.collectJpCasesInfo
code: /--
Return a map containing entries `jpFVarId ↦ { paramIdx, ctorNames }` where `jpFVarId` is the id of join point
in code that satisfies `isJpCases`, and `ctorNames` is a set of constructor names such that
there is a jump `.jmp jpFVarId #[..., x, ...]` in `code` and `x` is a constructor application.
`paramIdx` is the index of the parameter
-/
partial def collectJpCasesInfo (code : Code) : CompilerM JpCasesInfoMap 
goal: Lean.Compiler.LCNF.CompilerM Lean.Compiler.LCNF.Simp.JpCasesInfoMap

full_name: Lean.Compiler.LCNF.Simp.collectJpCasesInfo.go
code: /--
Return a map containing entries `jpFVarId ↦ { paramIdx, ctorNames }` where `jpFVarId` is the id of join point
in code that satisfies `isJpCases`, and `ctorNames` is a set of constructor names such that
there is a jump `.jmp jpFVarId #[..., x, ...]` in `code` and `x` is a constructor application.
`paramIdx` is the index of the parameter
-/
partial def collectJpCasesInfo (code : Code) : CompilerM JpCasesInfoMap 
goal: StateRefT' IO.RealWorld Lean.Compiler.LCNF.Simp.JpCasesInfoMap Lean.Compiler.LCNF.Simp.DiscrM Unit

full_name: _private.«.lake».packages.lean4.src.lean.Lean.Compiler.LCNF.Simp.JpCases.0.Lean.Compiler.LCNF.Simp.extractJpCases.go
code: /--
Extract the let-declarations and `cases` for a join point body that satisfies `isJpCases?`.
-/
private def extractJpCases (code : Code) : Array CodeDecl × Cases 
goal: Array Lean.Compiler.LCNF.CodeDecl × Lean.Compiler.LCNF.Cases

full_name: _private.«.lake».packages.lean4.src.lean.Lean.Compiler.LCNF.Simp.JpCases.0.Lean.Compiler.LCNF.Simp.extractJpCases
code: /--
Extract the let-declarations and `cases` for a join point body that satisfies `isJpCases?`.
-/
private def extractJpCases (code : Code) : Array CodeDecl × Cases 
goal: Array Lean.Compiler.LCNF.CodeDecl × Lean.Compiler.LCNF.Cases

full_name: Lean.Compiler.LCNF.Simp.JpCasesAlt.default
code: structure JpCasesAlt where
  decl           : FunDecl
  default        : Bool
  dependsOnDiscr : Bool
goal: Bool

full_name: Lean.Compiler.LCNF.Simp.JpCasesAlt.dependsOnDiscr
code: structure JpCasesAlt where
  decl           : FunDecl
  default        : Bool
  dependsOnDiscr : Bool
goal: Bool

full_name: Lean.Compiler.LCNF.Simp.JpCasesAlt.decl
code: structure JpCasesAlt where
  decl           : FunDecl
  default        : Bool
  dependsOnDiscr : Bool
goal: Lean.Compiler.LCNF.FunDecl

full_name: Lean.Compiler.LCNF.Simp.JpCasesAlt
code: structure JpCasesAlt where
  decl           : FunDecl
  default        : Bool
  dependsOnDiscr : Bool
goal: Type

full_name: Lean.Compiler.LCNF.Simp.Ctor2JpCasesAlt
code: abbrev Ctor2JpCasesAlt 
goal: Type

full_name: _private.«.lake».packages.lean4.src.lean.Lean.Compiler.LCNF.Simp.JpCases.0.Lean.Compiler.LCNF.Simp.mkJpAlt.go
code: /--
Construct an auxiliary join point for a particular alternative in a join-point that satisfies `isJpCases?`.
- `decls` is the prefix (before the `cases`). See `isJpCases?`.
- `params` are the parameters of the main join point that satisfies `isJpCases?`.
- `targetParamIdx` is the index of the parameter that we are expanding to `fields`
- `fields` are the fields/parameter of the alternative.
- `k` is the body of the alternative.
- `default` is true if it is a default alternative.
-/
private def mkJpAlt (decls : Array CodeDecl) (params : Array Param) (targetParamIdx : Nat) (fields : Array Param) (k : Code) (default : Bool) : CompilerM JpCasesAlt 
goal: Lean.Compiler.LCNF.Internalize.InternalizeM Lean.Compiler.LCNF.Simp.JpCasesAlt

full_name: _private.«.lake».packages.lean4.src.lean.Lean.Compiler.LCNF.Simp.JpCases.0.Lean.Compiler.LCNF.Simp.mkJpAlt
code: /--
Construct an auxiliary join point for a particular alternative in a join-point that satisfies `isJpCases?`.
- `decls` is the prefix (before the `cases`). See `isJpCases?`.
- `params` are the parameters of the main join point that satisfies `isJpCases?`.
- `targetParamIdx` is the index of the parameter that we are expanding to `fields`
- `fields` are the fields/parameter of the alternative.
- `k` is the body of the alternative.
- `default` is true if it is a default alternative.
-/
private def mkJpAlt (decls : Array CodeDecl) (params : Array Param) (targetParamIdx : Nat) (fields : Array Param) (k : Code) (default : Bool) : CompilerM JpCasesAlt 
goal: Lean.Compiler.LCNF.CompilerM Lean.Compiler.LCNF.Simp.JpCasesAlt

full_name: _private.«.lake».packages.lean4.src.lean.Lean.Compiler.LCNF.Simp.JpCases.0.Lean.Compiler.LCNF.Simp.mkJmpNewArgs
code: /-- Create the arguments for a jump to an auxiliary join point created using `mkJpAlt`. -/
private def mkJmpNewArgs (args : Array Arg) (targetParamIdx : Nat) (fields : Array Arg) (dependsOnTarget : Bool) : Array Arg 
goal: Array Lean.Compiler.LCNF.Arg

full_name: _private.«.lake».packages.lean4.src.lean.Lean.Compiler.LCNF.Simp.JpCases.0.Lean.Compiler.LCNF.Simp.mkJmpArgsAtJp
code: /--
Create the arguments for a jump to an auxiliary join point created using `mkJpAlt`.
This function is used to create jumps from the join point satisfying `isJpCases?` to the new auxiliary join points created using `mkJpAlt`.
-/
private def mkJmpArgsAtJp (params : Array Param) (targetParamIdx : Nat) (fields : Array Param) (dependsOnTarget : Bool) : Array Arg 
goal: Array Lean.Compiler.LCNF.Arg

full_name: Lean.Compiler.LCNF.Simp.simpJpCases?.visit
code: /--
Try to optimize `jpCases` join points.
We say a join point is a `jpCases` when it satisfies the predicate `isJpCases`.
If we have a jump to `jpCases` with a constructor, then we can optimize the code by creating an new join point for
the constructor.
Example: suppose we have
```lean
jp _jp.1 y :=
  let x.1 := true
  cases y
  | nil => let x.2 := g x.1; return x.2
  | cons h t => let x.3 := h x.1; return x.3
...
cases x.4
| ctor1 =>
  let x.5 := cons z.1 z.2
  jmp _jp.1 x.5
| ctor2 =>
  let x.6 := f x.4
  jmp _jp.1 x.6
```
This `simpJpCases?` converts it to
```lean
jp _jp.2 h t :=
  let x.1 := true
  let x.3 := h x.1
  return x.3
jp _jp.1 y :=
  let x.1 := true
  cases y
  | nil => let x.2 := g x.1; return x.2
  | cons h t => jmp _jp.2 h t
...
cases x.4
| ctor1 =>
  -- The constructor has been eliminated here
  jmp _jp.2 z.1 z.2
| ctor2 =>
  let x.6 := f x.4
  jmp _jp.1 x.6
```
Note that if all jumps to the join point are with constructors,
then the join point is eliminated as dead code.
-/
partial def simpJpCases? (code : Code) : CompilerM (Option Code) 
goal: ReaderT Lean.Compiler.LCNF.Simp.JpCasesInfoMap
  (StateRefT' IO.RealWorld Lean.Compiler.LCNF.Simp.Ctor2JpCasesAlt Lean.Compiler.LCNF.Simp.DiscrM)
  Lean.Compiler.LCNF.Code

full_name: Lean.Compiler.LCNF.Simp.simpJpCases?
code: /--
Try to optimize `jpCases` join points.
We say a join point is a `jpCases` when it satisfies the predicate `isJpCases`.
If we have a jump to `jpCases` with a constructor, then we can optimize the code by creating an new join point for
the constructor.
Example: suppose we have
```lean
jp _jp.1 y :=
  let x.1 := true
  cases y
  | nil => let x.2 := g x.1; return x.2
  | cons h t => let x.3 := h x.1; return x.3
...
cases x.4
| ctor1 =>
  let x.5 := cons z.1 z.2
  jmp _jp.1 x.5
| ctor2 =>
  let x.6 := f x.4
  jmp _jp.1 x.6
```
This `simpJpCases?` converts it to
```lean
jp _jp.2 h t :=
  let x.1 := true
  let x.3 := h x.1
  return x.3
jp _jp.1 y :=
  let x.1 := true
  cases y
  | nil => let x.2 := g x.1; return x.2
  | cons h t => jmp _jp.2 h t
...
cases x.4
| ctor1 =>
  -- The constructor has been eliminated here
  jmp _jp.2 z.1 z.2
| ctor2 =>
  let x.6 := f x.4
  jmp _jp.1 x.6
```
Note that if all jumps to the join point are with constructors,
then the join point is eliminated as dead code.
-/
partial def simpJpCases? (code : Code) : CompilerM (Option Code) 
goal: Lean.Compiler.LCNF.CompilerM (Option Lean.Compiler.LCNF.Code)

full_name: Lean.Compiler.LCNF.Simp.simpJpCases?.visitJmp?
code: /--
Try to optimize `jpCases` join points.
We say a join point is a `jpCases` when it satisfies the predicate `isJpCases`.
If we have a jump to `jpCases` with a constructor, then we can optimize the code by creating an new join point for
the constructor.
Example: suppose we have
```lean
jp _jp.1 y :=
  let x.1 := true
  cases y
  | nil => let x.2 := g x.1; return x.2
  | cons h t => let x.3 := h x.1; return x.3
...
cases x.4
| ctor1 =>
  let x.5 := cons z.1 z.2
  jmp _jp.1 x.5
| ctor2 =>
  let x.6 := f x.4
  jmp _jp.1 x.6
```
This `simpJpCases?` converts it to
```lean
jp _jp.2 h t :=
  let x.1 := true
  let x.3 := h x.1
  return x.3
jp _jp.1 y :=
  let x.1 := true
  cases y
  | nil => let x.2 := g x.1; return x.2
  | cons h t => jmp _jp.2 h t
...
cases x.4
| ctor1 =>
  -- The constructor has been eliminated here
  jmp _jp.2 z.1 z.2
| ctor2 =>
  let x.6 := f x.4
  jmp _jp.1 x.6
```
Note that if all jumps to the join point are with constructors,
then the join point is eliminated as dead code.
-/
partial def simpJpCases? (code : Code) : CompilerM (Option Code) 
goal: ReaderT Lean.Compiler.LCNF.Simp.JpCasesInfoMap
  (StateRefT' IO.RealWorld Lean.Compiler.LCNF.Simp.Ctor2JpCasesAlt Lean.Compiler.LCNF.Simp.DiscrM)
  (Option Lean.Compiler.LCNF.Code)

full_name: Lean.Compiler.LCNF.Simp.simpJpCases?.visitJp?
code: /--
Try to optimize `jpCases` join points.
We say a join point is a `jpCases` when it satisfies the predicate `isJpCases`.
If we have a jump to `jpCases` with a constructor, then we can optimize the code by creating an new join point for
the constructor.
Example: suppose we have
```lean
jp _jp.1 y :=
  let x.1 := true
  cases y
  | nil => let x.2 := g x.1; return x.2
  | cons h t => let x.3 := h x.1; return x.3
...
cases x.4
| ctor1 =>
  let x.5 := cons z.1 z.2
  jmp _jp.1 x.5
| ctor2 =>
  let x.6 := f x.4
  jmp _jp.1 x.6
```
This `simpJpCases?` converts it to
```lean
jp _jp.2 h t :=
  let x.1 := true
  let x.3 := h x.1
  return x.3
jp _jp.1 y :=
  let x.1 := true
  cases y
  | nil => let x.2 := g x.1; return x.2
  | cons h t => jmp _jp.2 h t
...
cases x.4
| ctor1 =>
  -- The constructor has been eliminated here
  jmp _jp.2 z.1 z.2
| ctor2 =>
  let x.6 := f x.4
  jmp _jp.1 x.6
```
Note that if all jumps to the join point are with constructors,
then the join point is eliminated as dead code.
-/
partial def simpJpCases? (code : Code) : CompilerM (Option Code) 
goal: ReaderT Lean.Compiler.LCNF.Simp.JpCasesInfoMap
  (StateRefT' IO.RealWorld Lean.Compiler.LCNF.Simp.Ctor2JpCasesAlt Lean.Compiler.LCNF.Simp.DiscrM)
  (Option Lean.Compiler.LCNF.Code)

full_name: Lean.Compiler.LCNF.initFn._@..lake.packages.lean4.src.lean.Lean.Compiler.LCNF.Simp.JpCases._hyg.3502
code: builtin_initialize
  registerTraceClass `Compiler.simp.jpCases
goal: IO Unit