Phi copies are now inserted as part of type inference. More opcodes.

This commit is contained in:
David Given 2016-10-24 22:14:08 +02:00
parent 111c13e253
commit 45a7f2e993
3 changed files with 87 additions and 29 deletions

View file

@ -184,6 +184,11 @@ struct hop* platform_move(struct basicblock* bb, struct hreg* src, struct hreg*
hop_add_insel(hop, "stfs %H, %S(fp) ! %H", src, dest, dest);
break;
case burm_long_ATTR:
hop_add_insel(hop, "stw %0H, 4+%S(fp) ! %H", src, dest, dest);
hop_add_insel(hop, "stw %1H, 0+%S(fp) ! %H", src, dest, dest);
break;
case burm_double_ATTR:
hop_add_insel(hop, "stfd %H, %S(fp) ! %H", src, dest, dest);
break;

View file

@ -237,7 +237,7 @@ PATTERNS
cost 16;
out:(long)reg = COPYD.L(in:(double)reg)
emit "sfdu %in, -8(sp)"
emit "stfdu %in, -8(sp)"
emit "lwz %out.0, 4(sp)"
emit "lwz %out.1, 0(sp)"
emit "addi sp, sp, 8"
@ -249,10 +249,14 @@ PATTERNS
/* Stores */
STORE.D(addr:address, value:(double)reg)
emit "sfd %value, %addr"
cost 4;
STORE.L(addr:address, value:(long)reg)
emit "stw %value.0, 4+%addr"
emit "stw %value.1, 0+%addr"
cost 4;
cost 8;
STORE.I(addr:address, value:(int)reg)
emit "stw %value, %addr"
@ -379,6 +383,11 @@ PATTERNS
emit "bl .fromf2l"
cost 4;
out:(long)reg = FROMSI.D(in:(double)reg)
with corrupted(volatile)
emit "bl .fromsi2d"
cost 4;
#if 0
/* byte conversions */

View file

@ -226,7 +226,37 @@ static struct ir* new_copy(char wanted, char real, struct ir* ir)
return copy;
}
static void insert_copies(void)
static void insert_copy(struct ir* ir, struct ir** child, char returntype, char childtype)
{
if (*child)
{
char wanted;
char real;
if ((returntype == '?') && (childtype == '?'))
{
wanted = ir->type;
real = (*child)->type;
}
else
{
wanted = effective_type(ir, childtype);
real = (*child)->type;
}
if (wanted)
{
if (wanted != real)
{
struct ir* copy = new_copy(wanted, real, *child);
copy->root = ir->root;
*child = copy;
}
}
}
}
static void insert_ir_copies(void)
{
int i;
@ -237,40 +267,54 @@ static void insert_copies(void)
struct ir* ir = irs.item[i];
const struct ir_data* ird = &ir_data[ir->opcode];
if (ir->left)
{
char wanted = effective_type(ir, ird->lefttype);
char real = ir->left->type;
if (wanted && (wanted != real))
{
struct ir* copy = new_copy(wanted, real, ir->left);
copy->root = ir->root;
ir->left = copy;
}
}
if (ir->right)
{
char wanted = effective_type(ir, ird->righttype);
char real = ir->right->type;
if (wanted && (wanted != real))
{
struct ir* copy = new_copy(wanted, real, ir->right);
copy->root = ir->root;
ir->right = copy;
}
}
insert_copy(ir, &ir->left, ird->returntype, ird->lefttype);
insert_copy(ir, &ir->right, ird->returntype, ird->righttype);
}
}
static void insert_phi_copies(void)
{
int i, j;
/* If the child of a phi isn't the same type as the phi itself, we need to
* insert the copy at the end of the block that exported the value. */
for (i=0; i<irs.count; i++)
{
struct ir* ir = irs.item[i];
for (j=0; j<ir->u.phivalue.count; j++)
{
struct ir* childir = ir->u.phivalue.item[j].right;
int wanted = ir->type;
int real = childir->type;
if (wanted != real)
{
struct basicblock* childbb = ir->u.phivalue.item[j].left;
struct ir* copy = new_copy(wanted, real, childir);
copy->root = copy;
/* The copy gets inserted as the second last item of the child
* basic block. That way it'll happen before the final jump
* that exits the block. */
array_insert(&childbb->irs, copy, childbb->irs.count-1);
/* And replace the value in the phi with our copy. */
ir->u.phivalue.item[j].right = copy;
}
}
}
}
void pass_infer_types(void)
{
collect_irs();
propagate_types();
assign_fallback_types();
insert_copies();
insert_ir_copies();
insert_phi_copies();
}
/* vim: set sw=4 ts=4 expandtab : */