Skip to content

Commit 010c9be

Browse files
committed
More index-loop conversion for allocation-sensitive passes
1 parent dd5977c commit 010c9be

3 files changed

Lines changed: 114 additions & 51 deletions

File tree

de.peeeq.wurstscript/src/main/java/de/peeeq/wurstscript/intermediatelang/optimizer/LocalMerger.java

Lines changed: 43 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -67,8 +67,11 @@ private void mergeLocals(Map<ImStmt, Set<ImVar>> livenessInfo, ImFunction func)
6767
ImVar v = queue.poll();
6868
boolean merged = false;
6969

70-
for (ImVar color : colors) {
71-
if (!canMerge(color.getType(), v.getType())) continue;
70+
for (int colorIndex = 0; colorIndex < colors.size(); colorIndex++) {
71+
ImVar color = colors.get(colorIndex);
72+
if (!canMerge(color.getType(), v.getType())) {
73+
continue;
74+
}
7275
if (localPlayerContextAnalyzer != null
7376
&& (localPlayerContextAnalyzer.isLocalPlayerDependent(v)
7477
|| localPlayerContextAnalyzer.isLocalPlayerDependent(color))) {
@@ -110,7 +113,9 @@ private static void applyMerges(ImFunction func, Map<ImVar, ImVar> merges) {
110113
}
111114
@Override public void visit(ImVarargLoop varargLoop) {
112115
super.visit(varargLoop);
113-
for (ImVarargLoopVar loopVar : varargLoop.getLoopVars()) {
116+
List<ImVarargLoopVar> loopVars = varargLoop.getLoopVars();
117+
for (int i = 0; i < loopVars.size(); i++) {
118+
ImVarargLoopVar loopVar = loopVars.get(i);
114119
ImVar m = merges.get(loopVar.getVar());
115120
if (m != null) loopVar.setVar(m);
116121
}
@@ -127,13 +132,20 @@ private static int removeUnusedLocals(ImFunction f) {
127132
@Override public void visit(ImVarArrayAccess vaa) { super.visit(vaa); used.add(vaa.getVar()); }
128133
@Override public void visit(ImVarargLoop loop) {
129134
super.visit(loop);
130-
loop.getLoopVars().forEach(v -> used.add(v.getVar()));
135+
for (int i = 0; i < loop.getLoopVars().size(); i++) {
136+
used.add(loop.getLoopVars().get(i).getVar());
137+
}
131138
}
132139
});
133140
List<ImVar> locals = new ArrayList<>(f.getLocals());
134141
int before = locals.size();
135142
List<ImVar> kept = new ArrayList<>(locals.size());
136-
for (ImVar v : locals) if (used.contains(v)) kept.add(v);
143+
for (int i = 0; i < locals.size(); i++) {
144+
ImVar v = locals.get(i);
145+
if (used.contains(v)) {
146+
kept.add(v);
147+
}
148+
}
137149
if (kept.size() != locals.size()) { f.getLocals().clear(); f.getLocals().addAll(kept); }
138150
return before - kept.size();
139151
}
@@ -183,7 +195,8 @@ private void eliminateDeadCode(Map<ImStmt, Set<ImVar>> livenessInfo) {
183195
AstEdits.deleteStmt(s); // remove the dead assignment entirely
184196
} else {
185197
ImStmts block = JassIm.ImStmts();
186-
for (ImExpr e : raw) {
198+
for (int i = 0; i < raw.size(); i++) {
199+
ImExpr e = raw.get(i);
187200
// wrap expression as a statement; add a *copy* to avoid re-parenting conflicts
188201
block.add(ImHelper.statementExprVoid(e.copy()));
189202
}
@@ -195,10 +208,22 @@ private void eliminateDeadCode(Map<ImStmt, Set<ImVar>> livenessInfo) {
195208

196209
private static void collectLhsSideEffects(ImLExpr lhs, List<ImExpr> out) {
197210
if (lhs instanceof ImVarArrayAccess a) {
198-
for (ImExpr idx : a.getIndexes()) if (hasSideEffects(idx)) out.add(idx);
211+
ImExprs indexes = a.getIndexes();
212+
for (int i = 0; i < indexes.size(); i++) {
213+
ImExpr idx = indexes.get(i);
214+
if (hasSideEffects(idx)) {
215+
out.add(idx);
216+
}
217+
}
199218
} else if (lhs instanceof ImMemberAccess m) {
200219
if (hasSideEffects(m.getReceiver())) out.add(m.getReceiver());
201-
for (ImExpr idx : m.getIndexes()) if (hasSideEffects(idx)) out.add(idx);
220+
ImExprs indexes = m.getIndexes();
221+
for (int i = 0; i < indexes.size(); i++) {
222+
ImExpr idx = indexes.get(i);
223+
if (hasSideEffects(idx)) {
224+
out.add(idx);
225+
}
226+
}
202227
} else if (lhs instanceof ImTupleSelection ts) {
203228
Element t = ts.getTupleExpr();
204229
if (hasSideEffects(t)) out.add((ImExpr) t);
@@ -255,7 +280,12 @@ public Map<ImStmt, Set<ImVar>> calculateLiveness(ImFunction func) {
255280
@Override public void case_ImVarArrayAccess(ImVarArrayAccess e) { e.getIndexes().accept(me); }
256281
@Override public void case_ImMemberAccess(ImMemberAccess e) { e.getReceiver().accept(me); e.getIndexes().accept(me); }
257282
@Override public void case_ImStatementExpr(ImStatementExpr e) { e.getStatements().accept(me); ((ImLExpr) e.getExpr()).match(this); }
258-
@Override public void case_ImTupleExpr(ImTupleExpr e) { for (ImExpr ex : e.getExprs()) ((ImLExpr) ex).match(this); }
283+
@Override public void case_ImTupleExpr(ImTupleExpr e) {
284+
ImExprs exprs = e.getExprs();
285+
for (int i = 0; i < exprs.size(); i++) {
286+
((ImLExpr) exprs.get(i)).match(this);
287+
}
288+
}
259289
});
260290
}
261291
});
@@ -291,14 +321,16 @@ protected Collection<Node> getIncidentNodes(Node t) {
291321
for (int i = 0; i < N; i++) { in[i] = new ObjectOpenHashSet<>(); out[i] = new ObjectOpenHashSet<>(); }
292322

293323
// 5. Iterate over SCCs in reverse topological order
294-
for (List<Node> scc : sccs) {
324+
for (int sccIndex = 0; sccIndex < sccs.size(); sccIndex++) {
325+
List<Node> scc = sccs.get(sccIndex);
295326
if (scc.isEmpty()) continue;
296327

297328
// Iterate within this SCC until a fixed point is reached for all its nodes.
298329
boolean changedInScc = true;
299330
while (changedInScc) {
300331
changedInScc = false;
301-
for (Node u_node : scc) {
332+
for (int uIndex = 0; uIndex < scc.size(); uIndex++) {
333+
Node u_node = scc.get(uIndex);
302334
int u_idx = idx.getInt(u_node);
303335

304336
// Recalculate OUT[u] from the IN sets of its successors.

de.peeeq.wurstscript/src/main/java/de/peeeq/wurstscript/intermediatelang/optimizer/LocalPlayerContextAnalyzer.java

Lines changed: 34 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -181,8 +181,9 @@ private boolean methodReturnsLocalPlayerDependentValue(ImMethod method) {
181181
if (localPlayerDependentReturns.contains(method.getImplementation())) {
182182
return true;
183183
}
184-
for (ImMethod subMethod : method.getSubMethods()) {
185-
if (methodReturnsLocalPlayerDependentValue(subMethod)) {
184+
List<ImMethod> subMethods = method.getSubMethods();
185+
for (int i = 0; i < subMethods.size(); i++) {
186+
if (methodReturnsLocalPlayerDependentValue(subMethods.get(i))) {
186187
return true;
187188
}
188189
}
@@ -259,9 +260,12 @@ private void indexElementAfterChildren(Element element, ImFunction owner, Object
259260
} else if (element instanceof ImMemberAccess) {
260261
addDependency(variableFact(((ImMemberAccess) element).getVar()), element);
261262
} else if (element instanceof ImVarargLoop) {
263+
ImVarargLoop loop = (ImVarargLoop) element;
262264
ImVar varargParameter = varargParameter(owner);
263265
if (varargParameter != null) {
264-
for (ImVarargLoopVar loopVar : ((ImVarargLoop) element).getLoopVars()) {
266+
List<ImVarargLoopVar> loopVars = loop.getLoopVars();
267+
for (int i = 0; i < loopVars.size(); i++) {
268+
ImVarargLoopVar loopVar = loopVars.get(i);
265269
addDependency(variableFact(varargParameter), variableFact(loopVar.getVar()));
266270
}
267271
}
@@ -292,7 +296,8 @@ private void scheduleStatementSequence(ImStmts statements,
292296
Deque<IndexTask> work) {
293297
List<IndexTask> tasks = new ArrayList<>(statements.size());
294298
Object continuationControl = controlContext;
295-
for (ImStmt statement : statements) {
299+
for (int i = 0; i < statements.size(); i++) {
300+
ImStmt statement = statements.get(i);
296301
addDependency(statement, statements);
297302
tasks.add(new IndexTask(statement, continuationControl, false));
298303

@@ -380,6 +385,8 @@ private void indexFunctionCall(ImFunctionCall call, ImFunction owner, Object con
380385
ImFunction called = call.getFunc();
381386
addDependency(returnFact(called), call);
382387
addDependency(useFact(called), useFact(owner));
388+
List<ImExpr> arguments = call.getArguments();
389+
List<ImVar> calledParameters = called.getParameters();
383390
if (!called.isNative()) {
384391
addEnclosingControlDependency(controlContext, entryControlFact(called));
385392
}
@@ -388,19 +395,20 @@ private void indexFunctionCall(ImFunctionCall call, ImFunction owner, Object con
388395
addLocalPlayerSource(called);
389396
}
390397

391-
int fixedParameterCount = called.getParameters().size();
398+
int fixedParameterCount = calledParameters.size();
392399
if (called.hasFlag(IS_VARARG) && fixedParameterCount > 0) {
393400
fixedParameterCount--;
394401
}
395-
int positionalCount = Math.min(call.getArguments().size(), fixedParameterCount);
402+
int argumentCount = arguments.size();
403+
int positionalCount = Math.min(argumentCount, fixedParameterCount);
396404
for (int i = 0; i < positionalCount; i++) {
397-
addDependency(call.getArguments().get(i),
398-
variableFact(called.getParameters().get(i)));
405+
addDependency(arguments.get(i),
406+
variableFact(calledParameters.get(i)));
399407
}
400408
ImVar varargParameter = varargParameter(called);
401409
if (varargParameter != null) {
402-
for (int i = fixedParameterCount; i < call.getArguments().size(); i++) {
403-
addDependency(call.getArguments().get(i),
410+
for (int i = fixedParameterCount; i < argumentCount; i++) {
411+
addDependency(arguments.get(i),
404412
variableFact(varargParameter));
405413
}
406414
}
@@ -425,14 +433,18 @@ private void indexMethodCall(ImMethodCall call, ImFunction owner, Object control
425433
addDependency(unknownDispatchSource, useFact(owner));
426434
}
427435

436+
List<ImExpr> arguments = call.getArguments();
428437
for (ImFunction implementation : implementations) {
429438
addDependency(returnFact(implementation), call);
430439
addDependency(useFact(implementation), useFact(owner));
431440
addEnclosingControlDependency(controlContext, entryControlFact(implementation));
432-
for (ImVar parameter : implementation.getParameters()) {
433-
addDependency(call.getReceiver(), variableFact(parameter));
434-
for (ImExpr argument : call.getArguments()) {
435-
addDependency(argument, variableFact(parameter));
441+
Element receiver = call.getReceiver();
442+
List<ImVar> parameters = implementation.getParameters();
443+
for (int i = 0; i < parameters.size(); i++) {
444+
ImVar parameter = parameters.get(i);
445+
addDependency(receiver, variableFact(parameter));
446+
for (int j = 0; j < arguments.size(); j++) {
447+
addDependency(arguments.get(j), variableFact(parameter));
436448
}
437449
}
438450
}
@@ -487,8 +499,9 @@ private boolean collectMethodImplementations(ImMethod method,
487499
return method != null && method.getImplementation() != null;
488500
}
489501
implementations.add(method.getImplementation());
490-
for (ImMethod subMethod : method.getSubMethods()) {
491-
if (!collectMethodImplementations(subMethod, implementations, visited)) {
502+
List<ImMethod> subMethods = method.getSubMethods();
503+
for (int i = 0; i < subMethods.size(); i++) {
504+
if (!collectMethodImplementations(subMethods.get(i), implementations, visited)) {
492505
return false;
493506
}
494507
}
@@ -508,9 +521,11 @@ private void forEachAssignedVariable(ImLExpr left, Consumer<ImVar> consumer) {
508521
forEachAssignedVariable((ImLExpr) tupleExpr, consumer);
509522
}
510523
} else if (left instanceof ImTupleExpr) {
511-
for (ImExpr expr : ((ImTupleExpr) left).getExprs()) {
512-
if (expr instanceof ImLExpr) {
513-
forEachAssignedVariable((ImLExpr) expr, consumer);
524+
ImExprs exprs = ((ImTupleExpr) left).getExprs();
525+
for (int i = 0; i < exprs.size(); i++) {
526+
ImExpr expr = exprs.get(i);
527+
if (expr instanceof ImLExpr lExpr) {
528+
forEachAssignedVariable(lExpr, consumer);
514529
}
515530
}
516531
} else if (left instanceof ImStatementExpr) {

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

Lines changed: 37 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@
1010
import java.util.Arrays;
1111
import java.util.Collections;
1212
import java.util.List;
13-
import java.util.stream.Collectors;
1413

1514
import static de.peeeq.wurstscript.jassIm.JassIm.*;
1615

@@ -136,7 +135,8 @@ public static class Result {
136135
public Result(List<ImStmt> stmts, ImExpr expr) {
137136
Preconditions.checkArgument(expr.getParent() == null, "expression must not have a parent");
138137
boolean b = true;
139-
for (ImStmt s : stmts) {
138+
for (int i = 0; i < stmts.size(); i++) {
139+
ImStmt s = stmts.get(i);
140140
if (s.getParent() != null) {
141141
b = false;
142142
break;
@@ -286,8 +286,8 @@ private static ImStmts flattenStatements(ImStmts statements, ImTranslator t, ImF
286286
}
287287

288288
private static void flattenStatementsInto(List<ImStmt> result, ImStmts statements, ImTranslator t, ImFunction f) {
289-
for (ImStmt s : statements) {
290-
s.flatten(t, f).intoStatements(result, t, f);
289+
for (int i = 0; i < statements.size(); i++) {
290+
statements.get(i).flatten(t, f).intoStatements(result, t, f);
291291
}
292292
}
293293

@@ -494,35 +494,48 @@ public static void flattenProg(ImProg imProg, ImTranslator translator) {
494494
// Choose execution strategy based on flags and size
495495
if (USE_PARALLEL_EXECUTION) {
496496
int total = imProg.getFunctions().size();
497-
for (ImClass c : imProg.getClasses()) {
498-
total += c.getFunctions().size();
497+
List<ImClass> classes = imProg.getClasses();
498+
for (int i = 0; i < classes.size(); i++) {
499+
total += classes.get(i).getFunctions().size();
499500
}
500501
if (total >= PARALLEL_THRESHOLD) {
501502
// Collect once for parallel traversal.
502503
List<ImFunction> allFunctions = new ArrayList<>(total);
503504
allFunctions.addAll(imProg.getFunctions());
504-
for (ImClass c : imProg.getClasses()) {
505-
allFunctions.addAll(c.getFunctions());
505+
for (int i = 0; i < classes.size(); i++) {
506+
allFunctions.addAll(classes.get(i).getFunctions());
506507
}
507508
allFunctions.parallelStream().forEach(f -> f.flatten(translator));
508509
} else {
509-
for (ImFunction f : imProg.getFunctions()) {
510-
f.flatten(translator);
510+
List<ImFunction> functions = imProg.getFunctions();
511+
for (int i = 0; i < functions.size(); i++) {
512+
ImFunction function = functions.get(i);
513+
function.flatten(translator);
511514
}
512-
for (ImClass c : imProg.getClasses()) {
513-
for (ImFunction f : c.getFunctions()) {
514-
f.flatten(translator);
515+
List<ImClass> classes = imProg.getClasses();
516+
for (int i = 0; i < classes.size(); i++) {
517+
ImClass c = classes.get(i);
518+
List<ImFunction> classFunctions = c.getFunctions();
519+
for (int j = 0; j < classFunctions.size(); j++) {
520+
ImFunction function = classFunctions.get(j);
521+
function.flatten(translator);
515522
}
516523
}
517524
}
518525
} else {
519526
// Sequential processing avoids intermediate list/lambda overhead.
520-
for (ImFunction f : imProg.getFunctions()) {
521-
f.flatten(translator);
527+
List<ImFunction> functions = imProg.getFunctions();
528+
for (int i = 0; i < functions.size(); i++) {
529+
ImFunction function = functions.get(i);
530+
function.flatten(translator);
522531
}
523-
for (ImClass c : imProg.getClasses()) {
524-
for (ImFunction f : c.getFunctions()) {
525-
f.flatten(translator);
532+
List<ImClass> classes = imProg.getClasses();
533+
for (int i = 0; i < classes.size(); i++) {
534+
ImClass c = classes.get(i);
535+
List<ImFunction> classFunctions = c.getFunctions();
536+
for (int j = 0; j < classFunctions.size(); j++) {
537+
ImFunction function = classFunctions.get(j);
538+
function.flatten(translator);
526539
}
527540
}
528541
}
@@ -665,9 +678,12 @@ public static Result flatten(ImVarargLoop s, ImTranslator translator, ImFunction
665678
}
666679

667680
private static ImVarargLoopVars copyVarargLoopVars(ImVarargLoopVars loopVars) {
668-
return JassIm.ImVarargLoopVars(loopVars.stream()
669-
.map(v -> JassIm.ImVarargLoopVar(v.getVar()))
670-
.collect(Collectors.toList()));
681+
int n = loopVars.size();
682+
List<ImVarargLoopVar> copiedVars = new ArrayList<>(n);
683+
for (int i = 0; i < n; i++) {
684+
copiedVars.add(JassIm.ImVarargLoopVar(loopVars.get(i).getVar()));
685+
}
686+
return JassIm.ImVarargLoopVars(copiedVars);
671687
}
672688

673689

0 commit comments

Comments
 (0)