1 // $Id: peephole.c,v 1.6 2003/10/13 22:53:04 iain Exp $
2 // Peephole optimiser for git
8 extern void resetPeepholeOptimiser ()
13 #define REPLACE_SINGLE(lastOp,thisOp,newOp) \
14 case label_ ## thisOp: \
15 if (sLastOp == label_ ## lastOp) \
17 op = label_ ## newOp; \
18 goto replaceNoOperands; \
22 #define CASE_NO_OPERANDS(lastOp,newOp) \
23 case label_ ## lastOp: op = label_ ## newOp; goto replaceNoOperands
25 #define CASE_ONE_OPERAND(lastOp,newOp) \
26 case label_ ## lastOp: op = label_ ## newOp; goto replaceOneOperand
28 #define REPLACE_STORE(storeOp) \
29 case label_ ## storeOp: \
32 CASE_NO_OPERANDS (add_discard, add_ ## storeOp); \
33 CASE_NO_OPERANDS (sub_discard, sub_ ## storeOp); \
34 CASE_NO_OPERANDS (mul_discard, mul_ ## storeOp); \
35 CASE_NO_OPERANDS (div_discard, div_ ## storeOp); \
36 CASE_NO_OPERANDS (mod_discard, mod_ ## storeOp); \
37 CASE_NO_OPERANDS (neg_discard, neg_ ## storeOp); \
38 CASE_NO_OPERANDS (bitand_discard, bitand_ ## storeOp); \
39 CASE_NO_OPERANDS (bitor_discard, bitor_ ## storeOp); \
40 CASE_NO_OPERANDS (bitxor_discard, bitxor_ ## storeOp); \
41 CASE_NO_OPERANDS (bitnot_discard, bitnot_ ## storeOp); \
42 CASE_NO_OPERANDS (shiftl_discard, shiftl_ ## storeOp); \
43 CASE_NO_OPERANDS (sshiftr_discard, sshiftr_ ## storeOp); \
44 CASE_NO_OPERANDS (ushiftr_discard, ushiftr_ ## storeOp); \
45 CASE_NO_OPERANDS (copys_discard, copys_ ## storeOp); \
46 CASE_NO_OPERANDS (copyb_discard, copyb_ ## storeOp); \
47 CASE_NO_OPERANDS (sexs_discard, sexs_ ## storeOp); \
48 CASE_NO_OPERANDS (sexb_discard, sexb_ ## storeOp); \
49 CASE_NO_OPERANDS (aload_discard, aload_ ## storeOp); \
50 CASE_NO_OPERANDS (aloads_discard, aloads_ ## storeOp); \
51 CASE_NO_OPERANDS (aloadb_discard, aloadb_ ## storeOp); \
52 CASE_NO_OPERANDS (aloadbit_discard, aloadbit_ ## storeOp); \
53 CASE_NO_OPERANDS (fadd_discard, fadd_ ## storeOp); \
54 CASE_NO_OPERANDS (fsub_discard, fsub_ ## storeOp); \
55 CASE_NO_OPERANDS (fmul_discard, fmul_ ## storeOp); \
56 CASE_NO_OPERANDS (fdiv_discard, fdiv_ ## storeOp); \
61 #define REPLACE_L1_L2(mode2) \
62 case label_L2_ ## mode2: \
65 CASE_ONE_OPERAND (L1_const, L1_const_L2_ ## mode2); \
66 CASE_NO_OPERANDS (L1_stack, L1_stack_L2_ ## mode2); \
67 CASE_ONE_OPERAND (L1_local, L1_local_L2_ ## mode2); \
68 CASE_ONE_OPERAND (L1_addr, L1_addr_L2_ ## mode2); \
73 #define REPLACE_LOAD_OP(loadOp,reg) \
74 case label_ ## loadOp: \
77 CASE_ONE_OPERAND (reg ## _const, loadOp ## _ ## reg ## _const); \
78 CASE_NO_OPERANDS (reg ## _stack, loadOp ## _ ## reg ## _stack); \
79 CASE_ONE_OPERAND (reg ## _local, loadOp ## _ ## reg ## _local); \
80 CASE_ONE_OPERAND (reg ## _addr, loadOp ## _ ## reg ## _addr); \
85 extern void emitCode (Label op)
93 REPLACE_SINGLE (args_stack, call_stub_discard, args_stack_call_stub_discard);
94 REPLACE_SINGLE (args_stack, call_stub_addr, args_stack_call_stub_addr);
95 REPLACE_SINGLE (args_stack, call_stub_local, args_stack_call_stub_local);
96 REPLACE_SINGLE (args_stack, call_stub_stack, args_stack_call_stub_stack);
98 REPLACE_STORE (S1_stack);
99 REPLACE_STORE (S1_local);
100 REPLACE_STORE (S1_addr);
102 REPLACE_L1_L2 (const);
103 REPLACE_L1_L2 (stack);
104 REPLACE_L1_L2 (local);
105 REPLACE_L1_L2 (addr);
107 REPLACE_LOAD_OP (return, L1);
108 REPLACE_LOAD_OP (astore, L3);
109 REPLACE_LOAD_OP (astores, L3);
110 REPLACE_LOAD_OP (astoreb, L3);
111 REPLACE_LOAD_OP (astorebit, L3);
119 // The previous opcode has one operand, so
120 // we have to go back two steps to update it.
121 temp = undoEmit(); // Save the operand.
122 undoEmit(); // Remove the old opcode.
123 emitFinalCode (op); // Emit the new opcode.
124 emitData (temp); // Emit the operand again.