mirror of
https://gitlab.com/camelot/kickc.git
synced 2024-09-08 17:54:40 +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);
|
//program.getLog().setVerboseUplift(true);
|
||||||
new Pass4RegisterUpliftCombinations(program).performUplift(10_000);
|
new Pass4RegisterUpliftCombinations(program).performUplift(10_000);
|
||||||
|
|
||||||
//program.getLog().setVerboseUplift(true);
|
program.getLog().setVerboseUplift(true);
|
||||||
//new Pass4RegisterUpliftStatic(program).performUplift();
|
new Pass4RegisterUpliftStatic(program).performUplift();
|
||||||
//program.getLog().setVerboseUplift(false);
|
program.getLog().setVerboseUplift(false);
|
||||||
|
|
||||||
// Attempt uplifting registers one at a time to catch remaining potential not realized by combination search
|
// Attempt uplifting registers one at a time to catch remaining potential not realized by combination search
|
||||||
new Pass4RegisterUpliftRemains(program).performUplift(10_000);
|
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 {
|
public class LiveRangeVariablesEffective {
|
||||||
|
|
||||||
/** Effectively alive variables by statement index. */
|
/** Effectively alive variables by statement index. */
|
||||||
Map<Integer, Collection<VariableRef>> effectiveLiveVariables;
|
Map<Integer, AliveCombinations> effectiveLiveCombinations;
|
||||||
|
|
||||||
public LiveRangeVariablesEffective(Map<Integer, Collection<VariableRef>> effectiveLiveVariables) {
|
public LiveRangeVariablesEffective(Map<Integer, AliveCombinations> effectiveLiveCombinations) {
|
||||||
this.effectiveLiveVariables = effectiveLiveVariables;
|
this.effectiveLiveCombinations = effectiveLiveCombinations;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get all variables alive at a statement.
|
* 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 the calls.
|
* If the statement is inside a method this also includes all variables alive at the exit of any call.
|
||||||
* <p>
|
|
||||||
* This method requires a number of other analysis to be present and updated in the (global) program - especailly the Call Graph.
|
|
||||||
* </p>
|
* </p>
|
||||||
* @param statement The statement to examine
|
* @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) {
|
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;
|
package dk.camelot64.kickc.model;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
/** Statement base class implementing shared properties and logic */
|
/** Statement base class implementing shared properties and logic */
|
||||||
@ -48,7 +49,22 @@ public abstract class StatementBase implements Statement {
|
|||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
LiveRangeVariables liveRanges = program.getLiveRangeVariables();
|
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();
|
StringBuilder str = new StringBuilder();
|
||||||
str.append(" [ ");
|
str.append(" [ ");
|
||||||
for (VariableRef variableRef : alive) {
|
for (VariableRef variableRef : alive) {
|
||||||
|
@ -90,7 +90,7 @@ parameterList
|
|||||||
;
|
;
|
||||||
|
|
||||||
asmLines
|
asmLines
|
||||||
: asmLine ( asmLine )*
|
: asmLine*
|
||||||
;
|
;
|
||||||
|
|
||||||
asmLine
|
asmLine
|
||||||
|
@ -2315,19 +2315,17 @@ public class KickCParser extends Parser {
|
|||||||
try {
|
try {
|
||||||
enterOuterAlt(_localctx, 1);
|
enterOuterAlt(_localctx, 1);
|
||||||
{
|
{
|
||||||
setState(288);
|
setState(291);
|
||||||
asmLine();
|
|
||||||
setState(292);
|
|
||||||
_errHandler.sync(this);
|
_errHandler.sync(this);
|
||||||
_la = _input.LA(1);
|
_la = _input.LA(1);
|
||||||
while ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__26) | (1L << MNEMONIC) | (1L << NAME))) != 0)) {
|
while ((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__26) | (1L << MNEMONIC) | (1L << NAME))) != 0)) {
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
setState(289);
|
setState(288);
|
||||||
asmLine();
|
asmLine();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
setState(294);
|
setState(293);
|
||||||
_errHandler.sync(this);
|
_errHandler.sync(this);
|
||||||
_la = _input.LA(1);
|
_la = _input.LA(1);
|
||||||
}
|
}
|
||||||
@ -2374,21 +2372,21 @@ public class KickCParser extends Parser {
|
|||||||
AsmLineContext _localctx = new AsmLineContext(_ctx, getState());
|
AsmLineContext _localctx = new AsmLineContext(_ctx, getState());
|
||||||
enterRule(_localctx, 28, RULE_asmLine);
|
enterRule(_localctx, 28, RULE_asmLine);
|
||||||
try {
|
try {
|
||||||
setState(297);
|
setState(296);
|
||||||
_errHandler.sync(this);
|
_errHandler.sync(this);
|
||||||
switch (_input.LA(1)) {
|
switch (_input.LA(1)) {
|
||||||
case T__26:
|
case T__26:
|
||||||
case NAME:
|
case NAME:
|
||||||
enterOuterAlt(_localctx, 1);
|
enterOuterAlt(_localctx, 1);
|
||||||
{
|
{
|
||||||
setState(295);
|
setState(294);
|
||||||
asmLabel();
|
asmLabel();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case MNEMONIC:
|
case MNEMONIC:
|
||||||
enterOuterAlt(_localctx, 2);
|
enterOuterAlt(_localctx, 2);
|
||||||
{
|
{
|
||||||
setState(296);
|
setState(295);
|
||||||
asmInstruction();
|
asmInstruction();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -2432,24 +2430,24 @@ public class KickCParser extends Parser {
|
|||||||
AsmLabelContext _localctx = new AsmLabelContext(_ctx, getState());
|
AsmLabelContext _localctx = new AsmLabelContext(_ctx, getState());
|
||||||
enterRule(_localctx, 30, RULE_asmLabel);
|
enterRule(_localctx, 30, RULE_asmLabel);
|
||||||
try {
|
try {
|
||||||
setState(303);
|
setState(302);
|
||||||
_errHandler.sync(this);
|
_errHandler.sync(this);
|
||||||
switch (_input.LA(1)) {
|
switch (_input.LA(1)) {
|
||||||
case NAME:
|
case NAME:
|
||||||
enterOuterAlt(_localctx, 1);
|
enterOuterAlt(_localctx, 1);
|
||||||
{
|
{
|
||||||
setState(299);
|
setState(298);
|
||||||
match(NAME);
|
match(NAME);
|
||||||
setState(300);
|
setState(299);
|
||||||
match(T__14);
|
match(T__14);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case T__26:
|
case T__26:
|
||||||
enterOuterAlt(_localctx, 2);
|
enterOuterAlt(_localctx, 2);
|
||||||
{
|
{
|
||||||
setState(301);
|
setState(300);
|
||||||
match(T__26);
|
match(T__26);
|
||||||
setState(302);
|
setState(301);
|
||||||
match(T__14);
|
match(T__14);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -2498,14 +2496,14 @@ public class KickCParser extends Parser {
|
|||||||
try {
|
try {
|
||||||
enterOuterAlt(_localctx, 1);
|
enterOuterAlt(_localctx, 1);
|
||||||
{
|
{
|
||||||
setState(305);
|
setState(304);
|
||||||
match(MNEMONIC);
|
match(MNEMONIC);
|
||||||
setState(307);
|
setState(306);
|
||||||
_errHandler.sync(this);
|
_errHandler.sync(this);
|
||||||
switch ( getInterpreter().adaptivePredict(_input,30,_ctx) ) {
|
switch ( getInterpreter().adaptivePredict(_input,30,_ctx) ) {
|
||||||
case 1:
|
case 1:
|
||||||
{
|
{
|
||||||
setState(306);
|
setState(305);
|
||||||
asmParamMode();
|
asmParamMode();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -2656,14 +2654,14 @@ public class KickCParser extends Parser {
|
|||||||
AsmParamModeContext _localctx = new AsmParamModeContext(_ctx, getState());
|
AsmParamModeContext _localctx = new AsmParamModeContext(_ctx, getState());
|
||||||
enterRule(_localctx, 34, RULE_asmParamMode);
|
enterRule(_localctx, 34, RULE_asmParamMode);
|
||||||
try {
|
try {
|
||||||
setState(332);
|
setState(331);
|
||||||
_errHandler.sync(this);
|
_errHandler.sync(this);
|
||||||
switch ( getInterpreter().adaptivePredict(_input,31,_ctx) ) {
|
switch ( getInterpreter().adaptivePredict(_input,31,_ctx) ) {
|
||||||
case 1:
|
case 1:
|
||||||
_localctx = new AsmModeAbsContext(_localctx);
|
_localctx = new AsmModeAbsContext(_localctx);
|
||||||
enterOuterAlt(_localctx, 1);
|
enterOuterAlt(_localctx, 1);
|
||||||
{
|
{
|
||||||
setState(309);
|
setState(308);
|
||||||
asmExpr(0);
|
asmExpr(0);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -2671,9 +2669,9 @@ public class KickCParser extends Parser {
|
|||||||
_localctx = new AsmModeImmContext(_localctx);
|
_localctx = new AsmModeImmContext(_localctx);
|
||||||
enterOuterAlt(_localctx, 2);
|
enterOuterAlt(_localctx, 2);
|
||||||
{
|
{
|
||||||
setState(310);
|
setState(309);
|
||||||
match(T__44);
|
match(T__44);
|
||||||
setState(311);
|
setState(310);
|
||||||
asmExpr(0);
|
asmExpr(0);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -2681,11 +2679,11 @@ public class KickCParser extends Parser {
|
|||||||
_localctx = new AsmModeAbsXYContext(_localctx);
|
_localctx = new AsmModeAbsXYContext(_localctx);
|
||||||
enterOuterAlt(_localctx, 3);
|
enterOuterAlt(_localctx, 3);
|
||||||
{
|
{
|
||||||
setState(312);
|
setState(311);
|
||||||
asmExpr(0);
|
asmExpr(0);
|
||||||
setState(313);
|
setState(312);
|
||||||
match(T__16);
|
match(T__16);
|
||||||
setState(314);
|
setState(313);
|
||||||
match(NAME);
|
match(NAME);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -2693,15 +2691,15 @@ public class KickCParser extends Parser {
|
|||||||
_localctx = new AsmModeIndIdxXYContext(_localctx);
|
_localctx = new AsmModeIndIdxXYContext(_localctx);
|
||||||
enterOuterAlt(_localctx, 4);
|
enterOuterAlt(_localctx, 4);
|
||||||
{
|
{
|
||||||
setState(316);
|
setState(315);
|
||||||
match(T__2);
|
match(T__2);
|
||||||
setState(317);
|
setState(316);
|
||||||
asmExpr(0);
|
asmExpr(0);
|
||||||
setState(318);
|
setState(317);
|
||||||
match(T__3);
|
match(T__3);
|
||||||
setState(319);
|
setState(318);
|
||||||
match(T__16);
|
match(T__16);
|
||||||
setState(320);
|
setState(319);
|
||||||
match(NAME);
|
match(NAME);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -2709,15 +2707,15 @@ public class KickCParser extends Parser {
|
|||||||
_localctx = new AsmModeIdxIndXYContext(_localctx);
|
_localctx = new AsmModeIdxIndXYContext(_localctx);
|
||||||
enterOuterAlt(_localctx, 5);
|
enterOuterAlt(_localctx, 5);
|
||||||
{
|
{
|
||||||
setState(322);
|
setState(321);
|
||||||
match(T__2);
|
match(T__2);
|
||||||
setState(323);
|
setState(322);
|
||||||
asmExpr(0);
|
asmExpr(0);
|
||||||
setState(324);
|
setState(323);
|
||||||
match(T__16);
|
match(T__16);
|
||||||
setState(325);
|
setState(324);
|
||||||
match(NAME);
|
match(NAME);
|
||||||
setState(326);
|
setState(325);
|
||||||
match(T__3);
|
match(T__3);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -2725,11 +2723,11 @@ public class KickCParser extends Parser {
|
|||||||
_localctx = new AsmModeIndContext(_localctx);
|
_localctx = new AsmModeIndContext(_localctx);
|
||||||
enterOuterAlt(_localctx, 6);
|
enterOuterAlt(_localctx, 6);
|
||||||
{
|
{
|
||||||
setState(328);
|
setState(327);
|
||||||
match(T__2);
|
match(T__2);
|
||||||
setState(329);
|
setState(328);
|
||||||
asmExpr(0);
|
asmExpr(0);
|
||||||
setState(330);
|
setState(329);
|
||||||
match(T__3);
|
match(T__3);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -2900,7 +2898,7 @@ public class KickCParser extends Parser {
|
|||||||
int _alt;
|
int _alt;
|
||||||
enterOuterAlt(_localctx, 1);
|
enterOuterAlt(_localctx, 1);
|
||||||
{
|
{
|
||||||
setState(344);
|
setState(343);
|
||||||
_errHandler.sync(this);
|
_errHandler.sync(this);
|
||||||
switch (_input.LA(1)) {
|
switch (_input.LA(1)) {
|
||||||
case T__20:
|
case T__20:
|
||||||
@ -2912,7 +2910,7 @@ public class KickCParser extends Parser {
|
|||||||
_ctx = _localctx;
|
_ctx = _localctx;
|
||||||
_prevctx = _localctx;
|
_prevctx = _localctx;
|
||||||
|
|
||||||
setState(335);
|
setState(334);
|
||||||
_la = _input.LA(1);
|
_la = _input.LA(1);
|
||||||
if ( !((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__20) | (1L << T__21) | (1L << T__24) | (1L << T__25))) != 0)) ) {
|
if ( !((((_la) & ~0x3f) == 0 && ((1L << _la) & ((1L << T__20) | (1L << T__21) | (1L << T__24) | (1L << T__25))) != 0)) ) {
|
||||||
_errHandler.recoverInline(this);
|
_errHandler.recoverInline(this);
|
||||||
@ -2922,7 +2920,7 @@ public class KickCParser extends Parser {
|
|||||||
_errHandler.reportMatch(this);
|
_errHandler.reportMatch(this);
|
||||||
consume();
|
consume();
|
||||||
}
|
}
|
||||||
setState(336);
|
setState(335);
|
||||||
asmExpr(8);
|
asmExpr(8);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -2931,7 +2929,7 @@ public class KickCParser extends Parser {
|
|||||||
_localctx = new AsmExprLabelContext(_localctx);
|
_localctx = new AsmExprLabelContext(_localctx);
|
||||||
_ctx = _localctx;
|
_ctx = _localctx;
|
||||||
_prevctx = _localctx;
|
_prevctx = _localctx;
|
||||||
setState(337);
|
setState(336);
|
||||||
match(NAME);
|
match(NAME);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -2940,7 +2938,7 @@ public class KickCParser extends Parser {
|
|||||||
_localctx = new AsmExprLabelRelContext(_localctx);
|
_localctx = new AsmExprLabelRelContext(_localctx);
|
||||||
_ctx = _localctx;
|
_ctx = _localctx;
|
||||||
_prevctx = _localctx;
|
_prevctx = _localctx;
|
||||||
setState(338);
|
setState(337);
|
||||||
match(ASMREL);
|
match(ASMREL);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -2949,11 +2947,11 @@ public class KickCParser extends Parser {
|
|||||||
_localctx = new AsmExprReplaceContext(_localctx);
|
_localctx = new AsmExprReplaceContext(_localctx);
|
||||||
_ctx = _localctx;
|
_ctx = _localctx;
|
||||||
_prevctx = _localctx;
|
_prevctx = _localctx;
|
||||||
setState(339);
|
setState(338);
|
||||||
match(T__0);
|
match(T__0);
|
||||||
setState(340);
|
setState(339);
|
||||||
match(NAME);
|
match(NAME);
|
||||||
setState(341);
|
setState(340);
|
||||||
match(T__1);
|
match(T__1);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -2962,7 +2960,7 @@ public class KickCParser extends Parser {
|
|||||||
_localctx = new AsmExprIntContext(_localctx);
|
_localctx = new AsmExprIntContext(_localctx);
|
||||||
_ctx = _localctx;
|
_ctx = _localctx;
|
||||||
_prevctx = _localctx;
|
_prevctx = _localctx;
|
||||||
setState(342);
|
setState(341);
|
||||||
match(NUMBER);
|
match(NUMBER);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -2971,7 +2969,7 @@ public class KickCParser extends Parser {
|
|||||||
_localctx = new AsmExprCharContext(_localctx);
|
_localctx = new AsmExprCharContext(_localctx);
|
||||||
_ctx = _localctx;
|
_ctx = _localctx;
|
||||||
_prevctx = _localctx;
|
_prevctx = _localctx;
|
||||||
setState(343);
|
setState(342);
|
||||||
match(CHAR);
|
match(CHAR);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -2979,7 +2977,7 @@ public class KickCParser extends Parser {
|
|||||||
throw new NoViableAltException(this);
|
throw new NoViableAltException(this);
|
||||||
}
|
}
|
||||||
_ctx.stop = _input.LT(-1);
|
_ctx.stop = _input.LT(-1);
|
||||||
setState(354);
|
setState(353);
|
||||||
_errHandler.sync(this);
|
_errHandler.sync(this);
|
||||||
_alt = getInterpreter().adaptivePredict(_input,34,_ctx);
|
_alt = getInterpreter().adaptivePredict(_input,34,_ctx);
|
||||||
while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) {
|
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();
|
if ( _parseListeners!=null ) triggerExitRuleEvent();
|
||||||
_prevctx = _localctx;
|
_prevctx = _localctx;
|
||||||
{
|
{
|
||||||
setState(352);
|
setState(351);
|
||||||
_errHandler.sync(this);
|
_errHandler.sync(this);
|
||||||
switch ( getInterpreter().adaptivePredict(_input,33,_ctx) ) {
|
switch ( getInterpreter().adaptivePredict(_input,33,_ctx) ) {
|
||||||
case 1:
|
case 1:
|
||||||
{
|
{
|
||||||
_localctx = new AsmExprBinaryContext(new AsmExprContext(_parentctx, _parentState));
|
_localctx = new AsmExprBinaryContext(new AsmExprContext(_parentctx, _parentState));
|
||||||
pushNewRecursionContext(_localctx, _startState, RULE_asmExpr);
|
pushNewRecursionContext(_localctx, _startState, RULE_asmExpr);
|
||||||
setState(346);
|
setState(345);
|
||||||
if (!(precpred(_ctx, 7))) throw new FailedPredicateException(this, "precpred(_ctx, 7)");
|
if (!(precpred(_ctx, 7))) throw new FailedPredicateException(this, "precpred(_ctx, 7)");
|
||||||
setState(347);
|
setState(346);
|
||||||
_la = _input.LA(1);
|
_la = _input.LA(1);
|
||||||
if ( !(_la==T__17 || _la==T__31) ) {
|
if ( !(_la==T__17 || _la==T__31) ) {
|
||||||
_errHandler.recoverInline(this);
|
_errHandler.recoverInline(this);
|
||||||
@ -3006,7 +3004,7 @@ public class KickCParser extends Parser {
|
|||||||
_errHandler.reportMatch(this);
|
_errHandler.reportMatch(this);
|
||||||
consume();
|
consume();
|
||||||
}
|
}
|
||||||
setState(348);
|
setState(347);
|
||||||
asmExpr(8);
|
asmExpr(8);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -3014,9 +3012,9 @@ public class KickCParser extends Parser {
|
|||||||
{
|
{
|
||||||
_localctx = new AsmExprBinaryContext(new AsmExprContext(_parentctx, _parentState));
|
_localctx = new AsmExprBinaryContext(new AsmExprContext(_parentctx, _parentState));
|
||||||
pushNewRecursionContext(_localctx, _startState, RULE_asmExpr);
|
pushNewRecursionContext(_localctx, _startState, RULE_asmExpr);
|
||||||
setState(349);
|
setState(348);
|
||||||
if (!(precpred(_ctx, 6))) throw new FailedPredicateException(this, "precpred(_ctx, 6)");
|
if (!(precpred(_ctx, 6))) throw new FailedPredicateException(this, "precpred(_ctx, 6)");
|
||||||
setState(350);
|
setState(349);
|
||||||
_la = _input.LA(1);
|
_la = _input.LA(1);
|
||||||
if ( !(_la==T__24 || _la==T__25) ) {
|
if ( !(_la==T__24 || _la==T__25) ) {
|
||||||
_errHandler.recoverInline(this);
|
_errHandler.recoverInline(this);
|
||||||
@ -3026,14 +3024,14 @@ public class KickCParser extends Parser {
|
|||||||
_errHandler.reportMatch(this);
|
_errHandler.reportMatch(this);
|
||||||
consume();
|
consume();
|
||||||
}
|
}
|
||||||
setState(351);
|
setState(350);
|
||||||
asmExpr(7);
|
asmExpr(7);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
setState(356);
|
setState(355);
|
||||||
_errHandler.sync(this);
|
_errHandler.sync(this);
|
||||||
_alt = getInterpreter().adaptivePredict(_input,34,_ctx);
|
_alt = getInterpreter().adaptivePredict(_input,34,_ctx);
|
||||||
}
|
}
|
||||||
@ -3117,7 +3115,7 @@ public class KickCParser extends Parser {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static final String _serializedATN =
|
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"+
|
"\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"+
|
"\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"+
|
"\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"+
|
"\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"+
|
"\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"+
|
"\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"+
|
"\16\u0121\13\16\3\17\7\17\u0124\n\17\f\17\16\17\u0127\13\17\3\20\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"+
|
"\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"+
|
||||||
"\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"+
|
"\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\3\23\3\23\5\23\u014f"+
|
"\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"+
|
||||||
"\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\3\24\3\24\3\24\5\24\u015a\n\24\3\24\3\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\3\24\3\24\3\24\7\24\u0162\n\24\f\24\16\24\u0165\13\24\3\24\2\6\22"+
|
||||||
"\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"+
|
"\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\27\30\3\2\31\32\5\2\24\24\27\30\33\37\3\2 !\4\2\24\24\"#\3\2\33\34"+
|
"\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$*\4\2\27\30\33\34\4\2\24\24\"\"\2\u019b\2(\3\2\2\2\4+\3\2\2"+
|
"$*\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\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"+
|
"\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"+
|
||||||
"\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"+
|
"\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"+
|
||||||
"\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"+
|
"\u00f1\3\2\2\2\32\u011a\3\2\2\2\34\u0125\3\2\2\2\36\u012a\3\2\2\2 \u0130"+
|
||||||
"\2\2 \u0131\3\2\2\2\"\u0133\3\2\2\2$\u014e\3\2\2\2&\u015a\3\2\2\2()\5"+
|
"\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"+
|
||||||
"\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*\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"+
|
||||||
"\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"+
|
"\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"+
|
||||||
"\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"+
|
"\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"+
|
||||||
"\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"+
|
"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"+
|
||||||
"=>\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"+
|
"\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"+
|
||||||
"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"+
|
"\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"+
|
||||||
"\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"+
|
"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\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"+
|
"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"+
|
||||||
"\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"+
|
"\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"+
|
||||||
"\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"+
|
"[\\\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"+
|
"\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"+
|
"\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"+
|
"\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"+
|
"\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"+
|
"\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"+
|
"\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"+
|
"\2\u0122\u0124\5\36\20\2\u0123\u0122\3\2\2\2\u0124\u0127\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"+
|
"\u0123\3\2\2\2\u0125\u0126\3\2\2\2\u0126\35\3\2\2\2\u0127\u0125\3\2\2"+
|
||||||
"\2\u0128\u0126\3\2\2\2\u0129\u012c\5 \21\2\u012a\u012c\5\"\22\2\u012b"+
|
"\2\u0128\u012b\5 \21\2\u0129\u012b\5\"\22\2\u012a\u0128\3\2\2\2\u012a"+
|
||||||
"\u0129\3\2\2\2\u012b\u012a\3\2\2\2\u012c\37\3\2\2\2\u012d\u012e\7>\2\2"+
|
"\u0129\3\2\2\2\u012b\37\3\2\2\2\u012c\u012d\7>\2\2\u012d\u0131\7\21\2"+
|
||||||
"\u012e\u0132\7\21\2\2\u012f\u0130\7\35\2\2\u0130\u0132\7\21\2\2\u0131"+
|
"\2\u012e\u012f\7\35\2\2\u012f\u0131\7\21\2\2\u0130\u012c\3\2\2\2\u0130"+
|
||||||
"\u012d\3\2\2\2\u0131\u012f\3\2\2\2\u0132!\3\2\2\2\u0133\u0135\7\60\2\2"+
|
"\u012e\3\2\2\2\u0131!\3\2\2\2\u0132\u0134\7\60\2\2\u0133\u0135\5$\23\2"+
|
||||||
"\u0134\u0136\5$\23\2\u0135\u0134\3\2\2\2\u0135\u0136\3\2\2\2\u0136#\3"+
|
"\u0134\u0133\3\2\2\2\u0134\u0135\3\2\2\2\u0135#\3\2\2\2\u0136\u014e\5"+
|
||||||
"\2\2\2\u0137\u014f\5&\24\2\u0138\u0139\7/\2\2\u0139\u014f\5&\24\2\u013a"+
|
"&\24\2\u0137\u0138\7/\2\2\u0138\u014e\5&\24\2\u0139\u013a\5&\24\2\u013a"+
|
||||||
"\u013b\5&\24\2\u013b\u013c\7\23\2\2\u013c\u013d\7>\2\2\u013d\u014f\3\2"+
|
"\u013b\7\23\2\2\u013b\u013c\7>\2\2\u013c\u014e\3\2\2\2\u013d\u013e\7\5"+
|
||||||
"\2\2\u013e\u013f\7\5\2\2\u013f\u0140\5&\24\2\u0140\u0141\7\6\2\2\u0141"+
|
"\2\2\u013e\u013f\5&\24\2\u013f\u0140\7\6\2\2\u0140\u0141\7\23\2\2\u0141"+
|
||||||
"\u0142\7\23\2\2\u0142\u0143\7>\2\2\u0143\u014f\3\2\2\2\u0144\u0145\7\5"+
|
"\u0142\7>\2\2\u0142\u014e\3\2\2\2\u0143\u0144\7\5\2\2\u0144\u0145\5&\24"+
|
||||||
"\2\2\u0145\u0146\5&\24\2\u0146\u0147\7\23\2\2\u0147\u0148\7>\2\2\u0148"+
|
"\2\u0145\u0146\7\23\2\2\u0146\u0147\7>\2\2\u0147\u0148\7\6\2\2\u0148\u014e"+
|
||||||
"\u0149\7\6\2\2\u0149\u014f\3\2\2\2\u014a\u014b\7\5\2\2\u014b\u014c\5&"+
|
"\3\2\2\2\u0149\u014a\7\5\2\2\u014a\u014b\5&\24\2\u014b\u014c\7\6\2\2\u014c"+
|
||||||
"\24\2\u014c\u014d\7\6\2\2\u014d\u014f\3\2\2\2\u014e\u0137\3\2\2\2\u014e"+
|
"\u014e\3\2\2\2\u014d\u0136\3\2\2\2\u014d\u0137\3\2\2\2\u014d\u0139\3\2"+
|
||||||
"\u0138\3\2\2\2\u014e\u013a\3\2\2\2\u014e\u013e\3\2\2\2\u014e\u0144\3\2"+
|
"\2\2\u014d\u013d\3\2\2\2\u014d\u0143\3\2\2\2\u014d\u0149\3\2\2\2\u014e"+
|
||||||
"\2\2\u014e\u014a\3\2\2\2\u014f%\3\2\2\2\u0150\u0151\b\24\1\2\u0151\u0152"+
|
"%\3\2\2\2\u014f\u0150\b\24\1\2\u0150\u0151\t\t\2\2\u0151\u015a\5&\24\n"+
|
||||||
"\t\t\2\2\u0152\u015b\5&\24\n\u0153\u015b\7>\2\2\u0154\u015b\7?\2\2\u0155"+
|
"\u0152\u015a\7>\2\2\u0153\u015a\7?\2\2\u0154\u0155\7\3\2\2\u0155\u0156"+
|
||||||
"\u0156\7\3\2\2\u0156\u0157\7>\2\2\u0157\u015b\7\4\2\2\u0158\u015b\7\65"+
|
"\7>\2\2\u0156\u015a\7\4\2\2\u0157\u015a\7\65\2\2\u0158\u015a\7\63\2\2"+
|
||||||
"\2\2\u0159\u015b\7\63\2\2\u015a\u0150\3\2\2\2\u015a\u0153\3\2\2\2\u015a"+
|
"\u0159\u014f\3\2\2\2\u0159\u0152\3\2\2\2\u0159\u0153\3\2\2\2\u0159\u0154"+
|
||||||
"\u0154\3\2\2\2\u015a\u0155\3\2\2\2\u015a\u0158\3\2\2\2\u015a\u0159\3\2"+
|
"\3\2\2\2\u0159\u0157\3\2\2\2\u0159\u0158\3\2\2\2\u015a\u0163\3\2\2\2\u015b"+
|
||||||
"\2\2\u015b\u0164\3\2\2\2\u015c\u015d\f\t\2\2\u015d\u015e\t\n\2\2\u015e"+
|
"\u015c\f\t\2\2\u015c\u015d\t\n\2\2\u015d\u0162\5&\24\n\u015e\u015f\f\b"+
|
||||||
"\u0163\5&\24\n\u015f\u0160\f\b\2\2\u0160\u0161\t\7\2\2\u0161\u0163\5&"+
|
"\2\2\u015f\u0160\t\7\2\2\u0160\u0162\5&\24\t\u0161\u015b\3\2\2\2\u0161"+
|
||||||
"\24\t\u0162\u015c\3\2\2\2\u0162\u015f\3\2\2\2\u0163\u0166\3\2\2\2\u0164"+
|
"\u015e\3\2\2\2\u0162\u0165\3\2\2\2\u0163\u0161\3\2\2\2\u0163\u0164\3\2"+
|
||||||
"\u0162\3\2\2\2\u0164\u0165\3\2\2\2\u0165\'\3\2\2\2\u0166\u0164\3\2\2\2"+
|
"\2\2\u0164\'\3\2\2\2\u0165\u0163\3\2\2\2%\61\65<AFL_rz\u0082\u0085\u008a"+
|
||||||
"%\61\65<AFL_rz\u0082\u0085\u008a\u0090\u0097\u009e\u00ac\u00af\u00b1\u00bb"+
|
"\u0090\u0097\u009e\u00ac\u00af\u00b1\u00bb\u00c0\u00cc\u00d5\u00e0\u00f1"+
|
||||||
"\u00c0\u00cc\u00d5\u00e0\u00f1\u0115\u0117\u011f\u0126\u012b\u0131\u0135"+
|
"\u0115\u0117\u011f\u0125\u012a\u0130\u0134\u014d\u0159\u0161\u0163";
|
||||||
"\u014e\u015a\u0162\u0164";
|
|
||||||
public static final ATN _ATN =
|
public static final ATN _ATN =
|
||||||
new ATNDeserializer().deserialize(_serializedATN.toCharArray());
|
new ATNDeserializer().deserialize(_serializedATN.toCharArray());
|
||||||
static {
|
static {
|
||||||
|
@ -227,7 +227,7 @@ public class Pass2AliasElimination extends Pass2SsaOptimization {
|
|||||||
|
|
||||||
|
|
||||||
private Aliases findAliases() {
|
private Aliases findAliases() {
|
||||||
Aliases candidates = findAliasesCandidates();
|
Aliases candidates = findAliasesCandidates(false, getProgram());
|
||||||
cleanupCandidates(candidates);
|
cleanupCandidates(candidates);
|
||||||
return candidates;
|
return candidates;
|
||||||
}
|
}
|
||||||
@ -265,9 +265,9 @@ public class Pass2AliasElimination extends Pass2SsaOptimization {
|
|||||||
*
|
*
|
||||||
* @return Map from Variable to the Constant value
|
* @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();
|
final Aliases aliases = new Aliases();
|
||||||
ControlFlowGraphBaseVisitor<Void> visitor = new ControlFlowGraphBaseVisitor<Void>() {
|
final ControlFlowGraphBaseVisitor<Void> visitor = new ControlFlowGraphBaseVisitor<Void>() {
|
||||||
@Override
|
@Override
|
||||||
public Void visitAssignment(StatementAssignment assignment) {
|
public Void visitAssignment(StatementAssignment assignment) {
|
||||||
if (assignment.getlValue() instanceof VariableRef) {
|
if (assignment.getlValue() instanceof VariableRef) {
|
||||||
@ -278,7 +278,11 @@ public class Pass2AliasElimination extends Pass2SsaOptimization {
|
|||||||
if(variable.getScopeNames().equals(alias.getScopeNames())){
|
if(variable.getScopeNames().equals(alias.getScopeNames())){
|
||||||
aliases.add(variable, alias);
|
aliases.add(variable, alias);
|
||||||
} else {
|
} 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) {
|
if (phiRValue.getrValue() instanceof VariableRef) {
|
||||||
alias = (VariableRef) phiRValue.getrValue();
|
alias = (VariableRef) phiRValue.getrValue();
|
||||||
if(!variable.getScopeNames().equals(alias.getScopeNames())){
|
if(!variable.getScopeNames().equals(alias.getScopeNames())){
|
||||||
getLog().append("Not aliassing across scopes: "+variable+" "+alias);
|
if(!allowCrossScope) {
|
||||||
alias = null;
|
program.getLog().append("Not aliassing across scopes: " + variable + " " + alias);
|
||||||
break;
|
alias = null;
|
||||||
|
break;
|
||||||
|
}
|
||||||
} else if(variable.equals(alias)) {
|
} else if(variable.equals(alias)) {
|
||||||
getLog().append("Not aliassing identity: "+variable+" "+alias);
|
program.getLog().append("Not aliassing identity: "+variable+" "+alias);
|
||||||
alias = null;
|
alias = null;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -325,7 +331,7 @@ public class Pass2AliasElimination extends Pass2SsaOptimization {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
visitor.visitGraph(getGraph());
|
visitor.visitGraph(program.getGraph());
|
||||||
return aliases;
|
return aliases;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
package dk.camelot64.kickc.passes;
|
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 dk.camelot64.kickc.model.*;
|
||||||
|
|
||||||
import java.util.*;
|
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 class Pass3LiveRangesEffectiveAnalysis extends Pass2Base {
|
||||||
|
|
||||||
public Pass3LiveRangesEffectiveAnalysis(Program program) {
|
public Pass3LiveRangesEffectiveAnalysis(Program program) {
|
||||||
@ -19,17 +19,17 @@ public class Pass3LiveRangesEffectiveAnalysis extends Pass2Base {
|
|||||||
//getLog().append("Calculated effective variable live ranges");
|
//getLog().append("Calculated effective variable live ranges");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private LiveRangeVariablesEffective findAliveEffective(Program program) {
|
private LiveRangeVariablesEffective findAliveEffective(Program program) {
|
||||||
LiveRangeVariables liveRangeVariables = program.getLiveRangeVariables();
|
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 (ControlFlowBlock block : program.getGraph().getAllBlocks()) {
|
||||||
for (Statement statement : block.getStatements()) {
|
for (Statement statement : block.getStatements()) {
|
||||||
Collection<VariableRef> aliveEffective = findAliveEffective( liveRangeVariables, statement);
|
Collection<Collection<VariableRef>> statementAliveCombinations = findAliveEffective(liveRangeVariables, statement);
|
||||||
effectiveLiveVariables.put(statement.getIndex(), aliveEffective);
|
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
|
* @param statement The statement to examine
|
||||||
* @return All variables alive at the statement
|
* @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
|
// Get variables alive from live range analysis
|
||||||
Collection<VariableRef> effectiveAlive = new LinkedHashSet<>();
|
Collection<VariableRef> effectiveAlive = liveRangeVariables.getAlive(statement);
|
||||||
effectiveAlive.addAll(liveRangeVariables.getAlive(statement));
|
|
||||||
// If the statement is inside a method recurse back to all calls
|
// 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
|
// 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());
|
ControlFlowBlock block = getProgram().getGraph().getBlockFromStatementIdx(statement.getIndex());
|
||||||
@ -57,16 +57,28 @@ public class Pass3LiveRangesEffectiveAnalysis extends Pass2Base {
|
|||||||
VariableReferenceInfo referenceInfo = new VariableReferenceInfo(getProgram());
|
VariableReferenceInfo referenceInfo = new VariableReferenceInfo(getProgram());
|
||||||
Collection<VariableRef> referencedInProcedure = referenceInfo.getReferenced(procedure.getRef().getLabelRef());
|
Collection<VariableRef> referencedInProcedure = referenceInfo.getReferenced(procedure.getRef().getLabelRef());
|
||||||
for (CallGraph.CallBlock.Call caller : callers) {
|
for (CallGraph.CallBlock.Call caller : callers) {
|
||||||
|
// Each caller creates its own combinations
|
||||||
StatementCall callStatement =
|
StatementCall callStatement =
|
||||||
(StatementCall) getProgram().getGraph().getStatementByIndex(caller.getCallStatementIdx());
|
(StatementCall) getProgram().getGraph().getStatementByIndex(caller.getCallStatementIdx());
|
||||||
Set<VariableRef> callAliveEffective = new LinkedHashSet<>(findAliveEffective(liveRangeVariables, callStatement));
|
Collection<Collection<VariableRef>> callerCombinations = findAliveEffective(liveRangeVariables, callStatement);
|
||||||
// Clear out any variables referenced in the method
|
for (Collection<VariableRef> callerCombination : callerCombinations) {
|
||||||
callAliveEffective.removeAll(referencedInProcedure);
|
LinkedHashSet<VariableRef> combination = new LinkedHashSet<>();
|
||||||
effectiveAlive.addAll(callAliveEffective);
|
// 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}.
|
* Stores the best combination directly in the {@link LiveRangeEquivalenceClassSet}.
|
||||||
*
|
*
|
||||||
* @param combinationIterator The combination iterator used for supplying different register allocations to test
|
* @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 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 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 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 program The program to test (used for accessing global data structures)
|
||||||
*/
|
*/
|
||||||
static void chooseBestUpliftCombination(
|
static void chooseBestUpliftCombination(
|
||||||
RegisterCombinationIterator combinationIterator, int maxCombinations,
|
RegisterCombinationIterator combinationIterator, int maxCombinations,
|
||||||
@ -93,15 +93,15 @@ public class Pass4RegisterUpliftCombinations extends Pass2Base {
|
|||||||
* Attempt generate ASM with a specific register combination.
|
* Attempt generate ASM with a specific register combination.
|
||||||
* The generation may result in failure if
|
* The generation may result in failure if
|
||||||
* <ul>
|
* <ul>
|
||||||
* <li>The combination has assigned the same register to variables with overlapping live ranges</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>The register combination results in clobbering registers containing values that are still alive</li>
|
||||||
* <li>some ASM fragments are missing </li>
|
* <li>some ASM fragments are missing </li>
|
||||||
* <li>the ALU register is used in a non-applicable way</li>
|
* <li>the ALU register is used in a non-applicable way</li>
|
||||||
* </ul>
|
* </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 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
|
* @return true if the generation was successful
|
||||||
*/
|
*/
|
||||||
public static boolean generateCombinationAsm(
|
public static boolean generateCombinationAsm(
|
||||||
@ -167,6 +167,7 @@ public class Pass4RegisterUpliftCombinations extends Pass2Base {
|
|||||||
* Programs that take less cycles to execute have lower scores.
|
* Programs that take less cycles to execute have lower scores.
|
||||||
* In practice the score is calculated by multiplying cycles of ASM instructions with
|
* 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).
|
* 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
|
* @param program The program containing the ASM to check
|
||||||
* @return The score of the ASM
|
* @return The score of the ASM
|
||||||
*/
|
*/
|
||||||
@ -190,17 +191,17 @@ public class Pass4RegisterUpliftCombinations extends Pass2Base {
|
|||||||
return score;
|
return score;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check the register allocation for whether a is register being allocated to two variables with overlapping live ranges
|
* Check the register allocation for whether a is register being allocated to two variables with overlapping live ranges
|
||||||
|
*
|
||||||
* @param program The program
|
* @param program The program
|
||||||
* @return true if the register allocation contains an overlapping allocation. false otherwise.
|
* @return true if the register allocation contains an overlapping allocation. false otherwise.
|
||||||
*/
|
*/
|
||||||
public static boolean isAllocationOverlapping(Program program) {
|
public static boolean isAllocationOverlapping(Program program) {
|
||||||
|
Pass2AliasElimination.Aliases aliases = Pass2AliasElimination.findAliasesCandidates(true, program);
|
||||||
for (ControlFlowBlock block : program.getGraph().getAllBlocks()) {
|
for (ControlFlowBlock block : program.getGraph().getAllBlocks()) {
|
||||||
for (Statement statement : block.getStatements()) {
|
for (Statement statement : block.getStatements()) {
|
||||||
LinkedHashMap<Registers.Register, LiveRangeEquivalenceClass> usedRegisters = new LinkedHashMap<>();
|
if (isStatementAllocationOverlapping(program, statement, aliases)) {
|
||||||
if (isStatementAllocationOverlapping(program, statement, usedRegisters)) {
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -211,32 +212,46 @@ public class Pass4RegisterUpliftCombinations extends Pass2Base {
|
|||||||
/**
|
/**
|
||||||
* Determine if a statement has an overlapping register allocation
|
* Determine if a statement has an overlapping register allocation
|
||||||
*
|
*
|
||||||
* @param program The program
|
* @param program The program
|
||||||
* @param statement The statement to check
|
* @param statement The statement to check
|
||||||
* @param usedRegisters The used registers. Will be extended with all registers used in the statement.
|
* @param usedRegisters The used registers. Will be extended with all registers used in the statement.
|
||||||
* @return true if there is an overlapping register allocation
|
* @return true if there is an overlapping register allocation
|
||||||
*/
|
*/
|
||||||
private static boolean isStatementAllocationOverlapping(
|
private static boolean isStatementAllocationOverlapping(Program program, Statement statement, Pass2AliasElimination.Aliases aliases) {
|
||||||
Program program,
|
|
||||||
Statement statement,
|
|
||||||
LinkedHashMap<Registers.Register, LiveRangeEquivalenceClass> usedRegisters) {
|
|
||||||
ProgramScope programScope = program.getScope();
|
ProgramScope programScope = program.getScope();
|
||||||
Collection<VariableRef> alive = program.getLiveRangeVariablesEffective().getAliveEffective(statement);
|
LiveRangeVariablesEffective.AliveCombinations aliveCombinations = program.getLiveRangeVariablesEffective().getAliveCombinations(statement);
|
||||||
for (VariableRef varRef : alive) {
|
for (LiveRangeVariablesEffective.AliveCombination aliveCombination : aliveCombinations.getCombinations()) {
|
||||||
Variable var = programScope.getVariable(varRef);
|
LinkedHashMap<Registers.Register, LiveRangeEquivalenceClass> usedRegisters = new LinkedHashMap<>();
|
||||||
Registers.Register allocation = var.getAllocation();
|
Collection<VariableRef> alive = aliveCombination.getAlive();
|
||||||
LiveRangeEquivalenceClass allocationClass = usedRegisters.get(allocation);
|
for (VariableRef varRef : alive) {
|
||||||
if (allocationClass != null && !allocationClass.contains(varRef)) {
|
Variable var = programScope.getVariable(varRef);
|
||||||
if (program.getLog().isVerboseUplift()) {
|
Registers.Register allocation = var.getAllocation();
|
||||||
StringBuilder msg = new StringBuilder();
|
LiveRangeEquivalenceClass allocationClass = usedRegisters.get(allocation);
|
||||||
msg.append("Overlap register " + allocation + " in " + statement.toString(program));
|
if (allocationClass != null && !allocationClass.contains(varRef)) {
|
||||||
program.getLog().append(msg.toString());
|
// 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;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -74,8 +74,15 @@ public class Pass4RegisterUpliftStatic extends Pass2Base {
|
|||||||
setRegister(combination, "line::$7", Registers.getRegisterALU());
|
setRegister(combination, "line::$7", Registers.getRegisterALU());
|
||||||
setRegister(combination, "initplottables::$6", Registers.getRegisterA());
|
setRegister(combination, "initplottables::$6", Registers.getRegisterA());
|
||||||
setRegister(combination, "initplottables::$7", Registers.getRegisterALU());
|
setRegister(combination, "initplottables::$7", Registers.getRegisterALU());
|
||||||
*/
|
|
||||||
setRegister(combination, "initplottables::$6", Registers.getRegisterA());
|
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(
|
boolean success = Pass4RegisterUpliftCombinations.generateCombinationAsm(
|
||||||
combination,
|
combination,
|
||||||
|
Loading…
Reference in New Issue
Block a user