Add code to remove unused phis, converting to pruned SSA form, to avoid
confusing the register allocator later.
This commit is contained in:
parent
df239b3f90
commit
4723a1442f
|
@ -112,6 +112,7 @@ extern void pass_live_vreg_analysis(void);
|
|||
extern void pass_promote_float_ops(struct procedure* proc);
|
||||
extern void pass_register_allocator(void);
|
||||
extern void pass_remove_dead_blocks(struct procedure* proc);
|
||||
extern void pass_remove_dead_phis(void);
|
||||
extern void pass_split_critical_edges(struct procedure* proc);
|
||||
|
||||
extern FILE* outputfile;
|
||||
|
|
88
mach/proto/mcg/pass_removedeadphis.c
Normal file
88
mach/proto/mcg/pass_removedeadphis.c
Normal file
|
@ -0,0 +1,88 @@
|
|||
#include "mcg.h"
|
||||
|
||||
static ARRAYOF(struct ir) phis;
|
||||
static bool changed;
|
||||
|
||||
static void collect_phis(struct basicblock* bb)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i=0; i<bb->irs.count; i++)
|
||||
{
|
||||
struct ir* ir = bb->irs.item[i];
|
||||
if (ir->opcode == IR_PHI)
|
||||
array_append(&phis, ir);
|
||||
}
|
||||
}
|
||||
|
||||
static bool ir_walker_cb(struct ir* ir, void* user)
|
||||
{
|
||||
if (ir->left)
|
||||
array_remove(&phis, ir->left);
|
||||
if (ir->right)
|
||||
array_remove(&phis, ir->right);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static void remove_referenced_phis(struct basicblock* bb)
|
||||
{
|
||||
int i, j;
|
||||
|
||||
for (i=0; i<bb->irs.count; i++)
|
||||
{
|
||||
struct ir* ir = bb->irs.item[i];
|
||||
switch (ir->opcode)
|
||||
{
|
||||
case IR_PHI:
|
||||
for (j=0; j<ir->u.phivalue.count; j++)
|
||||
array_remove(&phis, ir->u.phivalue.item[j].right);
|
||||
break;
|
||||
|
||||
default:
|
||||
ir_walk(ir, ir_walker_cb, NULL);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void purge_unused_phis(struct basicblock* bb)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i=0; i<bb->irs.count; i++)
|
||||
{
|
||||
struct ir* ir = bb->irs.item[i];
|
||||
if ((ir->opcode == IR_PHI) && (array_contains(&phis, ir)))
|
||||
{
|
||||
array_remove(&bb->irs, ir);
|
||||
i--;
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void pass_remove_dead_phis(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
do
|
||||
{
|
||||
changed = false;
|
||||
|
||||
phis.count = 0;
|
||||
for (i=0; i<cfg.preorder.count; i++)
|
||||
collect_phis(cfg.preorder.item[i]);
|
||||
|
||||
for (i=0; i<cfg.preorder.count; i++)
|
||||
remove_referenced_phis(cfg.preorder.item[i]);
|
||||
|
||||
for (i=0; i<cfg.preorder.count; i++)
|
||||
purge_unused_phis(cfg.preorder.item[i]);
|
||||
}
|
||||
while (changed);
|
||||
}
|
||||
|
||||
/* vim: set sw=4 ts=4 expandtab : */
|
||||
|
||||
|
|
@ -159,9 +159,9 @@ void procedure_compile(struct procedure* proc)
|
|||
{
|
||||
int i;
|
||||
|
||||
pass_group_irs(proc);
|
||||
print_blocks('1', proc);
|
||||
|
||||
pass_group_irs(proc);
|
||||
/* Passes from here on must preserve IR grouping */
|
||||
|
||||
pass_eliminate_trivial_blocks(proc);
|
||||
|
@ -180,6 +180,7 @@ void procedure_compile(struct procedure* proc)
|
|||
print_blocks('4', proc);
|
||||
pass_convert_locals_to_ssa(proc);
|
||||
print_blocks('5', proc);
|
||||
pass_remove_dead_phis();
|
||||
pass_promote_float_ops(proc);
|
||||
print_blocks('6', proc);
|
||||
|
||||
|
|
Loading…
Reference in a new issue