Refactor increment and decrement operations codegen

This commit is contained in:
Skylot
2013-06-06 21:48:57 +04:00
parent 59292a2bc1
commit 26800fb790
7 changed files with 56 additions and 52 deletions
+24 -17
View File
@@ -73,7 +73,7 @@ public class InsnGen {
public String arg(InsnArg arg) throws CodegenException {
if (arg.isRegister()) {
return mgen.makeArgName((RegisterArg) arg);
return arg((RegisterArg) arg);
} else if (arg.isLiteral()) {
return lit((LiteralArg) arg);
} else {
@@ -83,12 +83,16 @@ public class InsnGen {
}
}
public String arg(RegisterArg arg) {
return mgen.makeArgName(arg);
}
public String assignVar(InsnNode insn) {
RegisterArg arg = insn.getResult();
if (insn.getAttributes().contains(AttributeType.DECLARE_VARIABLE)) {
return declareVar(arg);
} else {
return mgen.makeArgName(arg);
return arg(arg);
}
}
@@ -324,11 +328,11 @@ public class InsnGen {
code.add(arg(insn.getArg(0)));
break;
/* fallback mode instructions */
case NOP:
state.add(InsnGenState.SKIP);
break;
/* fallback mode instructions */
case IF:
assert isFallback();
IfNode ifInsn = (IfNode) insn;
@@ -548,25 +552,28 @@ public class InsnGen {
private void makeArith(ArithNode insn, CodeWriter code, EnumSet<InsnGenState> state) throws CodegenException {
ArithOp op = insn.getOp();
String v1 = arg(insn.getArg(0));
if (op == ArithOp.INC || op == ArithOp.DEC) {
code.add(v1 + op.getSymbol());
state.add(InsnGenState.NO_RESULT);
String v2 = arg(insn.getArg(1));
if (state.contains(InsnGenState.BODY_ONLY)) {
// wrap insn in brackets for save correct operation order
// TODO don't wrap first insn in wrapped stack
code.add('(').add(v1).add(' ').add(op.getSymbol()).add(' ').add(v2).add(')');
} else {
String res = arg(insn.getResult());
String v2 = arg(insn.getArg(1));
if (res.equals(v1) && !state.contains(InsnGenState.BODY_ONLY)) {
code.add(assignVar(insn) + " " + op.getSymbol() + "= " + v2);
if (res.equals(v1)) {
state.add(InsnGenState.NO_RESULT);
// "++" or "--"
if (insn.getArg(1).isLiteral() && (op == ArithOp.ADD || op == ArithOp.SUB)) {
LiteralArg lit = (LiteralArg) insn.getArg(1);
if (Math.abs(lit.getLiteral()) == 1 && lit.isInteger()) {
code.add(assignVar(insn)).add(op.getSymbol()).add(op.getSymbol());
return;
}
}
// +=, -= ...
code.add(assignVar(insn)).add(' ').add(op.getSymbol()).add("= ").add(v2);
} else {
if (state.contains(InsnGenState.BODY_ONLY))
// wrap insn in brackets for save correct operation order
// TODO don't wrap first insn in wrapped stack
code.add("(" + v1 + " " + op.getSymbol() + " " + v2 + ")");
else
code.add(v1 + " " + op.getSymbol() + " " + v2);
code.add(v1).add(' ').add(op.getSymbol()).add(' ').add(v2);
}
}
}
}
+2 -2
View File
@@ -208,16 +208,16 @@ public class RegionGen extends InsnGen {
}
private void makeCaseBlock(IContainer c, CodeWriter code) throws CodegenException {
code.add(" {");
if (RegionUtils.notEmpty(c)) {
code.add(" {");
makeRegionIndent(code, c);
if (RegionUtils.hasExitEdge(c)) {
code.startLine(1, "break;");
}
code.startLine('}');
} else {
code.startLine(1, "break;");
}
code.startLine('}');
}
private void makeTryCatch(IContainer region, TryCatchBlock tryCatchBlock, CodeWriter code)
@@ -44,17 +44,17 @@ public class ArithNode extends InsnNode {
public ArithNode(ArithOp op, RegisterArg res, InsnArg a, InsnArg b) {
super(InsnType.ARITH, 2);
this.op = op;
setResult(res);
addArg(a);
addArg(b);
this.op = op;
}
public ArithNode(ArithOp op, RegisterArg res, InsnArg a) {
super(InsnType.ARITH, 1);
this.op = op;
setResult(res);
addArg(a);
this.op = op;
}
public ArithOp getOp() {
@@ -66,7 +66,9 @@ public class ArithNode extends InsnNode {
return InsnUtils.formatOffset(offset) + ": "
+ InsnUtils.insnTypeToString(insnType)
+ getResult() + " = "
+ getArg(0) + " " + op.getSymbol() + " " + getArg(1);
+ getArg(0) + " "
+ op.getSymbol() + " "
+ (getArgsCount() == 2 ? getArg(1) : "");
}
}
@@ -7,9 +7,6 @@ public enum ArithOp {
DIV("/"),
REM("%"),
INC("++"),
DEC("--"),
AND("&"),
OR("|"),
XOR("^"),
@@ -23,6 +23,15 @@ public class LiteralArg extends InsnArg {
return true;
}
public boolean isInteger() {
PrimitiveType type = typedVar.getType().getPrimitiveType();
return (type == PrimitiveType.INT
|| type == PrimitiveType.BYTE
|| type == PrimitiveType.CHAR
|| type == PrimitiveType.SHORT
|| type == PrimitiveType.LONG);
}
@Override
public String toString() {
try {
@@ -30,10 +30,6 @@ public class CodeShrinker extends AbstractVisitor {
if (mth.isNoCode() || mth.getAttributes().contains(AttributeFlag.DONT_SHRINK))
return;
// TODO pretify required inlined consts (made by shrink)
// 'dec' and 'inc' don't need to be inlined => must be replaced before shrink
pretify(mth);
shrink(mth);
pretify(mth);
}
@@ -57,11 +53,11 @@ public class CodeShrinker extends AbstractVisitor {
LOG.debug("parent insn null in " + useInsnArg + " from " + insn + " mth: " + mth);
} else if (useInsn != insn) {
boolean wrap = false;
// TODO don't reorder methods invocations
// if (insn.getResult().getTypedVar().getName() != null) {
// wrap = false;
// } else
if (BlockUtils.blockContains(block, useInsn)) {
if (false && insn.getResult().getTypedVar().getName() != null) {
// don't wrap if result variable has name from debug info
wrap = false;
} else if (BlockUtils.blockContains(block, useInsn)) {
// TODO don't reorder methods invocations
// wrap insn from current block
wrap = true;
} else {
@@ -72,8 +68,13 @@ public class CodeShrinker extends AbstractVisitor {
}
}
if (wrap) {
useInsnArg.wrapInstruction(insn);
remover.add(insn);
if (useInsn.getType() == InsnType.MOVE) {
// TODO
// remover.add(useInsn);
} else {
useInsnArg.wrapInstruction(insn);
remover.add(insn);
}
}
}
}
@@ -124,20 +125,6 @@ public class CodeShrinker extends AbstractVisitor {
if (arith.getOp() == ArithOp.ADD && lit < 0)
invert = true;
if (false && (lit == 1 || lit == -1) && arith.getArg(0).isRegister()) {
ArithOp op = arith.getOp();
if (op == ArithOp.ADD || op == ArithOp.SUB) {
RegisterArg res = arith.getResult();
RegisterArg v0 = (RegisterArg) arith.getArg(0);
if (v0.equals(res)) {
// use 'a++' instead 'a = a + 1' (similar for minus)
boolean inc = ((op == ArithOp.ADD && lit == 1)
|| (op == ArithOp.SUB && lit == -1));
return new ArithNode(inc ? ArithOp.INC : ArithOp.DEC, null, v0);
}
}
}
// fix 'c + (-1)' => 'c - (1)'
if (invert) {
return new ArithNode(ArithOp.SUB,
@@ -382,8 +382,10 @@ public class RegionMaker {
out = null;
}
if (stack.containsExit(elseBlock))
elseBlock = null;
if (elseBlock != null) {
if (stack.containsExit(elseBlock))
elseBlock = null;
}
IfRegion ifRegion = new IfRegion(currentRegion, block);
currentRegion.getSubBlocks().add(ifRegion);