cvsuser 03/02/22 07:12:25
Modified: languages/imcc ChangeLog cfg.c imc.c imc.h imcc.l imcc.y
instructions.c instructions.h optimizer.c
Log:
imcc: macros: line numbers; lifeinfo f. restoreall..
Revision Changes Path
1.14 +7 -0 parrot/languages/imcc/ChangeLog
Index: ChangeLog
===================================================================
RCS file: /cvs/public/parrot/languages/imcc/ChangeLog,v
retrieving revision 1.13
retrieving revision 1.14
diff -u -w -r1.13 -r1.14
--- ChangeLog 21 Feb 2003 12:26:39 -0000 1.13
+++ ChangeLog 22 Feb 2003 15:12:25 -0000 1.14
@@ -1,3 +1,10 @@
+- 2003-02-22 leo / Juergen Boemmels
+
+ * correct line numbers for debugger WRT macros
+ (thanks to Juergen Boemmels)
+ * first try to get effects of clear?, pop?, restoreall
+ ops into register life info
+
- 2003-02-21 leo
* version 0.0.9.15
1.17 +26 -6 parrot/languages/imcc/cfg.c
Index: cfg.c
===================================================================
RCS file: /cvs/public/parrot/languages/imcc/cfg.c,v
retrieving revision 1.16
retrieving revision 1.17
diff -u -w -r1.16 -r1.17
--- cfg.c 21 Feb 2003 12:26:39 -0000 1.16
+++ cfg.c 22 Feb 2003 15:12:25 -0000 1.17
@@ -24,6 +24,7 @@
int nu = 0;
int i;
+ info(2, "find_basic_blocks\n");
init_basic_blocks();
for(i = 0; i < HASH_SIZE; i++) {
SymReg * r = hash[i];
@@ -122,6 +123,7 @@
Basic_block *last, *bb;
Edge *pred;
+ info(2, "build_cfg\n");
for (i = 0; bb_list[i]; i++) {
bb = bb_list[i];
@@ -327,6 +329,7 @@
void life_analysis() {
int i;
+ info(2, "life_analysis\n");
propagate_alias();
for(i = 0; i < n_symbols; i++)
analyse_life_symbol(reglist[i]);
@@ -383,25 +386,40 @@
*/
void analyse_life_block(Basic_block* bb, SymReg* r) {
- Instruction* ins;
+ Instruction* ins, *special;
Life_range* l;
l = make_life_range(r, bb->index);
+ special = NULL;
for (ins = bb->start; ins ; ins = ins->next) {
if (ins==NULL) {
fatal(1,"analyse_life_block",
"Index %i of %i has NULL instruction\n",
ins->index, bb->end->index);
}
+ /* restoreall and such */
+ if (ins_writes2(ins, r->set))
+ special = ins;
+
if (instruction_reads(ins, r)) {
+ /* if instruction gets read after a special, consider
+ * the first read of this instruction, like if a write
+ * had happened at special, so that the reg doesn't pop into
+ * life */
if (! (l->flags & LF_def) ) {
-
+ if (special) {
+ l->first_ins = special;
+ l->flags |= LF_def;
+ special = NULL;
+ }
+ else {
/* we read before having written before, so the var was
* live at the beggining of the block */
l->first_ins = bb->start;
l->flags |= LF_use;
}
+ }
l->last_ins = ins;
}
@@ -473,6 +491,7 @@
int i, change, pred_index;
Edge *edge;
+ info(2, "compute_dominators\n");
dominators = malloc(sizeof(Set*) * n_basic_blocks);
dominators[0] = set_make (n_basic_blocks);
@@ -562,6 +581,7 @@
Set* dom;
Edge* edge;
+ info(2, "find_loops\n");
for (i = 0; i < n_basic_blocks; i++) {
dom = dominators[i];
1.37 +22 -22 parrot/languages/imcc/imc.c
Index: imc.c
===================================================================
RCS file: /cvs/public/parrot/languages/imcc/imc.c,v
retrieving revision 1.36
retrieving revision 1.37
diff -u -w -r1.36 -r1.37
--- imc.c 21 Feb 2003 13:28:50 -0000 1.36
+++ imc.c 22 Feb 2003 15:12:25 -0000 1.37
@@ -30,20 +30,21 @@
/* allocate is the main loop of the allocation algorithm */
void allocate(struct Parrot_Interp *interpreter) {
int to_spill;
- int todo;
+ int todo, first;
if (!instructions)
return;
if (!optimizer_level && pasm_file)
return;
+ init_tables(interpreter);
+
debug(DEBUG_IMC, "\n------------------------\n");
debug(DEBUG_IMC, "processing sub %s\n", function);
debug(DEBUG_IMC, "------------------------\n\n");
if (IMCC_VERBOSE > 1 || (IMCC_DEBUG & DEBUG_IMC))
imc_stat_init();
- info(2, "pre_optimize\n");
/* consecutive labels, if_branch, unused_labels ... */
pre_optimize(interpreter);
if (optimizer_level == OPT_PRE && pasm_file)
@@ -54,25 +55,22 @@
todo = 1;
while (todo) {
- info(2, "find_basic_blocks\n");
find_basic_blocks();
+ build_cfg();
todo = cfg_optimize(interpreter);
}
- todo = 1;
+ first = todo = 1;
while (todo) {
+ if (!first) {
find_basic_blocks();
- info(2, "build_cfg\n");
-
build_cfg();
+ }
+ first = 0;
- info(2, "compute_dominators\n");
compute_dominators();
- info(2, "find_loops\n");
find_loops();
- info(2, "build_reglist\n");
build_reglist();
- info(2, "life_analysis\n");
life_analysis();
/* optimize, as long as there is something to do */
if (IMCC_DEBUG & DEBUG_IMC)
@@ -80,7 +78,6 @@
if (dont_optimize)
todo = 0;
else {
- info(2, "optimize\n");
todo = optimize(interpreter);
}
}
@@ -205,6 +202,7 @@
void build_reglist(void) {
int i, count, unused;
+ info(2, "build_reglist\n");
/* count symbols */
if (reglist)
free_reglist();
@@ -236,7 +234,7 @@
reglist[count++] = r;
/* rearange I/N registers
* XXX not here, do it, when reading the source
- * .nciarg, rx_char, ... !!!1 */
+ * .nciarg, ... !!!1 */
if ((optimizer_level & OPT_PASM) && pasm_file &&
(reglist[count-1]->set == 'I' ||
reglist[count-1]->set == 'N'))
@@ -328,7 +326,6 @@
static void compute_one_du_chain(SymReg * r) {
Instruction * ins;
- int ix;
/* We cannot rely on computing the value of r->first when parsing,
* since the situation can be changed at any time by the register
@@ -337,7 +334,7 @@
r->first_ins = 0;
r->use_count = r->lhs_use_count = 0;
- for(ix=0, ins = instructions; ins; ins = ins->next, ix++) {
+ for(ins = instructions; ins; ins = ins->next) {
int ro, rw;
ro = instruction_reads(ins, r);
rw = instruction_writes(ins, r);
@@ -359,7 +356,10 @@
}
}
/* TODO score high if r is a array/hash key */
+ /* TODO score high if -Oj and register is used in JITtable instruction */
+
r->score = r->use_count + (r->lhs_use_count << 2);
+ /* r->score *= (r->jit_usage - r->use_count + 1) */
}
/* Computes the cost of spilling each symbol. This is estimated by the number
@@ -376,7 +376,7 @@
for (i = 0; ins->r[i] && i < IMCC_MAX_REGS; i++) {
ins->r[i]->score += 1 << (depth * 3);
if (ins->flags & ITSPILL)
- ins->r[i]->score = 50000000;
+ ins->r[i]->score = 100000;
}
}
@@ -732,9 +732,9 @@
* for e.g. calling out to unJITted functions
* This is of course processor dependend
*
- * TODO: rx_ ops may have a inout INT parameter for position/mark.
- * Do not assign registers, if any such inout branching
- * instruction is encountered.
+ * NOTE: rx_ ops may have a inout INT parameter for position/mark.
+ * Actually, the either branch or update the inout parameter
+ * so they are save.
*/
static void
1.29 +1 -0 parrot/languages/imcc/imc.h
Index: imc.h
===================================================================
RCS file: /cvs/public/parrot/languages/imcc/imc.h,v
retrieving revision 1.28
retrieving revision 1.29
diff -u -w -r1.28 -r1.29
--- imc.h 21 Feb 2003 12:26:39 -0000 1.28
+++ imc.h 22 Feb 2003 15:12:25 -0000 1.29
@@ -59,6 +59,7 @@
int check_op(struct Parrot_Interp *, char * fullname, char *op, SymReg *r[]);
int is_op(struct Parrot_Interp *, char *);
+void init_tables(struct Parrot_Interp * interp);
/* This should be common with Cola */
1.31 +10 -0 parrot/languages/imcc/imcc.l
Index: imcc.l
===================================================================
RCS file: /cvs/public/parrot/languages/imcc/imcc.l,v
retrieving revision 1.30
retrieving revision 1.31
diff -u -w -r1.30 -r1.31
--- imcc.l 21 Feb 2003 13:28:50 -0000 1.30
+++ imcc.l 22 Feb 2003 15:12:25 -0000 1.31
@@ -27,6 +27,7 @@
char *name;
struct params_t params;
char *expansion;
+ int line;
};
/* XXX: boe: rework this hack to use a hash */
@@ -41,6 +42,7 @@
struct params_t *params;
struct params_t expansion;
int label;
+ int line;
};
struct macro_frame_t *frames = NULL;
@@ -401,6 +403,7 @@
tmp = mem_sys_allocate_zeroed(sizeof(struct macro_frame_t));
tmp->label = ++label;
+ tmp->line = line;
return tmp;
}
@@ -427,6 +430,8 @@
free(frame->expansion.name[i]);
}
+ line = frame->line;
+
mem_sys_free(frame);
yy_switch_to_buffer(buffer);
@@ -508,6 +513,7 @@
fataly(EX_SOFTWARE, ".macro", line, "Macro names must be identifiers");
m->name = valp->s;
+ m->line = line;
/* white space is allowed between macro and opening paren) */
c = yylex_skip(valp, interp, " ");
@@ -624,6 +630,7 @@
frame->expansion.num_param, m->params.num_param);
}
+ line = m->line;
scan_string(frame, m->expansion);
return 1;
}
@@ -652,6 +659,9 @@
frame->buffer = YY_CURRENT_BUFFER;
frame->next = frames;
frames = frame;
+
+ /* XXX: Switch the filename */
+ line = 1;
yy_switch_to_buffer(yy_create_buffer(file, YY_BUF_SIZE));
}
1.48 +4 -2 parrot/languages/imcc/imcc.y
Index: imcc.y
===================================================================
RCS file: /cvs/public/parrot/languages/imcc/imcc.y,v
retrieving revision 1.47
retrieving revision 1.48
diff -u -w -r1.47 -r1.48
--- imcc.y 21 Feb 2003 12:26:40 -0000 1.47
+++ imcc.y 22 Feb 2003 15:12:25 -0000 1.48
@@ -440,9 +440,11 @@
;
emit:
- EMIT { open_comp_unit(); }
+ EMIT { open_comp_unit();
+ function = "(emit)"; }
pasmcode
- EOM { allocate(interp);
+ EOM { if (optimizer_level & OPT_PASM)
+ allocate(interp);
emit_flush(interp); $$=0;}
;
1.28 +76 -3 parrot/languages/imcc/instructions.c
Index: instructions.c
===================================================================
RCS file: /cvs/public/parrot/languages/imcc/instructions.c,v
retrieving revision 1.27
retrieving revision 1.28
diff -u -w -r1.27 -r1.28
--- instructions.c 21 Feb 2003 12:26:40 -0000 1.27
+++ instructions.c 22 Feb 2003 15:12:25 -0000 1.28
@@ -1,6 +1,7 @@
#include <stdlib.h>
#include <string.h>
+#include <assert.h>
#define _PARSER
#include "imc.h"
#include "pbc.h"
@@ -137,8 +138,78 @@
}
+/*
+ * some instructions don't have a hint in op_info, that they work
+ * on all registers:
+ * - push?, pop?, clear?
+ * - saveall/restoreall
+ */
+
+static int r_special[5];
+static int w_special[1+4*3];
+
+void
+init_tables(struct Parrot_Interp * interpreter)
+{
+ size_t i;
+ const char *reads[] = {
+ "saveall",
+ "pushi", "pushn", "pushp", "pushs"
+ };
+ const char *writes[] = {
+ "restoreall",
+ "pushi", "pushn", "pushp", "pushs",
+ "popi", "popn", "popp", "pops",
+ "cleari", "clearn", "clearp", "clears",
+ };
+ /* init opnums */
+ if (!r_special[0]) {
+ for (i = 0; i < sizeof(reads)/sizeof(reads[0]); i++) {
+ int n = interpreter->op_lib->op_code(reads[i], 1);
+ assert(n);
+ r_special[i] = n;
+ }
+ for (i = 0; i < sizeof(writes)/sizeof(writes[0]); i++) {
+ int n = interpreter->op_lib->op_code(writes[i], 1);
+ assert(n);
+ w_special[i] = n;
+ }
+ }
+}
+
+/* return TRUE, if ins reads register of type t */
+int
+ins_reads2(Instruction *ins, char t)
+{
+ size_t i;
+ const char types[] = "INPS";
+ if (ins->opnum == r_special[0])
+ return 1;
+ for (i = 1; i < sizeof(r_special)/sizeof(int); i += 4) {
+ if (ins->opnum == r_special[i + (strchr(types, t) - types)])
+ return 1;
+ }
+ return 0;
+}
+
+/* return TRUE, if ins writes register of type t */
+int
+ins_writes2(Instruction *ins, char t)
+{
+ size_t i;
+ const char types[] = "INPS";
+ if (ins->opnum == w_special[0])
+ return 1;
+ for (i = 1; i < sizeof(w_special)/sizeof(int); i += 4) {
+ if (ins->opnum == w_special[i + (strchr(types, t) - types)])
+ return 1;
+ }
+ return 0;
+}
+
+
/* next 2 functions are called very often, says gprof
- * theys should be fast
+ * they should be fast
*/
#ifdef HAS_INLINE
inline
@@ -326,7 +397,8 @@
sprintf(regb[i], "%c%d", p->set, p->color);
regstr[i] = regb[i];
}
- else if (p->set != 'K' && p->color < 0 && (p->type & VTREGISTER)) {
+ else if ((optimizer_level & OPT_J) && p->set != 'K' &&
+ p->color < 0 && (p->type & VTREGISTER)) {
sprintf(regb[i], "r%c%d", tolower(p->set), -1 - p->color);
regstr[i] = regb[i];
}
@@ -336,7 +408,8 @@
if (k->reg && k->reg->color >= 0)
sprintf(regb[i]+strlen(regb[i]), "%c%d",
k->reg->set, k->reg->color); /* XXX */
- else if (k->reg && k->reg->color < 0)
+ else if ((optimizer_level & OPT_J) && k->reg &&
+ k->reg->color < 0)
sprintf(regb[i]+strlen(regb[i]), "r%c%d",
tolower(k->reg->set), -1 - k->reg->color);
else
1.18 +4 -0 parrot/languages/imcc/instructions.h
Index: instructions.h
===================================================================
RCS file: /cvs/public/parrot/languages/imcc/instructions.h,v
retrieving revision 1.17
retrieving revision 1.18
diff -u -w -r1.17 -r1.18
--- instructions.h 10 Feb 2003 10:04:15 -0000 1.17
+++ instructions.h 22 Feb 2003 15:12:25 -0000 1.18
@@ -77,8 +77,12 @@
Instruction * iNEW(struct Parrot_Interp *,SymReg * r0, char * type, int emit);
Instruction * emitb(Instruction *);
+
int instruction_reads(Instruction *, SymReg *);
int instruction_writes(Instruction *, SymReg *);
+int ins_reads2(Instruction *, char);
+int ins_writes2(Instruction *, char);
+
void compute_spilling_costs(void);
void free_ins(Instruction *);
char * ins_string(Instruction * ins);
1.19 +5 -2 parrot/languages/imcc/optimizer.c
Index: optimizer.c
===================================================================
RCS file: /cvs/public/parrot/languages/imcc/optimizer.c,v
retrieving revision 1.18
retrieving revision 1.19
diff -u -w -r1.18 -r1.19
--- optimizer.c 21 Feb 2003 12:26:40 -0000 1.18
+++ optimizer.c 22 Feb 2003 15:12:25 -0000 1.19
@@ -63,6 +63,7 @@
void pre_optimize(struct Parrot_Interp *interp) {
if (optimizer_level & OPT_PRE) {
+ info(2, "pre_optimize\n");
subst_constants_mix(interp);
subst_constants_umix(interp);
subst_constants(interp);
@@ -76,6 +77,7 @@
int cfg_optimize(struct Parrot_Interp *interp) {
UNUSED(interp);
if (optimizer_level & OPT_PRE) {
+ info(2, "cfg_optimize\n");
if (branch_branch())
return 1;
/* XXX cfg / loop detection breaks e.g. in t/compiler/5_3 */
@@ -90,6 +92,7 @@
int optimize(struct Parrot_Interp *interp) {
if (optimizer_level & OPT_CFG) {
+ info(2, "optimize\n");
/* constant_propagation(); N/Y */
if (clone_remove())
return 1;
@@ -824,7 +827,7 @@
int bbi = bb->index;
debug(DEBUG_OPT1, "found dead block %d\n", bb->index);
for (ins = bb->start; ins && ins->index == bbi; ) {
- debug(DEBUG_OPT1, "unreachable ins deleted %s\n",
+ debug(DEBUG_OPT1, "unreachable ins deleted (dead block) %s\n",
ins_string(ins));
ins = delete_ins(ins, 1);
ostat.deleted_ins++;
@@ -838,7 +841,7 @@
return changed;
for (last = instructions, ins=last->next; last && ins; ins = ins->next) {
if ((last->type & IF_goto) && !(ins->type & ITLABEL)) {
- debug(DEBUG_OPT1, "unreachable ins deleted %s\n",
+ debug(DEBUG_OPT1, "unreachable ins deleted (after branch) %s\n",
ins_string(ins));
ins = delete_ins(ins, 1);
ostat.deleted_ins++;