static const struct burm_emitter_data emitter_data;
-void burm_trace(struct ir* p, int ruleno, int cost, int bestcost) {
+void burm_trace(struct burm_node* p, int ruleno, int cost, int bestcost) {
const struct burm_instruction_data* insndata = &burm_instruction_data[ruleno];
//tracef('I', "I: 0x%p matched %s with cost %d vs. %d\n", p,
// insndata->name, cost, bestcost);
}
-void burm_panic_cannot_match(struct ir* ir)
+void burm_panic_cannot_match(struct burm_node* node)
{
fprintf(stderr, "could not find any patterns to match:\n");
- ir_print(0, ir);
+ ir_print(0, node->ir);
fprintf(stderr, "aborting!\n");
exit(1);
}
-int burm_calculate_label(struct ir* ir)
-{
- if (ir->root != current_ir)
- return ir_to_esn(IR_REG, ir->size);
- return ir_to_esn(ir->opcode, ir->size);
-}
-
-static void emit_reg(struct ir* ir, int goal)
+static void emit_reg(struct burm_node* node, int goal)
{
struct hop* hop = imap_get(¤t_ir->hops, goal);
hop_add_string_insel(current_hop, data);
}
-static void emit_fragment(struct ir* ir, int goal)
+static void emit_fragment(struct burm_node* node, int goal)
{
- int insn_no = burm_rule(ir->state_label, goal);
+ int insn_no = burm_rule(node->state_label, goal);
const struct burm_instruction_data* insndata = &burm_instruction_data[insn_no];
if (insndata->emitter)
- insndata->emitter(ir, &emitter_data);
+ insndata->emitter(node, &emitter_data);
}
-static void emit_value(struct ir* ir)
+static void emit_value(struct burm_node* node)
{
- hop_add_value_insel(current_hop, ir);
+ hop_add_value_insel(current_hop, node->ir);
}
static void emit_eoi(void)
hop_add_eoi_insel(current_hop);
}
-static void emit_constraint_equals(struct ir* ir, int goal)
+static void emit_constraint_equals(struct burm_node* node, int goal)
{
+#if 0
struct hop* hop;
if (!goal)
- goal = 2;
+ goal = ir->goal_no;
hop = imap_get(¤t_ir->hops, goal);
current_hop->output = hop->output;
+#endif
}
static const struct burm_emitter_data emitter_data =
};
-static void walk_instructions(struct ir* ir, int goal)
+static void walk_instructions(struct burm_node* node, int goal)
{
- struct ir* children[10];
- int insn_no = burm_rule(ir->state_label, goal);
+ struct burm_node* children[10];
+ int insn_no = burm_rule(node->state_label, goal);
const struct burm_instruction_data* insndata = &burm_instruction_data[insn_no];
const short* nts = burm_nts[insn_no];
struct hop* parent_hop = NULL;
+ struct ir* ir = node->ir;
int i;
if (!insndata->is_fragment)
}
}
- burm_kids(ir, insn_no, children);
+ burm_kids(node, insn_no, children);
for (i=0; nts[i]; i++)
walk_instructions(children[i], nts[i]);
- ir->insn_no = insn_no;
- if (goal != 1)
- ir->goal_no = goal;
-
tracef('I', "I: $%d goal %d selected %s %d: %s\n",
ir->id,
- ir->goal_no,
+ goal,
insndata->is_fragment ? "fragment" : "instruction",
insn_no,
insndata->name);
/* This may cause the vregs to be reassigned for this instruction (and
* fragments contained within it). */
- insndata->emitter(ir, &emitter_data);
+ insndata->emitter(node, &emitter_data);
hop_print('I', current_hop);
array_append(&ir->hops, current_hop);
}
}
+static struct burm_node* build_shadow_tree(struct ir* root, struct ir* ir)
+{
+ struct burm_node* node = calloc(1, sizeof(*node));
+ node->ir = ir;
+
+ if (ir->root == root)
+ {
+ node->label = ir_to_esn(ir->opcode, ir->size);
+
+ if (ir->left)
+ node->left = build_shadow_tree(root, ir->left);
+
+ if (ir->right)
+ node->right = build_shadow_tree(root, ir->right);
+ }
+ else
+ node->label = ir_to_esn(IR_REG, 0);
+
+ return node;
+}
+
static void select_instructions(void)
{
int i;
for (i=0; i<current_bb->irs.count; i++)
{
+ struct burm_node* shadow;
int insnno;
+
current_ir = current_bb->irs.item[i];
- burm_label(current_ir);
+ shadow = build_shadow_tree(current_ir, current_ir);
+ burm_label(shadow);
- insnno = burm_rule(current_ir->state_label, 1);
+ insnno = burm_rule(shadow->state_label, 1);
if (!insnno)
- burm_panic_cannot_match(current_ir);
+ burm_panic_cannot_match(shadow);
ir_print('I', current_ir);
- walk_instructions(current_ir, 1);
+ walk_instructions(shadow, 1);
}
}
(size-1)))
#define STATE_TYPE void*
-typedef struct ir* NODEPTR_TYPE;
#define STATE_LABEL(p) ((p)->state_label)
+#define OP_LABEL(p) ((p)->label)
+#define LEFT_CHILD(p) ((p)->left)
+#define RIGHT_CHILD(p) ((p)->right)
-extern void* burm_label(struct ir* ir);
+struct burm_node
+{
+ int label;
+ void* state_label;
+ struct burm_node* left;
+ struct burm_node* right;
+ struct ir* ir;
+};
+
+typedef struct burm_node* NODEPTR_TYPE;
+
+extern void* burm_label(NODEPTR_TYPE node);
extern int burm_rule(void* state, int goalnt);
extern const short *burm_nts[];
-extern struct ir** burm_kids(struct ir* p, int eruleno, struct ir* kids[]);
-extern void burm_trace(struct ir* p, int ruleno, int cost, int bestcost);
+extern NODEPTR_TYPE* burm_kids(NODEPTR_TYPE p, int eruleno, NODEPTR_TYPE kids[]);
+extern void burm_trace(NODEPTR_TYPE p, int ruleno, int cost, int bestcost);
struct burm_emitter_data
{
void (*emit_string)(const char* data);
- void (*emit_fragment)(struct ir* ir, int goal);
- void (*emit_reg)(struct ir* ir, int goal);
- void (*emit_value)(struct ir* ir);
+ void (*emit_fragment)(NODEPTR_TYPE node, int goal);
+ void (*emit_reg)(NODEPTR_TYPE node, int goal);
+ void (*emit_value)(NODEPTR_TYPE node);
void (*emit_eoi)(void);
- void (*emit_constraint_equals)(struct ir* rightir, int rightgoal);
+ void (*emit_constraint_equals)(NODEPTR_TYPE node, int goal);
};
-typedef void burm_emitter_t(struct ir* ir, const struct burm_emitter_data* data);
+typedef void burm_emitter_t(NODEPTR_TYPE node, const struct burm_emitter_data* data);
struct burm_instruction_data
{