Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Regalloc single bb #453

Open
wants to merge 63 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
63 commits
Select commit Hold shift + click to select a range
aae2e8d
chore: start adding SSA
bollu Jul 10, 2024
e54f217
chore: add register allocation only for constants
tobiasgrosser Jul 11, 2024
ca883aa
chore: add register allocation only for constants
tobiasgrosser Jul 11, 2024
e969a81
feat: implement core regalloc loop
tobiasgrosser Jul 11, 2024
cabd7bd
feat: strengthen register map invariants
tobiasgrosser Jul 11, 2024
2da7668
chore: lean complains that it is unable to generate eqn theorem
tobiasgrosser Jul 11, 2024
1f00ca1
chore: pre structural termination checkpoint
tobiasgrosser Jul 11, 2024
d602d91
Merge remote-tracking branch 'origin/main' into regalloc-single-bb
tobiasgrosser Jul 11, 2024
1a430ee
chore: regalloc WIP
tobiasgrosser Jul 11, 2024
4ef15aa
chore: build theory needed for stating stuff
tobiasgrosser Jul 11, 2024
e74e8f0
chore: progress
tobiasgrosser Jul 11, 2024
4288c65
chore: continue adding simp lemmas for expr execution
tobiasgrosser Jul 11, 2024
14a1712
chore: unify
tobiasgrosser Jul 11, 2024
5a9dd2e
chore: add RegisterFile API
tobiasgrosser Jul 11, 2024
f1f1d7d
chore: push a lil' more
tobiasgrosser Jul 11, 2024
a5dd211
chore: streamline proof with more simp lemmas
bollu Jul 12, 2024
0c4161d
chore: proceed with proof, now need to push soundness backwards throu…
bollu Jul 12, 2024
88ca015
chore: stash
bollu Jul 12, 2024
7dddf4e
chore: show that expression evaluation is sound
bollu Jul 12, 2024
7d1a1b4
chore: more lemmas about toFun, live registers
bollu Jul 12, 2024
4e41dda
think: trying to figure out statement for toFun_doExpr
bollu Jul 12, 2024
1126383
Merge remote-tracking branch 'origin/main' into regalloc-single-bb
tobiasgrosser Jul 14, 2024
3ef75a9
chore: realize where the proof gets complex
bollu Jul 12, 2024
5593200
chore: write paper proof
bollu Jul 15, 2024
57c1406
chore: add simp theorem for toFun_doincr
bollu Jul 15, 2024
31223c2
chore: show what an add expression does to the register file.
bollu Jul 15, 2024
b06480c
chore: make a section, now rename everything to be sensible
bollu Jul 15, 2024
b1bd7f2
chore: cleanup theorem statements to make sense
bollu Jul 15, 2024
f5ce229
more cleanup
bollu Jul 15, 2024
cf644ce
cleanup upto const theorems
bollu Jul 15, 2024
a1069da
chore: implement clean version of toFun_incrment
bollu Jul 15, 2024
42056eb
chore: some more cleanup
bollu Jul 15, 2024
5dff905
chore: realize what lemma I need
bollu Jul 15, 2024
3175a66
chore: prove that liveness is preserved forward as well
bollu Jul 15, 2024
b4ca4b1
chore: finish one part of proof by savagely unfolding definitions.
bollu Jul 15, 2024
8f2b843
chore: write down why proof is true
bollu Jul 15, 2024
27c8bf2
chore: get rid of another sorry
bollu Jul 15, 2024
89f60f0
chore: one more sorry
bollu Jul 15, 2024
a624ac3
chore: reduce aliasing burden to a single result \neq s
bollu Jul 16, 2024
c8db5bd
chore: build machinery about 'maybeLiveFor'
bollu Jul 16, 2024
5e110d5
feat: finish large proof, now prove hundreds of lemmata about the con…
bollu Jul 16, 2024
8db2f67
chore: get rid of another sorry
bollu Jul 16, 2024
a008e23
chore: remove a sorry by consolidating some code
bollu Jul 16, 2024
5df7856
bug: unexpected number of goals created from split
bollu Jul 16, 2024
34716b4
feat: show that we have a sound_mapping between the original program …
bollu Jul 16, 2024
e1e84b7
chore: add regalloc example
bollu Jul 16, 2024
41915b2
chore: remove a sorry, realize I need another assumption of non-dupli…
bollu Jul 16, 2024
74c7690
feat: clear set of sorries about hdead
bollu Jul 16, 2024
bc57cf3
chore: remove sorry from nodup
bollu Jul 16, 2024
bbf19ce
chore: kill sorry for hinj
bollu Jul 16, 2024
273ed01
chore: get rid of all sorrys and add guard messages
bollu Jul 16, 2024
8ca874a
chore: delete commented code
bollu Jul 16, 2024
9e62fa9
chore: add mathlib files for chordality
bollu Jul 17, 2024
d99c695
chore: start multiple BB implementation
bollu Jul 17, 2024
8b1b57f
chore: add chordal to top level file
bollu Jul 17, 2024
e886078
chore: add multiple BB notes
bollu Jul 18, 2024
e739a9a
chore: cleanup notes
bollu Jul 18, 2024
012e4bb
chore: add multi-bb impl, still unclear how best to model dominance
bollu Jul 18, 2024
bd24bce
chore: add jad pairing
bollu Jul 18, 2024
0d6ec94
chore: push paired version
bollu Jul 18, 2024
b6e77ff
Chore: covaluations
bollu Jul 18, 2024
67ed98f
chore: covaluations
bollu Jul 18, 2024
9acb0b7
Fixed bug
imbrem Jul 22, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions SSA.lean
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import SSA.Projects.DCE.DCE
import SSA.Projects.CSE.CSE
import SSA.Projects.PaperExamples.PaperExamples
import SSA.Projects.Scf.ScfFunctor
import SSA.Projects.Regalloc.Regalloc
import SSA.Projects.LeanMlirCommon.LeanMlirCommon


Expand Down
56 changes: 55 additions & 1 deletion SSA/Core/ErasedContext.lean
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,24 @@ theorem succ_eq_toSnoc {Γ : Ctxt Ty} {t : Ty} {w} (h : (Γ.snoc t).get? (w+1) =
⟨w+1, h⟩ = toSnoc ⟨w, h⟩ :=
rfl

@[simp]
theorem Ctxt.Var.toSnoc_neq_last {Γ : Ctxt Ty} {t : Ty} {v : Γ.Var t} :
v.toSnoc ≠ Ctxt.Var.last Γ t := by
unfold Ctxt.Var.toSnoc Ctxt.Var.last
rcases v with ⟨v, hv⟩
simp only []
have heq : v + 1 ≠ 0 := by omega
simp [heq]
intros hcontra
unfold last at hcontra
obtain ⟨h₁, h₂⟩ := hcontra

@[simp]
theorem Ctxt.Var.last_neq_toSnoc {Γ : Ctxt Ty} {t : Ty} {v : Γ.Var t} :
Ctxt.Var.last Γ t ≠ v.toSnoc := by
symm
simp

/-- Transport a variable from `Γ` to any mapped context `Γ.map f` -/
def toMap : Var Γ t → Var (Γ.map f) (f t)
| ⟨i, h⟩ => ⟨i, by
Expand Down Expand Up @@ -401,9 +419,45 @@ theorem Valuation.reassignVar_eq_of_lookup [DecidableEq Ty]
subst x
rfl


end Valuation

section CoValuation

variable [TyDenote Ty]

/-- A Covaluation for a context. Provide a value for some type in the context. -/
structure CoValuation (Γ : Ctxt Ty) where
t : Ty
var : Γ.Var t
val : toType t

/-- Eliminate a CoValuation of an empty context. -/
@[simp]
def CoValuation.elim_nil (V : CoValuation (∅ : Ctxt Ty)) : False :=
V.var.emptyElim

/-- Build a covaluation for a single type context. -/
def CoValuation.singleton (t : Ty) (v : toType t) : CoValuation [t] :=
⟨t, Var.last _ _, v⟩

/-- Build a CoValuation from a variable and a value. -/
def CoValuation.ofVar {Γ : Ctxt Ty} (v : Γ.Var α) (a : toType α) : CoValuation Γ :=
⟨α, v, a⟩

/-- transport/pullback a valuation along a context homomorphism. -/
def CoValuation.comap {Γi Γo : Ctxt Ty} (Γiv: Γi.CoValuation) (hom : Ctxt.Hom Γi Γo) : Γo.CoValuation where
t := Γiv.t
var := hom Γiv.var
val := Γiv.val

-- fun _to vo => Γiv (hom vo)

/-
TODO: write helpers to coerce to a from a value of 'toType Γ.Var α'.
We suspect that this will come up when reasoning about straight line code.
-/

end CoValuation

/- ## VarSet -/

Expand Down
16 changes: 15 additions & 1 deletion SSA/Core/Framework.lean
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,6 @@ inductive Expr : (Γ : Ctxt d.Ty) → (eff : EffectKind) → (ty : d.Ty) → Typ
(regArgs : HVector (fun t : Ctxt d.Ty × d.Ty => Com t.1 .impure t.2)
(DialectSignature.regSig op)) : Expr Γ eff ty


/-- A very simple intrinsically typed program: a sequence of let bindings.
Note that the `EffectKind` is uniform: if a `Com` is `pure`, then the expression and its body are pure,
and if a `Com` is `impure`, then both the expression and the body are impure!
Expand Down Expand Up @@ -2598,3 +2597,18 @@ def Expr.ty : Expr d Γ eff t → d.Ty := fun _ => t
def Expr.ctxt : Expr d Γ eff t → Ctxt d.Ty := fun _ => Γ

end TypeProjections

section FlatComReprInstance
/-!
## Repr instance to convert a FlatCom into a zipper.
-/

/-- Convert a `FlatCom` to a `Zipper` that is at the end of the `FlatCom` -/
def FlatCom.toZipperAtRet {Γ : Ctxt d.Ty} {eff : EffectKind} {t : d.Ty}
(fc : FlatCom d Γ eff Δ t) : Zipper d Γ eff Δ t := ⟨fc.lets, Com.ret fc.ret⟩

instance [DialectSignature d] [Repr d.Op] [Repr d.Ty] :
Repr (FlatCom d Γ eff Γ_out ty) where
reprPrec flatCom n := reprPrec flatCom.toZipperAtRet.toCom n

end FlatComReprInstance
26 changes: 26 additions & 0 deletions SSA/Projects/Regalloc/Chordal.lean
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/-
Properties of chordal graphs.
Proof that a chordal graphs possess a perfect eliminiation ordering.
This implies that greedy coloring is optimal for chordal graphs.
We also provide easy lemmas that make the fact that
the interference graph of a SSA program is chordal.

References:
- https://compilers.cs.uni-saarland.de/projects/ssara/
- Optimal register allocation for SSA form programs in polytime:
https://www.sciencedirect.com/science/article/pii/S0020019006000196?via%3Dihub
-/

/-
TODO: think if this can be written abstractly in terms
of a matroid?
-/
import Mathlib.Combinatorics.SimpleGraph.Basic
import Mathlib.Combinatorics.SimpleGraph.Coloring
import Mathlib.Combinatorics.SimpleGraph.Finite
import Mathlib.Combinatorics.SimpleGraph.Operations
import Mathlib.Combinatorics.SimpleGraph.Maps
import Mathlib.Combinatorics.SimpleGraph.IncMatrix
import Mathlib.Data.Matroid.Basic
import Mathlib.Data.Matroid.IndepAxioms
import Mathlib.Combinatorics.SimpleGraph.Acyclic -- dominator tree.
3 changes: 3 additions & 0 deletions SSA/Projects/Regalloc/Regalloc.lean
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import SSA.Projects.Regalloc.RegallocSingleBB
import SSA.Projects.Regalloc.Chordal
-- import SSA.Projects.Regalloc.RegallocMultipleBB
137 changes: 137 additions & 0 deletions SSA/Projects/Regalloc/RegallocMultipleBB.lean
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
import Init.Data.BitVec.Basic
import Init.Data.BitVec.Lemmas
import Init.Data.BitVec.Bitblast

-- 1) RegionTree in Polly, from our work in Polly:
-- 2) https://github.com/llvm/llvm-project/blob/7b08c2774ca7350b372f70f63135eacc04d739c5/llvm/include/llvm/Analysis/RegionInfo.h#L9-L22
-- Which is, in turn, based on the program structure Tree: https://en.wikipedia.org/wiki/Program_structure_tree
-- 3) LLVM's functional API for BB utils,
-- which we shall provide as a surface level API https://llvm.org/doxygen/BasicBlockUtils_8h.html
-- import SSA.Core.Framework
import Lean.Data.HashMap
import Mathlib.Init.Function
import Mathlib.CategoryTheory.Category.Basic

import SSA.Core.ErasedContext
import SSA.Core.HVector
import SSA.Core.EffectKind
import Mathlib.Control.Monad.Basic
import SSA.Core.Framework.Dialect
import Mathlib.Data.List.AList
import Mathlib.Data.Finset.Piecewise

open Ctxt (Var VarSet Valuation)
open TyDenote (toType)

namespace Pure

variable [TyDenote Ty]

/-- A simple term, consisting of variables, operations, pairs, units, and booleans -/
inductive Term (Γ : Ctxt Ty) : Ty → Type where
| var : {α : Ty} → (v : Γ.Var α) → Term Γ α
| val : {α : Ty} → (v : toType α) → Term Γ α
-- | op : φ → Term φ → Term φ
-- | let1 : Term φ → Term φ → Term φ
-- | pair : Term φ → Term φ → Term φ
-- | unit : Term φ
-- | let2 : Term φ → Term φ → Term φ
-- | inl : Term φ → Term φ
-- | inr : Term φ → Term φ
-- | case: Term φ → Term φ → Term φ → Term φ
-- | abort : Term φ → Term φ

-- inductive Wf : Ctx α ε → Region φ → LCtx α → Prop
-- | br : L.Trg n A → a.Wf Γ ⟨A, ⊥⟩ → Wf Γ (br n a) L
-- | case : a.Wf Γ ⟨Ty.coprod A B, e⟩
-- → s.Wf (⟨A, ⊥⟩::Γ) L
-- → t.Wf (⟨B, ⊥⟩::Γ) L
-- → Wf Γ (case a s t) L
-- | let1 : a.Wf Γ ⟨A, e⟩ → t.Wf (⟨A, ⊥⟩::Γ) L → (let1 a t).Wf Γ L
-- | let2 : a.Wf Γ ⟨(Ty.prod A B), e⟩ → t.Wf (⟨B, ⊥⟩::⟨A, ⊥⟩::Γ) L → (let2 a t).Wf Γ L
-- | cfg (n) {G} (R : LCtx α) :
-- (hR : R.length = n) → β.Wf Γ (R ++ L) →
-- (∀i : Fin n, (G i).Wf (⟨R.get (i.cast hR.symm), ⊥⟩::Γ) (R ++ L)) →
-- Wf Γ (cfg β n G) L

def Term.evaluate [TyDenote Ty] {Γ : Ctxt Ty} {ty : Ty} (t : Term Γ ty) (VΓ : Ctxt.Valuation Γ) : toType ty :=
match t with
| var v => VΓ v
| val v => v

-- def InS.br {Γ : Ctx α ε} {L : LCtx α} (ℓ) (a : Term.InS φ Γ ⟨A, ⊥⟩)
-- (hℓ : L.Trg ℓ A) : InS φ Γ L
-- := ⟨Region.br ℓ a, Wf.br hℓ a.2⟩


-- | TODO: add a thingie that coerces case into `Bool`.
-- def InS.case {Γ : Ctx α ε} {L : LCtx α} {A B e}
-- (a : Term.InS φ Γ ⟨Ty.coprod A B, e⟩) (s : InS φ (⟨A, ⊥⟩::Γ) L) (t : InS φ (⟨B, ⊥⟩::Γ) L) : InS φ Γ L

class TyHasCoprod (Ty : Type) where
coprod : Ty → Ty → Ty

class TyHasCoprodDenote (Ty : Type) [TyDenote Ty] [C : TyHasCoprod Ty] where
inl : toType α → toType (C.coprod α β)
inr : toType α → toType (C.coprod α β)
elim : (toType α → γ) → (toType β → γ) → toType (C.coprod α β) → γ

/- TODO: implement a thing `left? : toType (C.coprod α β) → Option (toType α)` using `elim`.
This will allow us to cleanup case_inl by writing `(ha : (l : toType α) ∈ a.evaluate VΓ |>.left?)`-/
/-
TODO: add lawful instance of TyHasCoprodDenote for proving properties about the universal property.
-/

instance : Append (Ctxt Ty) where
append Γ Δ := Γ.append Δ

inductive Region [C : TyHasCoprod Ty] : (Γ : Ctxt Ty) → (L : Ctxt Ty) → Type
| br (a : Term Γ α) (hl : L.Var α) : Region Γ L
| case (a : Term Γ (C.coprod α β)) (s : Region (Γ.snoc α) L) (t : Region (Γ.snoc β) L) : Region Γ L
| let₁ (a : Term Γ α) (t : Region (Γ.snoc α) L) : Region Γ L
-- | cfg {R L D : Ctxt Ty}
-- (hD : D = R ++ L)
-- (t : Region Γ D) -- t for terminator, G for fixpoint graph.
-- (G : R.Var α → Region (Γ.snoc α) D)
-- : Region Γ L
| cfg {Γ R L D : Ctxt Ty}
-- (hD : D = R ++ L)
(inL : Ctxt.Hom D (R ++ L))
(t : Region Γ D) -- t for terminator, G for fixpoint graph.
(G : ∀{α}, R.Var α → Region (Γ.snoc α) D)
: Region Γ L

def _root_.Ctxt.CoValuation.ofAppend {R L : Ctxt Ty} (VRL : Ctxt.CoValuation (R ++ L)) : (Ctxt.CoValuation R)⊕(Ctxt.CoValuation L) :=
sorry

/- Show that CoVal (R++L) splits as (Either (CoVal R) (CoVal L))-/
/--
Bigstep operational semantics for evaluation of a control flow graph.
-/
inductive Region.Evaluated [C : TyHasCoprod Ty] [CD : TyHasCoprodDenote Ty] :
(Γ : Ctxt Ty) → (VΓ : Ctxt.Valuation Γ) → (L : Ctxt Ty) → (R : Region Γ L) → (VL' : Ctxt.CoValuation L) → Prop
| br : Evaluated Γ VL L (Region.br a hl) (Ctxt.CoValuation.ofVar hl (a.evaluate VΓ))
| case_inl : (ha : a.evaluate VΓ = CD.inl (α := α) l)
→ Evaluated (Ctxt.snoc Γ α) (Ctxt.Valuation.snoc VΓ l) L t VL
→ Evaluated Γ VΓ L (Region.case a s t) VL
| case_inr : (ha : a.evaluate VΓ = CD.inr (β := β) r)
→ Evaluated (Ctxt.snoc Γ β) (Ctxt.Valuation.snoc VΓ r) L t VL
→ Evaluated Γ VΓ L (Region.case a s t) VL
| let₁
: Evaluated (Ctxt.snoc Γ α) (Ctxt.Valuation.snoc VΓ (a.evaluate VΓ)) L t VL
→ Evaluated Γ VΓ L (let₁ a t) VL
| cfg_sibling {inL : Ctxt.Hom D (R ++ L)}
: Evaluated Γ VΓ D t VL
→ (hVL : (VL.comap inL).ofAppend = Sum.inr S)
→ Evaluated Γ VΓ L (cfg inL t G) S
| cfg_child {Γ : Ctxt Ty} {VΓ : Γ.Valuation} {L R D : Ctxt Ty}
{VL : L.CoValuation} {VD : D.CoValuation} {inL : Ctxt.Hom D (R ++ L)}
{C : Ctxt.CoValuation R}
{t : Region Γ D}
{G : ∀ {α}, R.Var α → Region (Γ.snoc α) D}
: Evaluated Γ VΓ D t VD
→ (hVL : (VD.comap inL).ofAppend = Sum.inl (α := R.CoValuation) (β := L.CoValuation) C)
→ Evaluated Γ VΓ L (cfg inL (let₁ (Term.val C.val) (G C.var)) G) VL
→ Evaluated Γ VΓ L (cfg (Γ := Γ) (R := R) (L := L) (D := D) inL t G) VL

end Pure
Loading
Loading