Collapse several rule arrays into one; actually generate the array properly.

This commit is contained in:
David Given 2016-09-25 17:14:54 +02:00
parent 67eb21d428
commit bde5792b1a
4 changed files with 93 additions and 76 deletions

View file

@ -25,8 +25,9 @@ static void dumpCover(NODEPTR_TYPE p, int goalnt, int indent) {
#endif #endif
void burm_trace(struct ir* p, int ruleno, int cost, int bestcost) { void burm_trace(struct ir* p, int ruleno, int cost, int bestcost) {
const struct burm_instruction_data* insndata = &burm_instruction_data[ruleno];
tracef('I', "I: 0x%p matched %s with cost %d vs. %d\n", p, tracef('I', "I: 0x%p matched %s with cost %d vs. %d\n", p,
burm_string[ruleno], cost, bestcost); insndata->name, cost, bestcost);
} }
void burm_panic_cannot_match(struct ir* ir) void burm_panic_cannot_match(struct ir* ir)
@ -41,6 +42,7 @@ static void queue_instructions(struct ir* ir, int goal)
{ {
struct ir* children[10]; struct ir* children[10];
int ruleno = burm_rule(ir->state_label, goal); int ruleno = burm_rule(ir->state_label, goal);
const struct burm_instruction_data* insndata = &burm_instruction_data[ruleno];
const short* nts = burm_nts[ruleno]; const short* nts = burm_nts[ruleno];
int i; int i;
@ -48,7 +50,11 @@ static void queue_instructions(struct ir* ir, int goal)
for (i=0; nts[i]; i++) for (i=0; nts[i]; i++)
queue_instructions(children[i], nts[i]); queue_instructions(children[i], nts[i]);
tracef('I', "I: $%d selected insn %d: %s\n", ir->id, ruleno, burm_string[ruleno]); tracef('I', "I: $%d selected %s %d: %s\n",
ir->id,
insndata->is_fragment ? "fragment" : "instruction",
ruleno,
insndata->name);
} }
static void select_instructions(struct basicblock* bb) static void select_instructions(struct basicblock* bb)

View file

@ -43,21 +43,25 @@ PATTERNS
emit "ldrb %reg, %addr" emit "ldrb %reg, %addr"
cost 4; cost 4;
reg = CII14(CIU41(CIU14(LOAD1(addr:address))))
emit "ldrsb %reg, %addr"
cost 4;
/* Locals */ /* Locals */
reg = in:LOCAL4 reg = in:LOCAL4
emit "add %reg, fp, #%in" emit "add %reg, fp, #$in"
cost 4; cost 4;
address = in:LOCAL4 address = in:LOCAL4
fragment "[fp, #%in]"; fragment "[fp, #$in]";
/* Memory addressing modes */ /* Memory addressing modes */
address = ADD4(addr:reg, offset:CONST) address = ADD4(addr:reg, offset:CONST)
fragment "[%addr, #%offset]"; fragment "[%addr, #$offset]";
address = addr:reg address = addr:reg
fragment "[%addr]"; fragment "[%addr]";
@ -66,12 +70,12 @@ PATTERNS
/* Branches */ /* Branches */
JUMP(addr:BLOCK4) JUMP(addr:BLOCK4)
emit "b %addr" emit "b $addr"
cost 4; cost 4;
CJUMPEQ(value:tristate, PAIR(true:BLOCK4, false:BLOCK4)) CJUMPEQ(value:tristate, PAIR(true:BLOCK4, false:BLOCK4))
emit "beq %true" emit "beq $true"
emit "bne %false" emit "bne $false"
cost 8; cost 8;
@ -111,7 +115,7 @@ PATTERNS
cost 4; cost 4;
aluparam = value:CONST4 aluparam = value:CONST4
fragment "#%value.ivalue"; fragment "#$value";
aluparam = reg; aluparam = reg;
@ -120,13 +124,13 @@ PATTERNS
cost 4; cost 4;
reg = value:LABEL4 reg = value:LABEL4
emit "adr %reg, %value" emit "adr %reg, $value"
cost 4; cost 4;
reg = value:BLOCK4 reg = value:BLOCK4
emit "adr %reg, %value" emit "adr %reg, $value"
cost 4; cost 4;
reg = value:CONST4 reg = value:CONST4
emit "ldr %reg, #value" emit "ldr %reg, #$value"
cost 4; cost 4;

View file

@ -41,7 +41,7 @@ static void emitnts(Rule rules, int nrules);
static void emitrecord(char* pre, Rule r, int cost); static void emitrecord(char* pre, Rule r, int cost);
static void emitrule(Nonterm nts); static void emitrule(Nonterm nts);
static void emitpredicatedefinitions(Rule rules); static void emitpredicatedefinitions(Rule rules);
static void emitemitters(Rule rules); static void emitinsndata(Rule rules);
static void emitstate(Term terms, Nonterm start, int ntnumber); static void emitstate(Term terms, Nonterm start, int ntnumber);
static void emitstring(Rule rules); static void emitstring(Rule rules);
static void emitstruct(Nonterm nts, int ntnumber); static void emitstruct(Nonterm nts, int ntnumber);
@ -135,7 +135,7 @@ int main(int argc, char* argv[])
emitrule(nts); emitrule(nts);
emitclosure(nts); emitclosure(nts);
emitpredicatedefinitions(rules); emitpredicatedefinitions(rules);
emitemitters(rules); emitinsndata(rules);
if (start) if (start)
emitstate(terms, start, ntnumber); emitstate(terms, start, ntnumber);
print("#ifdef STATE_LABEL\n"); print("#ifdef STATE_LABEL\n");
@ -800,59 +800,51 @@ static void emitpredicatedefinitions(Rule r)
} }
} }
static void emittreefetchers(uint32_t path, Tree tree) static void print_path(uint32_t path)
{ {
if (tree->label) int i = 0;
while (path > 0)
{ {
int i = 0; switch (path % 3)
uint32_t p = path;
print("%1NODEPTR_TYPE node_%s = ", tree->label);
while (p > 0)
{ {
switch (p % 3) case 1: print("LEFT_CHILD("); break;
{ case 2: print("RIGHT_CHILD("); break;
case 1: print("LEFT_CHILD("); break;
case 2: print("RIGHT_CHILD("); break;
}
p /= 3;
i++;
} }
path /= 3;
print("node"); i++;
while (i > 0)
{
print(")");
i--;
}
print(";\n");
} }
if (tree->left) print("node");
emittreefetchers(path*3 + 1, tree->left);
if (tree->right) while (i > 0)
emittreefetchers(path*3 + 2, tree->right); {
print(")");
i--;
}
} }
static Tree find_label(Tree root, const char* name) static const uint32_t PATH_MISSING = 0xffffffff;
static uint32_t find_label(Tree root, const char* name, uint32_t path)
{ {
Tree t; uint32_t p;
if (root->label && (strcmp(root->label, name) == 0)) if (root->label && (strcmp(root->label, name) == 0))
return root; return path;
t = NULL; p = PATH_MISSING;
if (root->left && !t) if (root->left && (p == PATH_MISSING))
t = find_label(root->left, name); p = find_label(root->left, name, path*3 + 1);
if (root->right && !t) if (root->right && (p == PATH_MISSING))
t = find_label(root->right, name); p = find_label(root->right, name, path*3 + 2);
return t; return p;
} }
/* emitemitters - emit the code generation routines */ /* emitinsndata - emit the code generation data */
static void emitemitters(Rule rules) static void emitinsndata(Rule rules)
{ {
int k;
Rule r; Rule r;
r = rules; r = rules;
@ -863,8 +855,6 @@ static void emitemitters(Rule rules)
{ {
print("/* %R */\n", r); print("/* %R */\n", r);
print("static void %Pemitter_%d(NODEPTR_TYPE node, struct %Pemitter_data* data) {\n", r->ern); print("static void %Pemitter_%d(NODEPTR_TYPE node, struct %Pemitter_data* data) {\n", r->ern);
emittreefetchers(0, r->pattern);
print("%1NODEPTR_TYPE node_%s = node;\n", r->lhs->name);
while (f) while (f)
{ {
@ -873,14 +863,22 @@ static void emitemitters(Rule rules)
case '%': case '%':
{ {
const char* label = f->data + 1; const char* label = f->data + 1;
Tree t = find_label(r->pattern, label);
if (!t && (strcmp(label, r->lhs->name) != 0)) print("%1data->emit_ir(");
if (strcmp(label, r->lhs->name) == 0)
print("node");
else
{ {
yylineno = r->lineno; uint32_t path = find_label(r->pattern, label, 0);
yyerror("label '%s' not found", label); if (path == PATH_MISSING)
exit(1); {
yylineno = r->lineno;
yyerror("label '%s' not found", label);
exit(1);
}
print_path(path);
} }
print("%1data->emit_ir(node_%s);\n", label); print(");\n");
break; break;
} }
@ -903,18 +901,27 @@ static void emitemitters(Rule rules)
} }
r = rules; r = rules;
print("%Pemitter_t* const %Pemitters[] = {\n"); print("const struct %Pinstruction_data %Pinstruction_data[] = {\n");
k = 0;
while (r) while (r)
{ {
struct stringfragment* f = r->code.first; for (; k < r->ern; k++)
print("%1{ 0 }, /* %d */\n", k);
k++;
print("%1"); print("%1{ /* %d: %R */\n", r->ern, r);
if (f)
print("&%Pemitter_%d,", r->ern); print("%2\"%R\",\n", r);
print("%2");
if (r->code.first)
print("&%Pemitter_%d,\n", r->ern);
else else
print("NULL,"); print("NULL,\n");
print(" /* %R */\n", r);
print("%2%s,\n", r->is_fragment ? "true" : "false");
print("%1},\n");
r = r->link; r = r->link;
} }
print("};\n\n"); print("};\n\n");
@ -971,13 +978,6 @@ static void emitstring(Rule rules)
print("%1{ 0 },%1/* %d */\n", k); print("%1{ 0 },%1/* %d */\n", k);
print("%1{ %d },%1/* %d = %R */\n", r->cost, k++, r); print("%1{ %d },%1/* %d = %R */\n", r->cost, k++, r);
} }
print("};\n\nconst char *%Pstring[] = {\n");
for (k = 0, r = rules; r; r = r->link)
{
for (; k < r->ern; k++)
print("%1/* %d */%10,\n", k);
print("%1/* %d */%1\"%R\",\n", k++, r);
}
print("};\n\n"); print("};\n\n");
} }

View file

@ -20,7 +20,6 @@ typedef struct ir* NODEPTR_TYPE;
extern void* burm_label(struct ir* ir); extern void* burm_label(struct ir* ir);
extern int burm_rule(void* state, int goalnt); extern int burm_rule(void* state, int goalnt);
extern const char* burm_string[];
extern const short *burm_nts[]; extern const short *burm_nts[];
extern struct ir** burm_kids(struct ir* p, int eruleno, struct ir* kids[]); extern struct ir** burm_kids(struct ir* p, int eruleno, struct ir* kids[]);
extern void burm_trace(struct ir* p, int ruleno, int cost, int bestcost); extern void burm_trace(struct ir* p, int ruleno, int cost, int bestcost);
@ -34,7 +33,15 @@ struct burm_emitter_data
}; };
typedef void burm_emitter_t(struct ir* ir, struct burm_emitter_data* data); typedef void burm_emitter_t(struct ir* ir, struct burm_emitter_data* data);
extern burm_emitter_t* const burm_emitters[];
struct burm_instruction_data
{
const char* name;
burm_emitter_t* emitter;
bool is_fragment;
};
extern const struct burm_instruction_data burm_instruction_data[];
#endif #endif