We're going to need some type inference after all, I think. Let's do a little
authorDavid Given <dg@cowlark.com>
Sat, 1 Oct 2016 17:10:22 +0000 (19:10 +0200)
committerDavid Given <dg@cowlark.com>
Sat, 1 Oct 2016 17:10:22 +0000 (19:10 +0200)
for now and see how it goes.

mach/proto/mcg/mcg.h
mach/proto/mcg/pass_promotefloatops.c [new file with mode: 0644]
mach/proto/mcg/procedure.c
mach/proto/mcg/table
util/mcgg/ir.dat

index 277bc6c..ddd33ae 100644 (file)
@@ -124,6 +124,7 @@ 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_promote_float_ops(struct procedure* proc);
 
 extern void procedure_compile(struct procedure* proc);
 
diff --git a/mach/proto/mcg/pass_promotefloatops.c b/mach/proto/mcg/pass_promotefloatops.c
new file mode 100644 (file)
index 0000000..478143b
--- /dev/null
@@ -0,0 +1,100 @@
+#include "mcg.h"
+
+static ARRAYOF(struct ir) pending;
+static ARRAYOF(struct ir) promotable;
+
+static void addall(struct ir* ir)
+{
+    if (array_appendu(&pending, ir))
+        return;
+
+    if (ir->left)
+        addall(ir->left);
+    if (ir->right)
+        addall(ir->right);
+}
+
+static void collect_irs(struct procedure* proc)
+{
+    int i;
+    
+    pending.count = 0;
+    promotable.count = 0;
+       for (i=0; i<proc->blocks.count; i++)
+    {
+        struct basicblock* bb = proc->blocks.item[i];
+        int j;
+
+        for (j=0; j<bb->irs.count; j++)
+            addall(bb->irs.item[j]);
+    }
+}
+
+static void promote(struct ir* ir)
+{
+    switch (ir->opcode)
+    {
+        case IR_CONST:
+        case IR_POP:
+        case IR_LOAD:
+            array_appendu(&promotable, ir);
+            break;
+
+        case IR_PHI:
+            if (!array_appendu(&promotable, ir))
+            {
+                if (ir->left)
+                    promote(ir->left);
+                if (ir->right)
+                    promote(ir->right);
+            }
+            break;
+    }
+}
+
+static void search_for_promotable_irs(void)
+{
+    int i;
+
+    for (i=0; i<pending.count; i++)
+    {
+        struct ir* ir = pending.item[i];
+
+        switch (ir->opcode)
+        {
+            case IR_ADDF:
+            case IR_SUBF:
+            case IR_MULF:
+            case IR_DIVF:
+            case IR_NEGF:
+                if (ir->left)
+                    promote(ir->left);
+                if (ir->right)
+                    promote(ir->right);
+                break;
+        }
+    }
+}
+
+static void modify_promotable_irs(void)
+{
+    int i;
+
+    for (i=0; i<promotable.count; i++)
+    {
+        struct ir* ir = promotable.item[i];
+        
+        if (ir->opcode != IR_PHI)
+            ir->opcode++;
+    }
+}
+
+void pass_promote_float_ops(struct procedure* proc)
+{
+       collect_irs(proc);
+    search_for_promotable_irs();
+    modify_promotable_irs();
+}
+
+/* vim: set sw=4 ts=4 expandtab : */
+
index a27aeed..300882e 100644 (file)
@@ -29,6 +29,7 @@ void procedure_compile(struct procedure* proc)
     pass_eliminate_trivial_blocks(proc);
     pass_remove_dead_blocks(proc);
     pass_convert_stack_ops(proc);
+    pass_promote_float_ops(proc);
 
     print_blocks('2', proc);
 
index c88c68f..59272c4 100644 (file)
@@ -190,7 +190,7 @@ PATTERNS
                emit "ldr %int, address-containing-$value"
                cost 8;
 
-       float = value:CONST4
+       float = value:CONSTF4
                emit "vldr %float, address-containing-$value"
                cost 8;
 
index 3dd785b..b12cf89 100644 (file)
@@ -3,7 +3,8 @@
 #   V: has no size (use in JUMP, CJUMP, RET forms)
 
 # Simple terminals
-S CONST
+S CONST # must be followed by float form
+S CONSTF
 S REG
 S LABEL
 S BLOCK
@@ -14,10 +15,12 @@ S PHI
 
 # Magic stack operations
 S PUSH
-S POP
+S POP # must be followed by float form
+S POPF
 
 #... Memory operations
-S LOAD
+S LOAD # must be followed by float form
+S LOADF
 S STORE
 
 # Arithemetic operations