elementary form yet).
PMAPOF(struct ir, struct ir) imports;
PMAPOF(struct ir, struct ir) exports;
+ struct hashtable* inputmapping;
+ struct hashtable* outputmapping;
+
bool is_fake : 1;
bool is_root : 1;
bool is_terminated : 1;
headers,
tables, -- for .h file
},
+ vars = {
+ ["+cflags"] = "-Werror"
+ }
}
end
)
}
}
-static void print_header(char k, struct hop* hop)
-{
- int i;
-
- tracef(k, "%c: %d", k, hop->id);
- if (hop->ir)
- tracef(k, " from $%d", hop->ir->id);
- tracef(k, ":");
-
- for (i=0; i<hop->inputs.count; i++)
- {
- struct value* value = hop->inputs.item[i];
- tracef(k, " r$%d:%d", value->ir->id, value->subid);
- }
-
- for (i=0; i<hop->outputs.count; i++)
- {
- struct value* value = hop->outputs.item[i];
- tracef(k, " w$%d:%d", value->ir->id, value->subid);
- }
-
- for (i=0; i<hop->throughs.count; i++)
- {
- struct value* value = hop->throughs.item[i];
- tracef(k, " =$%d:%d", value->ir->id, value->subid);
- }
-
- tracef(k, " ");
-}
-
static char* appendf(const char* fmt, ...)
{
int n;
return p;
}
+void appendvalue(struct hop* hop, struct value* value)
+{
+ struct vreg* vreg;
+
+ if (hop->vregmapping && ((vreg = hashtable_get(hop->vregmapping, value))))
+ appendf("%%%d", vreg->id);
+ else
+ appendf("$%d:%d", value->ir->id, value->subid);
+}
+
+static void appendheader(struct hop* hop)
+{
+ int i;
+
+ appendf("%d", hop->id);
+ if (hop->ir)
+ appendf(" from $%d", hop->ir->id);
+ appendf(":");
+
+ for (i=0; i<hop->inputs.count; i++)
+ {
+ struct value* value = hop->inputs.item[i];
+ appendf(" r");
+ appendvalue(hop, value);
+ }
+
+ for (i=0; i<hop->outputs.count; i++)
+ {
+ struct value* value = hop->outputs.item[i];
+ appendf(" w");
+ appendvalue(hop, value);
+ }
+
+ for (i=0; i<hop->throughs.count; i++)
+ {
+ struct value* value = hop->throughs.item[i];
+ appendf(" =");
+ appendvalue(hop, value);
+ }
+
+ appendf(" ");
+}
+
char* hop_render(struct hop* hop)
{
int i;
case INSEL_VREG:
{
- struct value* value = insel->u.value;
- #if 0
- struct hreg* hreg = pmap_findright(&hop->regsin, vreg);
- if (!hreg)
- hreg = pmap_findright(&hop->regsout, vreg);
- if (hreg)
- appendf("%s", hreg->brd->names[insel->index]);
- else
- appendf("%%%d.%d", vreg->id, insel->index);
- #endif
- appendf("$%d:%d", value->ir->id, value->subid);
+ appendvalue(hop, insel->u.value);
if (insel->index)
appendf(".%d", insel->index);
break;
int i;
bool soi = false;
char* p;
+ char* header;
+
+ appendf(""); /* ensure the buffer has been allocated */
+ bufferlen = 0;
+ buffer[0] = '\0';
+
+ appendheader(hop);
+ header = strdup(buffer);
hop_render(hop);
p = strtok(buffer, "\n");
- print_header(k, hop);
+ tracef(k, "%c: %s", k, header);
while (p)
{
tracef(k, "%s", p);
if (p)
{
tracef(k, "\n");
- print_header(k, hop);
+ tracef(k, "%c: %s", k, header);
}
}
tracef(k, "\n");
ARRAYOF(struct value) inputs;
ARRAYOF(struct value) outputs;
ARRAYOF(struct value) throughs;
+
+ struct hashtable* vregmapping;
};
extern struct hop* new_hop(struct basicblock* bb, struct ir* ir);
#include <stdint.h>
#include <string.h>
#include <assert.h>
+#include "hashtable.h"
#include "flt_arith.h"
#include "em_arith.h"
#include "em_label.h"
#include "graph.h"
#include "tables.h"
#include "mcgg.h"
-#include "hashtable.h"
#include "set.h"
#include "bigraph.h"
extern void tb_procedure(void);
extern void tb_regvar(struct procedure* proc, arith offset, int size, int type, int priority);
+extern void pass_assign_vregs(void);
extern void pass_convert_inputs_to_phis(void);
extern void pass_convert_locals_to_ssa(void);
extern void pass_convert_nonlocal_phis(void);
--- /dev/null
+#include "mcg.h"
+
+static const struct hashtable empty_hashtable_of_values = HASHTABLE_OF_VALUES;
+
+static struct basicblock* current_bb;
+
+static int vregcount = 0;
+
+static void create_and_map_vreg(struct hashtable* mapping, struct value* value)
+{
+ struct vreg* vreg = heap_alloc(&proc_heap, 1, sizeof(*vreg));
+ vreg->id = vregcount++;
+ vreg->value = value;
+
+ assert(!hashtable_get(mapping, value));
+ hashtable_put(mapping, value, vreg);
+}
+
+static bool hop_reads_value(struct hop* hop, struct value* value)
+{
+ int i;
+
+ for (i=0; i<hop->inputs.count; i++)
+ if (value_comparison_function(hop->inputs.item[i], value))
+ return true;
+
+ for (i=0; i<hop->throughs.count; i++)
+ if (value_comparison_function(hop->throughs.item[i], value))
+ return true;
+
+ return false;
+}
+
+static void assign_vregs(void)
+{
+ int i, j;
+ struct hashtable* previous_mapping;
+ struct hashtable* current_mapping;
+ struct hop* hop;
+
+ /* Preload the mapping from the first hop. It might be a move, but that
+ * does no harm. */
+
+ hop = current_bb->hops.item[0];
+ current_bb->inputmapping = heap_alloc(&proc_heap, 1, sizeof(struct hashtable));
+ *current_bb->inputmapping = empty_hashtable_of_values;
+ hashtable_empty(current_bb->inputmapping);
+ for (i=0; i<hop->inputs.count; i++)
+ create_and_map_vreg(current_bb->inputmapping, hop->inputs.item[i]);
+ for (i=0; i<hop->throughs.count; i++)
+ create_and_map_vreg(current_bb->inputmapping, hop->throughs.item[i]);
+
+ previous_mapping = current_bb->inputmapping;
+ for (i=0; i<current_bb->hops.count; i++)
+ {
+ hop = current_bb->hops.item[i];
+
+ /* TODO: clone vregs here */
+
+ /* Copy the previous mapping to this hop, pruning out any unused values. */
+
+ current_mapping = hop->vregmapping = heap_alloc(&proc_heap, 1, sizeof(struct hashtable));;
+ *current_mapping = empty_hashtable_of_values;
+ {
+ struct hashtable_iterator hit = {};
+ while (hashtable_next(previous_mapping, &hit))
+ {
+ struct value* value = hit.key;
+ if (hop_reads_value(hop, value))
+ hashtable_put(current_mapping, value, hit.value);
+ }
+ }
+
+ /* Create vregs for any new outputs. */
+
+ for (j=0; j<hop->outputs.count; j++)
+ create_and_map_vreg(current_mapping, hop->outputs.item[j]);
+
+ /* And move on to the next one. */
+
+ previous_mapping = current_mapping;
+ }
+
+ current_bb->outputmapping = previous_mapping;
+}
+
+void pass_assign_vregs(void)
+{
+ int i;
+
+ vregcount = 0;
+
+ for (i=0; i<dominance.preorder.count; i++)
+ {
+ current_bb = dominance.preorder.item[i];
+ assign_vregs();
+ }
+
+ tracef('V', "V: finished vreg assignment with %d vregs\n", vregcount);
+}
+
+/* vim: set sw=4 ts=4 expandtab : */
+
print_hops('7');
pass_live_value_analysis();
print_hops('8');
+ pass_assign_vregs();
+ print_hops('9');
#if 0
pass_split_live_ranges();
pass_determine_vreg_usage();
ARRAYOF(struct hreg) aliases;
};
+struct vreg
+{
+ int id;
+ struct value* value;
+};
+
extern struct hreg* new_hreg(const struct burm_register_data* brd);
extern struct hreg* new_stacked_hreg(uint32_t type);