737737
738738# ## Common subexprssion evaluation
739739
740- @inline newsym (:: Type{T} ) where T = Sym {T} (gensym (" cse" ))
740+ """
741+ newsym!(state::CSEState, ::Type{T})
742+
743+ Generates new symbol of type `T` with unique name in `state`.
744+ """
745+ @inline function newsym! (state, :: Type{T} ) where T
746+ name = " ##cse#$(state. varid[]) "
747+ state. varid[] += 1
748+ Sym {T} (Symbol (name))
749+ end
741750
742751"""
743752 $(TYPEDSIGNATURES)
@@ -769,11 +778,15 @@ struct CSEState
769778 A mapping of symbolic expression to the LHS in `sorted_exprs` that computes it.
770779 """
771780 visited:: IdDict{Any, Any}
781+ """
782+ Integer counter, used to generate unique names for intermediate variables.
783+ """
784+ varid:: Ref{Int}
772785end
773786
774- CSEState () = CSEState (Union{Assignment, DestructuredArgs}[], IdDict ())
787+ CSEState () = CSEState (Union{Assignment, DestructuredArgs}[], IdDict (), Ref ( 1 ) )
775788
776- Base. copy (x:: CSEState ) = CSEState (copy (x. sorted_exprs), copy (x. visited))
789+ Base. copy (x:: CSEState ) = CSEState (copy (x. sorted_exprs), copy (x. visited), Ref (x . varid[]) )
777790
778791"""
779792 $(TYPEDSIGNATURES)
@@ -860,13 +873,13 @@ function cse!(expr::Symbolic, state::CSEState)
860873 if arg isa Union{Tuple, AbstractArray}
861874 if arg isa Tuple
862875 new_arg = cse! (MakeTuple (arg), state)
863- sym = newsym ( Tuple{symtype .(arg)... })
876+ sym = newsym! (state, Tuple{symtype .(arg)... })
864877 elseif issparse (arg)
865878 new_arg = cse! (MakeSparseArray (arg), state)
866- sym = newsym ( AbstractSparseArray{symtype (eltype (arg)), indextype (arg), ndims (arg)})
879+ sym = newsym! (state, AbstractSparseArray{symtype (eltype (arg)), indextype (arg), ndims (arg)})
867880 else
868881 new_arg = cse! (MakeArray (arg, typeof (arg)), state)
869- sym = newsym ( AbstractArray{symtype (eltype (arg)), ndims (arg)})
882+ sym = newsym! (state, AbstractArray{symtype (eltype (arg)), ndims (arg)})
870883 end
871884 push! (state. sorted_exprs, sym ← new_arg)
872885 state. visited[arg] = sym
@@ -877,7 +890,7 @@ function cse!(expr::Symbolic, state::CSEState)
877890 # use `term` instead of `maketerm` because we only care about the operation being performed
878891 # and not the representation. This avoids issues with `newsym` symbols not having sizes, etc.
879892 new_expr = term (operation (expr), args... ; type = symtype (expr))
880- sym = newsym ( symtype (new_expr))
893+ sym = newsym! (state, symtype (new_expr))
881894 push! (state. sorted_exprs, sym ← new_expr)
882895 return sym
883896 end
0 commit comments