We're going to need some type inference after all, I think. Let's do a little

for now and see how it goes.
This commit is contained in:
David Given 2016-10-01 19:10:22 +02:00
parent 91e277e046
commit 21898f784a
5 changed files with 109 additions and 4 deletions

View file

@ -124,6 +124,7 @@ extern void pass_convert_stack_ops(struct procedure* proc);
extern void pass_remove_dead_blocks(struct procedure* proc); extern void pass_remove_dead_blocks(struct procedure* proc);
extern void pass_eliminate_trivial_blocks(struct procedure* proc); extern void pass_eliminate_trivial_blocks(struct procedure* proc);
extern void pass_instruction_selector(struct procedure* proc); extern void pass_instruction_selector(struct procedure* proc);
extern void pass_promote_float_ops(struct procedure* proc);
extern void procedure_compile(struct procedure* proc); extern void procedure_compile(struct procedure* proc);

View file

@ -0,0 +1,100 @@
#include "mcg.h"
static ARRAYOF(struct ir) pending;
static ARRAYOF(struct ir) promotable;
static void addall(struct ir* ir)
{
if (array_appendu(&pending, ir))
return;
if (ir->left)
addall(ir->left);
if (ir->right)
addall(ir->right);
}
static void collect_irs(struct procedure* proc)
{
int i;
pending.count = 0;
promotable.count = 0;
for (i=0; i<proc->blocks.count; i++)
{
struct basicblock* bb = proc->blocks.item[i];
int j;
for (j=0; j<bb->irs.count; j++)
addall(bb->irs.item[j]);
}
}
static void promote(struct ir* ir)
{
switch (ir->opcode)
{
case IR_CONST:
case IR_POP:
case IR_LOAD:
array_appendu(&promotable, ir);
break;
case IR_PHI:
if (!array_appendu(&promotable, ir))
{
if (ir->left)
promote(ir->left);
if (ir->right)
promote(ir->right);
}
break;
}
}
static void search_for_promotable_irs(void)
{
int i;
for (i=0; i<pending.count; i++)
{
struct ir* ir = pending.item[i];
switch (ir->opcode)
{
case IR_ADDF:
case IR_SUBF:
case IR_MULF:
case IR_DIVF:
case IR_NEGF:
if (ir->left)
promote(ir->left);
if (ir->right)
promote(ir->right);
break;
}
}
}
static void modify_promotable_irs(void)
{
int i;
for (i=0; i<promotable.count; i++)
{
struct ir* ir = promotable.item[i];
if (ir->opcode != IR_PHI)
ir->opcode++;
}
}
void pass_promote_float_ops(struct procedure* proc)
{
collect_irs(proc);
search_for_promotable_irs();
modify_promotable_irs();
}
/* vim: set sw=4 ts=4 expandtab : */

View file

@ -29,6 +29,7 @@ void procedure_compile(struct procedure* proc)
pass_eliminate_trivial_blocks(proc); pass_eliminate_trivial_blocks(proc);
pass_remove_dead_blocks(proc); pass_remove_dead_blocks(proc);
pass_convert_stack_ops(proc); pass_convert_stack_ops(proc);
pass_promote_float_ops(proc);
print_blocks('2', proc); print_blocks('2', proc);

View file

@ -190,7 +190,7 @@ PATTERNS
emit "ldr %int, address-containing-$value" emit "ldr %int, address-containing-$value"
cost 8; cost 8;
float = value:CONST4 float = value:CONSTF4
emit "vldr %float, address-containing-$value" emit "vldr %float, address-containing-$value"
cost 8; cost 8;

View file

@ -3,7 +3,8 @@
# V: has no size (use in JUMP, CJUMP, RET forms) # V: has no size (use in JUMP, CJUMP, RET forms)
# Simple terminals # Simple terminals
S CONST S CONST # must be followed by float form
S CONSTF
S REG S REG
S LABEL S LABEL
S BLOCK S BLOCK
@ -14,10 +15,12 @@ S PHI
# Magic stack operations # Magic stack operations
S PUSH S PUSH
S POP S POP # must be followed by float form
S POPF
#... Memory operations #... Memory operations
S LOAD S LOAD # must be followed by float form
S LOADF
S STORE S STORE
# Arithemetic operations # Arithemetic operations