2016-09-21 22:15:48 +00:00
|
|
|
#include "mcg.h"
|
|
|
|
|
|
|
|
static void print_blocks(char k, struct procedure* proc)
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
|
|
|
|
tracef(k, "%c: procedure %s\n", k, proc->name);
|
2016-09-26 20:48:58 +00:00
|
|
|
for (int i=0; i<proc->blocks.count; i++)
|
2016-09-21 22:15:48 +00:00
|
|
|
{
|
2016-09-26 20:48:58 +00:00
|
|
|
struct basicblock* bb = proc->blocks.item[i];
|
2016-09-21 22:15:48 +00:00
|
|
|
int j;
|
|
|
|
|
2016-09-22 21:19:29 +00:00
|
|
|
tracef(k, "%c:\n", k);
|
2016-09-23 23:04:00 +00:00
|
|
|
tracef(k, "%c: %sBLOCK: %s\n", k,
|
|
|
|
bb->is_fake ? "FAKE " : "",
|
|
|
|
bb->name);
|
2016-09-21 22:15:48 +00:00
|
|
|
|
2016-09-26 20:48:58 +00:00
|
|
|
for (int j=0; j<bb->irs.count; j++)
|
|
|
|
ir_print(k, bb->irs.item[j]);
|
2016-09-21 22:15:48 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-09-23 23:04:00 +00:00
|
|
|
void procedure_compile(struct procedure* proc)
|
2016-09-21 22:15:48 +00:00
|
|
|
{
|
|
|
|
int i;
|
|
|
|
|
|
|
|
print_blocks('1', proc);
|
2016-09-22 21:19:29 +00:00
|
|
|
|
2016-10-01 20:58:29 +00:00
|
|
|
pass_group_irs(proc);
|
2016-10-02 15:50:34 +00:00
|
|
|
/* Passes from here on must preserve IR grouping */
|
|
|
|
|
2016-09-23 21:59:15 +00:00
|
|
|
pass_eliminate_trivial_blocks(proc);
|
2016-09-23 19:07:16 +00:00
|
|
|
pass_remove_dead_blocks(proc);
|
2016-10-02 15:50:34 +00:00
|
|
|
|
|
|
|
procedure_update_bb_graph(proc);
|
|
|
|
/* Passes from here on can't alter the BB graph */
|
|
|
|
|
|
|
|
print_blocks('2', proc);
|
2016-09-23 19:07:16 +00:00
|
|
|
pass_convert_stack_ops(proc);
|
2016-10-02 15:50:34 +00:00
|
|
|
print_blocks('3', proc);
|
|
|
|
pass_convert_locals_to_ssa(proc);
|
|
|
|
print_blocks('4', proc);
|
2016-10-01 17:10:22 +00:00
|
|
|
pass_promote_float_ops(proc);
|
2016-10-02 15:50:34 +00:00
|
|
|
print_blocks('5', proc);
|
2016-09-22 21:19:29 +00:00
|
|
|
|
2016-09-24 20:46:08 +00:00
|
|
|
|
|
|
|
pass_instruction_selector(proc);
|
2016-09-21 22:15:48 +00:00
|
|
|
}
|
|
|
|
|
2016-10-02 15:50:34 +00:00
|
|
|
static bool collect_outputs_cb(struct ir* ir, void* user)
|
|
|
|
{
|
|
|
|
struct basicblock* caller = user;
|
|
|
|
|
|
|
|
if (ir->opcode == IR_BLOCK)
|
|
|
|
{
|
|
|
|
array_appendu(&caller->nexts, ir->u.bvalue);
|
|
|
|
array_appendu(&ir->u.bvalue->prevs, caller);
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
void procedure_update_bb_graph(struct procedure* proc)
|
|
|
|
{
|
|
|
|
int i, j;
|
|
|
|
|
|
|
|
for (i=0; i<proc->blocks.count; i++)
|
|
|
|
{
|
|
|
|
struct basicblock* bb = proc->blocks.item[i];
|
|
|
|
bb->prevs.count = bb->nexts.count = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
for (i=0; i<proc->blocks.count; i++)
|
|
|
|
{
|
|
|
|
struct basicblock* bb = proc->blocks.item[i];
|
|
|
|
for (j=0; j<bb->irs.count; j++)
|
|
|
|
ir_walk(bb->irs.item[j], collect_outputs_cb, bb);
|
|
|
|
}
|
|
|
|
|
|
|
|
for (i=0; i<proc->blocks.count; i++)
|
|
|
|
{
|
|
|
|
struct basicblock* bb = proc->blocks.item[i];
|
|
|
|
|
|
|
|
for (j=0; j<bb->nexts.count; j++)
|
|
|
|
{
|
|
|
|
tracef('G', "G: graph %s -> %s\n",
|
|
|
|
bb->name,
|
|
|
|
bb->nexts.item[j]->name);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-09-21 22:15:48 +00:00
|
|
|
/* vim: set sw=4 ts=4 expandtab : */
|
|
|
|
|