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_eliminate_trivial_blocks(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);
|
||||
|
||||
|
|
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_remove_dead_blocks(proc);
|
||||
pass_convert_stack_ops(proc);
|
||||
pass_promote_float_ops(proc);
|
||||
|
||||
print_blocks('2', proc);
|
||||
|
||||
|
|
|
@ -190,7 +190,7 @@ PATTERNS
|
|||
emit "ldr %int, address-containing-$value"
|
||||
cost 8;
|
||||
|
||||
float = value:CONST4
|
||||
float = value:CONSTF4
|
||||
emit "vldr %float, address-containing-$value"
|
||||
cost 8;
|
||||
|
||||
|
|
|
@ -3,7 +3,8 @@
|
|||
# V: has no size (use in JUMP, CJUMP, RET forms)
|
||||
|
||||
# Simple terminals
|
||||
S CONST
|
||||
S CONST # must be followed by float form
|
||||
S CONSTF
|
||||
S REG
|
||||
S LABEL
|
||||
S BLOCK
|
||||
|
@ -14,10 +15,12 @@ S PHI
|
|||
|
||||
# Magic stack operations
|
||||
S PUSH
|
||||
S POP
|
||||
S POP # must be followed by float form
|
||||
S POPF
|
||||
|
||||
#... Memory operations
|
||||
S LOAD
|
||||
S LOAD # must be followed by float form
|
||||
S LOADF
|
||||
S STORE
|
||||
|
||||
# Arithemetic operations
|
||||
|
|
Loading…
Reference in a new issue