Predicates work; we now have prefers and requires clauses. Predicates must be
authorDavid Given <dg@cowlark.com>
Sat, 1 Oct 2016 11:56:52 +0000 (13:56 +0200)
committerDavid Given <dg@cowlark.com>
Sat, 1 Oct 2016 11:56:52 +0000 (13:56 +0200)
functions. Not convinced that semantic types are actually working --- there are
still problems with earlier statements leaving things in the wrong registers.

mach/proto/mcg/hop.c
mach/proto/mcg/ir.h
mach/proto/mcg/mcgg_generated_header.h
mach/proto/mcg/pass_instructionselection.c
mach/proto/mcg/table
util/mcgg/gram.y
util/mcgg/iburg.c
util/mcgg/iburg.h
util/mcgg/scan.l

index 35bed38..a57d498 100644 (file)
@@ -89,6 +89,10 @@ void hop_print(char k, struct hop* hop)
                                                tracef(k, "%s", ir->u.bvalue->name);
                                                break;
 
+                                       case IR_LABEL:
+                                               tracef(k, "%s", ir->u.lvalue);
+                                               break;
+
                                        case IR_LOCAL:
                                        case IR_CONST:
                                                tracef(k, "0x%d", ir->u.ivalue);
index 069a76b..abf4a17 100644 (file)
@@ -20,6 +20,7 @@ struct ir
 
        void* state_label; /* used by the iburg instruction selector */
        int insn_no;       /* the table rule number for this instruction */
+       int goal_no;       /* the semantic type of this instruction; not stmt */
        ARRAYOF(struct hop) hops; /* only for root IRs */
 
        bool is_root : 1;
index a3e79af..b37fe8c 100644 (file)
@@ -20,3 +20,13 @@ static int OP_LABEL(struct ir* ir)
 
 extern void burm_panic_cannot_match(struct ir* ir);
 
+static bool burm_predicate_int(struct ir* ir)
+{
+       return ir->goal_no == 3;
+}
+
+static bool burm_predicate_float(struct ir* ir)
+{
+       return ir->goal_no == 5;
+}
+
index 2b0bb96..ea13ae5 100644 (file)
@@ -83,10 +83,13 @@ static void walk_instructions(struct ir* ir, int goal)
 
     ir->is_generated = true;
     ir->insn_no = insn_no;
+    if (goal != 1)
+        ir->goal_no = goal;
 
-    tracef('I', "I: $%d %s selected %s %d: %s\n",
+    tracef('I', "I: $%d %s goal %d selected %s %d: %s\n",
         ir->id,
         ir->is_root ? "S" : " ",
+        ir->goal_no,
         insndata->is_fragment ? "fragment" : "instruction",
         insn_no,
         insndata->name);
index 31e51cd..c88c68f 100644 (file)
@@ -61,13 +61,19 @@ PATTERNS
                emit "mov r0, %in"
                cost 4;
 
-       int = REG4 cost 1;
-       float = REG4 cost 1;
+       int = in:REG4
+               prefers int(in)
+               cost 1;
 
-       any = int cost 1;
-       int = any cost 1;
-       any = float cost 1;
-       float = any cost 1;
+       float = in:REG4
+               prefers float(in)
+               cost 1;
+
+       ret = in:any emit "mov %ret, %in" cost 1;
+       any = in:int emit "mov %any, %in" cost 1;
+       int = in:any emit "mov %int, %in" cost 1;
+       any = in:float emit "mov %any, %in" cost 1;
+       float = in:any emit "mov %float, %in" cost 1;
 
 
 /* Memory operations */
@@ -180,8 +186,12 @@ PATTERNS
                emit "adr %int, $value"
                cost 4;
 
-       any = value:CONST4
-               emit "ldr %any, address-containing-$value"
+       int = value:CONST4
+               emit "ldr %int, address-containing-$value"
+               cost 8;
+
+       float = value:CONST4
+               emit "vldr %float, address-containing-$value"
                cost 8;
 
 /* FPU operations */
index 94b1883..e65a625 100644 (file)
@@ -23,6 +23,7 @@ static int nextern = 1;
     struct reg* reg;
     struct stringlist* stringlist;
     struct terminfo terminfo;
+    struct expr* expr;
 }
 
 %term ALLOCATES
@@ -30,15 +31,13 @@ static int nextern = 1;
 %term DECLARATIONS
 %term EMIT
 %term FRAGMENT
-%term INS
-%term OUTS
 %term PATTERNS
 %term REGISTERS
-%term WHEN
+%term PREFERS
+%term REQUIRES
 
 %token <n>          INT
 %token <string>     ID
-%token <string>     CFRAGMENT
 %token <string>     QFRAGMENT
 
 %type  <nonterm>    allocates
@@ -50,6 +49,8 @@ static int nextern = 1;
 %type  <stringlist> qfragments
 %type  <terminfo>   terminfo
 %type  <tree>       rhs
+%type  <expr>       predicate
+%type  <expr>       predicate_args
 %%
 
 spec
@@ -100,7 +101,8 @@ patterns
 pattern
     : ID '=' rhs                      { nonterm($1, false); $$ = rule($1,     $3, nextern++); }
     | rhs                             {                     $$ = rule("stmt", $1, nextern++); }
-    | pattern WHEN cfragments         { $$ = $1; stringlist_addall(&$$->when, $3); }
+    | pattern PREFERS predicate       { $$ = $1; array_append(&$$->prefers, $3); }
+    | pattern REQUIRES predicate      { $$ = $1; array_append(&$$->requires, $3); }
     | emit                            { $$ = $1; }
     | pattern COST INT                { $$ = $1; $$->cost = $3; }
     ;
@@ -118,11 +120,6 @@ terminfo
     | ID ':' ID '.' ID                { $$.label = $1; $$.name = $3; $$.regattr = $5; }
     ;
 
-cfragments 
-    : /* nothing */                   { $$ = calloc(1, sizeof *$$); }
-    | cfragments CFRAGMENT            { $$ = $1; stringlist_add($$, $2); }
-    ;
-    
 emit
     : pattern EMIT qfragments           {
                                             $$ = $1;
@@ -137,6 +134,16 @@ qfragments
     | qfragments QFRAGMENT              { $$ = $1; stringlist_add($$, $2); }
     ;
 
+predicate
+    : ID '(' predicate_args ')'         { $$ = calloc(1, sizeof *$$); $$->name = $1; $$->next = $3; }
+    ;
+
+predicate_args
+    : /* nothing */
+    | ID                                { $$ = calloc(1, sizeof *$$); $$->name = $1; }
+    | ID ',' predicate_args             { $$ = calloc(1, sizeof *$$); $$->name = $1; $$->next = $3; }
+    ;
+
 %%
 #include <stdarg.h>
 #include <ctype.h>
@@ -157,6 +164,7 @@ void yyerror(char *fmt, ...) {
        if (fmt[strlen(fmt)-1] != '\n')
                 fprintf(stderr, "\n");
        errcnt++;
+    exit(1);
 }
 
 void yywarn(char *fmt, ...) {
index 70d4ab0..074198d 100644 (file)
@@ -598,7 +598,7 @@ static void emitcase(Term p, int ntnumber)
                        default:
                                assert(0);
                }
-               print("%d;\n", r->cost);
+               print("%d);\n", r->cost);
                emitrecord("\t\t\t", r, 0);
                print("%2}\n");
        }
@@ -859,27 +859,6 @@ static void emitrule(Nonterm nts)
        print("%1default:\n%2%Passert(0, PANIC(\"Bad goal nonterminal %%d in %Prule\\n\", goalnt));\n%1}\n%1return 0;\n}\n\n");
 }
 
-/* emitpredicates - emit predicates for rules */
-static void emitpredicatedefinitions(Rule r)
-{
-       while (r)
-       {
-               struct stringfragment* f = r->when.first;
-               if (f)
-               {
-                       print("/* %R */\n", r);
-                       print("static int %Ppredicate_%d(NODEPTR_TYPE n) {\n", r->ern);
-                       while (f)
-                       {
-                               print("%s", f->data);
-                               f = f->next;
-                       }
-                       print("\n}\n\n");
-               }
-               r = r->link;
-       }
-}
-
 static void print_path(uint32_t path)
 {
        int i = 0;
@@ -932,6 +911,50 @@ static void label_not_found(Rule rule, const char* label)
        exit(1);
 }
 
+/* emitpredicates - emit predicates for rules */
+static void emitpredicatedefinitions(Rule r)
+{
+       int i;
+
+       while (r)
+       {
+               print("/* %R */\n", r);
+               print("static int %Padjust_cost_%d(NODEPTR_TYPE node, int cost) {\n", r->ern);
+
+               for (i=0; i<r->prefers.count; i++)
+               {
+                       struct expr* p = r->prefers.item[i];
+                       bool first = true;
+
+                       print("%1if (%Ppredicate_%s(", p->name);
+
+                       p = p->next;
+                       while (p)
+                       {
+                               uint32_t path = find_label(r->pattern, p->name, 0, NULL);
+                               if (path == PATH_MISSING)
+                                       label_not_found(r, p->name);
+
+                               if (!first)
+                                       print(", ");
+                               else
+                                       first = false;
+
+                               print_path(path);
+                               p = p->next;
+                       }
+
+                       print(")) cost -= 1;\n");
+               }
+
+               print("%1if (cost > %d) return %d;\n", maxcost, maxcost);
+               print("%1if (cost < 1) return 1;\n");
+               print("%1return cost;\n");
+               print("}\n\n");
+               r = r->link;
+       }
+}
+
 /* emitinsndata - emit the code generation data */
 static void emitinsndata(Rule rules)
 {
@@ -1051,8 +1074,7 @@ static void emitinsndata(Rule rules)
 /* emitcost - emit a cost calculation via a predicate */
 static void emitcostcalc(Rule r)
 {
-       if (r->when.first)
-               print("!%Ppredicate_%d(node) ? %d : ", r->ern, maxcost);
+       print("%Padjust_cost_%d(node, ", r->ern);
 }
 
 /* emitstate - emit state function */
index 1a4211e..919f447 100644 (file)
@@ -2,6 +2,7 @@
 #define BURG_INCLUDED
 
 #include "stringlist.h"
+#include "array.h"
 
 extern char* stringf(char* fmt, ...);
 
@@ -15,6 +16,12 @@ typedef enum
 typedef struct rule* Rule;
 typedef struct term* Term;
 
+struct expr
+{
+       const char* name;
+       struct expr* next;
+};
+
 struct terminfo
 {
        const char* name;
@@ -90,7 +97,8 @@ struct rule
        Rule chain;              /* next chain rule with same rhs */
        Rule decode;             /* next rule with same lhs */
        Rule kids;               /* next rule with same burm_kids pattern */
-       struct stringlist when;  /* C predicate string */
+       ARRAYOF(struct predicate) prefers;  /* C predicates */
+       ARRAYOF(struct predicate) requires; /* C predicates */
        struct stringlist code;  /* compiler output code strings */
 };
 extern Rule rule(char* id, Tree pattern, int ern);
index 83e0fe3..30280c4 100644 (file)
@@ -12,41 +12,11 @@ static int braces = 0;
 %option yylineno
 %option debug
 
-%x CSTRING
 %x QSTRING
 %x COMMENT
 
 %%
 
-<INITIAL>"{"                {
-                                yylval.string = ""; //stringf("#line %d\n", yylineno);
-                                braces = 1;
-                                BEGIN(CSTRING);
-                                return CFRAGMENT;
-                            }
-
-<CSTRING>"{"                {
-                                braces++;
-                                yylval.string = strdup(yytext);
-                                return CFRAGMENT;
-                            }
-
-<CSTRING>"}"                {
-                                braces--;
-                                if (braces == 0)
-                                    BEGIN(INITIAL);
-                                else
-                                {
-                                    yylval.string = strdup(yytext);
-                                    return CFRAGMENT;
-                                }
-                            }
-
-<CSTRING>[^{}]+             {
-                                yylval.string = strdup(yytext);
-                                return CFRAGMENT;
-                            }
-
 <INITIAL>"\""               BEGIN(QSTRING);
 <QSTRING>"\""               BEGIN(INITIAL);
 
@@ -72,9 +42,8 @@ static int braces = 0;
 "cost"                      return COST;
 "emit"                      return EMIT;
 "fragment"                  return FRAGMENT;
-"ins"                       return INS;
-"outs"                      return OUTS;
-"when"                      return WHEN;
+"prefers"                   return PREFERS;
+"requires"                  return REQUIRES;
 
 "//"[^\n]*\n                ;