0 | module Compiler.Opts.Identity
2 | import Core.CompileExpr
3 | import Core.Context.Log
6 | import Libraries.Data.List.SizeOf
8 | makeArgs : (args : Scope) -> List (Var (args ++ vars))
9 | makeArgs args = embed @{ListFreelyEmbeddable} (Var.allVars args)
11 | parameters (fn1 : Name) (idIdx : Nat)
14 | isUnsucc : Var vars -> CExp vars -> Maybe (Constant, Var (x :: vars))
15 | isUnsucc var (COp _ (Sub _) [CLocal _ p, CPrimVal _ c]) =
17 | then Just (c, first)
19 | isUnsucc _ _ = Nothing
21 | unsuccIdentity : Constant -> Var vars -> CExp vars -> Bool
22 | unsuccIdentity c1 var (COp _ (Add _) [exp, CPrimVal _ c2]) = c1 == c2 && cexpIdentity var Nothing Nothing exp
23 | unsuccIdentity _ _ _ = False
26 | cexpIdentity : Var vars -> Maybe (Name, List (Var vars)) -> Maybe Constant -> CExp vars -> Bool
27 | cexpIdentity var _ _ (CLocal fc p) = var == MkVar p
28 | cexpIdentity var _ _ (CRef {}) = False
29 | cexpIdentity var _ _ (CLam {}) = False
30 | cexpIdentity var con const (CLet _ _ NotInline val sc) = False
31 | cexpIdentity var con const (CLet _ _ _ val sc) = (case isUnsucc var val of
32 | Just (c, var') => unsuccIdentity c var' sc
36 | (map (map (map weaken)) con)
39 | cexpIdentity var con const (CApp _ (CRef _ fn2) as) =
41 | case getAt idIdx as of
42 | Just exp => cexpIdentity var con const exp
44 | cexpIdentity _ _ _ (CApp {}) = False
45 | cexpIdentity var (Just (con1, as1)) const (CCon _ con2 _ _ as2) =
49 | eqArgs : List (Var vars) -> List (CExp vars) -> Bool
51 | eqArgs (v :: vs) (a :: as) = cexpIdentity v Nothing Nothing a && eqArgs vs as
53 | cexpIdentity var Nothing const (CCon {}) = False
60 | cexpIdentity var _ _ (COp _ (Add _) [a1, a2]) = case a2 of
61 | CPrimVal _ c1 => case a1 of
62 | CApp _ (CRef _ fn2) as =>
64 | && (case getAt idIdx as of
65 | Just (COp _ (Sub _) [a3, (CPrimVal _ c2)]) =>
66 | c1 == c2 && cexpIdentity var Nothing Nothing a3
70 | cexpIdentity var _ _ (COp {}) = False
71 | cexpIdentity var _ _ (CExtPrim {}) = False
72 | cexpIdentity var _ _ (CForce {}) = False
73 | cexpIdentity var _ _ (CDelay {}) = False
74 | cexpIdentity var con const (CConCase _ sc xs x) =
75 | cexpIdentity var Nothing Nothing sc
77 | && maybeVarEq var con const x
80 | altEq : CConAlt vars -> Bool
81 | altEq (MkConAlt y _ _ args exp) =
83 | (weakenNs (mkSizeOf args) var)
84 | (Just (y, makeArgs args))
87 | cexpIdentity var con const (CConstCase fc sc xs x) =
88 | cexpIdentity var Nothing Nothing sc
90 | && maybeVarEq var con const x
92 | altEq : CConstAlt vars -> Bool
93 | altEq (MkConstAlt c exp) = cexpIdentity var con (Just c) exp
94 | cexpIdentity _ _ (Just c1) (CPrimVal _ c2) = c1 == c2
95 | cexpIdentity _ _ Nothing (CPrimVal {}) = False
96 | cexpIdentity _ _ _ (CErased _) = False
97 | cexpIdentity _ _ _ (CCrash {}) = False
100 | maybeVarEq : Var vars -> Maybe (Name, List (Var vars)) -> Maybe Constant -> Maybe (CExp vars) -> Bool
101 | maybeVarEq _ _ _ Nothing = True
102 | maybeVarEq var con const (Just exp) = cexpIdentity var con const exp
104 | checkIdentity : (fullName : Name) -> List (Var vars) -> CExp vars -> Nat -> Maybe Nat
105 | checkIdentity _ [] _ _ = Nothing
106 | checkIdentity fn (v :: vs) exp idx = if cexpIdentity fn idx v Nothing Nothing exp
108 | else checkIdentity fn vs exp (S idx)
110 | calcIdentity : (fullName : Name) -> CDef -> Maybe Nat
111 | calcIdentity fn (MkFun args exp) = checkIdentity fn (Var.allVars args) exp Z
112 | calcIdentity _ _ = Nothing
114 | getArg : FC -> Nat -> (args : Scope) -> Maybe (CExp args)
115 | getArg _ _ [] = Nothing
116 | getArg fc Z (a :: _) = Just $
CLocal fc First
117 | getArg fc (S k) (_ :: as) = weaken <$> getArg fc k as
119 | idCDef : Nat -> CDef -> Maybe CDef
120 | idCDef idx (MkFun args exp) = MkFun args <$> getArg (getFC exp) idx args
121 | idCDef _ def = Just def
124 | rewriteIdentityFlag : Ref Ctxt Defs => Name -> Core ()
125 | rewriteIdentityFlag fn = do
127 | Just (fnIdx, gdef) <- lookupCtxtExactI fn defs.gamma
128 | | Nothing => pure ()
129 | let Just flg@(Identity idx) = find isId gdef.flags
131 | log "compiler.identity" 5 $
"found identity flag for: "
132 | ++ show !(getFullName fn) ++ ", " ++ show idx
133 | ++ "\n\told def: " ++ show gdef.compexpr
134 | let Just cdef = the _ $
gdef.compexpr >>= idCDef idx
135 | | Nothing => pure ()
136 | log "compiler.identity" 5 $
"\tnew def: " ++ show cdef
137 | unsetFlag EmptyFC (Resolved fnIdx) flg
138 | setFlag EmptyFC (Resolved fnIdx) Inline
139 | setCompiled (Resolved fnIdx) cdef
141 | isId : DefFlag -> Bool
142 | isId (Identity _) = True
146 | setIdentity : Ref Ctxt Defs => Name -> Core ()
147 | setIdentity fn = do
149 | Just (fnIdx, gdef) <- lookupCtxtExactI fn defs.gamma
150 | | Nothing => pure ()
151 | let Just idx = the _ $
gdef.compexpr >>= calcIdentity fn
152 | | Nothing => pure ()
153 | setFlag EmptyFC (Resolved fnIdx) (Identity idx)
154 | rewriteIdentityFlag (Resolved fnIdx)