Skip to content

Commit e1df8a6

Browse files
committed
Update ImInliner.java
1 parent f7266a4 commit e1df8a6

1 file changed

Lines changed: 62 additions & 13 deletions

File tree

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

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

Lines changed: 62 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import com.google.common.collect.Lists;
44
import com.google.common.collect.Maps;
55
import com.google.common.collect.Sets;
6+
import de.peeeq.wurstscript.WLogger;
67
import de.peeeq.wurstscript.jassIm.*;
78
import de.peeeq.wurstscript.translation.imtranslation.*;
89
import de.peeeq.wurstscript.types.TypesHelper;
@@ -20,6 +21,7 @@ public class ImInliner {
2021
private static final double THRESHOLD_MODIFIER_CONSTANT_ARG = 2;
2122

2223
private static final Set<String> dontInline = Sets.newLinkedHashSet();
24+
private static final boolean LOG_INLINER = Boolean.getBoolean("wurst.inliner.log");
2325
private final ImTranslator translator;
2426
private final ImProg prog;
2527
private final Set<ImFunction> inlinableFunctions = Sets.newLinkedHashSet();
@@ -71,7 +73,14 @@ private ImFunction inlineFunctions(ImFunction f, Element parent, int parentI, El
7173
if (e instanceof ImFunctionCall) {
7274
ImFunctionCall call = (ImFunctionCall) e;
7375
ImFunction called = call.getFunc();
74-
if (f != called && shouldInline(call, called)) {
76+
boolean canInline = f != called && shouldInline(call, called);
77+
if (LOG_INLINER) {
78+
String msg = "[INLINER] caller=" + f.getName() + " callee=" + called.getName() + " decision=" + (canInline ? "inline" : "keep") +
79+
(canInline ? "" : " reason=" + skipReason(call, called));
80+
WLogger.info(msg);
81+
System.out.println(msg);
82+
}
83+
if (canInline) {
7584
if (alreadyInlined.getOrDefault(called, 0) < 5) { // check maximum to ensure termination
7685
inlineCall(f, parent, parentI, call);
7786
// translator.removeCallRelation(f, called); // XXX is it safe to remove this call relation?
@@ -100,6 +109,33 @@ private ImFunction inlineFunctions(ImFunction f, Element parent, int parentI, El
100109
return null;
101110
}
102111

112+
private String skipReason(ImFunctionCall call, ImFunction f) {
113+
if (f.isNative()) {
114+
return "native";
115+
}
116+
if (call.getCallType() == CallType.EXECUTE) {
117+
return "execute_call";
118+
}
119+
if (!inlinableFunctions.contains(f)) {
120+
return "not_in_inlinable_set";
121+
}
122+
if (isRecursive(f)) {
123+
return "recursive";
124+
}
125+
double threshold = inlineTreshold;
126+
for (ImExpr arg : call.getArguments()) {
127+
if (arg instanceof ImConst) {
128+
threshold *= THRESHOLD_MODIFIER_CONSTANT_ARG;
129+
break;
130+
}
131+
}
132+
double rating = getRating(f);
133+
if (rating >= threshold) {
134+
return "rating_too_high(" + rating + ">=" + threshold + ")";
135+
}
136+
return "unknown";
137+
}
138+
103139
private void inlineCall(ImFunction f, Element parent, int parentI, ImFunctionCall call) {
104140
ImFunction called = call.getFunc();
105141
if (called == f) {
@@ -229,7 +265,8 @@ private ImStmt rewriteStmtForEarlyReturn(ImStmt s, ImVar doneVar, ImVar retVar)
229265
loopBody.addAll(rewriteForEarlyReturns(l.getBody().copy(), doneVar, retVar).removeAll());
230266
return JassIm.ImVarargLoop(l.getTrace(), loopBody, l.getLoopVar());
231267
}
232-
return s;
268+
// Keep tree ownership valid when rewrapping statements into new blocks.
269+
return s.copy();
233270
}
234271

235272
private void rateInlinableFunctions() {
@@ -346,22 +383,34 @@ private int getCallCount(ImFunction f) {
346383

347384
private void collectInlinableFunctions() {
348385
for (ImFunction f : ImHelper.calculateFunctionsOfProg(prog)) {
349-
if (f.hasFlag(FunctionFlagEnum.IS_COMPILETIME_NATIVE) || f.hasFlag(FunctionFlagEnum.IS_NATIVE)) {
350-
// do not inline natives
351-
continue;
352-
}
353-
if (f == translator.getGlobalInitFunc()) {
354-
continue;
386+
if (isInlineCandidate(f)) {
387+
inlinableFunctions.add(f);
355388
}
356-
if (f.hasFlag(IS_VARARG)) {
357-
// do not inline vararg functions
358-
// this is only relevant for lua, because in JASS they are eliminated before inlining
359-
continue;
389+
}
390+
// Some call targets can survive in the call graph but not in prog/classes lists.
391+
for (ImFunction f : translator.getCalledFunctions().values()) {
392+
if (isInlineCandidate(f)) {
393+
inlinableFunctions.add(f);
360394
}
361-
inlinableFunctions.add(f);
362395
}
363396
}
364397

398+
private boolean isInlineCandidate(ImFunction f) {
399+
if (f.hasFlag(FunctionFlagEnum.IS_COMPILETIME_NATIVE) || f.hasFlag(FunctionFlagEnum.IS_NATIVE)) {
400+
// do not inline natives
401+
return false;
402+
}
403+
if (f == translator.getGlobalInitFunc()) {
404+
return false;
405+
}
406+
if (f.hasFlag(IS_VARARG)) {
407+
// do not inline vararg functions
408+
// this is only relevant for lua, because in JASS they are eliminated before inlining
409+
return false;
410+
}
411+
return true;
412+
}
413+
365414
private boolean maxOneReturn(ImFunction f) {
366415
return maxOneReturn(f.getBody());
367416
}

0 commit comments

Comments
 (0)