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:
parent
91e277e046
commit
21898f784a
|
@ -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);
|
||||||
|
|
||||||
|
|
100
mach/proto/mcg/pass_promotefloatops.c
Normal file
100
mach/proto/mcg/pass_promotefloatops.c
Normal 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 : */
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in a new issue