66import de .peeeq .wurstscript .intermediatelang .optimizer .BranchMerger ;
77import de .peeeq .wurstscript .intermediatelang .optimizer .ConstantAndCopyPropagation ;
88import de .peeeq .wurstscript .intermediatelang .optimizer .LocalMerger ;
9- import de .peeeq .wurstscript .intermediatelang .optimizer .SideEffectAnalyzer ;
109import de .peeeq .wurstscript .intermediatelang .optimizer .SimpleRewrites ;
1110import de .peeeq .wurstscript .jassIm .*;
1211import de .peeeq .wurstscript .translation .imtranslation .ImHelper ;
@@ -98,9 +97,6 @@ public void removeGarbage() {
9897 while (changes && iterations ++ < 10 ) {
9998 ImProg prog = trans .imProg ();
10099 trans .calculateCallRelationsAndUsedVariables ();
101- SideEffectAnalyzer sideEffectAnalyzer = new SideEffectAnalyzer (prog );
102- Map <ImFunction , Boolean > sideEffectCache = new HashMap <>();
103- Set <ImFunction > sideEffectInProgress = new HashSet <>();
104100
105101 // keep only used variables
106102 int globalsBefore = prog .getGlobals ().size ();
@@ -141,30 +137,25 @@ public void visit(ImSet e) {
141137 if (e .getLeft () instanceof ImVarAccess ) {
142138 ImVarAccess va = (ImVarAccess ) e .getLeft ();
143139 if (!trans .getReadVariables ().contains (va .getVar ()) && !TRVEHelper .protectedVariables .contains (va .getVar ().getName ())) {
144- List <ImExpr > sideEffects = collectSideEffects (e .getRight (), sideEffectAnalyzer , sideEffectCache , sideEffectInProgress );
145- replacements .add (Pair .create (e , sideEffects ));
140+ replacements .add (Pair .create (e , Collections .singletonList (e .getRight ())));
146141 }
147142 } else if (e .getLeft () instanceof ImVarArrayAccess ) {
148143 ImVarArrayAccess va = (ImVarArrayAccess ) e .getLeft ();
149144 if (!trans .getReadVariables ().contains (va .getVar ()) && !TRVEHelper .protectedVariables .contains (va .getVar ().getName ())) {
150- List <ImExpr > exprs = new ArrayList <>();
151- for (ImExpr index : va .getIndexes ()) {
152- exprs .addAll (collectSideEffects (index , sideEffectAnalyzer , sideEffectCache , sideEffectInProgress ));
153- }
154- exprs .addAll (collectSideEffects (e .getRight (), sideEffectAnalyzer , sideEffectCache , sideEffectInProgress ));
145+ // IMPORTANT: removeAll() clears parent references
146+ List <ImExpr > exprs = va .getIndexes ().removeAll ();
147+ exprs .add (e .getRight ());
155148 replacements .add (Pair .create (e , exprs ));
156149 }
157150 } else if (e .getLeft () instanceof ImTupleSelection ) {
158151 ImVar var = TypesHelper .getTupleVar ((ImTupleSelection ) e .getLeft ());
159152 if (var != null && !trans .getReadVariables ().contains (var ) && !TRVEHelper .protectedVariables .contains (var .getName ())) {
160- List <ImExpr > sideEffects = collectSideEffects (e .getRight (), sideEffectAnalyzer , sideEffectCache , sideEffectInProgress );
161- replacements .add (Pair .create (e , sideEffects ));
153+ replacements .add (Pair .create (e , Collections .singletonList (e .getRight ())));
162154 }
163155 } else if (e .getLeft () instanceof ImMemberAccess ) {
164156 ImMemberAccess va = ((ImMemberAccess ) e .getLeft ());
165157 if (!trans .getReadVariables ().contains (va .getVar ()) && !TRVEHelper .protectedVariables .contains (va .getVar ().getName ())) {
166- List <ImExpr > sideEffects = collectSideEffects (e .getRight (), sideEffectAnalyzer , sideEffectCache , sideEffectInProgress );
167- replacements .add (Pair .create (e , sideEffects ));
158+ replacements .add (Pair .create (e , Collections .singletonList (e .getRight ())));
168159 }
169160 }
170161 }
@@ -174,9 +165,7 @@ public void visit(ImSet e) {
174165 for (Pair <ImStmt , List <ImExpr >> pair : replacements ) {
175166 changes = true ;
176167 ImExpr r ;
177- if (pair .getB ().isEmpty ()) {
178- r = ImHelper .statementExprVoid (JassIm .ImStmts ());
179- } else if (pair .getB ().size () == 1 ) {
168+ if (pair .getB ().size () == 1 ) {
180169 r = pair .getB ().get (0 );
181170 // CRITICAL: Clear parent before reusing the node
182171 r .setParent (null );
@@ -198,83 +187,4 @@ public void visit(ImSet e) {
198187 }
199188 }
200189 }
201-
202- private List <ImExpr > collectSideEffects (ImExpr expr , SideEffectAnalyzer analyzer , Map <ImFunction , Boolean > cache ,
203- Set <ImFunction > inProgress ) {
204- if (expr == null ) {
205- return Collections .emptyList ();
206- }
207- if (hasSideEffects (expr , analyzer , cache , inProgress )) {
208- return Collections .singletonList (expr );
209- }
210- return Collections .emptyList ();
211- }
212-
213- private boolean hasSideEffects (ImExpr expr , SideEffectAnalyzer analyzer , Map <ImFunction , Boolean > cache ,
214- Set <ImFunction > inProgress ) {
215- if (expr instanceof ImDealloc || expr instanceof ImGetStackTrace || expr instanceof ImTypeVarDispatch ) {
216- return true ;
217- }
218- if (!SideEffectAnalyzer .quickcheckHasSideeffects (expr )) {
219- return false ;
220- }
221- for (ImVar var : analyzer .directlySetVariables (expr )) {
222- if (var .isGlobal ()) {
223- return true ;
224- }
225- }
226- for (ImFunction nativeFunc : analyzer .calledNatives (expr )) {
227- if (!UselessFunctionCallsRemover .isFunctionWithoutSideEffect (nativeFunc .getName ())) {
228- return true ;
229- }
230- }
231- for (ImFunction called : analyzer .calledFunctions (expr )) {
232- if (functionHasSideEffects (called , analyzer , cache , inProgress )) {
233- return true ;
234- }
235- }
236- return false ;
237- }
238-
239- private boolean functionHasSideEffects (ImFunction func , SideEffectAnalyzer analyzer , Map <ImFunction , Boolean > cache ,
240- Set <ImFunction > inProgress ) {
241- Boolean cached = cache .get (func );
242- if (cached != null ) {
243- return cached ;
244- }
245- if (func .isNative ()) {
246- boolean sideEffect = !UselessFunctionCallsRemover .isFunctionWithoutSideEffect (func .getName ());
247- cache .put (func , sideEffect );
248- return sideEffect ;
249- }
250- if (!inProgress .add (func )) {
251- return true ;
252- }
253- boolean sideEffect = false ;
254- for (ImVar var : analyzer .directlySetVariables (func .getBody ())) {
255- if (var .isGlobal ()) {
256- sideEffect = true ;
257- break ;
258- }
259- }
260- if (!sideEffect ) {
261- for (ImFunction nativeFunc : analyzer .calledNatives (func .getBody ())) {
262- if (!UselessFunctionCallsRemover .isFunctionWithoutSideEffect (nativeFunc .getName ())) {
263- sideEffect = true ;
264- break ;
265- }
266- }
267- }
268- if (!sideEffect ) {
269- for (ImFunction called : analyzer .calledFunctions (func .getBody ())) {
270- if (functionHasSideEffects (called , analyzer , cache , inProgress )) {
271- sideEffect = true ;
272- break ;
273- }
274- }
275- }
276- inProgress .remove (func );
277- cache .put (func , sideEffect );
278- return sideEffect ;
279- }
280190}
0 commit comments