2cc2c0ae98
(needed for CHAINFP and FPTOAB). Wire up lfrs to calls via a phi when necessary, to allow call-bra-lfr chains.
76 lines
1.6 KiB
C
76 lines
1.6 KiB
C
#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(¤t, &bb->liveouts);
|
|
|
|
for (i=bb->hops.count-1; i>=0; i--)
|
|
{
|
|
struct hop* hop = bb->hops.item[i];
|
|
|
|
array_removeall(¤t, &hop->outs);
|
|
finished &= array_appendallu(&hop->throughs, ¤t);
|
|
array_appendallu(¤t, &hop->ins);
|
|
}
|
|
|
|
for (i=0; i<bb->phis.count; i++)
|
|
array_remove(¤t, bb->phis.item[i].left);
|
|
|
|
finished &= array_appendallu(&bb->liveins, ¤t);
|
|
|
|
for (i=0; i<bb->prevs.count; i++)
|
|
{
|
|
struct basicblock* prev = bb->prevs.item[i];
|
|
finished &= array_appendallu(&prev->liveouts, ¤t);
|
|
}
|
|
}
|
|
|
|
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);
|
|
|
|
//assert(cfg.entry->liveins.count == 0);
|
|
}
|
|
|
|
/* vim: set sw=4 ts=4 expandtab : */
|
|
|