You know what, the type inference stuff is a complete red herring. What this

actually needs is a more intelligent register allocator. So, remove the type
inference.
This commit is contained in:
David Given 2016-09-29 19:58:02 +02:00
parent ba1a3656a1
commit a0131fdb47
9 changed files with 51 additions and 160 deletions

View file

@ -106,12 +106,6 @@ static void print_expr(char k, const struct ir* ir)
tracef(k, "%s", ir_data[ir->opcode].name); tracef(k, "%s", ir_data[ir->opcode].name);
if (ir->size) if (ir->size)
tracef(k, "%d", ir->size); tracef(k, "%d", ir->size);
if (ir->type)
tracef(k, ".%s",
((ir->type == IRT_INT) ? "I" :
(ir->type == IRT_FLOAT) ? "F" :
(ir->type == IRT_ANY) ? "*" :
"?"));
tracef(k, "("); tracef(k, "(");
switch (ir->opcode) switch (ir->opcode)

View file

@ -8,7 +8,6 @@ struct ir
int id; int id;
enum ir_opcode opcode; enum ir_opcode opcode;
int size; int size;
enum ir_type type;
struct ir* left; struct ir* left;
struct ir* right; struct ir* right;
union union

View file

@ -123,7 +123,6 @@ 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_type_inference(struct procedure* proc);
extern void procedure_compile(struct procedure* proc); extern void procedure_compile(struct procedure* proc);

View file

@ -1,63 +0,0 @@
#include "mcg.h"
static enum ir_type search_for_type(struct ir* ir, enum ir_type desired)
{
const struct ir_data* data;
if (ir->type != IRT_UNSET)
return ir->type;
data = &ir_data[ir->opcode];
if (ir->left)
ir->left->type = search_for_type(ir->left, data->lefttype);
if (ir->right)
ir->right->type = search_for_type(ir->right, data->righttype);
switch (data->returntype)
{
case IRT_ANY:
if (desired == IRT_FLOAT)
ir->opcode++;
return desired;
case IRT_UNSET:
assert(!((data->lefttype == IRT_ANY) && (data->righttype == IRT_ANY)));
if (((data->lefttype == IRT_ANY) && (ir->left->type == IRT_FLOAT)) ||
((data->righttype == IRT_ANY) && (ir->right->type == IRT_FLOAT)))
{
ir->opcode++;
return IRT_FLOAT;
}
if ((data->lefttype == IRT_ANY) && (ir->left->type == IRT_ANY))
ir->left->type = IRT_INT;
if ((data->righttype == IRT_ANY) && (ir->right->type == IRT_ANY))
ir->right->type = IRT_INT;
return IRT_INT;
default:
return data->returntype;
}
}
static void push_types_up(struct basicblock* bb)
{
int i;
for (i=0; i<bb->irs.count; i++)
{
struct ir* ir = bb->irs.item[i];
ir->type = search_for_type(ir, ir->type);
}
}
void pass_type_inference(struct procedure* proc)
{
int i;
for (i=0; i<proc->blocks.count; i++)
push_types_up(proc->blocks.item[i]);
}
/* vim: set sw=4 ts=4 expandtab : */

View file

@ -29,7 +29,6 @@ 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_type_inference(proc);
print_blocks('2', proc); print_blocks('2', proc);

View file

@ -174,4 +174,4 @@ PATTERNS
reg = value:CONST4 reg = value:CONST4
emit "ldr %reg, #$value" emit "ldr %reg, #$value"
cost 4; cost 8;

View file

@ -1,92 +1,76 @@
# Flags: # Flags:
# S: has size (use in CONST1, CONST2, CONST4, CONST8 forms) # S: has size (use in CONST1, CONST2, CONST4, CONST8 forms)
# V: has no size (use in JUMP, CJUMP, RET forms) # V: has no size (use in JUMP, CJUMP, RET forms)
#
# Types:
# I, F: integer, float
# A: any (will be coerced to I or F during IR postprocessing)
#
# Any instruction with an A type must be followed by the corresponding F
# version.
# Simple terminals # Simple terminals
SA.. CONST S CONST
SF.. CONSTF S REG
SA.. REG S LABEL
SF.. REGF S BLOCK
SI.. LABEL V PAIR
SI.. BLOCK S ANY
V... PAIR S LOCAL
SA.. ANY S PHI
SF.. ANYF
S... LOCAL
S... PHI
# Magic stack operations # Magic stack operations
S.A. PUSH S PUSH
S.F. PUSHF S POP
SA.. POP
SF.. POPF
#... Memory operations #... Memory operations
SAI. LOAD S LOAD
SFI. LOADF S STORE
S.IA STORE
S.IF STOREF
# Arithemetic operations # Arithemetic operations
SIII ADD S ADD
SIII SUB S SUB
SIII MUL S MUL
SIII DIV S DIV
SIII MOD S MOD
SIII NEG S NEG
SFFF ADDF S ADDF
SFFF SUBF S SUBF
SFFF MULF S MULF
SFFF DIVF S DIVF
SFFF NEGF S NEGF
SIII AND S AND
SIII OR S OR
SIII EOR S EOR
SIII NOT S NOT
# Conversions # Conversions
SIII CII1 S CII1
SIII CII2 S CII2
SIII CII4 S CII4
SIII CII8 S CII8
SIII CIU1 S CIU1
SIII CIU2 S CIU2
SIII CIU4 S CIU4
SIII CIU8 S CIU8
# Tristate comparisons # Tristate comparisons
SIII COMPARES S COMPARES
SIII COMPAREU S COMPAREU
# Boolean comparisons # Boolean comparisons
SIII IFEQ S IFEQ
SIII IFLT S IFLT
SIII IFLE S IFLE
# Procedures # Procedures
VI.. CALL V CALL
# Flow control --- these never return # Flow control --- these never return
V.I. JUMP V JUMP
VIII CJUMPEQ V CJUMPEQ
VIII CJUMPLT V CJUMPLT
VIII CJUMPLE V CJUMPLE
V... RET V RET
# Special # Special
SI.. STACKADJUST S STACKADJUST
SA.. GETRET S GETRET
SF.. GETRETF S SETRET
S.A. SETRET
S.F. SETRETF

View file

@ -6,21 +6,10 @@ enum
IRF_SIZED = 1, IRF_SIZED = 1,
}; };
enum ir_type
{
IRT_UNSET = 0,
IRT_INT,
IRT_FLOAT,
IRT_ANY
};
struct ir_data struct ir_data
{ {
const char* name; const char* name;
int flags; int flags;
enum ir_type returntype;
enum ir_type lefttype;
enum ir_type righttype;
}; };
extern const struct ir_data ir_data[]; extern const struct ir_data ir_data[];

View file

@ -25,13 +25,6 @@ awk -f - $in >$source << "EOF"
print "const struct ir_data ir_data[IR__COUNT] = {" print "const struct ir_data ir_data[IR__COUNT] = {"
} }
function char_to_type(c) {
if (c == "I") return "IRT_INT"
if (c == "F") return "IRT_FLOAT"
if (c == "A") return "IRT_ANY"
return "IRT_UNSET"
}
function char_to_flags(c) { function char_to_flags(c) {
if (c == "S") return "IRF_SIZED" if (c == "S") return "IRF_SIZED"
return "0" return "0"
@ -39,10 +32,7 @@ awk -f - $in >$source << "EOF"
/^ *[^# ]+/ { /^ *[^# ]+/ {
printf("\t{ \"%s\", ", $2) printf("\t{ \"%s\", ", $2)
printf("%s, ", char_to_flags(substr($1, 1, 1))) printf("%s", char_to_flags(substr($1, 1, 1)))
printf("%s, ", char_to_type(substr($1, 2, 1)))
printf("%s, ", char_to_type(substr($1, 3, 1)))
printf("%s", char_to_type(substr($1, 4, 1)))
printf(" },\n") printf(" },\n")
} }