end_final()函数在toplev.c里面被调用。定义在final.c文件里。
end_final (main_input_filename);
final()函数:
void
final (first, file, write_symbols, optimize, prescan)
rtx first;
FILE *file;
enum debugger write_symbols;
int optimize;
int prescan;
{
register rtx insn;
last_ignored_compare = 0;
new_block = 1;
init_recog ();
CC_STATUS_INIT;
for (insn = NEXT_INSN (first); insn;)
insn = final_scan_insn (insn, file, write_symbols, optimize,
prescan, 0);
}
可以看出这是最后一遍处理。
final_scan_insn ( )函数关键代码:
/* Try to recognize the instruction.
If successful, verify that the operands satisfy the
constraints for the instruction. Crash if they don't,
since `reload' should have changed them so that they do. */
insn_code_number = recog_memoized (insn);
insn_extract (insn);
for (i = 0; i < insn_n_operands[insn_code_number]; i++)
{
if (GET_CODE (recog_operand[i]) == SUBREG)
recog_operand[i] = alter_subreg (recog_operand[i]);
}
/*insn_n_operands[140]=3,紧接着的insn_template[140]=0*/
template = insn_template[insn_code_number];
if (template == 0)
{
template = (*insn_outfun[insn_code_number]) (recog_operand, insn);
/* If the C code returns 0, it means that it is a jump insn
which follows a deleted test insn, and that test insn
needs to be reinserted. */
if (template == 0)
{
if (PREV_INSN (insn) != last_ignored_compare)
abort ();
new_block = 0;
return PREV_INSN (insn);
}
}
if (prescan > 0)
break;
/* Output assembler code from the template. */
output_asm_insn (template, recog_operand);
/* Mark this insn as having been output. */
INSN_DELETED_P (insn) = 1;
}
}
return NEXT_INSN (insn);
}
/*template = (*insn_outfun[140]) (recog_operand, insn);
/*template = output_140 (recog_operand, insn);
recog_operand[]数组是比较重要的数组,和insn_extract()函数产生,用于output_asm_insn()函数,还有这里的(*insn_outfun[insn_code_number])函数。