Skip to content

Commit

Permalink
docu update; uninitialized warning
Browse files Browse the repository at this point in the history
git-svn-id: https://svn.parrot.org/parrot/trunk@3111 d31e2699-5ff4-0310-a27c-f18f2fbe73fe
  • Loading branch information
Leopold Toetsch committed Mar 5, 2003
1 parent 7cc62db commit 6bfa31a
Show file tree
Hide file tree
Showing 17 changed files with 505 additions and 40 deletions.
1 change: 1 addition & 0 deletions MANIFEST
Expand Up @@ -1369,6 +1369,7 @@ languages/imcc/cfg.c
languages/imcc/cfg.h
languages/imcc/debug.c
languages/imcc/debug.h
languages/imcc/docs/calling_conventions.pod
languages/imcc/docs/imcc.pod
languages/imcc/docs/macros.pod
languages/imcc/docs/operation.pod
Expand Down
35 changes: 31 additions & 4 deletions imcc/cfg.c
Expand Up @@ -15,6 +15,7 @@
*/

static void add_instruc_reads(Instruction *ins, SymReg *r0);
static void propagate_need(Basic_block *bb, SymReg* r, int i);

/* Code: */

Expand Down Expand Up @@ -313,13 +314,17 @@ static void add_instruc_reads(Instruction *ins, SymReg *r0)
/* this gets read */
ins->flags |= (1<<i);
}

#ifdef ALIAS
/*
* set P1, P0
*
* means, the PMC P1 points to whatever, P0 pointed to
*
* set P1, 4 sets P0 value
* as long as P1 is used (not overwritten, by new or clone)
*
* XXX currently turned off, this extends life ranges too much
*/

static void propagate_alias(void)
Expand All @@ -331,7 +336,7 @@ static void propagate_alias(void)
for (ins = instructions ; ins ; ins = ins->next) {
if (ins->type & ITALIAS) {
/* make r1 live in each instruction
* where r0 lifes, until r0 is written
* where r0 lives, until r0 is written
*/
curr = ins;
r0 = ins->r[0];
Expand Down Expand Up @@ -359,12 +364,15 @@ static void propagate_alias(void)
dump_instructions();
}
}
#endif

void life_analysis() {
int i;

info(2, "life_analysis\n");
#ifdef ALIAS
propagate_alias();
#endif
for(i = 0; i < n_symbols; i++)
analyse_life_symbol(reglist[i]);
}
Expand Down Expand Up @@ -396,7 +404,7 @@ void analyse_life_symbol(SymReg* r) {
r->life_info[i]->flags |= LF_lv_in;

/* propagate this info to every predecessor */
propagate_need (bb_list[i], r);
propagate_need (bb_list[i], r, i);
}
}
}
Expand Down Expand Up @@ -483,7 +491,8 @@ void analyse_life_block(Basic_block* bb, SymReg* r) {
}


void propagate_need(Basic_block *bb, SymReg* r) {
static void
propagate_need(Basic_block *bb, SymReg* r, int i) {
Edge *edge;
Basic_block *pred;
Life_range *l;
Expand All @@ -510,8 +519,26 @@ void propagate_need(Basic_block *bb, SymReg* r) {
l->flags |= LF_lv_in;
l->first_ins = pred->start;
l->last_ins = pred->end;
/* we arrived at block 0
*
* emit a warning if -w
* looking at some perl6 examples, where this warning
* is emitted, there seems always to be a code path
* where the var is not initialized, so this might
* even be correct :)
*/
if (pred->index == 0) {
Instruction *ins = r->life_info[i]->first_ins;
int bbi = ins->bbindex;
for ( ; ins && ins->bbindex == bbi; ins = ins->next)
if (instruction_reads(ins, r))
break;
warning("propagate_need",
"'%s' might be used uninitialized in %s:%d\n",
r->name, function, ins->line);
}

propagate_need(pred, r);
propagate_need(pred, r, i);
}
}
}
Expand Down
1 change: 0 additions & 1 deletion imcc/cfg.h
Expand Up @@ -58,7 +58,6 @@ void life_analysis(void);
void analyse_life_symbol(SymReg*);
void analyse_life_block(Basic_block*, SymReg*);
void add_life_interval(Life_range*, int, int);
void propagate_need(Basic_block*, SymReg*);

void init_basic_blocks(void);
Basic_block* make_basic_block(Instruction*);
Expand Down
15 changes: 12 additions & 3 deletions imcc/debug.c
Expand Up @@ -34,6 +34,8 @@ void fataly(int code, const char *func, int lin, const char *fmt, ...)
void warning(const char *func, const char *fmt, ...)
{
va_list ap;
if (!IMCC_WARN)
return;

va_start(ap, fmt);
fprintf(stderr, "warning:imcc:%s: ", func);
Expand Down Expand Up @@ -71,13 +73,14 @@ void dump_instructions() {
int pc;

fprintf(stderr, "\nDumping the instructions status:\n-------------------------------\n");
fprintf(stderr, "nins blck deep flags\t type opnr size pc X ins\n");
fprintf(stderr,
"nins line blck deep flags\t type opnr size pc X ins\n");
for (pc = 0, ins = instructions; ins; ins = ins->next) {
bb = bb_list[ins->bbindex];

if (bb) {
fprintf(stderr, "%4i %4d %4d\t%x\t%8x %4d %4d %4d %c ",
ins->index, bb->index, bb->loop_depth,
fprintf(stderr, "%4i %4d %4d %4d\t%x\t%8x %4d %4d %4d %c ",
ins->index, ins->line, bb->index, bb->loop_depth,
ins->flags, (ins->type & ~ITEXT), ins->opnum,
ins->opsize, pc, ins->type & ITEXT ? 'X' : ' ');
}
Expand Down Expand Up @@ -224,6 +227,12 @@ void dump_liveness_status_var(SymReg* r) {
fprintf(stderr, "\n\t%i: OUT\t", i);
else if (l->first_ins)
fprintf(stderr, "\n\t%i: INS\t", i);
if (l->flags & LF_use)
fprintf(stderr, "u ");
else if (l->flags & LF_def)
fprintf(stderr, "d ");
else
fprintf(stderr, " ");

if(l->first_ins) {
fprintf(stderr, "[%d,%d]\t", l->first_ins->index,
Expand Down
117 changes: 117 additions & 0 deletions imcc/docs/calling_conventions.pod
@@ -0,0 +1,117 @@
=head1 NAME

IMCC - calling conventions

=head1 VERSION

=over 4

=item 0.1 initial proposal

=item 0.2 initial, checked in

=back

=head1 OVERVIEW

This document describes subroutine calling conventions.

=head1 DESCRIPTION

A imcc does register allocation, it has to track the life span of
variables. This includes the (possible) data flow in and out of
subroutines.

=head1 Stack calling conventions

Arguments are B<save>d in reverse order onto the user stack:

.arg y # save args in reversed order
.arg x
call _foo #(r, s) = _foo(x,y)
.local int r
.local int s
.result s # restore results in reversed order
.result r # [1]

and return values are B<restore>d in reversed order from there.

The subroutine is responsible for preserving registers.

.sub _foo # sub foo(int a, int b)
saveall
.param int a
.param int b
...

.return pl # return (pl, mi)
.return mi # [1]
restoreall
ret
.end

[1] or vice versa?

=head2 Status

Implemented. When the subroutine is in the same compilation unit, the
callee can B<saveall> registers, when the subroutine is in a different
compilation unit, the callee must preserve all used registers.

=head1 Parrot calling conventions (NCI)

Proposed syntax:

$P0 = load_lib "libname"
$P1 = dlfunc $P0, "funcname", "signature"
.nciarg z # I5
.nciarg y # I6
.nciarg x # I7
ncicall $P1 # r = funcname(x, y, z)
.local int r
.nciresult r

This prepares parameters like described in
F<pdd03_calling_conventions.pod>, saves the registers and invokes the
function.
The B<.nciarg> pseudo ops put the given argument into increasing
registers of the appropriate type. They have to be in reversed
argument order.

=head2 Status

Unimplemented.

=head1 Continuations

TBD.

=head1 Coroutines

TBD.

=head1 Exception handlers

TBD.

=head1 Parrot calling conventions (Method calls)

TBD.

=head1 Namespaces and lexicals

- Should imcc keep track of pad opcodes?
- Should imcc even emit such opcodes from e.g. .local directives?

=head1 FILES

F<imcc.y>, F<t/syn/bsr.t>

=head1 AUTHOR

Leopold Toetsch <lt@toetsch.at>

=cut

# vim: expandtab shiftwidth=4 tw=70:

0 comments on commit 6bfa31a

Please sign in to comment.