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 /* invalidate pairs */
100 if (spec
[MONO_INST_DEST
] == 'f') {
101 acp
= remove_acp (acp
, ins
->dreg
, 'f');
102 } else if (spec
[MONO_INST_DEST
]) {
103 acp
= remove_acp (acp
, ins
->dreg
, 'i');
108 * Later copy-propagate also immediate values and memory stores.
110 if (ins
->opcode
== OP_MOVE
&& ins
->sreg1
!= ins
->dreg
) {
111 // g_print ("added acp of %d <- %d '%c'\n", ins->dreg, ins->sreg1, spec [MONO_INST_SRC1]);
112 acp
= add_acp (cfg
, acp
, ins
->sreg1
, ins
->dreg
, spec
[MONO_INST_SRC1
]);
115 if (spec
[MONO_INST_CLOB
] == 'c') {
116 /* this is a call, invalidate all the pairs */
118 } else if ((ins
->opcode
) == OP_BR
|| (ins
->opcode
>= CEE_BEQ
&& ins
->opcode
<= CEE_BLT
) ||
119 (ins
->opcode
>= CEE_BNE_UN
&& ins
->opcode
<= CEE_BLT_UN
)) {
120 acp
= NULL
; /* invalidate all pairs */
121 /* it's not enough to invalidate the pairs, because we don't always
122 * generate extended basic blocks (the BRANCH_LABEL stuff in the burg rules)
123 * This issue is going to reduce a lot the possibilities for optimization!