Skip to content

Commit 6f0a742

Browse files
committed
Revert "Emit less garbage without opts, if it has no side effects"
This reverts commit 044797f.
1 parent 044797f commit 6f0a742

5 files changed

Lines changed: 7 additions & 336 deletions

File tree

de.peeeq.wurstscript/src/main/java/de/peeeq/wurstio/WurstCompilerJassImpl.java

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -561,11 +561,6 @@ public JassProg transformProgToJass() {
561561
// translate flattened intermediate lang to jass:
562562

563563
beginPhase(14, "translate to jass");
564-
optimizer.removeGarbage();
565-
imProg.flatten(imTranslator);
566-
imTranslator.removeEmptyPackageInits();
567-
optimizer.removeGarbage();
568-
imProg.flatten(imTranslator);
569564
getImTranslator().calculateCallRelationsAndUsedVariables();
570565
ImToJassTranslator translator =
571566
new ImToJassTranslator(getImProg(), getImTranslator().getCalledFunctions(), getImTranslator().getMainFunc(), getImTranslator().getConfFunc());

de.peeeq.wurstscript/src/main/java/de/peeeq/wurstscript/translation/imoptimizer/ImOptimizer.java

Lines changed: 7 additions & 97 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
import de.peeeq.wurstscript.intermediatelang.optimizer.BranchMerger;
77
import de.peeeq.wurstscript.intermediatelang.optimizer.ConstantAndCopyPropagation;
88
import de.peeeq.wurstscript.intermediatelang.optimizer.LocalMerger;
9-
import de.peeeq.wurstscript.intermediatelang.optimizer.SideEffectAnalyzer;
109
import de.peeeq.wurstscript.intermediatelang.optimizer.SimpleRewrites;
1110
import de.peeeq.wurstscript.jassIm.*;
1211
import 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
}

de.peeeq.wurstscript/src/main/java/de/peeeq/wurstscript/translation/imtranslation/EliminateTuples.java

Lines changed: 0 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -455,29 +455,6 @@ private static ImStatementExpr inSet(ImSet imSet, ImFunction f) {
455455
+ "\nLHS=" + left + "\nRHS=" + right);
456456
}
457457

458-
boolean allLiteral = true;
459-
for (ImExpr r : rhsLeaves) {
460-
if (!isSimpleLiteral(r)) {
461-
allLiteral = false;
462-
break;
463-
}
464-
}
465-
466-
if (allLiteral) {
467-
for (int i = 0; i < lhsLeaves.size(); i++) {
468-
ImLExpr l = lhsLeaves.get(i);
469-
ImType targetT = l.attrTyp();
470-
ImExpr r = rhsLeaves.get(i);
471-
if (r instanceof ImNull) {
472-
r = ImHelper.defaultValueForComplexType(targetT);
473-
}
474-
l.setParent(null);
475-
r.setParent(null);
476-
stmts.add(JassIm.ImSet(imSet.getTrace(), l, r));
477-
}
478-
return ImHelper.statementExprVoid(stmts);
479-
}
480-
481458
// 4) Evaluate RHS leaves first into temps (preserve side-effect order & alias safety)
482459
List<ImVar> temps = new ArrayList<>(rhsLeaves.size());
483460
for (int i = 0; i < rhsLeaves.size(); i++) {
@@ -508,14 +485,6 @@ private static ImStatementExpr inSet(ImSet imSet, ImFunction f) {
508485
return ImHelper.statementExprVoid(stmts);
509486
}
510487

511-
private static boolean isSimpleLiteral(ImExpr expr) {
512-
return expr instanceof ImBoolVal
513-
|| expr instanceof ImIntVal
514-
|| expr instanceof ImRealVal
515-
|| expr instanceof ImStringVal
516-
|| expr instanceof ImNull;
517-
}
518-
519488
/** Flatten LHS recursively into addressable leaves (ImLExpr), hoisting side-effects */
520489
private static void flattenLhsTuple(ImExpr e, List<ImLExpr> out, ImStmts sideStmts) {
521490
ImExpr x = extractSideEffect(e, sideStmts);

de.peeeq.wurstscript/src/main/java/de/peeeq/wurstscript/translation/imtranslation/ImTranslator.java

Lines changed: 0 additions & 148 deletions
Original file line numberDiff line numberDiff line change
@@ -183,154 +183,6 @@ public ImProg translateProg() {
183183
}
184184
}
185185

186-
public void removeEmptyPackageInits() {
187-
Set<ImFunction> emptyInitFunctions = new HashSet<>();
188-
for (ImFunction initFunc : imProg.getFunctions()) {
189-
if (initFunc.getName().startsWith("init_") && isTrivialInitFunction(initFunc)) {
190-
emptyInitFunctions.add(initFunc);
191-
}
192-
}
193-
if (emptyInitFunctions.isEmpty()) {
194-
return;
195-
}
196-
197-
Map<ImVar, ImFunction> initFuncRefs = collectInitFuncRefs();
198-
removeInitCallsFromMain(emptyInitFunctions, initFuncRefs);
199-
removeInitFuncRefsFromGlobals(emptyInitFunctions);
200-
imProg.getFunctions().removeIf(emptyInitFunctions::contains);
201-
initFuncMap.values().removeIf(emptyInitFunctions::contains);
202-
}
203-
204-
private boolean isTrivialInitFunction(ImFunction initFunc) {
205-
if (initFunc.getBody().isEmpty()) {
206-
return true;
207-
}
208-
if (initFunc.getBody().size() != 1) {
209-
return false;
210-
}
211-
ImStmt stmt = initFunc.getBody().get(0);
212-
if (!(stmt instanceof ImReturn)) {
213-
return false;
214-
}
215-
ImExprOpt returnValue = ((ImReturn) stmt).getReturnValue();
216-
if (returnValue instanceof ImNoExpr) {
217-
return true;
218-
}
219-
return returnValue instanceof ImBoolVal && ((ImBoolVal) returnValue).getValB();
220-
}
221-
222-
private void removeInitCallsFromMain(Set<ImFunction> emptyInitFunctions, Map<ImVar, ImFunction> initFuncRefs) {
223-
ImFunction main = getMainFunc();
224-
if (main == null) {
225-
return;
226-
}
227-
228-
ImFunction native_TriggerAddCondition = getNativeFunc("TriggerAddCondition");
229-
ImFunction native_Condition = getNativeFunc("Condition");
230-
ImFunction native_ClearTrigger = getNativeFunc("TriggerClearConditions");
231-
232-
ImStmts mainBody = main.getBody();
233-
for (int i = 0; i < mainBody.size(); i++) {
234-
ImStmt stmt = mainBody.get(i);
235-
if (stmt instanceof ImFunctionCall) {
236-
ImFunctionCall call = (ImFunctionCall) stmt;
237-
if (emptyInitFunctions.contains(call.getFunc())) {
238-
mainBody.remove(i--);
239-
continue;
240-
}
241-
if (native_TriggerAddCondition != null && native_Condition != null
242-
&& call.getFunc() == native_TriggerAddCondition
243-
&& hasInitCondition(call, native_Condition, emptyInitFunctions, initFuncRefs)) {
244-
if (i + 2 < mainBody.size()
245-
&& mainBody.get(i + 1) instanceof ImIf
246-
&& isTriggerClear(mainBody.get(i + 2), native_ClearTrigger)) {
247-
mainBody.remove(i + 2);
248-
mainBody.remove(i + 1);
249-
mainBody.remove(i--);
250-
}
251-
}
252-
}
253-
}
254-
}
255-
256-
private void removeInitFuncRefsFromGlobals(Set<ImFunction> emptyInitFunctions) {
257-
ImFunction globalInit = getGlobalInitFunc();
258-
if (globalInit == null) {
259-
return;
260-
}
261-
ImStmts body = globalInit.getBody();
262-
for (int i = 0; i < body.size(); i++) {
263-
ImStmt stmt = body.get(i);
264-
if (!(stmt instanceof ImSet)) {
265-
continue;
266-
}
267-
ImExpr right = ((ImSet) stmt).getRight();
268-
if (right instanceof ImFuncRef && emptyInitFunctions.contains(((ImFuncRef) right).getFunc())) {
269-
body.remove(i--);
270-
}
271-
}
272-
}
273-
274-
private Map<ImVar, ImFunction> collectInitFuncRefs() {
275-
ImFunction globalInit = getGlobalInitFunc();
276-
if (globalInit == null) {
277-
return Collections.emptyMap();
278-
}
279-
Map<ImVar, ImFunction> refs = new HashMap<>();
280-
ImStmts body = globalInit.getBody();
281-
for (int i = 0; i < body.size(); i++) {
282-
ImStmt stmt = body.get(i);
283-
if (!(stmt instanceof ImSet)) {
284-
continue;
285-
}
286-
ImSet set = (ImSet) stmt;
287-
if (!(set.getLeft() instanceof ImVarAccess)) {
288-
continue;
289-
}
290-
if (!(set.getRight() instanceof ImFuncRef)) {
291-
continue;
292-
}
293-
refs.put(((ImVarAccess) set.getLeft()).getVar(), ((ImFuncRef) set.getRight()).getFunc());
294-
}
295-
return refs;
296-
}
297-
298-
private boolean hasInitCondition(ImFunctionCall call, ImFunction nativeCondition, Set<ImFunction> emptyInitFunctions,
299-
Map<ImVar, ImFunction> initFuncRefs) {
300-
if (call.getArguments().size() < 2) {
301-
return false;
302-
}
303-
ImExpr conditionExpr = call.getArguments().get(1);
304-
if (!(conditionExpr instanceof ImFunctionCall)) {
305-
return false;
306-
}
307-
ImFunctionCall conditionCall = (ImFunctionCall) conditionExpr;
308-
if (conditionCall.getFunc() != nativeCondition) {
309-
return false;
310-
}
311-
if (conditionCall.getArguments().size() != 1) {
312-
return false;
313-
}
314-
ImExpr argument = conditionCall.getArguments().get(0);
315-
if (argument instanceof ImFuncRef) {
316-
ImFuncRef funcRef = (ImFuncRef) argument;
317-
return emptyInitFunctions.contains(funcRef.getFunc());
318-
}
319-
if (argument instanceof ImVarAccess) {
320-
ImVar var = ((ImVarAccess) argument).getVar();
321-
ImFunction target = initFuncRefs.get(var);
322-
return target != null && emptyInitFunctions.contains(target);
323-
}
324-
return false;
325-
}
326-
327-
private boolean isTriggerClear(ImStmt stmt, ImFunction nativeClearTrigger) {
328-
if (nativeClearTrigger == null) {
329-
return false;
330-
}
331-
return stmt instanceof ImFunctionCall && ((ImFunctionCall) stmt).getFunc() == nativeClearTrigger;
332-
}
333-
334186
/**
335187
* Number all the compiletime functions and expressions,
336188
* so that the one with the lowest number can be executed first.

0 commit comments

Comments
 (0)