extern void tb_regvar(struct procedure* proc, arith offset, int size, int type, int priority);
extern void pass_assign_vregs(void);
+extern void pass_calculate_vreg_spillibility(void);
extern void pass_convert_inputs_to_phis(void);
extern void pass_convert_locals_to_ssa(void);
extern void pass_convert_nonlocal_phis(void);
extern void pass_convert_stack_ops(void);
-extern void pass_determine_vreg_usage(void);
extern void pass_eliminate_trivial_blocks(void);
extern void pass_find_phi_congruence_groups(void);
extern void pass_group_irs(void);
extern void pass_remove_dead_blocks(void);
extern void pass_remove_dead_phis(void);
extern void pass_split_critical_edges(void);
-extern void pass_split_live_ranges(void);
extern void pass_wire_up_return_values(void);
extern void platform_calculate_offsets(void);
{
int i, j, k;
- current_proc->usedregs.count = 0;
- for (i=0; i<cfg.preorder.count; i++)
- {
- struct basicblock* bb = cfg.preorder.item[i];
-
- for (j=0; j<bb->hops.count; j++)
- {
- struct hop* hop = bb->hops.item[j];
-
- for (k=0; k<hop->regsin.count; k++)
- {
- struct hreg* hreg = hop->regsin.item[k].left;
- if (!hreg->is_stacked)
- array_appendu(¤t_proc->usedregs, hreg);
- }
-
- for (k=0; k<hop->regsout.count; k++)
- {
- struct hreg* hreg = hop->regsout.item[k].left;
- if (!hreg->is_stacked)
- array_appendu(¤t_proc->usedregs, hreg);
- }
- }
- }
-
- platform_calculate_offsets();
+ // current_proc->usedregs.count = 0;
+ // for (i=0; i<cfg.preorder.count; i++)
+ // {
+ // struct basicblock* bb = cfg.preorder.item[i];
+
+ // for (j=0; j<bb->hops.count; j++)
+ // {
+ // struct hop* hop = bb->hops.item[j];
+
+ // for (k=0; k<hop->regsin.count; k++)
+ // {
+ // struct hreg* hreg = hop->regsin.item[k].left;
+ // if (!hreg->is_stacked)
+ // array_appendu(¤t_proc->usedregs, hreg);
+ // }
+
+ // for (k=0; k<hop->regsout.count; k++)
+ // {
+ // struct hreg* hreg = hop->regsout.item[k].left;
+ // if (!hreg->is_stacked)
+ // array_appendu(¤t_proc->usedregs, hreg);
+ // }
+ // }
+ // }
+
+ // platform_calculate_offsets();
array_insert(¤t_proc->entry->hops, platform_prologue(), 0);
* http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.32.5924
*/
-static const int DEGREE = 10;
+static const int DEGREE = 5;
static struct graph interference;
static struct graph affinity;
static void dump_vreg(struct vreg* vreg)
{
fprintf(regalloc_dot_file, "[%%%d]", vreg->id);
+ if (!vreg->needs_register)
+ fprintf(regalloc_dot_file, "S");
}
static void dump_interference_graph(void)
if (degree > DEGREE)
return false;
- tracef('R', "R: lowest degree affinity edge: %%%d->%%%d, degree %d\n",
+ tracef('R', "R: coalescing affinity edge: %%%d->%%%d, degree %d\n",
v1->id, v2->id, degree);
coalesce(v1, v2);
return true;
}
+static bool attempt_to_simplify(void)
+{
+ return false;
+}
+
static void iterate(void)
{
struct anode* spill;
if (attempt_to_coalesce())
continue;
- // if (attempt_to_simplify())
- // continue;
+ if (attempt_to_simplify())
+ continue;
// if (attempt_to_spill_or_simplify())
// continue;
wire_together_bbs();
generate_graph();
- iterate();
+ //iterate();
dump_interference_graph();
--- /dev/null
+#include "mcg.h"
+
+static struct basicblock* current_bb;
+
+static void calculate_spillibility(void)
+{
+ int i;
+
+ for (i=0; i<current_bb->hops.count; i++)
+ {
+ struct hop* hop = current_bb->hops.item[i];
+ if (!hop->is_move)
+ {
+ struct hashtable_iterator hit = {};
+ while (hashtable_next(hop->valueusage, &hit))
+ {
+ struct value* value = hit.key;
+ struct valueusage* usage = hit.value;
+
+ if (!usage->through)
+ {
+ if (usage->invreg)
+ usage->invreg->needs_register = true;
+ if (usage->outvreg)
+ usage->outvreg->needs_register = true;
+ }
+ }
+ }
+ }
+}
+
+void pass_calculate_vreg_spillibility(void)
+{
+ int i;
+
+ for (i=0; i<dominance.preorder.count; i++)
+ {
+ current_bb = dominance.preorder.item[i];
+ calculate_spillibility();
+ }
+}
+
+/* vim: set sw=4 ts=4 expandtab : */
+++ /dev/null
-#include "mcg.h"
-
-static struct basicblock* current_bb;
-
-static void rewrite_vregs(struct basicblock* bb,
- int pos, struct vreg* src, struct vreg* dest)
-{
- int i, j;
-
- while (pos < bb->hops.count)
- {
- struct hop* hop = bb->hops.item[pos];
-
- array_replace(&hop->ins, src, dest);
- array_replace(&hop->throughs, src, dest);
- array_replace(&hop->outs, src, dest);
-
- for (i=0; i<hop->insels.count; i++)
- {
- struct insel* insel = hop->insels.item[i];
- if ((insel->type == INSEL_VREG) && (insel->u.vreg == src))
- insel->u.vreg = dest;
- }
-
- for (i=0; i<hop->constraints.count; i++)
- {
- struct constraint* c = hop->constraints.item[i].right;
-
- if (hop->constraints.item[i].left == src)
- hop->constraints.item[i].left = dest;
-
- if (c->equals_to == src)
- c->equals_to = dest;
- }
-
- pos++;
- }
-
- for (i=0; i<bb->nexts.count; i++)
- {
- struct basicblock* nextbb = bb->nexts.item[i];
-
- for (j=0; j<nextbb->phis.count; j++)
- {
- struct phi* phi = nextbb->phis.item[j].right;
- if (phi->ir->result == src)
- phi->ir->result = dest;
- }
- }
-}
-
-static void rewrite_blocks(struct basicblock* startbb, int startindex,
- struct vreg* src, struct vreg* dest)
-{
- int i;
-
- for (i=0; i<dominance.preorder.count; i++)
- {
- struct basicblock* bb = dominance.preorder.item[i];
- if (bb == startbb)
- break;
- }
- assert(i < dominance.preorder.count);
-
- while (i < dominance.preorder.count)
- {
- struct basicblock* bb = dominance.preorder.item[i];
- rewrite_vregs(bb, startindex, src, dest);
- startindex = 0;
- i++;
- }
-}
-
-static int insert_move_after(int index, struct vreg* src)
-{
- struct vreg* dest;
- struct hop* copy;
-
- dest = new_vreg();
- dest->type = src->type;
- copy = new_copy_hop(current_bb, src, dest);
-
- array_insert(¤t_bb->hops, copy, index+1);
-
- rewrite_blocks(current_bb, index+2, src, dest);
- return 1;
-}
-
-void pass_split_live_ranges(void)
-{
- int i, j, k;
-
- for (i=0; i<dominance.preorder.count; i++)
- {
- current_bb = dominance.preorder.item[i];
-
- for (j=0; j<current_bb->hops.count; j++)
- {
- struct hop* hop = current_bb->hops.item[j];
-
- if (!hop->is_move)
- {
- for (k=0; k<hop->ins.count; k++)
- {
- struct vreg* vreg = hop->ins.item[k];
- j += insert_move_after(j-1, vreg);
- }
-
- for (k=0; k<hop->outs.count; k++)
- {
- struct vreg* vreg = hop->outs.item[k];
- insert_move_after(j, vreg);
- }
-
- for (k=0; k<hop->ins.count; k++)
- {
- struct vreg* vreg = hop->ins.item[k];
- j += insert_move_after(j, vreg);
- }
- }
- }
- }
-}
-
-/* vim: set sw=4 ts=4 expandtab : */
\ No newline at end of file
+++ /dev/null
-#include "mcg.h"
-
-static struct set vregs;
-
-static void assign_uses_cb(struct hop* hop, void* user)
-{
- int i;
-
- for (i=0; i<hop->ins.count; i++)
- array_appendu(&hop->ins.item[i]->usedhops, hop);
-
- for (i=0; i<hop->outs.count; i++)
- {
- struct vreg* vreg = hop->outs.item[i];
- assert(vreg->defined == NULL);
- vreg->defined = hop;
- set_add(&vregs, vreg);
- }
-}
-
-static bool is_spillable_vreg(struct vreg* vreg)
-{
- int i;
-
- if (vreg->defined && !vreg->defined->is_move)
- return false;
-
- for (i=0; i<vreg->usedhops.count; i++)
- if (!vreg->usedhops.item[i]->is_move)
- return false;
-
- return true;
-}
-
-void pass_determine_vreg_usage(void)
-{
- int i, j;
-
- set_empty(&vregs);
- hop_walk(assign_uses_cb, NULL);
-
- for (i=0; i<dominance.preorder.count; i++)
- {
- struct basicblock* bb = dominance.preorder.item[i];
- for (j=0; j<bb->phis.count; j++)
- {
- struct vreg* dest = bb->phis.item[j].left;
- struct phi* phi = bb->phis.item[j].right;
- struct vreg* src = phi->ir->result;
- array_appendu(&src->usedphis, bb);
- set_add(&vregs, src);
- set_add(&vregs, dest);
- }
- }
-
- {
- struct set_iterator sit = {};
- while (set_next(&vregs, &sit))
- {
- struct vreg* vreg = sit.item;
- vreg->is_spillable = is_spillable_vreg(vreg);
- }
- }
-}
-
-/* vim: set sw=4 ts=4 expandtab : */
pass_live_value_analysis();
print_hops('8');
pass_assign_vregs();
+ pass_calculate_vreg_spillibility();
print_hops('9');
pass_register_allocator();
#if 0
- pass_split_live_ranges();
- pass_determine_vreg_usage();
-
pass_add_prologue_epilogue();
print_hops('9');
int id;
struct value* value;
struct vreg* coalesced_with;
+ bool needs_register;
};
extern struct hreg* new_hreg(const struct burm_register_data* brd);