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
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,
burm_string[ruleno], cost, bestcost);
insndata->name, cost, bestcost);
}
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];
int ruleno = burm_rule(ir->state_label, goal);
const struct burm_instruction_data* insndata = &burm_instruction_data[ruleno];
const short* nts = burm_nts[ruleno];
int i;
@ -48,7 +50,11 @@ static void queue_instructions(struct ir* ir, int goal)
for (i=0; nts[i]; 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)

View file

@ -43,21 +43,25 @@ PATTERNS
emit "ldrb %reg, %addr"
cost 4;
reg = CII14(CIU41(CIU14(LOAD1(addr:address))))
emit "ldrsb %reg, %addr"
cost 4;
/* Locals */
reg = in:LOCAL4
emit "add %reg, fp, #%in"
emit "add %reg, fp, #$in"
cost 4;
address = in:LOCAL4
fragment "[fp, #%in]";
fragment "[fp, #$in]";
/* Memory addressing modes */
address = ADD4(addr:reg, offset:CONST)
fragment "[%addr, #%offset]";
fragment "[%addr, #$offset]";
address = addr:reg
fragment "[%addr]";
@ -66,12 +70,12 @@ PATTERNS
/* Branches */
JUMP(addr:BLOCK4)
emit "b %addr"
emit "b $addr"
cost 4;
CJUMPEQ(value:tristate, PAIR(true:BLOCK4, false:BLOCK4))
emit "beq %true"
emit "bne %false"
emit "beq $true"
emit "bne $false"
cost 8;
@ -111,7 +115,7 @@ PATTERNS
cost 4;
aluparam = value:CONST4
fragment "#%value.ivalue";
fragment "#$value";
aluparam = reg;
@ -120,13 +124,13 @@ PATTERNS
cost 4;
reg = value:LABEL4
emit "adr %reg, %value"
emit "adr %reg, $value"
cost 4;
reg = value:BLOCK4
emit "adr %reg, %value"
emit "adr %reg, $value"
cost 4;
reg = value:CONST4
emit "ldr %reg, #value"
emit "ldr %reg, #$value"
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 emitrule(Nonterm nts);
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 emitstring(Rule rules);
static void emitstruct(Nonterm nts, int ntnumber);
@ -135,7 +135,7 @@ int main(int argc, char* argv[])
emitrule(nts);
emitclosure(nts);
emitpredicatedefinitions(rules);
emitemitters(rules);
emitinsndata(rules);
if (start)
emitstate(terms, start, ntnumber);
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;
uint32_t p = path;
print("%1NODEPTR_TYPE node_%s = ", tree->label);
while (p > 0)
switch (path % 3)
{
switch (p % 3)
{
case 1: print("LEFT_CHILD("); break;
case 2: print("RIGHT_CHILD("); break;
}
p /= 3;
i++;
case 1: print("LEFT_CHILD("); break;
case 2: print("RIGHT_CHILD("); break;
}
print("node");
while (i > 0)
{
print(")");
i--;
}
print(";\n");
path /= 3;
i++;
}
if (tree->left)
emittreefetchers(path*3 + 1, tree->left);
if (tree->right)
emittreefetchers(path*3 + 2, tree->right);
print("node");
while (i > 0)
{
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))
return root;
return path;
t = NULL;
if (root->left && !t)
t = find_label(root->left, name);
if (root->right && !t)
t = find_label(root->right, name);
return t;
p = PATH_MISSING;
if (root->left && (p == PATH_MISSING))
p = find_label(root->left, name, path*3 + 1);
if (root->right && (p == PATH_MISSING))
p = find_label(root->right, name, path*3 + 2);
return p;
}
/* emitemitters - emit the code generation routines */
static void emitemitters(Rule rules)
/* emitinsndata - emit the code generation data */
static void emitinsndata(Rule rules)
{
int k;
Rule r;
r = rules;
@ -863,8 +855,6 @@ static void emitemitters(Rule rules)
{
print("/* %R */\n", r);
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)
{
@ -873,14 +863,22 @@ static void emitemitters(Rule rules)
case '%':
{
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;
yyerror("label '%s' not found", label);
exit(1);
uint32_t path = find_label(r->pattern, label, 0);
if (path == PATH_MISSING)
{
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;
}
@ -903,18 +901,27 @@ static void emitemitters(Rule rules)
}
r = rules;
print("%Pemitter_t* const %Pemitters[] = {\n");
print("const struct %Pinstruction_data %Pinstruction_data[] = {\n");
k = 0;
while (r)
{
struct stringfragment* f = r->code.first;
for (; k < r->ern; k++)
print("%1{ 0 }, /* %d */\n", k);
k++;
print("%1");
if (f)
print("&%Pemitter_%d,", r->ern);
print("%1{ /* %d: %R */\n", r->ern, r);
print("%2\"%R\",\n", r);
print("%2");
if (r->code.first)
print("&%Pemitter_%d,\n", r->ern);
else
print("NULL,");
print(" /* %R */\n", r);
print("NULL,\n");
print("%2%s,\n", r->is_fragment ? "true" : "false");
print("%1},\n");
r = r->link;
}
print("};\n\n");
@ -971,13 +978,6 @@ static void emitstring(Rule rules)
print("%1{ 0 },%1/* %d */\n", k);
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");
}

View file

@ -20,7 +20,6 @@ typedef struct ir* NODEPTR_TYPE;
extern void* burm_label(struct ir* ir);
extern int burm_rule(void* state, int goalnt);
extern const char* burm_string[];
extern const short *burm_nts[];
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);
@ -34,7 +33,15 @@ struct burm_emitter_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