cvsuser 03/02/07 09:04:20
Modified: languages/imcc ChangeLog cfg.c imcc.y
languages/imcc/docs operation.pod
Added: languages/imcc/t/syn bsr.t
Log:
imcc-bsr
Revision Changes Path
1.9 +7 -0 parrot/languages/imcc/ChangeLog
Index: ChangeLog
===================================================================
RCS file: /cvs/public/parrot/languages/imcc/ChangeLog,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -w -r1.8 -r1.9
--- ChangeLog 7 Feb 2003 14:05:51 -0000 1.8
+++ ChangeLog 7 Feb 2003 17:04:13 -0000 1.9
@@ -1,4 +1,11 @@
- 2003-02-07 leo
+ * first step for bsr handling in the CFG
+ local bsrs (target in the same compilation unit) can
+ preserve registers.
+
+ s. docs/operation.pod
+
+- 2003-02-07 leo
* version 0.0.9.12
* changed -d (--debug) options and made more granular
debug output. s. docs/running.pod
1.13 +67 -9 parrot/languages/imcc/cfg.c
Index: cfg.c
===================================================================
RCS file: /cvs/public/parrot/languages/imcc/cfg.c,v
retrieving revision 1.12
retrieving revision 1.13
diff -u -w -r1.12 -r1.13
--- cfg.c 7 Feb 2003 14:05:51 -0000 1.12
+++ cfg.c 7 Feb 2003 17:04:13 -0000 1.13
@@ -20,7 +20,7 @@
void find_basic_blocks () {
Basic_block *bb;
- Instruction *ins;
+ Instruction *ins, *lab;
int nu = 0;
init_basic_blocks();
@@ -42,10 +42,41 @@
/* a branch is the end of a basic block
* so start a new with the next ins */
if (ins->type & ITBRANCH) {
+ int found = 1;
+ /* if we have a bsr, then consider it only as a branch,
+ * when we have the target here
+ * and it doesn't saveall - like P6C recursive bsr's
+ */
+ if (!strcmp(ins->op, "bsr")) {
+ char *name = ins->r[0]->name;
+ found = 0;
+ for (lab = instructions; lab; lab = lab->next) {
+ if ((lab->type & ITLABEL) &&
+ !strcmp(lab->r[0]->name, name)) {
+ int j = 0;
+ found = 1;
+ /* XXX look if first 5 ins have saveall
+ * this is a ugly but working hack ;-)
+ */
+ for (lab = lab->next; j < 5 && lab;
+ lab = lab->next, j++) {
+ if (!strcmp(lab->op, "saveall")) {
+ found = 0;
+ break;
+ }
+ }
+ break;
+ }
+ }
+ debug(DEBUG_CFG, "bsr %s local:%s\n",
+ name, found ? "yes": "no");
+ }
+ if (found) {
if (ins->next)
bb = make_basic_block(ins->next);
nu = 1;
}
+ }
/* XXX instruction type ITADDR is probably address of a
* CATCH block - we don't optimize them
* XXX they are marked as branch, to avoid dead code removal
@@ -63,9 +94,10 @@
the dependences between them. */
void build_cfg() {
- int i;
+ int i, j;
SymReg * addr;
Basic_block *last, *bb;
+ Edge *pred;
for (i = 0; bb_list[i]; i++) {
bb = bb_list[i];
@@ -77,6 +109,32 @@
addr = get_branch_reg(bb->end);
if (addr)
bb_findadd_edge(bb, addr);
+ if (!strcmp(bb->end->op, "ret")) {
+ debug(DEBUG_CFG, "found ret in bb %d\n", i);
+ /* now go back, find labels and connect these with
+ * bsrs
+ */
+ for (pred = bb->pred_list; pred; pred=pred->pred_next) {
+ if (!strcmp(pred->from->end->op, "bsr")) {
+ SymReg *r = pred->from->end->r[0];
+ int found = 0;
+
+ j = pred->from->index;
+ debug(DEBUG_CFG, "\tcalled from bb %d label '%s'? - ",
+ j, r->name);
+ if ((bb->start->type & ITLABEL) &&
+ (!strcmp(bb->start->r[0]->name, r->name)))
+ found = 1;
+ if (found) {
+ debug(DEBUG_CFG, "yep!\n");
+ bb_add_edge(bb, bb_list[j+1]);
+ }
+ else
+ debug(DEBUG_CFG, "na!\n");
+
+ }
+ }
+ }
last = bb;
}
1.42 +8 -3 parrot/languages/imcc/imcc.y
Index: imcc.y
===================================================================
RCS file: /cvs/public/parrot/languages/imcc/imcc.y,v
retrieving revision 1.41
retrieving revision 1.42
diff -u -w -r1.41 -r1.42
--- imcc.y 7 Feb 2003 14:05:51 -0000 1.41
+++ imcc.y 7 Feb 2003 17:04:13 -0000 1.42
@@ -360,18 +360,23 @@
ins->opnum = op;
ins->opsize = op_info->arg_count;
/* set up branch flags */
- if (op_info->jump) {
+ if (op_info->jump || !strcmp(name, "end")) {
+
+#if 0
if (!strcmp(name, "bsr") || !strcmp(name, "ret")) {
/* ignore subcalls and ret
* because they saveall
*/
}
- else {
+ else
+#endif
+ {
+
/* XXX: assume the jump is relative and to the last arg.
* usually true.
*/
ins->type = ITBRANCH | (1 << (nargs-1));
- if (!strcmp(name, "branch"))
+ if (!strcmp(name, "branch") || !strcmp(name, "end"))
ins->type |= IF_goto;
}
}
1.2 +15 -0 parrot/languages/imcc/docs/operation.pod
Index: operation.pod
===================================================================
RCS file: /cvs/public/parrot/languages/imcc/docs/operation.pod,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -w -r1.1 -r1.2
--- operation.pod 10 Dec 2002 08:55:11 -0000 1.1
+++ operation.pod 7 Feb 2003 17:04:15 -0000 1.2
@@ -63,6 +63,17 @@
pieces, called B<basic block>s. A B<basic block> starts at a label,
which can get jumped to, and ends at a branch instruction.
+=head2 Special case: subroutine calls (bsr)
+
+Currently, imcc assumes, that a subroutine saves all registers on entry,
+as P6C does per B<saveall>, and thus a B<bsr> doesn't count as a branch.
+
+But there is one exception to this rule: When the target of the
+subroutine is known (the label is in the same compilation unit, and when
+no B<saveall> instruction is found in the first 5 instructions after the
+label, then the control flow from the B<bsr> call to the label and from
+the B<ret> to the next basic block is calculated.
+
=head2 Call graph
All connection between the B<basic block>s are calculated. This allows
@@ -82,6 +93,10 @@
Variables used as B<IN> parameters must keep their parrot register
over their usage range.
+
+Note: imcc does currently not know, that certain register operations do
+globber registers: mainly B<restoreall> and friends, which have no hint
+in core.ops, that they do what they do.
=head2 Interference graph
1.1 parrot/languages/imcc/t/syn/bsr.t
Index: bsr.t
===================================================================
#!perl
use strict;
use TestCompiler tests => 2;
use Test::More qw(skip);
##############################
# this tests register allocation/preserving of local bsr calls
#
output_is(<<'CODE', <<'OUT', "bsr 1");
.sub _test
$I0 = 2
$I1 = 3
bsr L
print $I0
print $I1
print "\n"
end
noop
L: $I2 = 4
$I3 = 5
ret
.end
CODE
23
OUT
##############################
# this is considered a non local bsr
#
output_is(<<'CODE', <<'OUT', "recursive bsr with saveall");
.sub _test
$I0 = 5
$I1 = $I0
bsr fact
print $I1
print "\n"
end
fact:
save $I0
save $I1
saveall
restore $I1
restore $I0
if $I0 <= 1 goto fin
dec $I0
$I1 = $I1 * $I0
bsr fact
fin:
save $I1
restoreall
restore $I1
ret
.end
CODE
120
OUT