return usage;
}
+void hop_add_move(struct hop* hop, struct value* src, struct value* dest)
+{
+ struct valueusage* usage;
+
+ assert(hop->insels.count == 0);
+ hop_get_value_usage(hop, src)->input = true;
+ hop_get_value_usage(hop, dest)->output = true;
+ hop->is_move = true;
+}
+
static struct insel* new_insel(enum insel_type type)
{
struct insel* insel = heap_alloc(&proc_heap, 1, sizeof(*insel));
void hop_add_string_insel(struct hop* hop, const char* string)
{
- if ((hop->insels.count == 0) && (string[0] == '@'))
- {
- char* pseudo = strdup(string+1);
- char* end = strchr(pseudo, ' ');
- if (end)
- *end = '\0';
-
- hop->pseudo = pseudo;
- }
- else if (!hop->pseudo)
- {
- struct insel* insel = new_insel(INSEL_STRING);
- insel->u.string = string;
- array_append(&hop->insels, insel);
- }
+ struct insel* insel = new_insel(INSEL_STRING);
+ insel->u.string = string;
+ array_append(&hop->insels, insel);
}
void hop_add_hreg_insel(struct hop* hop, struct hreg* hreg, int index)
while (hashtable_next(hop->valueusage, &hit))
{
struct valueusage* usage = hit.value;
- if (usage->input && usage->output)
- {
- struct vreg* left = actual(usage->invreg);
- struct vreg* right = actual(usage->outvreg);
- if (left != right)
- {
- appendf(" ");
- appendvreg(usage->invreg);
- appendf("->");
- appendvreg(usage->outvreg);
- }
- }
+ appendf(" ");
+ if (usage->input && usage->invreg)
+ appendvreg(actual(usage->invreg));
+ appendf("->");
+ if (usage->output && usage->outvreg)
+ appendvreg(actual(usage->outvreg));
}
appendf("\n");
return buffer;
}
- if (hop->pseudo)
- appendf("@%s ", hop->pseudo);
-
for (i=0; i<hop->insels.count; i++)
{
struct insel* insel = hop->insels.item[i];
default:
assert(false);
}
-
- if (hop->pseudo)
- appendf(" ");
}
return buffer;
ARRAYOF(struct insel) insels;
struct value* value;
bool is_move;
- const char* pseudo;
PMAPOF(struct value, struct value) equals_constraint;
struct hashtable* valueusage;
extern struct hop* new_move_hop(struct basicblock* bb);
extern struct valueusage* hop_get_value_usage(struct hop* hop, struct value* value);
+extern void hop_add_move(struct hop* hop, struct value* src, struct value* dest);
extern void hop_add_string_insel(struct hop* hop, const char* string);
extern void hop_add_hreg_insel(struct hop* hop, struct hreg* hreg, int index);
for (j=0; j<bb->hops.count; j++)
{
struct hop* hop = bb->hops.item[j];
- if (hop->pseudo && (strcmp(hop->pseudo, "copy") == 0))
+ if (hop->is_move)
{
struct valueusage* usage;
struct hashtable_iterator hit = {};
while (hashtable_next(hop->valueusage, &hit))
{
usage = hit.value;
- if (usage->input)
+ if (usage->input && !usage->output)
{
assert(!invreg);
invreg = usage->invreg;
}
- if (usage->output)
+ if (!usage->input && usage->output)
{
assert(!outvreg);
outvreg = usage->outvreg;
}
}
- assert(invreg && outvreg);
- usage = hop_get_value_usage(hop, outvreg->value);
- assert(!usage->invreg);
- assert(!usage->input);
- usage->input = true;
- usage->invreg = invreg;
- hop->is_move = true;
+ if (invreg && outvreg)
+ {
+ usage = hop_get_value_usage(hop, outvreg->value);
+ assert(!usage->input);
+ usage->input = true;
+ usage->invreg = invreg;
+ }
}
}
}
current_hop->value = &insn->value;
if (insn_no == INSN_STMT)
- {
- tracef('I', "I: label=%d\n", node->label);
- hop_get_value_usage(current_hop, firstchild)->input = true;
- hop_get_value_usage(current_hop, current_hop->value)->output = true;
- hop_add_insel(current_hop, "@copy %V %V", firstchild, current_hop->value);
- }
+ hop_add_move(current_hop, firstchild, current_hop->value);
else
{
switch (node->label)
{
case ir_to_esn(IR_REG, 0):
- hop_get_value_usage(current_hop, &node->ir->value)->input = true;
- hop_get_value_usage(current_hop, current_hop->value)->output = true;
- hop_add_insel(current_hop, "@copy %V %V", &node->ir->value, current_hop->value);
+ hop_add_move(current_hop, &node->ir->value, current_hop->value);
break;
case ir_to_esn(IR_NOP, 'I'):
case ir_to_esn(IR_NOP, 'F'):
case ir_to_esn(IR_NOP, 'L'):
case ir_to_esn(IR_NOP, 'D'):
- hop_get_value_usage(current_hop, firstchild)->input = true;
- hop_get_value_usage(current_hop, current_hop->value)->output = true;
- hop_add_insel(current_hop, "@copy %V %V", firstchild, current_hop->value);
+ hop_add_move(current_hop, firstchild, current_hop->value);
break;
}
}