+
+ visit_inst (cfg, bb, ins->next, cvars, bblist, carray);
+ }
+ } else if (ins->opcode == OP_BR) {
+ add_cprop_bb (cfg, ins->inst_target_bb, bblist);
+ } else if (MONO_IS_COND_BRANCH_OP (ins)) {
+ if (ins->flags & MONO_INST_CFOLD_TAKEN) {
+ add_cprop_bb (cfg, ins->inst_true_bb, bblist);
+ } else if (ins->flags & MONO_INST_CFOLD_NOT_TAKEN) {
+ if (ins->inst_false_bb)
+ add_cprop_bb (cfg, ins->inst_false_bb, bblist);
+ } else {
+ add_cprop_bb (cfg, ins->inst_true_bb, bblist);
+ if (ins->inst_false_bb)
+ add_cprop_bb (cfg, ins->inst_false_bb, bblist);
+ }
+ }
+}
+
+/**
+ * fold_ins:
+ *
+ * Replace INS with its constant value, if it exists
+ */
+static void
+fold_ins (MonoCompile *cfg, MonoBasicBlock *bb, MonoInst *ins, MonoInst **carray)
+{
+ const char *spec = INS_INFO (ins->opcode);
+ int opcode2;
+ int num_sregs = mono_inst_get_num_src_registers (ins);
+
+ if ((ins->opcode != OP_NOP) && (ins->dreg != -1) && !MONO_IS_STORE_MEMBASE (ins)) {
+ if (carray [ins->dreg] && (spec [MONO_INST_DEST] == 'i') && (ins->dreg >= MONO_MAX_IREGS)) {
+ /* Perform constant folding */
+ /* FIXME: */
+ g_assert (carray [ins->dreg]->opcode == OP_ICONST);
+ ins->opcode = OP_ICONST;
+ ins->inst_c0 = carray [ins->dreg]->inst_c0;
+ MONO_INST_NULLIFY_SREGS (ins);
+ } else if (num_sregs == 2 && carray [ins->sreg2]) {
+ /* Perform op->op_imm conversion */
+ opcode2 = mono_op_to_op_imm (ins->opcode);
+ if (opcode2 != -1) {
+ ins->opcode = opcode2;
+ ins->inst_imm = carray [ins->sreg2]->inst_c0;
+ ins->sreg2 = -1;
+
+ if ((opcode2 == OP_VOIDCALL) || (opcode2 == OP_CALL) || (opcode2 == OP_LCALL) || (opcode2 == OP_FCALL))
+ ((MonoCallInst*)ins)->fptr = (gpointer)ins->inst_imm;