Write a powerpc.descr for ego and use it with osxppc.
authorGeorge Koehler <xkernigh@netscape.net>
Wed, 30 Nov 2016 20:29:19 +0000 (15:29 -0500)
committerGeorge Koehler <xkernigh@netscape.net>
Wed, 30 Nov 2016 20:29:19 +0000 (15:29 -0500)
No change to linuxppc and qemuppc.  They continue to run ego without
any descr file.

I copied m68020.descr to powerpc.descr and changed some numbers.  My
numbers are guesses; I know little about PowerPC cycle counts, and
almost nothing about ego.  This powerpc.descr causes most of the
example programs to shrink in size (without descr -> with descr):

  65429 -> 57237  hilo_b.osxppc        -8192
  36516 -> 32420  hilo_c.osxppc        -4096
  55782 -> 51686  hilo_mod.osxppc      -4096
  20096 -> 20096  hilo_p.osxppc            0
   8813 ->  8813  mandelbrot_c.osxppc      0
  93355 -> 89259  paranoia_c.osxppc    -4096
  92751 -> 84559  startrek_c.osxppc    -8192

(Each file has 2 Mach segments, then a symbol table.  Each segment
takes a multiple of 4096 bytes.  When the code shrinks, we lose a
multiple of 4096 bytes.)

I used "ack -mosxppc -O6 -c.so" to examine the assembly code for
hilo.mod and mandelbrot.c, both without and with descr.  This reveals
optimizations made only with descr, from 2 ego phases: SP (stack
pollution) and RA (register allocation).  In hilo.mod, SP deletes some
instructions that remove items from the stack.  These items get
removed when the function returns.  In both hilo.mod and mandelbrot.c,
RA moves some values into local variables, so ncg can make them into
register variables.  This shrinks code size, probably because register
variables get preserved across function calls.  More values stay in
registers, and ncg emits shorter code.

I believe that the ego descr file uses (time,space) tuples but the ncg
table uses (space,time) tuples.  This is confusing.  Perhaps I am
wrong, and some or all tuples are backwards.  My time values are the
cycle counts in latency from the MPC7450 Reference Manual (but not
including complications like "store serialization").

In powerpc.descr, I give the cost for saving and restoring registers
as if I was using chains of stw and lwz instructions.  Actually ncg
uses single stmw and lmw instructions with at least 2 instructions.
The (time,space) for stmw and lmw would be much less than the
(time,space) for chains of stw and lwz.  But this ignores the pipeline
of the MPC7450.  The chains of stw and lwz may run faster than stmw
and lmw in the pipeline, because the throughput may be better than the
latency.  By using the wrong values for (time,space), I'm trying to
tell ego that stmw and lmw are not better than chains of stw and lwz.

plat/osxppc/descr
util/ego/descr/build.lua
util/ego/descr/powerpc.descr [new file with mode: 0644]

index 2a6d478..1aa6159 100644 (file)
@@ -20,7 +20,7 @@ var PLATFORMDIR={EM}/share/ack/{PLATFORM}
 var CPP_F=-D__unix
 var ALIGN=-a0:4 -a1:4 -a2:4096 -a3:4 -b0:0x129c
 var MACHOPT_F=-m3
-var EGO_PLAT_FLAGS=-M{EM}/share/ack/ego/{ARCH}.descr
+var EGO_PLAT_FLAGS=-M{EM}/share/ack/ego/{ARCH}.descr
 
 # Override the setting in fe so that files compiled for osxppc can see
 # the platform-specific headers.
index 034ffa3..e9a008c 100644 (file)
@@ -22,6 +22,7 @@ end
 build_descr("i386")
 build_descr("i86")
 build_descr("m68020")
+build_descr("powerpc")
 
 installable {
        name = "pkg",
diff --git a/util/ego/descr/powerpc.descr b/util/ego/descr/powerpc.descr
new file mode 100644 (file)
index 0000000..5138cc4
--- /dev/null
@@ -0,0 +1,118 @@
+wordsize: 4
+pointersize: 4
+%%RA
+general registers: 19
+address registers: 0
+floating point registers: 0
+use general as pointer: yes
+
+register score parameters:
+       local variable:
+               (2 cases)
+               pointer,general
+                       (1 size)
+                       default ->      (3,4)
+               general,general
+                       (1 size)
+                       default ->      (3,4)
+       address of local variable:
+               (2 cases)
+               pointer,general
+                       (1 size)
+                       default ->      (0,0)
+               general,general
+                       (1 size)
+                       default ->      (0,0)
+       constant:
+               (2 sizes)
+               fitbyte ->      (-1,-1)
+               default ->      (-1,-1)
+       double constant:
+               (1 size)
+               default ->      (-1,-1)
+       address of global variable:
+               (1 size)
+               default ->      (2,8)
+       address of procedure:
+               (1 size)
+               default ->      (-1,-1)
+
+opening cost parameters:
+       local variable:
+               (2 cases)
+               pointer
+                       (1 size)
+                       default ->      (3,4)
+               general
+                       (1 size)
+                       default ->      (3,4)
+       address of local variable:
+               (2 cases)
+               pointer
+                       (1 size)
+                       default ->      (1,4)
+               general
+                       (1 size)
+                       general ->      (1,4)
+       constant:
+               (2 sizes)
+               fitbyte ->      (1000,1000)
+               default ->      (1000,1000)
+       double constant:
+               (1 size)
+               default ->      (1000,1000)
+       address of global variable:
+               (1 size)
+               default ->      (2,8)
+       address of procedure:
+               (1 size)
+               default ->      (1000,1000)
+
+register save costs:
+       (21 cases)
+       0 -> (0,0)
+       1 -> (6,8)
+       2 -> (12,16)
+       3 -> (18,24)
+       4 -> (24,32)
+       5 -> (30,40)
+       6 -> (36,48)
+       7 -> (42,56)
+       8 -> (48,64)
+       9 -> (54,72)
+       10 -> (60,80)
+       11 -> (66,88)
+       12 -> (72,96)
+       13 -> (78,104)
+       14 -> (84,112)
+       15 -> (90,120)
+       16 -> (96,128)
+       17 -> (102,136)
+       18 -> (108,144)
+       19 -> (114,152)
+       0 -> (0,0)
+%%UD
+access costs of global variables:
+       (1 size)
+       default ->      (5,12)
+access costs of local variables:
+       (1 size)
+       default ->      (3,4)
+%%SR
+overflow harmful?:  no
+array bound harmful?:  yes
+reduce sli if shift count larger than:  0
+%%CS
+#include "em_mnem.h"
+first time then space:
+addressing modes: op_ads op_adp op_lof op_ldf op_loi op_dch op_lpb -1
+                 op_ads op_adp op_lof op_ldf op_loi op_dch op_lpb -1
+cheap operations: op_cii op_ciu op_cui op_cuu op_cmi op_cmu op_cmp -1 
+                 op_cii op_ciu op_cui op_cuu op_cmi op_cmu op_cmp -1
+lexical tresholds: 1 1
+indirection limit: 8
+do not eliminate sli if index on shiftcounts:  -1
+                                               -1
+forbidden operators: -1 -1
+%%SP
+global stack pollution allowed?: yes