22
33import com .google .common .base .Charsets ;
44import com .google .common .io .Files ;
5+ import de .peeeq .wurstio .TimeTaker ;
56import de .peeeq .wurstio .UtilsIO ;
67import de .peeeq .wurstscript .RunArgs ;
78import de .peeeq .wurstscript .ast .Ast ;
1314import de .peeeq .wurstscript .intermediatelang .optimizer .SideEffectAnalyzer ;
1415import de .peeeq .wurstscript .jassIm .*;
1516import de .peeeq .wurstscript .translation .imoptimizer .ImInliner ;
17+ import de .peeeq .wurstscript .translation .imoptimizer .ImOptimizer ;
1618import de .peeeq .wurstscript .translation .imtranslation .ImTranslator ;
1719import de .peeeq .wurstscript .translation .imtranslation .FunctionFlagEnum ;
1820import de .peeeq .wurstscript .types .TypesHelper ;
@@ -1557,9 +1559,10 @@ public void localMergerKeepsImplicitEntryLocalSeparateFromParameter() {
15571559 ImFunctionCall call = JassIm .ImFunctionCall (model , sink , JassIm .ImTypeArguments (),
15581560 JassIm .ImExprs (JassIm .ImVarAccess (parameter ), JassIm .ImVarAccess (implicit )), false ,
15591561 de .peeeq .wurstscript .translation .imtranslation .CallType .NORMAL );
1562+ ImSet laterDefinition = JassIm .ImSet (model , JassIm .ImVarAccess (implicit ), JassIm .ImIntVal (1 ));
15601563 ImFunction caller = JassIm .ImFunction (model , "caller" , JassIm .ImTypeVars (),
15611564 JassIm .ImVars (parameter ), JassIm .ImVoid (), JassIm .ImVars (implicit ),
1562- JassIm .ImStmts (call ), Collections .emptyList ());
1565+ JassIm .ImStmts (call , laterDefinition ), Collections .emptyList ());
15631566 prog .getFunctions ().add (sink );
15641567 prog .getFunctions ().add (caller );
15651568
@@ -1572,6 +1575,28 @@ public void localMergerKeepsImplicitEntryLocalSeparateFromParameter() {
15721575 "function-entry values must not be assigned the same allocation slot" );
15731576 }
15741577
1578+ @ Test
1579+ public void repeatedLocalOptimizationStartsANewIteration () {
1580+ WurstModel model = Ast .WurstModel ();
1581+ ImTranslator translator = new ImTranslator (model , false , new RunArgs ());
1582+ ImFunction main = JassIm .ImFunction (model , "main" , JassIm .ImTypeVars (), JassIm .ImVars (),
1583+ JassIm .ImVoid (), JassIm .ImVars (), JassIm .ImStmts (), Collections .emptyList ());
1584+ ImFunction config = JassIm .ImFunction (model , "config" , JassIm .ImTypeVars (), JassIm .ImVars (),
1585+ JassIm .ImVoid (), JassIm .ImVars (), JassIm .ImStmts (), Collections .emptyList ());
1586+ translator .getImProg ().getFunctions ().add (main );
1587+ translator .getImProg ().getFunctions ().add (config );
1588+ translator .setMainFunc (main );
1589+ translator .setConfigFunc (config );
1590+ ImOptimizer optimizer = new ImOptimizer (new TimeTaker .Default (), translator );
1591+
1592+ optimizer .localOptimizations ();
1593+ main .getLocals ().add (JassIm .ImVar (model , TypesHelper .imInt (), "lateUnused" , false ));
1594+ optimizer .localOptimizations ();
1595+
1596+ assertTrue (main .getLocals ().isEmpty (),
1597+ "a second local-optimization invocation must execute its passes" );
1598+ }
1599+
15751600 @ Test
15761601 public void luaArithmeticHelperRetryRespectsFunctionLocalBudget () {
15771602 WurstModel model = Ast .WurstModel ();
@@ -1587,7 +1612,7 @@ public void luaArithmeticHelperRetryRespectsFunctionLocalBudget() {
15871612 translator .luaModIntFunc = helper ;
15881613
15891614 ImVars callerParameters = JassIm .ImVars ();
1590- for (int i = 0 ; i < 170 ; i ++) {
1615+ for (int i = 0 ; i < 177 ; i ++) {
15911616 callerParameters .add (JassIm .ImVar (model , TypesHelper .imInt (), "p" + i , false ));
15921617 }
15931618 ImVar result = JassIm .ImVar (model , TypesHelper .imInt (), "result" , false );
@@ -1603,10 +1628,21 @@ public void luaArithmeticHelperRetryRespectsFunctionLocalBudget() {
16031628 JassIm .ImExprs (JassIm .ImIntVal (7 ), JassIm .ImIntVal (3 )), false ,
16041629 de .peeeq .wurstscript .translation .imtranslation .CallType .NORMAL );
16051630 callerBody .add (JassIm .ImSet (model , JassIm .ImVarAccess (result ), call ));
1631+ ImVars sinkParameters = JassIm .ImVars ();
1632+ ImExprs sinkArguments = JassIm .ImExprs ();
1633+ for (int i = 0 ; i < callerParameters .size (); i ++) {
1634+ sinkParameters .add (JassIm .ImVar (model , TypesHelper .imInt (), "value" + i , false ));
1635+ sinkArguments .add (JassIm .ImVarAccess (callerParameters .get (i )));
1636+ }
1637+ ImFunction sink = JassIm .ImFunction (model , "sink" , JassIm .ImTypeVars (), sinkParameters ,
1638+ JassIm .ImVoid (), JassIm .ImVars (), JassIm .ImStmts (), Collections .emptyList ());
1639+ callerBody .add (JassIm .ImFunctionCall (model , sink , JassIm .ImTypeArguments (), sinkArguments ,
1640+ false , de .peeeq .wurstscript .translation .imtranslation .CallType .NORMAL ));
16061641 ImFunction caller = JassIm .ImFunction (model , "caller" , JassIm .ImTypeVars (), callerParameters ,
16071642 JassIm .ImVoid (), callerLocals , callerBody ,
16081643 Collections .emptyList ());
16091644 prog .getFunctions ().add (helper );
1645+ prog .getFunctions ().add (sink );
16101646 prog .getFunctions ().add (caller );
16111647
16121648 assertEquals (0 , new ImInliner (translator ).inlineLuaDivModHelpersWithinLocalBudget ());
@@ -1615,6 +1651,39 @@ public void luaArithmeticHelperRetryRespectsFunctionLocalBudget() {
16151651 "the late retry must retain the helper when declarations exceed the safe budget" );
16161652 }
16171653
1654+ @ Test
1655+ public void luaArithmeticHelperRetryReusesSequentialSlots () {
1656+ WurstModel model = Ast .WurstModel ();
1657+ ImTranslator translator = new ImTranslator (model , false , new RunArgs ().with ("-lua" ));
1658+ ImProg prog = translator .getImProg ();
1659+ ImVar helperA = JassIm .ImVar (model , TypesHelper .imInt (), "a" , false );
1660+ ImVar helperB = JassIm .ImVar (model , TypesHelper .imInt (), "b" , false );
1661+ ImFunction helper = JassIm .ImFunction (model , "__wurst_modInt" , JassIm .ImTypeVars (),
1662+ JassIm .ImVars (helperA , helperB ), TypesHelper .imInt (), JassIm .ImVars (),
1663+ JassIm .ImStmts (JassIm .ImReturn (model , JassIm .ImVarAccess (helperA ))),
1664+ Collections .emptyList ());
1665+ translator .luaModIntFunc = helper ;
1666+ ImVars parameters = JassIm .ImVars ();
1667+ for (int i = 0 ; i < 187 ; i ++) {
1668+ parameters .add (JassIm .ImVar (model , TypesHelper .imInt (), "p" + i , false ));
1669+ }
1670+ ImVar result = JassIm .ImVar (model , TypesHelper .imInt (), "result" , false );
1671+ ImFunction caller = JassIm .ImFunction (model , "caller" , JassIm .ImTypeVars (), parameters ,
1672+ JassIm .ImVoid (), JassIm .ImVars (result ), JassIm .ImStmts (
1673+ JassIm .ImSet (model , JassIm .ImVarAccess (result ), JassIm .ImFunctionCall (model , helper ,
1674+ JassIm .ImTypeArguments (), JassIm .ImExprs (JassIm .ImIntVal (7 ), JassIm .ImIntVal (3 )),
1675+ false , de .peeeq .wurstscript .translation .imtranslation .CallType .NORMAL )),
1676+ JassIm .ImSet (model , JassIm .ImVarAccess (result ), JassIm .ImFunctionCall (model , helper ,
1677+ JassIm .ImTypeArguments (), JassIm .ImExprs (JassIm .ImIntVal (8 ), JassIm .ImIntVal (3 )),
1678+ false , de .peeeq .wurstscript .translation .imtranslation .CallType .NORMAL ))),
1679+ Collections .emptyList ());
1680+ prog .getFunctions ().add (helper );
1681+ prog .getFunctions ().add (caller );
1682+
1683+ assertEquals (new ImInliner (translator ).inlineLuaDivModHelpersWithinLocalBudget (), 2 ,
1684+ "sequential helper sites should share the same peak allocation slots" );
1685+ }
1686+
16181687 @ Test
16191688 public void testFunctionSplitter () {
16201689 WurstModel model = Ast .WurstModel ();
0 commit comments