mirror of
https://gitlab.com/camelot/kickc.git
synced 2024-11-20 02:32:36 +00:00
Working on better live ranges that take into account the call-path taken to the current statement and any aliases on that path (due to phi statements)
This commit is contained in:
parent
9d3c8afdf0
commit
b20327590f
@ -262,9 +262,9 @@ public class Compiler {
|
||||
//program.getLog().setVerboseUplift(true);
|
||||
new Pass4RegisterUpliftCombinations(program).performUplift(10_000);
|
||||
|
||||
//program.getLog().setVerboseUplift(true);
|
||||
//new Pass4RegisterUpliftStatic(program).performUplift();
|
||||
//program.getLog().setVerboseUplift(false);
|
||||
program.getLog().setVerboseUplift(true);
|
||||
new Pass4RegisterUpliftStatic(program).performUplift();
|
||||
program.getLog().setVerboseUplift(false);
|
||||
|
||||
// Attempt uplifting registers one at a time to catch remaining potential not realized by combination search
|
||||
new Pass4RegisterUpliftRemains(program).performUplift(10_000);
|
||||
|
@ -0,0 +1,6 @@
|
||||
lda {zpptrby1}
|
||||
asl
|
||||
sta {zpptrby1}
|
||||
lda {zpptrby1}+1
|
||||
rol
|
||||
sta {zpptrby1}+1
|
@ -8,23 +8,76 @@ import java.util.*;
|
||||
public class LiveRangeVariablesEffective {
|
||||
|
||||
/** Effectively alive variables by statement index. */
|
||||
Map<Integer, Collection<VariableRef>> effectiveLiveVariables;
|
||||
Map<Integer, AliveCombinations> effectiveLiveCombinations;
|
||||
|
||||
public LiveRangeVariablesEffective(Map<Integer, Collection<VariableRef>> effectiveLiveVariables) {
|
||||
this.effectiveLiveVariables = effectiveLiveVariables;
|
||||
public LiveRangeVariablesEffective(Map<Integer, AliveCombinations> effectiveLiveCombinations) {
|
||||
this.effectiveLiveCombinations = effectiveLiveCombinations;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all variables alive at a statement.
|
||||
* If the statement is inside a method this also includes all variables alive at the exit of the calls.
|
||||
* <p>
|
||||
* This method requires a number of other analysis to be present and updated in the (global) program - especailly the Call Graph.
|
||||
* Get all variables potentially alive at a statement.
|
||||
* If the statement is inside a method this also includes all variables alive at the exit of any call.
|
||||
* </p>
|
||||
* @param statement The statement to examine
|
||||
* @return All variables alive at the statement
|
||||
* @return All variables potentially alive at the statement
|
||||
*/
|
||||
public Collection<VariableRef> getAliveEffective(Statement statement) {
|
||||
return effectiveLiveVariables.get(statement.getIndex());
|
||||
Set<VariableRef> effectiveAliveTotal = new LinkedHashSet<>();
|
||||
AliveCombinations aliveCombinations = effectiveLiveCombinations.get(statement.getIndex());
|
||||
for (AliveCombination aliveCombination : aliveCombinations.getCombinations()) {
|
||||
effectiveAliveTotal.addAll(aliveCombination.getAlive());
|
||||
}
|
||||
return effectiveAliveTotal;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all combinations of variables alive at a statement.
|
||||
* If the statement is inside a method the different combinations in the result arises from different calls of the method
|
||||
* (recursively up til the main()-method.
|
||||
* Each combination includes all variables alive at the exit of any surrounding call.
|
||||
* </p>
|
||||
* @param statement The statement to examine
|
||||
* @return All combinations of variables alive at the statement
|
||||
*/
|
||||
public AliveCombinations getAliveCombinations(Statement statement) {
|
||||
return effectiveLiveCombinations.get(statement.getIndex());
|
||||
}
|
||||
|
||||
/** Combinations of variables effectively alive at a specific statement.
|
||||
* If the statement is inside a method the combinations are the live variables inside the method combined with each calling statements alive vars.
|
||||
* As each caller might also be inside a methos there may be a large amount of combinations.
|
||||
*/
|
||||
public static class AliveCombinations {
|
||||
|
||||
private Collection<AliveCombination> combinations;
|
||||
|
||||
public AliveCombinations(Collection<Collection<VariableRef>> aliveCombinations) {
|
||||
ArrayList<AliveCombination> combinations = new ArrayList<>();
|
||||
for (Collection<VariableRef> aliveCombination : aliveCombinations) {
|
||||
combinations.add(new AliveCombination(aliveCombination));
|
||||
}
|
||||
this.combinations = combinations;
|
||||
}
|
||||
|
||||
public Collection<AliveCombination> getCombinations() {
|
||||
return combinations;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/** One single combinations of variables effectively alive at a specific statement. */
|
||||
public static class AliveCombination {
|
||||
|
||||
private Collection<VariableRef> alive;
|
||||
|
||||
public AliveCombination(Collection<VariableRef> alive) {
|
||||
this.alive = alive;
|
||||
}
|
||||
|
||||
public Collection<VariableRef> getAlive() {
|
||||
return alive;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -1,5 +1,6 @@
|
||||
package dk.camelot64.kickc.model;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
/** Statement base class implementing shared properties and logic */
|
||||
@ -48,7 +49,22 @@ public abstract class StatementBase implements Statement {
|
||||
return "";
|
||||
}
|
||||
LiveRangeVariables liveRanges = program.getLiveRangeVariables();
|
||||
List<VariableRef> alive = liveRanges.getAlive(this);
|
||||
StringBuilder alive = new StringBuilder();
|
||||
alive.append(getAliveString(liveRanges.getAlive(this)));
|
||||
LiveRangeVariablesEffective liveRangeVariablesEffective = program.getLiveRangeVariablesEffective();
|
||||
if(liveRangeVariablesEffective!=null) {
|
||||
LiveRangeVariablesEffective.AliveCombinations aliveCombinations = liveRangeVariablesEffective.getAliveCombinations(this);
|
||||
alive.append(" ( ");
|
||||
for (LiveRangeVariablesEffective.AliveCombination aliveCombination : aliveCombinations.getCombinations()) {
|
||||
alive.append(getAliveString(aliveCombination.getAlive()));
|
||||
alive.append(" ");
|
||||
}
|
||||
alive.append(")");
|
||||
}
|
||||
return alive.toString();
|
||||
}
|
||||
|
||||
private String getAliveString(Collection<VariableRef> alive) {
|
||||
StringBuilder str = new StringBuilder();
|
||||
str.append(" [ ");
|
||||
for (VariableRef variableRef : alive) {
|
||||
|
@ -90,7 +90,7 @@ parameterList
|
||||
;
|
||||
|
||||
asmLines
|
||||
: asmLine ( asmLine )*
|
||||
: asmLine*
|
||||
;
|
||||
|
||||
asmLine
|
||||
|
@ -2315,19 +2315,17 @@ public class KickCParser extends Parser {
|
||||
try {
|
||||
enterOuterAlt(_localctx, 1);
|
||||
{
|
||||
setState(288);
|
||||
asmLine();
|
||||
setState(292);
|
||||
setState(291);
|
||||
_errHandler.sync(this);
|
||||
_la = _input.LA(1);
|
||||
while ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__26) | (1L << MNEMONIC) | (1L << NAME))) != 0)) {
|
||||
{
|
||||
{
|
||||
setState(289);
|
||||
setState(288);
|
||||
asmLine();
|
||||
}
|
||||
}
|
||||
setState(294);
|
||||
setState(293);
|
||||
_errHandler.sync(this);
|
||||
_la = _input.LA(1);
|
||||
}
|
||||
@ -2374,21 +2372,21 @@ public class KickCParser extends Parser {
|
||||
AsmLineContext _localctx = new AsmLineContext(_ctx, getState());
|
||||
enterRule(_localctx, 28, RULE_asmLine);
|
||||
try {
|
||||
setState(297);
|
||||
setState(296);
|
||||
_errHandler.sync(this);
|
||||
switch (_input.LA(1)) {
|
||||
case T__26:
|
||||
case NAME:
|
||||
enterOuterAlt(_localctx, 1);
|
||||
{
|
||||
setState(295);
|
||||
setState(294);
|
||||
asmLabel();
|
||||
}
|
||||
break;
|
||||
case MNEMONIC:
|
||||
enterOuterAlt(_localctx, 2);
|
||||
{
|
||||
setState(296);
|
||||
setState(295);
|
||||
asmInstruction();
|
||||
}
|
||||
break;
|
||||
@ -2432,24 +2430,24 @@ public class KickCParser extends Parser {
|
||||
AsmLabelContext _localctx = new AsmLabelContext(_ctx, getState());
|
||||
enterRule(_localctx, 30, RULE_asmLabel);
|
||||
try {
|
||||
setState(303);
|
||||
setState(302);
|
||||
_errHandler.sync(this);
|
||||
switch (_input.LA(1)) {
|
||||
case NAME:
|
||||
enterOuterAlt(_localctx, 1);
|
||||
{
|
||||
setState(299);
|
||||
setState(298);
|
||||
match(NAME);
|
||||
setState(300);
|
||||
setState(299);
|
||||
match(T__14);
|
||||
}
|
||||
break;
|
||||
case T__26:
|
||||
enterOuterAlt(_localctx, 2);
|
||||
{
|
||||
setState(301);
|
||||
setState(300);
|
||||
match(T__26);
|
||||
setState(302);
|
||||
setState(301);
|
||||
match(T__14);
|
||||
}
|
||||
break;
|
||||
@ -2498,14 +2496,14 @@ public class KickCParser extends Parser {
|
||||
try {
|
||||
enterOuterAlt(_localctx, 1);
|
||||
{
|
||||
setState(305);
|
||||
setState(304);
|
||||
match(MNEMONIC);
|
||||
setState(307);
|
||||
setState(306);
|
||||
_errHandler.sync(this);
|
||||
switch ( getInterpreter().adaptivePredict(_input,30,_ctx) ) {
|
||||
case 1:
|
||||
{
|
||||
setState(306);
|
||||
setState(305);
|
||||
asmParamMode();
|
||||
}
|
||||
break;
|
||||
@ -2656,14 +2654,14 @@ public class KickCParser extends Parser {
|
||||
AsmParamModeContext _localctx = new AsmParamModeContext(_ctx, getState());
|
||||
enterRule(_localctx, 34, RULE_asmParamMode);
|
||||
try {
|
||||
setState(332);
|
||||
setState(331);
|
||||
_errHandler.sync(this);
|
||||
switch ( getInterpreter().adaptivePredict(_input,31,_ctx) ) {
|
||||
case 1:
|
||||
_localctx = new AsmModeAbsContext(_localctx);
|
||||
enterOuterAlt(_localctx, 1);
|
||||
{
|
||||
setState(309);
|
||||
setState(308);
|
||||
asmExpr(0);
|
||||
}
|
||||
break;
|
||||
@ -2671,9 +2669,9 @@ public class KickCParser extends Parser {
|
||||
_localctx = new AsmModeImmContext(_localctx);
|
||||
enterOuterAlt(_localctx, 2);
|
||||
{
|
||||
setState(310);
|
||||
setState(309);
|
||||
match(T__44);
|
||||
setState(311);
|
||||
setState(310);
|
||||
asmExpr(0);
|
||||
}
|
||||
break;
|
||||
@ -2681,11 +2679,11 @@ public class KickCParser extends Parser {
|
||||
_localctx = new AsmModeAbsXYContext(_localctx);
|
||||
enterOuterAlt(_localctx, 3);
|
||||
{
|
||||
setState(312);
|
||||
setState(311);
|
||||
asmExpr(0);
|
||||
setState(313);
|
||||
setState(312);
|
||||
match(T__16);
|
||||
setState(314);
|
||||
setState(313);
|
||||
match(NAME);
|
||||
}
|
||||
break;
|
||||
@ -2693,15 +2691,15 @@ public class KickCParser extends Parser {
|
||||
_localctx = new AsmModeIndIdxXYContext(_localctx);
|
||||
enterOuterAlt(_localctx, 4);
|
||||
{
|
||||
setState(316);
|
||||
setState(315);
|
||||
match(T__2);
|
||||
setState(317);
|
||||
setState(316);
|
||||
asmExpr(0);
|
||||
setState(318);
|
||||
setState(317);
|
||||
match(T__3);
|
||||
setState(319);
|
||||
setState(318);
|
||||
match(T__16);
|
||||
setState(320);
|
||||
setState(319);
|
||||
match(NAME);
|
||||
}
|
||||
break;
|
||||
@ -2709,15 +2707,15 @@ public class KickCParser extends Parser {
|
||||
_localctx = new AsmModeIdxIndXYContext(_localctx);
|
||||
enterOuterAlt(_localctx, 5);
|
||||
{
|
||||
setState(322);
|
||||
setState(321);
|
||||
match(T__2);
|
||||
setState(323);
|
||||
setState(322);
|
||||
asmExpr(0);
|
||||
setState(324);
|
||||
setState(323);
|
||||
match(T__16);
|
||||
setState(325);
|
||||
setState(324);
|
||||
match(NAME);
|
||||
setState(326);
|
||||
setState(325);
|
||||
match(T__3);
|
||||
}
|
||||
break;
|
||||
@ -2725,11 +2723,11 @@ public class KickCParser extends Parser {
|
||||
_localctx = new AsmModeIndContext(_localctx);
|
||||
enterOuterAlt(_localctx, 6);
|
||||
{
|
||||
setState(328);
|
||||
setState(327);
|
||||
match(T__2);
|
||||
setState(329);
|
||||
setState(328);
|
||||
asmExpr(0);
|
||||
setState(330);
|
||||
setState(329);
|
||||
match(T__3);
|
||||
}
|
||||
break;
|
||||
@ -2900,7 +2898,7 @@ public class KickCParser extends Parser {
|
||||
int _alt;
|
||||
enterOuterAlt(_localctx, 1);
|
||||
{
|
||||
setState(344);
|
||||
setState(343);
|
||||
_errHandler.sync(this);
|
||||
switch (_input.LA(1)) {
|
||||
case T__20:
|
||||
@ -2912,7 +2910,7 @@ public class KickCParser extends Parser {
|
||||
_ctx = _localctx;
|
||||
_prevctx = _localctx;
|
||||
|
||||
setState(335);
|
||||
setState(334);
|
||||
_la = _input.LA(1);
|
||||
if ( !((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__20) | (1L << T__21) | (1L << T__24) | (1L << T__25))) != 0)) ) {
|
||||
_errHandler.recoverInline(this);
|
||||
@ -2922,7 +2920,7 @@ public class KickCParser extends Parser {
|
||||
_errHandler.reportMatch(this);
|
||||
consume();
|
||||
}
|
||||
setState(336);
|
||||
setState(335);
|
||||
asmExpr(8);
|
||||
}
|
||||
break;
|
||||
@ -2931,7 +2929,7 @@ public class KickCParser extends Parser {
|
||||
_localctx = new AsmExprLabelContext(_localctx);
|
||||
_ctx = _localctx;
|
||||
_prevctx = _localctx;
|
||||
setState(337);
|
||||
setState(336);
|
||||
match(NAME);
|
||||
}
|
||||
break;
|
||||
@ -2940,7 +2938,7 @@ public class KickCParser extends Parser {
|
||||
_localctx = new AsmExprLabelRelContext(_localctx);
|
||||
_ctx = _localctx;
|
||||
_prevctx = _localctx;
|
||||
setState(338);
|
||||
setState(337);
|
||||
match(ASMREL);
|
||||
}
|
||||
break;
|
||||
@ -2949,11 +2947,11 @@ public class KickCParser extends Parser {
|
||||
_localctx = new AsmExprReplaceContext(_localctx);
|
||||
_ctx = _localctx;
|
||||
_prevctx = _localctx;
|
||||
setState(339);
|
||||
setState(338);
|
||||
match(T__0);
|
||||
setState(340);
|
||||
setState(339);
|
||||
match(NAME);
|
||||
setState(341);
|
||||
setState(340);
|
||||
match(T__1);
|
||||
}
|
||||
break;
|
||||
@ -2962,7 +2960,7 @@ public class KickCParser extends Parser {
|
||||
_localctx = new AsmExprIntContext(_localctx);
|
||||
_ctx = _localctx;
|
||||
_prevctx = _localctx;
|
||||
setState(342);
|
||||
setState(341);
|
||||
match(NUMBER);
|
||||
}
|
||||
break;
|
||||
@ -2971,7 +2969,7 @@ public class KickCParser extends Parser {
|
||||
_localctx = new AsmExprCharContext(_localctx);
|
||||
_ctx = _localctx;
|
||||
_prevctx = _localctx;
|
||||
setState(343);
|
||||
setState(342);
|
||||
match(CHAR);
|
||||
}
|
||||
break;
|
||||
@ -2979,7 +2977,7 @@ public class KickCParser extends Parser {
|
||||
throw new NoViableAltException(this);
|
||||
}
|
||||
_ctx.stop = _input.LT(-1);
|
||||
setState(354);
|
||||
setState(353);
|
||||
_errHandler.sync(this);
|
||||
_alt = getInterpreter().adaptivePredict(_input,34,_ctx);
|
||||
while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) {
|
||||
@ -2987,16 +2985,16 @@ public class KickCParser extends Parser {
|
||||
if ( _parseListeners!=null ) triggerExitRuleEvent();
|
||||
_prevctx = _localctx;
|
||||
{
|
||||
setState(352);
|
||||
setState(351);
|
||||
_errHandler.sync(this);
|
||||
switch ( getInterpreter().adaptivePredict(_input,33,_ctx) ) {
|
||||
case 1:
|
||||
{
|
||||
_localctx = new AsmExprBinaryContext(new AsmExprContext(_parentctx, _parentState));
|
||||
pushNewRecursionContext(_localctx, _startState, RULE_asmExpr);
|
||||
setState(346);
|
||||
setState(345);
|
||||
if (!(precpred(_ctx, 7))) throw new FailedPredicateException(this, "precpred(_ctx, 7)");
|
||||
setState(347);
|
||||
setState(346);
|
||||
_la = _input.LA(1);
|
||||
if ( !(_la==T__17 || _la==T__31) ) {
|
||||
_errHandler.recoverInline(this);
|
||||
@ -3006,7 +3004,7 @@ public class KickCParser extends Parser {
|
||||
_errHandler.reportMatch(this);
|
||||
consume();
|
||||
}
|
||||
setState(348);
|
||||
setState(347);
|
||||
asmExpr(8);
|
||||
}
|
||||
break;
|
||||
@ -3014,9 +3012,9 @@ public class KickCParser extends Parser {
|
||||
{
|
||||
_localctx = new AsmExprBinaryContext(new AsmExprContext(_parentctx, _parentState));
|
||||
pushNewRecursionContext(_localctx, _startState, RULE_asmExpr);
|
||||
setState(349);
|
||||
setState(348);
|
||||
if (!(precpred(_ctx, 6))) throw new FailedPredicateException(this, "precpred(_ctx, 6)");
|
||||
setState(350);
|
||||
setState(349);
|
||||
_la = _input.LA(1);
|
||||
if ( !(_la==T__24 || _la==T__25) ) {
|
||||
_errHandler.recoverInline(this);
|
||||
@ -3026,14 +3024,14 @@ public class KickCParser extends Parser {
|
||||
_errHandler.reportMatch(this);
|
||||
consume();
|
||||
}
|
||||
setState(351);
|
||||
setState(350);
|
||||
asmExpr(7);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
setState(356);
|
||||
setState(355);
|
||||
_errHandler.sync(this);
|
||||
_alt = getInterpreter().adaptivePredict(_input,34,_ctx);
|
||||
}
|
||||
@ -3117,7 +3115,7 @@ public class KickCParser extends Parser {
|
||||
}
|
||||
|
||||
public static final String _serializedATN =
|
||||
"\3\u608b\ua72a\u8133\ub9ed\u417c\u3be7\u7786\u5964\3B\u0168\4\2\t\2\4"+
|
||||
"\3\u608b\ua72a\u8133\ub9ed\u417c\u3be7\u7786\u5964\3B\u0167\4\2\t\2\4"+
|
||||
"\3\t\3\4\4\t\4\4\5\t\5\4\6\t\6\4\7\t\7\4\b\t\b\4\t\t\t\4\n\t\n\4\13\t"+
|
||||
"\13\4\f\t\f\4\r\t\r\4\16\t\16\4\17\t\17\4\20\t\20\4\21\t\21\4\22\t\22"+
|
||||
"\4\23\t\23\4\24\t\24\3\2\3\2\3\2\3\3\3\3\3\3\3\4\6\4\60\n\4\r\4\16\4\61"+
|
||||
@ -3137,29 +3135,29 @@ public class KickCParser extends Parser {
|
||||
"\3\r\3\r\3\r\3\r\3\r\3\r\3\r\3\r\3\r\3\r\3\r\3\r\3\r\3\r\3\r\3\r\3\r\3"+
|
||||
"\r\3\r\3\r\3\r\3\r\3\r\3\r\3\r\3\r\3\r\3\r\3\r\3\r\3\r\3\r\3\r\3\r\7\r"+
|
||||
"\u0116\n\r\f\r\16\r\u0119\13\r\3\16\3\16\3\16\7\16\u011e\n\16\f\16\16"+
|
||||
"\16\u0121\13\16\3\17\3\17\7\17\u0125\n\17\f\17\16\17\u0128\13\17\3\20"+
|
||||
"\3\20\5\20\u012c\n\20\3\21\3\21\3\21\3\21\5\21\u0132\n\21\3\22\3\22\5"+
|
||||
"\22\u0136\n\22\3\23\3\23\3\23\3\23\3\23\3\23\3\23\3\23\3\23\3\23\3\23"+
|
||||
"\3\23\3\23\3\23\3\23\3\23\3\23\3\23\3\23\3\23\3\23\3\23\3\23\5\23\u014f"+
|
||||
"\n\23\3\24\3\24\3\24\3\24\3\24\3\24\3\24\3\24\3\24\3\24\5\24\u015b\n\24"+
|
||||
"\3\24\3\24\3\24\3\24\3\24\3\24\7\24\u0163\n\24\f\24\16\24\u0166\13\24"+
|
||||
"\3\24\2\6\22\26\30&\25\2\4\6\b\n\f\16\20\22\24\26\30\32\34\36 \"$&\2\13"+
|
||||
"\3\2\27\30\3\2\31\32\5\2\24\24\27\30\33\37\3\2 !\4\2\24\24\"#\3\2\33\34"+
|
||||
"\4\2\27\30$*\4\2\27\30\33\34\4\2\24\24\"\"\2\u019b\2(\3\2\2\2\4+\3\2\2"+
|
||||
"\2\6/\3\2\2\2\b\u0082\3\2\2\2\n\u0085\3\2\2\2\f\u0097\3\2\2\2\16\u0099"+
|
||||
"\3\2\2\2\20\u00a1\3\2\2\2\22\u00a4\3\2\2\2\24\u00c0\3\2\2\2\26\u00cc\3"+
|
||||
"\2\2\2\30\u00f1\3\2\2\2\32\u011a\3\2\2\2\34\u0122\3\2\2\2\36\u012b\3\2"+
|
||||
"\2\2 \u0131\3\2\2\2\"\u0133\3\2\2\2$\u014e\3\2\2\2&\u015a\3\2\2\2()\5"+
|
||||
"\6\4\2)*\7\2\2\3*\3\3\2\2\2+,\5\34\17\2,-\7\2\2\3-\5\3\2\2\2.\60\5\b\5"+
|
||||
"\2/.\3\2\2\2\60\61\3\2\2\2\61/\3\2\2\2\61\62\3\2\2\2\62\7\3\2\2\2\63\65"+
|
||||
"\7\3\2\2\64\66\5\6\4\2\65\64\3\2\2\2\65\66\3\2\2\2\66\67\3\2\2\2\67\u0083"+
|
||||
"\7\4\2\289\5\22\n\29:\7>\2\2:<\7\5\2\2;=\5\16\b\2<;\3\2\2\2<=\3\2\2\2"+
|
||||
"=>\3\2\2\2>?\7\6\2\2?A\7\3\2\2@B\5\6\4\2A@\3\2\2\2AB\3\2\2\2BC\3\2\2\2"+
|
||||
"CD\7\4\2\2D\u0083\3\2\2\2EG\7\7\2\2FE\3\2\2\2FG\3\2\2\2GH\3\2\2\2HI\5"+
|
||||
"\22\n\2IL\7>\2\2JK\7\b\2\2KM\5\24\13\2LJ\3\2\2\2LM\3\2\2\2MN\3\2\2\2N"+
|
||||
"O\7\t\2\2O\u0083\3\2\2\2PQ\5\26\f\2QR\7\b\2\2RS\5\30\r\2ST\7\t\2\2T\u0083"+
|
||||
"\3\2\2\2UV\5\30\r\2VW\7\t\2\2W\u0083\3\2\2\2XY\7\n\2\2YZ\7\5\2\2Z[\5\30"+
|
||||
"\r\2[\\\7\6\2\2\\_\5\b\5\2]^\7\13\2\2^`\5\b\5\2_]\3\2\2\2_`\3\2\2\2`\u0083"+
|
||||
"\16\u0121\13\16\3\17\7\17\u0124\n\17\f\17\16\17\u0127\13\17\3\20\3\20"+
|
||||
"\5\20\u012b\n\20\3\21\3\21\3\21\3\21\5\21\u0131\n\21\3\22\3\22\5\22\u0135"+
|
||||
"\n\22\3\23\3\23\3\23\3\23\3\23\3\23\3\23\3\23\3\23\3\23\3\23\3\23\3\23"+
|
||||
"\3\23\3\23\3\23\3\23\3\23\3\23\3\23\3\23\3\23\3\23\5\23\u014e\n\23\3\24"+
|
||||
"\3\24\3\24\3\24\3\24\3\24\3\24\3\24\3\24\3\24\5\24\u015a\n\24\3\24\3\24"+
|
||||
"\3\24\3\24\3\24\3\24\7\24\u0162\n\24\f\24\16\24\u0165\13\24\3\24\2\6\22"+
|
||||
"\26\30&\25\2\4\6\b\n\f\16\20\22\24\26\30\32\34\36 \"$&\2\13\3\2\27\30"+
|
||||
"\3\2\31\32\5\2\24\24\27\30\33\37\3\2 !\4\2\24\24\"#\3\2\33\34\4\2\27\30"+
|
||||
"$*\4\2\27\30\33\34\4\2\24\24\"\"\2\u019a\2(\3\2\2\2\4+\3\2\2\2\6/\3\2"+
|
||||
"\2\2\b\u0082\3\2\2\2\n\u0085\3\2\2\2\f\u0097\3\2\2\2\16\u0099\3\2\2\2"+
|
||||
"\20\u00a1\3\2\2\2\22\u00a4\3\2\2\2\24\u00c0\3\2\2\2\26\u00cc\3\2\2\2\30"+
|
||||
"\u00f1\3\2\2\2\32\u011a\3\2\2\2\34\u0125\3\2\2\2\36\u012a\3\2\2\2 \u0130"+
|
||||
"\3\2\2\2\"\u0132\3\2\2\2$\u014d\3\2\2\2&\u0159\3\2\2\2()\5\6\4\2)*\7\2"+
|
||||
"\2\3*\3\3\2\2\2+,\5\34\17\2,-\7\2\2\3-\5\3\2\2\2.\60\5\b\5\2/.\3\2\2\2"+
|
||||
"\60\61\3\2\2\2\61/\3\2\2\2\61\62\3\2\2\2\62\7\3\2\2\2\63\65\7\3\2\2\64"+
|
||||
"\66\5\6\4\2\65\64\3\2\2\2\65\66\3\2\2\2\66\67\3\2\2\2\67\u0083\7\4\2\2"+
|
||||
"89\5\22\n\29:\7>\2\2:<\7\5\2\2;=\5\16\b\2<;\3\2\2\2<=\3\2\2\2=>\3\2\2"+
|
||||
"\2>?\7\6\2\2?A\7\3\2\2@B\5\6\4\2A@\3\2\2\2AB\3\2\2\2BC\3\2\2\2CD\7\4\2"+
|
||||
"\2D\u0083\3\2\2\2EG\7\7\2\2FE\3\2\2\2FG\3\2\2\2GH\3\2\2\2HI\5\22\n\2I"+
|
||||
"L\7>\2\2JK\7\b\2\2KM\5\24\13\2LJ\3\2\2\2LM\3\2\2\2MN\3\2\2\2NO\7\t\2\2"+
|
||||
"O\u0083\3\2\2\2PQ\5\26\f\2QR\7\b\2\2RS\5\30\r\2ST\7\t\2\2T\u0083\3\2\2"+
|
||||
"\2UV\5\30\r\2VW\7\t\2\2W\u0083\3\2\2\2XY\7\n\2\2YZ\7\5\2\2Z[\5\30\r\2"+
|
||||
"[\\\7\6\2\2\\_\5\b\5\2]^\7\13\2\2^`\5\b\5\2_]\3\2\2\2_`\3\2\2\2`\u0083"+
|
||||
"\3\2\2\2ab\7\f\2\2bc\7\5\2\2cd\5\30\r\2de\7\6\2\2ef\5\b\5\2f\u0083\3\2"+
|
||||
"\2\2gh\7\r\2\2hi\5\b\5\2ij\7\f\2\2jk\7\5\2\2kl\5\30\r\2lm\7\6\2\2mn\7"+
|
||||
"\t\2\2n\u0083\3\2\2\2op\7\16\2\2pr\7\5\2\2qs\5\n\6\2rq\3\2\2\2rs\3\2\2"+
|
||||
@ -3224,33 +3222,32 @@ public class KickCParser extends Parser {
|
||||
"\31\3\2\2\2\u0119\u0117\3\2\2\2\u011a\u011f\5\30\r\2\u011b\u011c\7\23"+
|
||||
"\2\2\u011c\u011e\5\30\r\2\u011d\u011b\3\2\2\2\u011e\u0121\3\2\2\2\u011f"+
|
||||
"\u011d\3\2\2\2\u011f\u0120\3\2\2\2\u0120\33\3\2\2\2\u0121\u011f\3\2\2"+
|
||||
"\2\u0122\u0126\5\36\20\2\u0123\u0125\5\36\20\2\u0124\u0123\3\2\2\2\u0125"+
|
||||
"\u0128\3\2\2\2\u0126\u0124\3\2\2\2\u0126\u0127\3\2\2\2\u0127\35\3\2\2"+
|
||||
"\2\u0128\u0126\3\2\2\2\u0129\u012c\5 \21\2\u012a\u012c\5\"\22\2\u012b"+
|
||||
"\u0129\3\2\2\2\u012b\u012a\3\2\2\2\u012c\37\3\2\2\2\u012d\u012e\7>\2\2"+
|
||||
"\u012e\u0132\7\21\2\2\u012f\u0130\7\35\2\2\u0130\u0132\7\21\2\2\u0131"+
|
||||
"\u012d\3\2\2\2\u0131\u012f\3\2\2\2\u0132!\3\2\2\2\u0133\u0135\7\60\2\2"+
|
||||
"\u0134\u0136\5$\23\2\u0135\u0134\3\2\2\2\u0135\u0136\3\2\2\2\u0136#\3"+
|
||||
"\2\2\2\u0137\u014f\5&\24\2\u0138\u0139\7/\2\2\u0139\u014f\5&\24\2\u013a"+
|
||||
"\u013b\5&\24\2\u013b\u013c\7\23\2\2\u013c\u013d\7>\2\2\u013d\u014f\3\2"+
|
||||
"\2\2\u013e\u013f\7\5\2\2\u013f\u0140\5&\24\2\u0140\u0141\7\6\2\2\u0141"+
|
||||
"\u0142\7\23\2\2\u0142\u0143\7>\2\2\u0143\u014f\3\2\2\2\u0144\u0145\7\5"+
|
||||
"\2\2\u0145\u0146\5&\24\2\u0146\u0147\7\23\2\2\u0147\u0148\7>\2\2\u0148"+
|
||||
"\u0149\7\6\2\2\u0149\u014f\3\2\2\2\u014a\u014b\7\5\2\2\u014b\u014c\5&"+
|
||||
"\24\2\u014c\u014d\7\6\2\2\u014d\u014f\3\2\2\2\u014e\u0137\3\2\2\2\u014e"+
|
||||
"\u0138\3\2\2\2\u014e\u013a\3\2\2\2\u014e\u013e\3\2\2\2\u014e\u0144\3\2"+
|
||||
"\2\2\u014e\u014a\3\2\2\2\u014f%\3\2\2\2\u0150\u0151\b\24\1\2\u0151\u0152"+
|
||||
"\t\t\2\2\u0152\u015b\5&\24\n\u0153\u015b\7>\2\2\u0154\u015b\7?\2\2\u0155"+
|
||||
"\u0156\7\3\2\2\u0156\u0157\7>\2\2\u0157\u015b\7\4\2\2\u0158\u015b\7\65"+
|
||||
"\2\2\u0159\u015b\7\63\2\2\u015a\u0150\3\2\2\2\u015a\u0153\3\2\2\2\u015a"+
|
||||
"\u0154\3\2\2\2\u015a\u0155\3\2\2\2\u015a\u0158\3\2\2\2\u015a\u0159\3\2"+
|
||||
"\2\2\u015b\u0164\3\2\2\2\u015c\u015d\f\t\2\2\u015d\u015e\t\n\2\2\u015e"+
|
||||
"\u0163\5&\24\n\u015f\u0160\f\b\2\2\u0160\u0161\t\7\2\2\u0161\u0163\5&"+
|
||||
"\24\t\u0162\u015c\3\2\2\2\u0162\u015f\3\2\2\2\u0163\u0166\3\2\2\2\u0164"+
|
||||
"\u0162\3\2\2\2\u0164\u0165\3\2\2\2\u0165\'\3\2\2\2\u0166\u0164\3\2\2\2"+
|
||||
"%\61\65<AFL_rz\u0082\u0085\u008a\u0090\u0097\u009e\u00ac\u00af\u00b1\u00bb"+
|
||||
"\u00c0\u00cc\u00d5\u00e0\u00f1\u0115\u0117\u011f\u0126\u012b\u0131\u0135"+
|
||||
"\u014e\u015a\u0162\u0164";
|
||||
"\2\u0122\u0124\5\36\20\2\u0123\u0122\3\2\2\2\u0124\u0127\3\2\2\2\u0125"+
|
||||
"\u0123\3\2\2\2\u0125\u0126\3\2\2\2\u0126\35\3\2\2\2\u0127\u0125\3\2\2"+
|
||||
"\2\u0128\u012b\5 \21\2\u0129\u012b\5\"\22\2\u012a\u0128\3\2\2\2\u012a"+
|
||||
"\u0129\3\2\2\2\u012b\37\3\2\2\2\u012c\u012d\7>\2\2\u012d\u0131\7\21\2"+
|
||||
"\2\u012e\u012f\7\35\2\2\u012f\u0131\7\21\2\2\u0130\u012c\3\2\2\2\u0130"+
|
||||
"\u012e\3\2\2\2\u0131!\3\2\2\2\u0132\u0134\7\60\2\2\u0133\u0135\5$\23\2"+
|
||||
"\u0134\u0133\3\2\2\2\u0134\u0135\3\2\2\2\u0135#\3\2\2\2\u0136\u014e\5"+
|
||||
"&\24\2\u0137\u0138\7/\2\2\u0138\u014e\5&\24\2\u0139\u013a\5&\24\2\u013a"+
|
||||
"\u013b\7\23\2\2\u013b\u013c\7>\2\2\u013c\u014e\3\2\2\2\u013d\u013e\7\5"+
|
||||
"\2\2\u013e\u013f\5&\24\2\u013f\u0140\7\6\2\2\u0140\u0141\7\23\2\2\u0141"+
|
||||
"\u0142\7>\2\2\u0142\u014e\3\2\2\2\u0143\u0144\7\5\2\2\u0144\u0145\5&\24"+
|
||||
"\2\u0145\u0146\7\23\2\2\u0146\u0147\7>\2\2\u0147\u0148\7\6\2\2\u0148\u014e"+
|
||||
"\3\2\2\2\u0149\u014a\7\5\2\2\u014a\u014b\5&\24\2\u014b\u014c\7\6\2\2\u014c"+
|
||||
"\u014e\3\2\2\2\u014d\u0136\3\2\2\2\u014d\u0137\3\2\2\2\u014d\u0139\3\2"+
|
||||
"\2\2\u014d\u013d\3\2\2\2\u014d\u0143\3\2\2\2\u014d\u0149\3\2\2\2\u014e"+
|
||||
"%\3\2\2\2\u014f\u0150\b\24\1\2\u0150\u0151\t\t\2\2\u0151\u015a\5&\24\n"+
|
||||
"\u0152\u015a\7>\2\2\u0153\u015a\7?\2\2\u0154\u0155\7\3\2\2\u0155\u0156"+
|
||||
"\7>\2\2\u0156\u015a\7\4\2\2\u0157\u015a\7\65\2\2\u0158\u015a\7\63\2\2"+
|
||||
"\u0159\u014f\3\2\2\2\u0159\u0152\3\2\2\2\u0159\u0153\3\2\2\2\u0159\u0154"+
|
||||
"\3\2\2\2\u0159\u0157\3\2\2\2\u0159\u0158\3\2\2\2\u015a\u0163\3\2\2\2\u015b"+
|
||||
"\u015c\f\t\2\2\u015c\u015d\t\n\2\2\u015d\u0162\5&\24\n\u015e\u015f\f\b"+
|
||||
"\2\2\u015f\u0160\t\7\2\2\u0160\u0162\5&\24\t\u0161\u015b\3\2\2\2\u0161"+
|
||||
"\u015e\3\2\2\2\u0162\u0165\3\2\2\2\u0163\u0161\3\2\2\2\u0163\u0164\3\2"+
|
||||
"\2\2\u0164\'\3\2\2\2\u0165\u0163\3\2\2\2%\61\65<AFL_rz\u0082\u0085\u008a"+
|
||||
"\u0090\u0097\u009e\u00ac\u00af\u00b1\u00bb\u00c0\u00cc\u00d5\u00e0\u00f1"+
|
||||
"\u0115\u0117\u011f\u0125\u012a\u0130\u0134\u014d\u0159\u0161\u0163";
|
||||
public static final ATN _ATN =
|
||||
new ATNDeserializer().deserialize(_serializedATN.toCharArray());
|
||||
static {
|
||||
|
@ -227,7 +227,7 @@ public class Pass2AliasElimination extends Pass2SsaOptimization {
|
||||
|
||||
|
||||
private Aliases findAliases() {
|
||||
Aliases candidates = findAliasesCandidates();
|
||||
Aliases candidates = findAliasesCandidates(false, getProgram());
|
||||
cleanupCandidates(candidates);
|
||||
return candidates;
|
||||
}
|
||||
@ -265,9 +265,9 @@ public class Pass2AliasElimination extends Pass2SsaOptimization {
|
||||
*
|
||||
* @return Map from Variable to the Constant value
|
||||
*/
|
||||
private Aliases findAliasesCandidates() {
|
||||
public static Aliases findAliasesCandidates(final boolean allowCrossScope, final Program program) {
|
||||
final Aliases aliases = new Aliases();
|
||||
ControlFlowGraphBaseVisitor<Void> visitor = new ControlFlowGraphBaseVisitor<Void>() {
|
||||
final ControlFlowGraphBaseVisitor<Void> visitor = new ControlFlowGraphBaseVisitor<Void>() {
|
||||
@Override
|
||||
public Void visitAssignment(StatementAssignment assignment) {
|
||||
if (assignment.getlValue() instanceof VariableRef) {
|
||||
@ -278,7 +278,11 @@ public class Pass2AliasElimination extends Pass2SsaOptimization {
|
||||
if(variable.getScopeNames().equals(alias.getScopeNames())){
|
||||
aliases.add(variable, alias);
|
||||
} else {
|
||||
getLog().append("Not aliassing across scopes: "+variable+" "+alias);
|
||||
if(allowCrossScope) {
|
||||
aliases.add(variable, alias);
|
||||
} else {
|
||||
program.getLog().append("Not aliassing across scopes: " + variable + " " + alias);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -296,11 +300,13 @@ public class Pass2AliasElimination extends Pass2SsaOptimization {
|
||||
if (phiRValue.getrValue() instanceof VariableRef) {
|
||||
alias = (VariableRef) phiRValue.getrValue();
|
||||
if(!variable.getScopeNames().equals(alias.getScopeNames())){
|
||||
getLog().append("Not aliassing across scopes: "+variable+" "+alias);
|
||||
alias = null;
|
||||
break;
|
||||
if(!allowCrossScope) {
|
||||
program.getLog().append("Not aliassing across scopes: " + variable + " " + alias);
|
||||
alias = null;
|
||||
break;
|
||||
}
|
||||
} else if(variable.equals(alias)) {
|
||||
getLog().append("Not aliassing identity: "+variable+" "+alias);
|
||||
program.getLog().append("Not aliassing identity: "+variable+" "+alias);
|
||||
alias = null;
|
||||
break;
|
||||
}
|
||||
@ -325,7 +331,7 @@ public class Pass2AliasElimination extends Pass2SsaOptimization {
|
||||
return null;
|
||||
}
|
||||
};
|
||||
visitor.visitGraph(getGraph());
|
||||
visitor.visitGraph(program.getGraph());
|
||||
return aliases;
|
||||
}
|
||||
|
||||
|
@ -1,12 +1,12 @@
|
||||
package dk.camelot64.kickc.passes;
|
||||
|
||||
/**
|
||||
* Find effective alive intervals for all variables in all statements. Add the intervals to the Program.
|
||||
*/
|
||||
import dk.camelot64.kickc.model.*;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* Find effective alive intervals for all variables in all statements. Add the intervals to the Program.
|
||||
*/
|
||||
public class Pass3LiveRangesEffectiveAnalysis extends Pass2Base {
|
||||
|
||||
public Pass3LiveRangesEffectiveAnalysis(Program program) {
|
||||
@ -19,17 +19,17 @@ public class Pass3LiveRangesEffectiveAnalysis extends Pass2Base {
|
||||
//getLog().append("Calculated effective variable live ranges");
|
||||
}
|
||||
|
||||
|
||||
private LiveRangeVariablesEffective findAliveEffective(Program program) {
|
||||
LiveRangeVariables liveRangeVariables = program.getLiveRangeVariables();
|
||||
Map<Integer, Collection<VariableRef>> effectiveLiveVariables = new HashMap<>();
|
||||
Map<Integer, LiveRangeVariablesEffective.AliveCombinations> effectiveLiveVariablesCombinations = new HashMap<>();
|
||||
for (ControlFlowBlock block : program.getGraph().getAllBlocks()) {
|
||||
for (Statement statement : block.getStatements()) {
|
||||
Collection<VariableRef> aliveEffective = findAliveEffective( liveRangeVariables, statement);
|
||||
effectiveLiveVariables.put(statement.getIndex(), aliveEffective);
|
||||
Collection<Collection<VariableRef>> statementAliveCombinations = findAliveEffective(liveRangeVariables, statement);
|
||||
LiveRangeVariablesEffective.AliveCombinations aliveCombinations = new LiveRangeVariablesEffective.AliveCombinations(statementAliveCombinations);
|
||||
effectiveLiveVariablesCombinations.put(statement.getIndex(), aliveCombinations);
|
||||
}
|
||||
}
|
||||
return new LiveRangeVariablesEffective(effectiveLiveVariables);
|
||||
return new LiveRangeVariablesEffective(effectiveLiveVariablesCombinations);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -41,10 +41,10 @@ public class Pass3LiveRangesEffectiveAnalysis extends Pass2Base {
|
||||
* @param statement The statement to examine
|
||||
* @return All variables alive at the statement
|
||||
*/
|
||||
private Collection<VariableRef> findAliveEffective(LiveRangeVariables liveRangeVariables, Statement statement) {
|
||||
private Collection<Collection<VariableRef>> findAliveEffective(LiveRangeVariables liveRangeVariables, Statement statement) {
|
||||
Set<Collection<VariableRef>> combinations = new LinkedHashSet<>();
|
||||
// Get variables alive from live range analysis
|
||||
Collection<VariableRef> effectiveAlive = new LinkedHashSet<>();
|
||||
effectiveAlive.addAll(liveRangeVariables.getAlive(statement));
|
||||
Collection<VariableRef> effectiveAlive = liveRangeVariables.getAlive(statement);
|
||||
// If the statement is inside a method recurse back to all calls
|
||||
// For each call add the variables alive after the call that are not referenced (used/defined) inside the method
|
||||
ControlFlowBlock block = getProgram().getGraph().getBlockFromStatementIdx(statement.getIndex());
|
||||
@ -57,16 +57,28 @@ public class Pass3LiveRangesEffectiveAnalysis extends Pass2Base {
|
||||
VariableReferenceInfo referenceInfo = new VariableReferenceInfo(getProgram());
|
||||
Collection<VariableRef> referencedInProcedure = referenceInfo.getReferenced(procedure.getRef().getLabelRef());
|
||||
for (CallGraph.CallBlock.Call caller : callers) {
|
||||
// Each caller creates its own combinations
|
||||
StatementCall callStatement =
|
||||
(StatementCall) getProgram().getGraph().getStatementByIndex(caller.getCallStatementIdx());
|
||||
Set<VariableRef> callAliveEffective = new LinkedHashSet<>(findAliveEffective(liveRangeVariables, callStatement));
|
||||
// Clear out any variables referenced in the method
|
||||
callAliveEffective.removeAll(referencedInProcedure);
|
||||
effectiveAlive.addAll(callAliveEffective);
|
||||
Collection<Collection<VariableRef>> callerCombinations = findAliveEffective(liveRangeVariables, callStatement);
|
||||
for (Collection<VariableRef> callerCombination : callerCombinations) {
|
||||
LinkedHashSet<VariableRef> combination = new LinkedHashSet<>();
|
||||
// Add alive at call
|
||||
combination.addAll(callerCombination);
|
||||
// Clear out any variables referenced in the method
|
||||
combination.removeAll(referencedInProcedure);
|
||||
// Add alive at statement
|
||||
combination.addAll(effectiveAlive);
|
||||
// Add combination
|
||||
combinations.add(combination);
|
||||
}
|
||||
}
|
||||
}
|
||||
return effectiveAlive;
|
||||
if(combinations.size()==0) {
|
||||
// Add the combination at the current statement if no other combinations have been created
|
||||
combinations.add(effectiveAlive);
|
||||
}
|
||||
return combinations;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -42,10 +42,10 @@ public class Pass4RegisterUpliftCombinations extends Pass2Base {
|
||||
* Stores the best combination directly in the {@link LiveRangeEquivalenceClassSet}.
|
||||
*
|
||||
* @param combinationIterator The combination iterator used for supplying different register allocations to test
|
||||
* @param maxCombinations The maximal number of combinations to test. It the iterator has more combinations he rest is skipped (and a message logged)
|
||||
* @param unknownFragments Receives any unknown ASM fragments encountered during the combinsation search
|
||||
* @param scope The scope where the variables are being tested. (Only used for logging)
|
||||
* @param program The program to test (used for accessing global data structures)
|
||||
* @param maxCombinations The maximal number of combinations to test. It the iterator has more combinations he rest is skipped (and a message logged)
|
||||
* @param unknownFragments Receives any unknown ASM fragments encountered during the combinsation search
|
||||
* @param scope The scope where the variables are being tested. (Only used for logging)
|
||||
* @param program The program to test (used for accessing global data structures)
|
||||
*/
|
||||
static void chooseBestUpliftCombination(
|
||||
RegisterCombinationIterator combinationIterator, int maxCombinations,
|
||||
@ -93,15 +93,15 @@ public class Pass4RegisterUpliftCombinations extends Pass2Base {
|
||||
* Attempt generate ASM with a specific register combination.
|
||||
* The generation may result in failure if
|
||||
* <ul>
|
||||
* <li>The combination has assigned the same register to variables with overlapping live ranges</li>
|
||||
* <li>The register combination results in clobbering registers containing values that are still alive</li>
|
||||
* <li>some ASM fragments are missing </li>
|
||||
* <li>the ALU register is used in a non-applicable way</li>
|
||||
* <li>The combination has assigned the same register to variables with overlapping live ranges</li>
|
||||
* <li>The register combination results in clobbering registers containing values that are still alive</li>
|
||||
* <li>some ASM fragments are missing </li>
|
||||
* <li>the ALU register is used in a non-applicable way</li>
|
||||
* </ul>
|
||||
*
|
||||
* @param combination The register allocation combination
|
||||
* @param combination The register allocation combination
|
||||
* @param unknownFragments Will receive any AsmFragments that can not be found during the ASM code generation
|
||||
* @param scope The scope where the combination is tested. (Only used for logging)
|
||||
* @param scope The scope where the combination is tested. (Only used for logging)
|
||||
* @return true if the generation was successful
|
||||
*/
|
||||
public static boolean generateCombinationAsm(
|
||||
@ -167,6 +167,7 @@ public class Pass4RegisterUpliftCombinations extends Pass2Base {
|
||||
* Programs that take less cycles to execute have lower scores.
|
||||
* In practice the score is calculated by multiplying cycles of ASM instructions with
|
||||
* an estimate of the invocation count based on the loop depth of the instructions (10^depth).
|
||||
*
|
||||
* @param program The program containing the ASM to check
|
||||
* @return The score of the ASM
|
||||
*/
|
||||
@ -190,17 +191,17 @@ public class Pass4RegisterUpliftCombinations extends Pass2Base {
|
||||
return score;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Check the register allocation for whether a is register being allocated to two variables with overlapping live ranges
|
||||
*
|
||||
* @param program The program
|
||||
* @return true if the register allocation contains an overlapping allocation. false otherwise.
|
||||
*/
|
||||
public static boolean isAllocationOverlapping(Program program) {
|
||||
Pass2AliasElimination.Aliases aliases = Pass2AliasElimination.findAliasesCandidates(true, program);
|
||||
for (ControlFlowBlock block : program.getGraph().getAllBlocks()) {
|
||||
for (Statement statement : block.getStatements()) {
|
||||
LinkedHashMap<Registers.Register, LiveRangeEquivalenceClass> usedRegisters = new LinkedHashMap<>();
|
||||
if (isStatementAllocationOverlapping(program, statement, usedRegisters)) {
|
||||
if (isStatementAllocationOverlapping(program, statement, aliases)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -211,32 +212,46 @@ public class Pass4RegisterUpliftCombinations extends Pass2Base {
|
||||
/**
|
||||
* Determine if a statement has an overlapping register allocation
|
||||
*
|
||||
* @param program The program
|
||||
* @param statement The statement to check
|
||||
* @param program The program
|
||||
* @param statement The statement to check
|
||||
* @param usedRegisters The used registers. Will be extended with all registers used in the statement.
|
||||
* @return true if there is an overlapping register allocation
|
||||
*/
|
||||
private static boolean isStatementAllocationOverlapping(
|
||||
Program program,
|
||||
Statement statement,
|
||||
LinkedHashMap<Registers.Register, LiveRangeEquivalenceClass> usedRegisters) {
|
||||
private static boolean isStatementAllocationOverlapping(Program program, Statement statement, Pass2AliasElimination.Aliases aliases) {
|
||||
ProgramScope programScope = program.getScope();
|
||||
Collection<VariableRef> alive = program.getLiveRangeVariablesEffective().getAliveEffective(statement);
|
||||
for (VariableRef varRef : alive) {
|
||||
Variable var = programScope.getVariable(varRef);
|
||||
Registers.Register allocation = var.getAllocation();
|
||||
LiveRangeEquivalenceClass allocationClass = usedRegisters.get(allocation);
|
||||
if (allocationClass != null && !allocationClass.contains(varRef)) {
|
||||
if (program.getLog().isVerboseUplift()) {
|
||||
StringBuilder msg = new StringBuilder();
|
||||
msg.append("Overlap register " + allocation + " in " + statement.toString(program));
|
||||
program.getLog().append(msg.toString());
|
||||
LiveRangeVariablesEffective.AliveCombinations aliveCombinations = program.getLiveRangeVariablesEffective().getAliveCombinations(statement);
|
||||
for (LiveRangeVariablesEffective.AliveCombination aliveCombination : aliveCombinations.getCombinations()) {
|
||||
LinkedHashMap<Registers.Register, LiveRangeEquivalenceClass> usedRegisters = new LinkedHashMap<>();
|
||||
Collection<VariableRef> alive = aliveCombination.getAlive();
|
||||
for (VariableRef varRef : alive) {
|
||||
Variable var = programScope.getVariable(varRef);
|
||||
Registers.Register allocation = var.getAllocation();
|
||||
LiveRangeEquivalenceClass allocationClass = usedRegisters.get(allocation);
|
||||
if (allocationClass != null && !allocationClass.contains(varRef)) {
|
||||
// Examine if the var is an alias of a var in the allocation class
|
||||
boolean overlap = true;
|
||||
Pass2AliasElimination.AliasSet aliasSet = aliases.findAliasSet(varRef);
|
||||
if(aliasSet!=null) {
|
||||
for (VariableRef aliasVar : aliasSet.getVars()) {
|
||||
if(allocationClass.contains(aliasVar)) {
|
||||
overlap = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(overlap) {
|
||||
if (program.getLog().isVerboseUplift()) {
|
||||
StringBuilder msg = new StringBuilder();
|
||||
msg.append("Overlap register " + allocation + " in " + statement.toString(program));
|
||||
program.getLog().append(msg.toString());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
LiveRangeEquivalenceClass varClass =
|
||||
program.getLiveRangeEquivalenceClassSet().getEquivalenceClass(varRef);
|
||||
usedRegisters.put(allocation, varClass);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
LiveRangeEquivalenceClass varClass =
|
||||
program.getLiveRangeEquivalenceClassSet().getEquivalenceClass(varRef);
|
||||
usedRegisters.put(allocation, varClass);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
@ -74,8 +74,15 @@ public class Pass4RegisterUpliftStatic extends Pass2Base {
|
||||
setRegister(combination, "line::$7", Registers.getRegisterALU());
|
||||
setRegister(combination, "initplottables::$6", Registers.getRegisterA());
|
||||
setRegister(combination, "initplottables::$7", Registers.getRegisterALU());
|
||||
*/
|
||||
setRegister(combination, "initplottables::$6", Registers.getRegisterA());
|
||||
*/
|
||||
|
||||
setRegister(combination, "plot::x#0", Registers.getRegisterX());
|
||||
setRegister(combination, "plot::x#1", Registers.getRegisterX());
|
||||
setRegister(combination, "plot::x#2", Registers.getRegisterX());
|
||||
setRegister(combination, "plot::x#3", Registers.getRegisterX());
|
||||
setRegister(combination, "main::i#1", Registers.getRegisterX());
|
||||
setRegister(combination, "main::i#2", Registers.getRegisterX());
|
||||
|
||||
boolean success = Pass4RegisterUpliftCombinations.generateCombinationAsm(
|
||||
combination,
|
||||
|
Loading…
Reference in New Issue
Block a user