ack/mach/proto/mcg/pass_livevreganalysis.c

74 lines
1.6 KiB
C
Raw Normal View History

#include "mcg.h"
static bool finished;
static void preload_blocks(void)
{
/* Any variable referenced in a phi *must* be a liveout of one of our
* predecessors. */
int i, j;
for (i=0; i<cfg.preorder.count; i++)
{
struct basicblock* bb = cfg.preorder.item[i];
for (j=0; j<bb->phis.count; j++)
{
struct vreg* vreg = bb->phis.item[j].left;
struct phi* phi = bb->phis.item[j].right;
assert(array_contains(&bb->prevs, phi->prev));
array_appendu(&phi->prev->liveouts, phi->ir->result);
}
}
}
static void propagate_liveness(struct basicblock* bb)
{
static ARRAYOF(struct vreg) current;
int i;
current.count = 0;
array_appendall(&current, &bb->liveouts);
for (i=bb->hops.count-1; i>=0; i--)
{
struct hop* hop = bb->hops.item[i];
array_removeall(&current, &hop->outs);
finished &= array_appendallu(&hop->throughs, &current);
array_appendallu(&current, &hop->ins);
}
for (i=0; i<bb->phis.count; i++)
array_remove(&current, bb->phis.item[i].left);
finished &= array_appendallu(&bb->liveins, &current);
for (i=0; i<bb->prevs.count; i++)
{
struct basicblock* prev = bb->prevs.item[i];
finished &= array_appendallu(&prev->liveouts, &current);
}
}
void pass_live_vreg_analysis(void)
{
int i;
preload_blocks();
do
{
finished = true;
tracef('L', "L: beginning liveness pass\n");
for (i=0; i<dominance.postorder.count; i++)
propagate_liveness(dominance.postorder.item[i]);
}
while (!finished);
}
/* vim: set sw=4 ts=4 expandtab : */