Front page | perl.cvs.parrot |
Postings from December 2008
[svn:parrot] r34700 - trunk/compilers/pirc/new
From:
kjs
Date:
December 31, 2008 04:57
Subject:
[svn:parrot] r34700 - trunk/compilers/pirc/new
Message ID:
20081231125719.CFC1BCB9FA@x12.develooper.com
Author: kjs
Date: Wed Dec 31 04:57:17 2008
New Revision: 34700
Modified:
trunk/compilers/pirc/new/pircompiler.c
trunk/compilers/pirc/new/pircompunit.c
trunk/compilers/pirc/new/pircompunit.h
trunk/compilers/pirc/new/piremit.c
trunk/compilers/pirc/new/pirpcc.c
trunk/compilers/pirc/new/pirregalloc.c
trunk/compilers/pirc/new/pirregalloc.h
trunk/compilers/pirc/new/pirsymbol.c
Log:
[pirc] fix bug: parameter registers were stored incorrectly by their assigned vanilla register; however, the register allocator, keeping pointers to syminfo thingies that store the actual (optimized) allocated register could not change those. The solution is to store the operands of get_params as target nodes, not just their vanilla registers.
+ some other fixes.
Modified: trunk/compilers/pirc/new/pircompiler.c
==============================================================================
--- trunk/compilers/pirc/new/pircompiler.c (original)
+++ trunk/compilers/pirc/new/pircompiler.c Wed Dec 31 04:57:17 2008
@@ -161,11 +161,17 @@
PARROT_WARN_UNUSED_RESULT
lexer_state *
new_lexer(NULLOK(char * const filename), int flags) {
- lexer_state *lexer = mem_allocate_zeroed_typed(lexer_state);
- lexer->filename = filename;
- lexer->interp = Parrot_new(NULL);
- lexer->flags = flags;
- lexer->mem_allocations = new_mem_ptrs_block();
+ lexer_state *lexer = mem_allocate_zeroed_typed(lexer_state);
+ lexer->filename = filename;
+ lexer->interp = Parrot_new(NULL);
+ lexer->flags = flags;
+ lexer->mem_allocations = new_mem_ptrs_block();
+
+ /* the PIR register generator must start counting at -2 (the value is pre-decremented
+ * before returning, hence -1), because -1 is the value for unassigned PASM
+ * registers.
+ */
+ lexer->pir_reg_generator = -1;
if (!lexer->interp)
panic(lexer, "Failed to create a Parrot interpreter structure.");
Modified: trunk/compilers/pirc/new/pircompunit.c
==============================================================================
--- trunk/compilers/pirc/new/pircompunit.c (original)
+++ trunk/compilers/pirc/new/pircompunit.c Wed Dec 31 04:57:17 2008
@@ -2319,6 +2319,8 @@
Update register usage for the current subroutine with the register usage
information in C<reg_usage>.
+XXX the passed register usage info is 1 too high for each type.
+
=cut
*/
Modified: trunk/compilers/pirc/new/pircompunit.h
==============================================================================
--- trunk/compilers/pirc/new/pircompunit.h (original)
+++ trunk/compilers/pirc/new/pircompunit.h Wed Dec 31 04:57:17 2008
@@ -56,8 +56,9 @@
* for another structure field. As soon as there is a need for 32 target flags, these
* flags must be encoded into a different flag member.
*/
- TARGET_FLAG_IS_REG = 1 << 31 /* set if the target node represents a register; cleared if
- it's a .local/.param. */
+ TARGET_FLAG_IS_INITIALIZED = 1 << 30, /* set if the target was written to */
+ TARGET_FLAG_IS_REG = 1 << 31 /* set if the target node represents a register;
+ cleared if it's a .local/.param. */
} target_flag;
Modified: trunk/compilers/pirc/new/piremit.c
==============================================================================
--- trunk/compilers/pirc/new/piremit.c (original)
+++ trunk/compilers/pirc/new/piremit.c Wed Dec 31 04:57:17 2008
@@ -55,7 +55,7 @@
/* the order of these letters match with the pir_type enumeration.
* These are used for human-readable PASM output.
*/
-static char const pir_register_types[5] = {'I', 'S', 'P', 'N', '?'};
+char const pir_register_types[5] = {'I', 'S', 'P', 'N', '?'};
static void emit_pir_statement(lexer_state * const lexer, subroutine * const sub);
static void emit_pir_instruction(lexer_state * const lexer, instruction * const instr);
@@ -308,13 +308,14 @@
do {
- /*
- fprintf(out, "# subroutine '%s' register usage\n", subiter->sub_name);
- fprintf(out, "# int : %d\n", subiter->regs_used[INT_TYPE]);
- fprintf(out, "# num : %d\n", subiter->regs_used[NUM_TYPE]);
- fprintf(out, "# string: %d\n", subiter->regs_used[STRING_TYPE]);
- fprintf(out, "# pmc : %d\n", subiter->regs_used[PMC_TYPE]);
- */
+ /*
+ fprintf(out, "# subroutine '%s' register usage\n", subiter->info.subname);
+ fprintf(out, "# int : %d\n", subiter->info.regs_used[INT_TYPE]);
+ fprintf(out, "# num : %d\n", subiter->info.regs_used[NUM_TYPE]);
+ fprintf(out, "# string: %d\n", subiter->info.regs_used[STRING_TYPE]);
+ fprintf(out, "# pmc : %d\n", subiter->info.regs_used[PMC_TYPE]);
+ */
+
fprintf(out, ".namespace ");
print_key(lexer, subiter->name_space);
fprintf(out, "\n");
Modified: trunk/compilers/pirc/new/pirpcc.c
==============================================================================
--- trunk/compilers/pirc/new/pirpcc.c (original)
+++ trunk/compilers/pirc/new/pirpcc.c Wed Dec 31 04:57:17 2008
@@ -232,7 +232,11 @@
*/
PARROT_ASSERT(iter->info->color != NO_REG_ALLOCATED);
- push_operand(lexer, expr_from_int(lexer, iter->info->color));
+ /* be sure to push the target as a whole as operand, not just an integer
+ * constant for the assigned register; the register optimizer may
+ * update the register in the target.
+ */
+ push_operand(lexer, expr_from_target(lexer, iter));
/* go to next target in list */
iter = iter->next;
@@ -393,8 +397,10 @@
new_sub_instr(lexer, PARROT_OP_set_args_pc, "set_args_pc", inv->num_arguments);
arguments_to_operands(lexer, inv->arguments, inv->num_arguments);
+ /*
new_sub_instr(lexer, PARROT_OP_get_results_pc, "get_results_pc", inv->num_results);
targets_to_operands(lexer, inv->results, inv->num_results);
+*/
/* if the target is a register, invoke that. */
if (TEST_FLAG(inv->sub->flags, TARGET_FLAG_IS_REG)) {
@@ -439,6 +445,9 @@
save_global_reference(lexer, CURRENT_INSTRUCTION(lexer), inv->sub->info->id.name);
}
+ new_sub_instr(lexer, PARROT_OP_get_results_pc, "get_results_pc", inv->num_results);
+ targets_to_operands(lexer, inv->results, inv->num_results);
+
new_sub_instr(lexer, PARROT_OP_invokecc_p, "invokecc_p", 0);
add_operands(lexer, "%T", sub);
Modified: trunk/compilers/pirc/new/pirregalloc.c
==============================================================================
--- trunk/compilers/pirc/new/pirregalloc.c (original)
+++ trunk/compilers/pirc/new/pirregalloc.c Wed Dec 31 04:57:17 2008
@@ -348,6 +348,7 @@
available->next = lsr->cached_regs;
lsr->cached_regs = available;
+ fprintf(stderr, "get_free_reg(): cached: %d\n", available->regno);
return available->regno;
}
else {
@@ -357,6 +358,7 @@
*/
unsigned reg = lsr->r[type] - 1;
lsr->r[type]++;
+ fprintf(stderr, "get_free_reg(): non-cached: %d\n", reg);
return reg;
}
}
@@ -503,6 +505,9 @@
*/
for (i = lsr->intervals[type]; i != NULL; i = i->nexti) {
+ /* XXX temp. hack */
+ extern char const pir_register_types[5];
+
/* expire all intervals whose endpoint is smaller than i's start
* point; that means that i can be mapped to a register that was
* previously assigned to one of the expired intervals; that one
@@ -513,7 +518,12 @@
/* get a free register */
i->realreg = get_free_reg(lsr, type);
- /* fprintf(stderr, "Vanilla register %u is mapped to %u\n", *i->color, i->realreg); */
+
+ /*
+ fprintf(stderr, "Vanilla register %c%u (symbol %s) is mapped to %u\n",
+ pir_register_types[type], *i->color, i->info->id.name, i->realreg);
+ */
+
/* update the symbol/pir_reg with this newly allocated reg */
*i->color = i->realreg;
Modified: trunk/compilers/pirc/new/pirregalloc.h
==============================================================================
--- trunk/compilers/pirc/new/pirregalloc.h (original)
+++ trunk/compilers/pirc/new/pirregalloc.h Wed Dec 31 04:57:17 2008
@@ -7,6 +7,7 @@
#define PARROT_PIR_PIRREGALLOC_H_GUARD
+
typedef enum interval_flags {
INTERVAL_FLAG_UNIQUE_REG = 1 << 0
@@ -26,15 +27,15 @@
* list.
*/
typedef struct live_interval {
- unsigned symreg; /* the interval is for this variable */
- int realreg; /* the newly allocated register */
- unsigned startpoint; /* start point of the live range of the variable */
- unsigned endpoint; /* end point of the live range of the variable */
+ unsigned symreg; /* the interval is for this variable */
+ int realreg; /* the newly allocated register */
+ unsigned startpoint; /* start point of the live range of the variable */
+ unsigned endpoint; /* end point of the live range of the variable */
/* pointer to the symbol or pir_reg, in order to update (re-color) the PASM register */
- int *color;
- interval_flag flags;
+ int *color;
+ interval_flag flags;
/* union next_union { */
struct live_interval *nexti;
Modified: trunk/compilers/pirc/new/pirsymbol.c
==============================================================================
--- trunk/compilers/pirc/new/pirsymbol.c (original)
+++ trunk/compilers/pirc/new/pirsymbol.c Wed Dec 31 04:57:17 2008
@@ -47,6 +47,7 @@
*/
+extern char const pir_register_types[5];
#define NO_REG_ALLOCATED -1
@@ -83,10 +84,12 @@
sym->info.color = next_register(lexer, sym->info.type);
if (TEST_FLAG(lexer->flags, LEXER_FLAG_REGALLOC)) {
+
sym->info.interval = new_live_interval(lexer->lsr, lexer->stmt_counter, sym->info.type);
/* set the reference of the interval to the symbol's color */
sym->info.interval->color = &sym->info.color;
+
}
/* mark the interval, so that its register is not reused, if the :unique_reg
@@ -186,9 +189,7 @@
Declare the local variables in the list pointed to by C<list>, all of which
are of the type C<type>. The variables are entered into the symbol table for
the current subroutine that is being parsed (each subroutine has its
-own symbol table). Each symbol will be allocated a (PASM) register; in
-other words, afer invoking this function, each of the symbol nodes in C<list>
-will have been given a PASM register.
+own symbol table).
=cut
@@ -296,15 +297,19 @@
symbol *sym = bucket_symbol(buck);
if (STREQ(sym->info.id.name, name)) {
+ fprintf(stderr, "found symbol %c:%s\n", pir_register_types[sym->info.type], name);
+
if (sym->info.color == NO_REG_ALLOCATED) /* no PASM register assigned yet */
/* get a new reg from vanilla reg. allocator */
assign_vanilla_register(lexer, sym);
else /* update end point of interval */
- if (TEST_FLAG(lexer->flags, LEXER_FLAG_REGALLOC))
+ if (TEST_FLAG(lexer->flags, LEXER_FLAG_REGALLOC)) {
+ fprintf(stderr, "updating live of symbol %s\n", name);
sym->info.interval->endpoint = lexer->stmt_counter;
+ }
- if (TEST_FLAG(lexer->flags, LEXER_FLAG_VERBOSE))
+ if (TEST_FLAG(lexer->flags, LEXER_FLAG_REGALLOC))
fprintf(stderr, "live range of variable %s: (%d, %d)\n", sym->info.id.name,
sym->info.interval->startpoint, sym->info.interval->endpoint);
@@ -362,6 +367,8 @@
pir_reg *iter = CURRENT_SUB(lexer)->registers[type];
while (iter != NULL) {
if (iter->info.id.regno == regno) {
+
+ fprintf(stderr, "Found regster $%c%d\n", pir_register_types[type], regno);
/* update the end point of this register's live interval */
if (TEST_FLAG(lexer->flags, LEXER_FLAG_REGALLOC))
iter->info.interval->endpoint = lexer->stmt_counter;
@@ -412,6 +419,7 @@
/* let the interval have a pointer to this symbolic register */
reg->info.interval->color = ®->info.color;
+
}
@@ -580,10 +588,6 @@
bucket_constant(b) = c;
store_bucket(table, b, hash);
- /* add it as a constant in the PBC constant table */
- /* XXX is this necessary? Seems not. 12/27/2008. --kjs
- c->const_table_index = emit_pbc_const(lexer, c);
- */
}
/*
-
[svn:parrot] r34700 - trunk/compilers/pirc/new
by kjs