1 19 20 package jode.flow; 21 import jode.expr.*; 22 import jode.type.Type; 23 24 public class CreatePrePostIncExpression { 25 26 public static boolean transform(InstructionContainer ic, 27 StructuredBlock last) 28 { 29 return (createLocalPrePostInc(ic, last) || createPostInc(ic, last)); 30 } 31 32 public static boolean createLocalPrePostInc(InstructionContainer ic, 33 StructuredBlock last) { 34 42 43 if (!(last.outer instanceof SequentialBlock) 44 || !(last.outer.getSubBlocks()[0] instanceof InstructionBlock)) 45 return false; 46 47 Expression instr1 = ((InstructionBlock) 48 last.outer.getSubBlocks()[0]).getInstruction(); 49 Expression instr2 = ic.getInstruction(); 50 51 IIncOperator iinc; 52 LocalLoadOperator load; 53 boolean isPost; 54 if (instr1 instanceof IIncOperator 55 && instr2 instanceof LocalLoadOperator) { 56 iinc = (IIncOperator) instr1; 57 load = (LocalLoadOperator) instr2; 58 isPost = false; 59 } else if (instr1 instanceof LocalLoadOperator 60 && instr2 instanceof IIncOperator) { 61 load = (LocalLoadOperator) instr1; 62 iinc = (IIncOperator) instr2; 63 isPost = true; 64 } else 65 return false; 66 67 int op; 68 if (iinc.getOperatorIndex() == iinc.ADD_OP + iinc.OPASSIGN_OP) 69 op = Operator.INC_OP; 70 else if (iinc.getOperatorIndex() == iinc.SUB_OP + iinc.OPASSIGN_OP) 71 op = Operator.DEC_OP; 72 else 73 return false; 74 75 if (iinc.getValue() == -1) 76 op ^= 1; 77 else if (iinc.getValue() != 1) 78 return false; 79 80 if (!iinc.lvalueMatches(load)) 81 return false; 82 83 Type type = load.getType().intersection(Type.tUInt); 84 iinc.makeNonVoid(); 85 Operator ppop = 86 new PrePostFixOperator(type, op, iinc.getLValue(), isPost); 87 88 ic.setInstruction(ppop); 89 ic.moveDefinitions(last.outer, last); 90 last.replace(last.outer); 91 return true; 92 } 93 94 public static boolean createPostInc(InstructionContainer ic, 95 StructuredBlock last) { 96 97 106 107 if (!(ic.getInstruction() instanceof StoreInstruction)) 108 return false; 109 110 StoreInstruction store = (StoreInstruction) ic.getInstruction(); 111 112 116 Expression lvalue = store.getSubExpressions()[0]; 117 int lvalueCount = lvalue.getFreeOperandCount(); 118 if (!((Operator)lvalue).isFreeOperator() 119 || !store.isVoid() 120 || !(store.getSubExpressions()[1] instanceof BinaryOperator)) 121 return false; 122 123 BinaryOperator binOp = (BinaryOperator) store.getSubExpressions()[1]; 124 if (binOp.getSubExpressions() == null 125 || !(binOp.getSubExpressions()[0] instanceof NopOperator) 126 || !(binOp.getSubExpressions()[1] instanceof ConstOperator)) 127 return false; 128 129 ConstOperator constOp = (ConstOperator) binOp.getSubExpressions()[1]; 130 int op; 131 if (binOp.getOperatorIndex() == store.ADD_OP) 132 op = Operator.INC_OP; 133 else if (binOp.getOperatorIndex() == store.SUB_OP) 134 op = Operator.DEC_OP; 135 else 136 return false; 137 138 if (!constOp.isOne(lvalue.getType())) 139 return false; 140 141 if (!(last.outer instanceof SequentialBlock)) 142 return false; 143 SequentialBlock sb = (SequentialBlock)last.outer; 144 if (!(sb.subBlocks[0] instanceof SpecialBlock)) 145 return false; 146 147 SpecialBlock dup = (SpecialBlock) sb.subBlocks[0]; 148 if (dup.type != SpecialBlock.DUP 149 || dup.count != lvalue.getType().stackSize() 150 || dup.depth != lvalueCount) 151 return false; 152 153 if (!(sb.outer instanceof SequentialBlock)) 154 return false; 155 sb = (SequentialBlock) sb.outer; 156 if (!(sb.subBlocks[0] instanceof InstructionBlock)) 157 return false; 158 InstructionBlock ib = (InstructionBlock) sb.subBlocks[0]; 159 160 if (!(ib.getInstruction() instanceof Operator) 161 || !store.lvalueMatches((Operator) ib.getInstruction())) 162 return false; 163 164 if (lvalueCount > 0) { 165 if (!(sb.outer instanceof SequentialBlock)) 166 return false; 167 sb = (SequentialBlock) sb.outer; 168 if (!(sb.subBlocks[0] instanceof SpecialBlock)) 169 return false; 170 SpecialBlock dup2 = (SpecialBlock) sb.subBlocks[0]; 171 if (dup2.type != SpecialBlock.DUP 172 || dup2.count != lvalueCount 173 || dup2.depth != 0) 174 return false; 175 } 176 ic.setInstruction 177 (new PrePostFixOperator(lvalue.getType(), op, 178 store.getLValue(), true)); 179 ic.moveDefinitions(sb, last); 180 last.replace(sb); 181 return true; 182 } 183 } 184 | Popular Tags |