Author: leo
Date: Thu Feb 2 06:45:05 2006
New Revision: 11402
Modified:
trunk/compilers/imcc/cfg.c
trunk/compilers/imcc/instructions.c
trunk/compilers/imcc/parser_util.c
trunk/t/examples/subs.t
Log:
Register allocator - returncc, tailcall, get_results, ...
* returncc and tailcall don't branch to the next basic block, like
e.g a conditional branch - set branch flags accordingly
* better life-range handling for get_results:
while the get_results opcode comes before a sub call, the effect
WRT life analysis happens only after the call - postpone
get_results' effect after the call
* fix a bogus test (t/examples/sub_2) - it was expectiong obviously
wrong results due to earlier register alligator errors
Modified: trunk/compilers/imcc/cfg.c
==============================================================================
--- trunk/compilers/imcc/cfg.c (original)
+++ trunk/compilers/imcc/cfg.c Thu Feb 2 06:45:05 2006
@@ -513,7 +513,8 @@ analyse_life_symbol(Parrot_Interp interp
*/
if (ins->prev) {
prev = ins->prev;
- if (prev->type & (ITPCCSUB|ITPCCYIELD))
+ if ((prev->type & (ITPCCSUB|ITPCCYIELD)) &&
+ prev->opnum != PARROT_OP_tailcall_p)
r->usage |= U_NON_VOLATILE;
else if (prev->opnum == PARROT_OP_invoke_p_p ||
prev->opnum == PARROT_OP_invokecc_p)
@@ -574,14 +575,9 @@ analyse_life_block(Parrot_Interp interpr
"Index %i of %i has NULL instruction\n",
ins->index, bb->end->index);
}
- if (ins->opnum == -1) {
- if (ins == bb->end)
- break;
- continue;
- }
/*
* if we have a setp_ind opcode, it may write all PMC
- * registers from 5..15
+ * registers
*/
if (ins->opnum == PARROT_OP_setp_ind_i_p && r->set == 'P') {
r->usage |= U_NON_VOLATILE;
Modified: trunk/compilers/imcc/instructions.c
==============================================================================
--- trunk/compilers/imcc/instructions.c (original)
+++ trunk/compilers/imcc/instructions.c Thu Feb 2 06:45:05 2006
@@ -228,8 +228,24 @@ instruction_writes(Instruction* ins, Sym
f = ins->flags;
- if (ins->opnum == PARROT_OP_get_params_pc ||
- ins->opnum == PARROT_OP_get_results_pc) {
+ /*
+ * a get_results opcode is before the actual sub call
+ * but for the register allocator, the effect matters, thus
+ * postpone the effect after the invoke
+ */
+ if (ins->opnum == PARROT_OP_get_results_pc)
+ return 0;
+ else if (ins->prev && (ins->prev->type & ITPCCSUB)) {
+ ins = ins->prev;
+ assert(ins->r[0]->pcc_sub);
+ for (i = 0; i < ins->r[0]->pcc_sub->nret; ++i) {
+ if (r == ins->r[0]->pcc_sub->ret[i])
+ return 1;
+ }
+ return 0;
+ }
+
+ if (ins->opnum == PARROT_OP_get_params_pc) {
for (i = 0; i < ins->n_r; i++) {
if (ins->r[i] == r)
return 1;
Modified: trunk/compilers/imcc/parser_util.c
==============================================================================
--- trunk/compilers/imcc/parser_util.c (original)
+++ trunk/compilers/imcc/parser_util.c Thu Feb 2 06:45:05 2006
@@ -557,7 +557,10 @@ INS(Interp *interpreter, IMC_Unit * unit
}
if (op_info->jump && op_info->jump != PARROT_JUMP_ENEXT) {
ins->type |= ITBRANCH;
- if (!strcmp(name, "branch"))
+ /* TODO use opnum constants */
+ if (!strcmp(name, "branch") ||
+ !strcmp(name, "tailcall") ||
+ !strcmp(name, "returncc"))
ins->type |= IF_goto;
else if (!strcmp(fullname, "jump_i") ||
!strcmp(fullname, "jsr_i") ||
Modified: trunk/t/examples/subs.t
==============================================================================
--- trunk/t/examples/subs.t (original)
+++ trunk/t/examples/subs.t Thu Feb 2 06:45:05 2006
@@ -72,9 +72,9 @@ Hello from main
END_EXPECTED
'single_retval.pir' => << 'END_EXPECTED',
-7 10 nine 10
+7 8 nine 10
return: 10
-7 10 nine 10
+7 8 nine 10
return: 10
END_EXPECTED