Skip to content

Commit

Permalink
Merge e7c9d8e into 53e60e8
Browse files Browse the repository at this point in the history
  • Loading branch information
Frotty committed Sep 5, 2018
2 parents 53e60e8 + e7c9d8e commit dd54e0d
Show file tree
Hide file tree
Showing 2 changed files with 74 additions and 11 deletions.
Expand Up @@ -4,16 +4,18 @@
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import de.peeeq.wurstscript.jassIm.*;
import de.peeeq.wurstscript.translation.imtranslation.FunctionFlagEnum;
import de.peeeq.wurstscript.translation.imtranslation.ImHelper;
import de.peeeq.wurstscript.translation.imtranslation.ImTranslator;
import de.peeeq.wurstscript.translation.imtranslation.*;

import java.util.*;

import static de.peeeq.wurstscript.jassIm.JassIm.ImStatementExpr;
import static de.peeeq.wurstscript.jassIm.JassIm.ImStmts;

public class ImInliner {
private static final String FORCEINLINE = "@inline";
private static final String NOINLINE = "@noinline";

private static final double THRESHOLD_MODIFIER_CONSTANT_ARG = 2;

private static final Set<String> dontInline = Sets.newLinkedHashSet();
private ImTranslator translator;
Expand All @@ -24,9 +26,10 @@ public class ImInliner {
private Set<ImFunction> done = Sets.newLinkedHashSet();
private double inlineTreshold = 50;

static {
static {
dontInline.add("SetPlayerAllianceStateAllyBJ");
dontInline.add("InitBlizzard");
dontInline.add("error");
}

public ImInliner(ImTranslator translator) {
Expand All @@ -37,7 +40,7 @@ public ImInliner(ImTranslator translator) {
public void doInlining() {
prog.flatten(translator);
collectInlinableFunctions();
rateInitalizableFunctions();
rateInlinableFunctions();
inlineFunctions();
}

Expand Down Expand Up @@ -66,7 +69,7 @@ private ImFunction inlineFunctions(ImFunction f, Element parent, int parentI, El
if (e instanceof ImFunctionCall) {
ImFunctionCall call = (ImFunctionCall) e;
ImFunction called = call.getFunc();
if (f != called && shouldInline(called)) {
if (f != called && shouldInline(call, called)) {
if (alreadyInlined.getOrDefault(called, 0) < 5) { // check maximum to ensure termination
inlineCall(f, parent, parentI, call);
// translator.removeCallRelation(f, called); // XXX is it safe to remove this call relation?
Expand Down Expand Up @@ -158,9 +161,9 @@ public void visit(ImFunctionCall called) {

}

private void rateInitalizableFunctions() {
for (ImFunction f : translator.getCalledFunctions().values()) {
incCallCount(f);
private void rateInlinableFunctions() {
for (Map.Entry<ImFunction, ImFunction> f : translator.getCalledFunctions().entries()) {
incCallCount(f.getKey());
}
for (ImFunction f : inlinableFunctions) {
int size = estimateSize(f);
Expand All @@ -173,6 +176,16 @@ private double getRating(ImFunction f) {
return Double.MAX_VALUE;
}

for (FunctionFlag flag : f.getFlags()) {
if (flag instanceof FunctionFlagAnnotation) {
if (((FunctionFlagAnnotation) flag).getAnnotation().equals(FORCEINLINE)) {
return 1;
} else if (((FunctionFlagAnnotation) flag).getAnnotation().equals(NOINLINE)) {
return Double.MAX_VALUE;
}
}
}

double size = getFuncSize(f);
if (size < 20) {
// always inline small functions
Expand All @@ -193,15 +206,23 @@ private int getFuncSize(ImFunction f) {
}
}

private boolean shouldInline(ImFunction f) {
private boolean shouldInline(ImFunctionCall call, ImFunction f) {
if (f.isNative()) {
return false;
}

double threshold = inlineTreshold;
for (ImExpr arg : call.getArguments()) {
if (arg instanceof ImConst) {
threshold *= THRESHOLD_MODIFIER_CONSTANT_ARG;
break;
}
}
// WLogger.info("Should I inline function " + f.getName() + "?");
// WLogger.info(" ininable: " + inlinableFunctions.contains(f));
// WLogger.info(" rating: " + getRating(f));
return inlinableFunctions.contains(f)
&& getRating(f) < inlineTreshold
&& getRating(f) < threshold
&& !isRecursive(f);
}

Expand Down
Expand Up @@ -738,4 +738,46 @@ public void optimizeDuplicateNullSets() throws IOException {
assertEquals(compiledAndOptimized.indexOf("u = null"), compiledAndOptimized.lastIndexOf("u = null"));
}

@Test
public void testInlineAnnotation() throws IOException {
testAssertOkLinesWithStdLib(false,
"package Test",
"@inline function over9000(int i, boolean b, real r)",
" var s = \"\"",
" s += r.toString()",
" s += i.toString()",
" s += b.toString()",
" if s.length() > 5",
" print(s)",
" print(\"end\")",
"function over9001(int i, boolean b, real r)",
" var s = \"\"",
" s += r.toString()",
" s += i.toString()",
" s += b.toString()",
" if s.length() > 5",
" print(s)",
" print(\"end\")",
"function foo()",
" over9000(141, true and true, 12315.233)",
" over9001(141, true and true, 12315.233)",
"function bar()",
" print(\"end\")",
"@noinline function noot()",
" print(\"end\")",
"init",
" over9000(12412411, true and true, 12315.233)",
" over9001(12412411, true and true, 12315.233)",
" foo()",
" bar()",
" noot()"

);
String inlined = Files.toString(new File("test-output/OptimizerTests_testInlineAnnotation_inl.j"), Charsets.UTF_8);
assertFalse(inlined.contains("function bar"));
assertFalse(inlined.contains("function over9000"));
assertTrue(inlined.contains("function over9001"));
assertTrue(inlined.contains("function noot"));
}

}

0 comments on commit dd54e0d

Please sign in to comment.