Skip to content

Commit c321866

Browse files
authored
Add name mangling pass to make VarIds globally unique (#120)
* Add name mangling pass to make VarIds globally unique * Use slightly more esoteric mangling to avoid clashes * Actually update the varNames map * Make LambdaLift use manglenames * Fix Lambda lift pass * Fix things after different binder structure * Still broken, waiting for types to appear in binders * Ok ok ok ok * Get it compiling * Passtests * Some small fixes * Use symbol table to generate fresh names in InsertRefCounting * Use symbol table to generate fresh names in LambdaLifting * Use symbol table to generate fresh names in DesugarPattern
1 parent 14444bb commit c321866

File tree

10 files changed

+375
-194
lines changed

10 files changed

+375
-194
lines changed

src/IR.hs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import IR.ExternToCall (externToCall)
2121
import IR.InsertRefCounting (insertRefCounting)
2222
import IR.LambdaLift (liftProgramLambdas)
2323
import IR.LowerAst (lowerProgram)
24+
import IR.MangleNames (mangleProgram)
2425
import IR.OptimizePar (optimizePar)
2526
import IR.Pattern (checkAnomaly)
2627
import IR.SegmentLets (segmentLets)
@@ -44,6 +45,7 @@ data Mode
4445
| DumpIRConstraints
4546
| DumpIRTyped
4647
| DumpIRTypedUgly
48+
| DumpIRMangled
4749
| DumpIRInlined
4850
| DumpIRTypedShow
4951
| DumpIRLifted
@@ -88,6 +90,11 @@ options =
8890
["dump-ir-typed-ugly"]
8991
(NoArg $ setMode DumpIRTypedShow)
9092
"Ugly-Print the fully-typed IR after type inference"
93+
, Option
94+
""
95+
["dump-ir-mangled"]
96+
(NoArg $ setMode DumpIRMangled)
97+
"Print the IR after mangling"
9198
, Option
9299
""
93100
["dump-ir-lifted"]
@@ -139,6 +146,8 @@ anomalycheck p = do
139146
-- | IR transformations to prepare for codegen.
140147
transform :: Options -> I.Program I.Type -> Pass (I.Program I.Type)
141148
transform opt p = do
149+
p <- mangleProgram p
150+
when (mode opt == DumpIRMangled) $ dump p
142151
p <- desugarPattern p
143152
p <- instProgram p
144153
p <- segmentLets p

src/IR/Constraint/Constrain.hs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ sprinkleVariables
2020
:: I.Program Can.Annotations -> TC (I.Program (Can.Annotations, Variable))
2121
sprinkleVariables prog = do
2222
sprinkledDefs <- mapM sprinkleDef (I.programDefs prog)
23-
return prog{I.programDefs = sprinkledDefs}
23+
return prog{I.programDefs = sprinkledDefs, I.symTable = I.uninitializedSymTable}
2424
where
2525
sprinkleDef (name, expr) = do
2626
name' <- mapM sprinkle name
@@ -35,4 +35,4 @@ discardAnnotations
3535
:: I.Program (Can.Annotations, Variable) -> I.Program Variable
3636
discardAnnotations sprinkledProg =
3737
let discardedDefs = map (bimap (fmap snd) (fmap snd)) (I.programDefs sprinkledProg)
38-
in sprinkledProg{I.programDefs = discardedDefs}
38+
in sprinkledProg{I.programDefs = discardedDefs, I.symTable = I.uninitializedSymTable}

src/IR/Constraint/Elaborate.hs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,4 +12,4 @@ run pVar = do
1212
exprs' <- mapM (mapM Type.toCanType) exprs
1313
let reattachBinders (I.BindVar v _) expr = (I.BindVar v $ I.extract expr, expr)
1414
reattachBinders (I.BindAnon _) expr = (I.BindAnon $ I.extract expr, expr)
15-
return $ pVar{I.programDefs = zipWith reattachBinders names exprs'}
15+
return $ pVar{I.programDefs = zipWith reattachBinders names exprs', I.symTable = I.uninitializedSymTable }

src/IR/DesugarPattern.hs

Lines changed: 37 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -13,21 +13,19 @@ import Common.Compiler as Compiler (
1313
Pass,
1414
fromString,
1515
)
16-
import Common.Identifiers (Identifier (..))
1716
import qualified IR.IR as I
17+
import qualified IR.MangleNames as I
1818

1919
import Common.Pretty (Pretty (..))
20-
import Control.Monad (forM, replicateM)
20+
import Control.Monad (forM)
2121
import Control.Monad.State.Lazy (
2222
MonadState,
2323
StateT (..),
24-
evalStateT,
2524
gets,
2625
modify,
2726
)
2827
import Data.Bifunctor (Bifunctor (..))
2928
import Data.Foldable (foldrM)
30-
import Data.Functor ((<&>))
3129
import qualified Data.Map as M
3230
import qualified Data.Set as S
3331

@@ -39,7 +37,6 @@ data CInfo = CInfo
3937
{ cName :: I.DConId
4038
, cType :: I.TConId
4139
, argsType :: [I.Type]
42-
, cArity :: Int
4340
}
4441
deriving (Eq, Show)
4542

@@ -54,7 +51,7 @@ data TInfo = TInfo
5451
data DesugarCtx = DesugarCtx
5552
{ typeMap :: M.Map I.TConId TInfo
5653
, consMap :: M.Map I.DConId CInfo
57-
, anonCount :: Int
54+
, symTable :: I.SymTable I.Type
5855
}
5956

6057

@@ -67,24 +64,18 @@ newtype DesugarFn a = DesugarFn (StateT DesugarCtx Compiler.Pass a)
6764
deriving (MonadState DesugarCtx) via (StateT DesugarCtx Compiler.Pass)
6865

6966

70-
runDesugarFn :: DesugarFn a -> DesugarCtx -> Compiler.Pass a
71-
runDesugarFn (DesugarFn m) = evalStateT m
67+
unDesugarFn :: DesugarFn a -> StateT DesugarCtx Compiler.Pass a
68+
unDesugarFn (DesugarFn a) = a
7269

7370

74-
freshVar :: DesugarFn Identifier
75-
freshVar = do
76-
currCount <- gets anonCount
77-
modify $ \ctx -> ctx{anonCount = anonCount ctx + 1}
78-
return $ fromString ("__pat_anon" ++ show currCount)
79-
80-
81-
buildCtx :: [(I.TConId, I.TypeDef)] -> DesugarCtx
82-
buildCtx tds =
83-
DesugarCtx
84-
{ anonCount = 0
85-
, typeMap = buildTypeMap tds
86-
, consMap = buildConsMap tds
87-
}
71+
freshVar :: I.Type -> DesugarFn I.VarId
72+
freshVar t = do
73+
syms <- gets symTable
74+
let origin = "__anonymous_pattern"
75+
name = I.pickId syms origin
76+
syms' = M.insert name I.SymInfo{I.symOrigin = origin, I.symType = t} syms
77+
modify $ \ctx -> ctx{symTable = syms'}
78+
return name
8879

8980

9081
-- TODO: this should be a pattern synonym
@@ -93,12 +84,12 @@ unreachableExpr = I.Exception $ I.ExceptDefault $ I.LitIntegral 0
9384

9485

9586
desugarPattern :: I.Program I.Type -> Compiler.Pass (I.Program I.Type)
96-
desugarPattern p@I.Program{I.programDefs = defs, I.typeDefs = tds} =
97-
(`runDesugarFn` buildCtx tds) $ do
98-
defs' <- mapM desugarExprsDefs defs
99-
return $ p{I.programDefs = defs'}
87+
desugarPattern p@I.Program{I.programDefs = defs, I.typeDefs = tds, I.symTable = syms} = do
88+
(defs', symTable -> syms') <- runStateT (unDesugarFn $ mapM desugarExprsDefs defs) initCtx
89+
return $ p{I.programDefs = defs', I.symTable = syms'}
10090
where
101-
desugarExprsDefs (vs, es) = desugarExpr es <&> (vs,)
91+
desugarExprsDefs (vs, es) = (vs,) <$> desugarExpr es
92+
initCtx = DesugarCtx{typeMap = buildTypeMap tds, consMap = buildConsMap tds, symTable = syms}
10293

10394

10495
desugarExpr :: I.Expr I.Type -> DesugarFn (I.Expr I.Type)
@@ -116,19 +107,19 @@ desugarExpr (I.Match e arms t) = do
116107
I.Var _ _ -> desugarMatch [e] eqns (unreachableExpr t) -- TODO: add let alias
117108
_ -> do
118109
-- Bind scrutinee to a variable before threading it through desugarMatch
119-
var <- I.VarId <$> freshVar
120110
let et = I.extract e
111+
var <- freshVar et
121112
I.Let [(I.BindVar var et, e)]
122113
<$> desugarMatch [I.Var var et] eqns (unreachableExpr t)
123114
<*> pure et
124115
desugarExpr e = return e
125116

126117

127-
desugarMatch
128-
:: [I.Expr I.Type]
129-
-> [Equation]
130-
-> I.Expr I.Type -- Default expression the 'I.Match' should return
131-
-> DesugarFn (I.Expr I.Type)
118+
desugarMatch ::
119+
[I.Expr I.Type] ->
120+
[Equation] ->
121+
I.Expr I.Type -> -- Default expression the 'I.Match' should return
122+
DesugarFn (I.Expr I.Type)
132123
desugarMatch [] [] def = return def
133124
desugarMatch [] (([], e) : _) _ = return e
134125
desugarMatch [] _ _ = error "can't happen 1"
@@ -190,27 +181,28 @@ desugarMatchCons (u : us) qs@(q : _) def = do
190181
getCon ((I.AltData dcon _ _) : _, _) = dcon
191182
getCon _ = error "can't happen 5"
192183
getTyp ((I.AltData _ _ t) : _, _) = t
193-
getTyp _ = error "no no no -- Simon Peyton Jones"
194-
makeBinder vid t = I.AltBinder $ I.BindVar vid t
184+
getTyp _ = error "no no no 555"
195185

196186
sameConsAs c = filter ((== c) . getCon) qs
197187

198188
desugarArm :: I.DConId -> I.Type -> [Equation] -> DesugarFn (I.Alt I.Type, I.Expr I.Type)
199189
desugarArm dcon dconTyp qs' = do
200-
k <- getArity dcon
201-
newIds <- replicateM k freshVar
202-
cinfo <- getCInfo dcon
203-
let newVars = I.VarId <$> newIds
204-
argsTyps = argsType cinfo
205-
bs' = zipWith makeBinder newVars argsTyps
206-
us' = zipWith I.Var newVars argsTyps
207-
qs'' = [(as' ++ as, e) | ((I.AltData _ as' _) : as, e) <- qs']
190+
argsTyps <- argsType <$> getCInfo dcon
191+
192+
(unzip -> (bs', us')) <- forM argsTyps $ \argTyp -> do
193+
name <- freshVar argTyp
194+
return (I.AltBinder $ I.BindVar name argTyp, I.Var name argTyp)
195+
208196
body <-
209197
if null qs'
210-
then -- We're done desugaring this equation, just use default body
198+
then do
199+
-- We're done desugaring this equation, just use default body
211200
return def
212-
else -- Recursively generate body from remaining equations
201+
else do
202+
-- Recursively generate body from remaining equations
203+
let qs'' = [(as' ++ as, e) | ((I.AltData _ as' _) : as, e) <- qs']
213204
desugarMatch (us' ++ us) qs'' def
205+
214206
return (I.AltData dcon bs' dconTyp, body)
215207
desugarMatchCons _ _ _ = error "can't happen 7"
216208

@@ -232,12 +224,6 @@ getConstructors dcon = do
232224
return $ tCSet t
233225

234226

235-
getArity :: I.DConId -> DesugarFn Int
236-
getArity dcon = do
237-
c <- getCInfo dcon
238-
return $ cArity c
239-
240-
241227
getCInfo :: I.DConId -> DesugarFn CInfo
242228
getCInfo dcon = gets (M.lookup dcon . consMap) >>= maybe (desugarError dcon) return
243229

@@ -269,5 +255,4 @@ buildConsMap = foldr (build . second I.variants) M.empty
269255
{ cName = dcon
270256
, cType = tcon
271257
, argsType = variantTypes typs
272-
, cArity = length $ variantTypes typs
273258
}

src/IR/IR.hs

Lines changed: 27 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
-- | Sslang's intermediate representation and its associated helpers.
99
module IR.IR (
1010
Program (..),
11+
SymInfo (..),
1112
TypeDef (..),
1213
TypeVariant (..),
1314
Binder (..),
@@ -37,6 +38,8 @@ module IR.IR (
3738
pattern BindAnon,
3839
binderToVar,
3940
Carrier,
41+
uninitializedSymTable,
42+
SymTable,
4043
) where
4144

4245
import Common.Identifiers (
@@ -52,6 +55,7 @@ import Data.Data (
5255
Typeable,
5356
)
5457

58+
import qualified Data.Map as M
5559
import Data.Maybe (
5660
catMaybes,
5761
mapMaybe,
@@ -67,16 +71,31 @@ import IR.Types.Type (
6771
)
6872

6973

70-
{- | Top-level compilation unit.
71-
72-
@t@ is the type system in use, e.g., "IR.Types.Flat"
73-
-}
74+
-- | Top-level compilation unit, parameterized by the type system.
7475
data Program t = Program
7576
{ programEntry :: VarId
7677
, cDefs :: String
7778
, externDecls :: [(VarId, Type)]
7879
, programDefs :: [(Binder t, Expr t)]
7980
, typeDefs :: [(TConId, TypeDef)]
81+
, symTable :: M.Map VarId (SymInfo t)
82+
}
83+
deriving (Eq, Show, Typeable, Data, Functor, Foldable, Traversable)
84+
85+
86+
{- | Contains information about all (globally unique) variable names.
87+
88+
Populated by name mangling pass.
89+
-}
90+
type SymTable t = M.Map VarId (SymInfo t)
91+
92+
93+
-- | Information stored in global symbol table.
94+
data SymInfo t = SymInfo
95+
{ -- | Original name of symbol
96+
symOrigin :: VarId
97+
, -- | Type information of symbol
98+
symType :: t
8099
}
81100
deriving (Eq, Show, Typeable, Data, Functor, Foldable, Traversable)
82101

@@ -409,6 +428,10 @@ binderToVar (BindVar v _) = Just v
409428
binderToVar _ = Nothing
410429

411430

431+
uninitializedSymTable :: M.Map VarId (SymInfo t)
432+
uninitializedSymTable = M.empty
433+
434+
412435
instance HasFreeVars (Expr t) VarId where
413436
freeVars (Var v _) = S.singleton v
414437
freeVars Data{} = S.empty

0 commit comments

Comments
 (0)