2 * cprop.c: Constant propagation.
5 * Paolo Molaro (lupus@ximian.com)
7 * (C) 2003 Ximian, Inc.
10 /* dumb list-based implementation for now */
12 typedef struct _MiniACP MiniACP;
22 copy_value (MiniACP *acp, int reg, int type)
26 //g_print ("search reg %d '%c'\n", reg, type);
28 // g_print ("considering dreg %d, sreg %d '%c'\n", tmp->dreg, tmp->sreg, tmp->type);
29 if (tmp->type == type && tmp->dreg == reg) {
30 // g_print ("copy prop from %d to %d\n", tmp->sreg, tmp->dreg);
39 remove_acp (MiniACP *acp, int reg, int type)
45 if (tmp->type == type && (tmp->dreg == reg || tmp->sreg == reg)) {
47 prev->next = tmp->next;
59 add_acp (MonoCompile *cfg, MiniACP *acp, int sreg, int dreg, int type)
61 MiniACP *newacp = mono_mempool_alloc (cfg->mempool, sizeof (MiniACP));;
71 local_copy_prop (MonoCompile *cfg, MonoInst *code)
77 //g_print ("starting BB\n");
80 spec = ins_get_spec (ins->opcode);
83 if (spec [MONO_INST_CLOB] != 's' && spec [MONO_INST_CLOB] != '1' && spec [MONO_INST_CLOB] != 'd' && spec [MONO_INST_CLOB] != 'a' && spec [MONO_INST_CLOB] != 'c') {
84 if (spec [MONO_INST_SRC1] == 'f') {
85 ins->sreg1 = copy_value (acp, ins->sreg1, 'f');
86 } else if (spec [MONO_INST_SRC1]) {
87 ins->sreg1 = copy_value (acp, ins->sreg1, 'i');
91 if (spec [MONO_INST_CLOB] != 's') {
92 if (spec [MONO_INST_SRC2] == 'f') {
93 ins->sreg2 = copy_value (acp, ins->sreg2, 'f');
94 } else if (spec [MONO_INST_SRC2]) {
95 ins->sreg2 = copy_value (acp, ins->sreg2, 'i');
99 if (mono_inst_get_src_registers (ins, NULL) > 2)
102 /* invalidate pairs */
103 if (spec [MONO_INST_DEST] == 'f') {
104 acp = remove_acp (acp, ins->dreg, 'f');
105 } else if (spec [MONO_INST_DEST]) {
106 acp = remove_acp (acp, ins->dreg, 'i');
111 * Later copy-propagate also immediate values and memory stores.
113 if (ins->opcode == OP_MOVE && ins->sreg1 != ins->dreg) {
114 // g_print ("added acp of %d <- %d '%c'\n", ins->dreg, ins->sreg1, spec [MONO_INST_SRC1]);
115 acp = add_acp (cfg, acp, ins->sreg1, ins->dreg, spec [MONO_INST_SRC1]);
118 if (spec [MONO_INST_CLOB] == 'c') {
119 /* this is a call, invalidate all the pairs */
121 } else if ((ins->opcode) == OP_BR || (ins->opcode >= CEE_BEQ && ins->opcode <= CEE_BLT) ||
122 (ins->opcode >= CEE_BNE_UN && ins->opcode <= CEE_BLT_UN)) {
123 acp = NULL; /* invalidate all pairs */
124 /* it's not enough to invalidate the pairs, because we don't always
125 * generate extended basic blocks (the BRANCH_LABEL stuff in the burg rules)
126 * This issue is going to reduce a lot the possibilities for optimization!