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);
if (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, "(");
switch (ir->opcode)

View file

@ -8,7 +8,6 @@ struct ir
int id;
enum ir_opcode opcode;
int size;
enum ir_type type;
struct ir* left;
struct ir* right;
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_eliminate_trivial_blocks(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);

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_remove_dead_blocks(proc);
pass_convert_stack_ops(proc);
pass_type_inference(proc);
print_blocks('2', proc);

View file

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

View file

@ -1,92 +1,76 @@
# Flags:
# S: has size (use in CONST1, CONST2, CONST4, CONST8 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
SA.. CONST
SF.. CONSTF
SA.. REG
SF.. REGF
SI.. LABEL
SI.. BLOCK
V... PAIR
SA.. ANY
SF.. ANYF
S... LOCAL
S... PHI
S CONST
S REG
S LABEL
S BLOCK
V PAIR
S ANY
S LOCAL
S PHI
# Magic stack operations
S.A. PUSH
S.F. PUSHF
SA.. POP
SF.. POPF
S PUSH
S POP
#... Memory operations
SAI. LOAD
SFI. LOADF
S.IA STORE
S.IF STOREF
S LOAD
S STORE
# Arithemetic operations
SIII ADD
SIII SUB
SIII MUL
SIII DIV
SIII MOD
SIII NEG
S ADD
S SUB
S MUL
S DIV
S MOD
S NEG
SFFF ADDF
SFFF SUBF
SFFF MULF
SFFF DIVF
SFFF NEGF
S ADDF
S SUBF
S MULF
S DIVF
S NEGF
SIII AND
SIII OR
SIII EOR
SIII NOT
S AND
S OR
S EOR
S NOT
# Conversions
SIII CII1
SIII CII2
SIII CII4
SIII CII8
S CII1
S CII2
S CII4
S CII8
SIII CIU1
SIII CIU2
SIII CIU4
SIII CIU8
S CIU1
S CIU2
S CIU4
S CIU8
# Tristate comparisons
SIII COMPARES
SIII COMPAREU
S COMPARES
S COMPAREU
# Boolean comparisons
SIII IFEQ
SIII IFLT
SIII IFLE
S IFEQ
S IFLT
S IFLE
# Procedures
VI.. CALL
V CALL
# Flow control --- these never return
V.I. JUMP
VIII CJUMPEQ
VIII CJUMPLT
VIII CJUMPLE
V... RET
V JUMP
V CJUMPEQ
V CJUMPLT
V CJUMPLE
V RET
# Special
SI.. STACKADJUST
SA.. GETRET
SF.. GETRETF
S.A. SETRET
S.F. SETRETF
S STACKADJUST
S GETRET
S SETRET

View file

@ -6,21 +6,10 @@ enum
IRF_SIZED = 1,
};
enum ir_type
{
IRT_UNSET = 0,
IRT_INT,
IRT_FLOAT,
IRT_ANY
};
struct ir_data
{
const char* name;
int flags;
enum ir_type returntype;
enum ir_type lefttype;
enum ir_type righttype;
};
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] = {"
}
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) {
if (c == "S") return "IRF_SIZED"
return "0"
@ -39,10 +32,7 @@ awk -f - $in >$source << "EOF"
/^ *[^# ]+/ {
printf("\t{ \"%s\", ", $2)
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("%s", char_to_flags(substr($1, 1, 1)))
printf(" },\n")
}