Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package de.peeeq.wurstscript.intermediatelang.optimizer;

import de.peeeq.wurstscript.jassIm.*;
import de.peeeq.wurstscript.translation.imoptimizer.OptimizerPass;
import de.peeeq.wurstscript.translation.imtranslation.ImTranslator;

import java.util.ListIterator;
Expand All @@ -11,15 +10,17 @@
* <p>
* the input must be a flattened program
*/
public class BranchMerger implements OptimizerPass {
public class BranchMerger implements LocalPlayerAwareOptimizerPass {
private SideEffectAnalyzer sideEffectAnalyzer;
private LocalPlayerContextAnalyzer localPlayerContextAnalyzer;
public int branchesMerged = 0;

@Override
public int optimize(ImTranslator trans) {
public int optimize(ImTranslator trans, LocalPlayerContextAnalyzer analyzer) {
branchesMerged = 0;
ImProg prog = trans.getImProg();
this.sideEffectAnalyzer = new SideEffectAnalyzer(prog);
this.localPlayerContextAnalyzer = analyzer;

for (ImFunction func : prog.getFunctions()) {
optimizeFunc(func);
Expand Down Expand Up @@ -52,6 +53,7 @@ public void visit(ImStmts stmts) {
// if first statement in both branches is the same
// and has no side-effects that could affect the if-condition:
if (firstStmtThen.structuralEquals(firstStmtElse)
&& !localPlayerContextAnalyzer.isLocalPlayerDependent(ifStmt.getCondition())
&& !sideEffectAnalyzer.mightAffect(firstStmtThen, ifStmt.getCondition())) {
// remove statements
ifStmt.getThenBlock().remove(0);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
import de.peeeq.wurstscript.WurstOperator;
import de.peeeq.wurstscript.intermediatelang.optimizer.ControlFlowGraph.Node;
import de.peeeq.wurstscript.jassIm.*;
import de.peeeq.wurstscript.translation.imoptimizer.OptimizerPass;
import de.peeeq.wurstscript.translation.imtranslation.ImHelper;
import de.peeeq.wurstscript.translation.imtranslation.ImTranslator;
import de.peeeq.wurstscript.types.TypesHelper;
Expand All @@ -17,11 +16,13 @@

import static de.peeeq.wurstscript.WurstOperator.*;

public class ConstantAndCopyPropagation implements OptimizerPass {
public class ConstantAndCopyPropagation implements LocalPlayerAwareOptimizerPass {
private int totalPropagated = 0;
private @Nullable LocalPlayerContextAnalyzer localPlayerContextAnalyzer;

public int optimize(ImTranslator trans) {
public int optimize(ImTranslator trans, LocalPlayerContextAnalyzer analyzer) {
ImProg prog = trans.getImProg();
localPlayerContextAnalyzer = analyzer;

totalPropagated = 0;
for (ImFunction func : ImHelper.calculateFunctionsOfProg(prog)) {
Expand Down Expand Up @@ -144,6 +145,11 @@ void optimizeFunc(ImFunction func) {
rewriteCode(cfg, knowledge);
}

void optimizeFunc(ImFunction func, LocalPlayerContextAnalyzer analyzer) {
localPlayerContextAnalyzer = analyzer;
optimizeFunc(func);
}

private void rewriteCode(ControlFlowGraph cfg, Map<Node, Knowledge> knowledge) {
for (Node node : cfg.getNodes()) {
ImStmt stmt = node.getStmt();
Expand Down Expand Up @@ -311,7 +317,13 @@ private void analyzeComponent(List<Node> scc, Map<Node, Knowledge> knowledge) {

// Constant folding is intentionally centralized in SimpleRewrites.
// This pass performs propagation only to keep fold semantics in one place.
if (right instanceof ImConst) {
if (localPlayerContextAnalyzer != null
&& localPlayerContextAnalyzer.isLocalPlayerDependent(right)) {
// Keep GetLocalPlayer-derived values at their original
// variable boundary. This is deliberately conservative:
// later rewrites must still be able to see that boundary.
newValue = null;
} else if (right instanceof ImConst) {
newValue = Value.tryValue(right);
} else if (right instanceof ImVarAccess) {
ImVar varRight = ((ImVarAccess) right).getVar();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,11 @@ private void optimize() {
Preconditions.checkArgument(func.getReturnType() instanceof ImVoid, "func must return void");
// run some basic optimizations first:
func.flatten(tr);
new ConstantAndCopyPropagation().optimizeFunc(func);
LocalPlayerContextAnalyzer localPlayerContextAnalyzer =
new LocalPlayerContextAnalyzer(tr.getImProg());
new ConstantAndCopyPropagation().optimizeFunc(func, localPlayerContextAnalyzer);
// new TempMerger().optimizeFunc(func);
new LocalMerger().optimizeFunc(func);
new LocalMerger().optimizeFunc(func, localPlayerContextAnalyzer);
Set<ImVar> usedVars = UsedVariables.calculate(func);
func.getLocals().removeIf(v -> !usedVars.contains(v));
func.flatten(tr);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
import de.peeeq.datastructures.GraphInterpreter;
import de.peeeq.wurstscript.intermediatelang.optimizer.ControlFlowGraph.Node;
import de.peeeq.wurstscript.jassIm.*;
import de.peeeq.wurstscript.translation.imoptimizer.OptimizerPass;
import de.peeeq.wurstscript.translation.imtranslation.ImHelper;
import de.peeeq.wurstscript.translation.imtranslation.ImTranslator;
import de.peeeq.wurstscript.types.TypesHelper;
Expand All @@ -14,12 +13,14 @@

import java.util.*;

public class LocalMerger implements OptimizerPass {
public class LocalMerger implements LocalPlayerAwareOptimizerPass {
private int totalLocalsMerged = 0;
private LocalPlayerContextAnalyzer localPlayerContextAnalyzer;

@Override
public int optimize(ImTranslator trans) {
public int optimize(ImTranslator trans, LocalPlayerContextAnalyzer analyzer) {
ImProg prog = trans.getImProg();
localPlayerContextAnalyzer = analyzer;
totalLocalsMerged = 0;
for (ImFunction func : de.peeeq.wurstscript.translation.imtranslation.ImHelper.calculateFunctionsOfProg(prog)) {
if (!func.isNative() && !func.isBj()) {
Expand All @@ -38,6 +39,11 @@ void optimizeFunc(ImFunction func) {
mergeLocals(livenessInfo, func);
}

void optimizeFunc(ImFunction func, LocalPlayerContextAnalyzer analyzer) {
localPlayerContextAnalyzer = analyzer;
optimizeFunc(func);
}

private boolean canMerge(ImType a, ImType b) { return a.equalsType(b); }

private void mergeLocals(Map<ImStmt, Set<ImVar>> livenessInfo, ImFunction func) {
Expand All @@ -63,6 +69,11 @@ private void mergeLocals(Map<ImStmt, Set<ImVar>> livenessInfo, ImFunction func)

for (ImVar color : colors) {
if (!canMerge(color.getType(), v.getType())) continue;
if (localPlayerContextAnalyzer != null
&& (localPlayerContextAnalyzer.isLocalPlayerDependent(v)
|| localPlayerContextAnalyzer.isLocalPlayerDependent(color))) {
continue;
}

boolean conflict = false;
for (ImVar neigh : interference.get(v)) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package de.peeeq.wurstscript.intermediatelang.optimizer;

import de.peeeq.wurstscript.translation.imoptimizer.OptimizerPass;
import de.peeeq.wurstscript.translation.imtranslation.ImTranslator;

/**
* An optimizer pass which can share a local-player dependency analysis with
* adjacent passes that preserve the analysis' conservative facts.
*/
public interface LocalPlayerAwareOptimizerPass extends OptimizerPass {

int optimize(ImTranslator trans, LocalPlayerContextAnalyzer analyzer);

@Override
default int optimize(ImTranslator trans) {
return optimize(trans, new LocalPlayerContextAnalyzer(trans.getImProg()));
}
}
Loading
Loading