241e5727c46b — Leonard Ritter 7 months ago
* NOIR: all integer operations are reduced if constant
M lib/scopes/compiler/noir/Builder.sc +13 -0
@@ 177,6 177,19 @@ struct Builder
             'set self._cache H id
             id
 
+    fn intern-byte-data (self ptr sz)
+        H := uhash.from-bytes ptr sz
+        try
+            copy ('get self._cache H)
+        else
+            local data : Module.ConstDataType
+            'resize-noinit data sz
+            dstptr := 'data data
+            arcmemcopyn (dstptr as ~rawstring) (ptr as rawstring) sz
+            id := self._module.const data
+            'set self._cache H id
+            id
+
     inline interned-symbol (self blob)
         H := uhash.from-bytes ('data blob)
         copy ('get self._cache H)

          
M lib/scopes/compiler/noir/Index.sc +1 -0
@@ 332,6 332,7 @@ struct ProcSchema
         case Module.Id.ConstEmpty (id) (id as usize)
         case Module.Id.ConstUndef (id) (id as usize)
         case Module.Id.ConstNull (id) (id as usize * INTPTRSIZE)
+        case Module.Id.ProcMap (id) 0:usize
         default
             report id
             assert false

          
M lib/scopes/compiler/noir/reduce.sc +124 -0
@@ 119,6 119,130 @@ struct Reduce
                                 continue;
 
                     switch row.op
+                    pass 'iadd
+                    pass 'isub
+                    pass 'imul
+                    pass 'sdiv
+                    pass 'udiv
+                    pass 'srem
+                    pass 'urem
+                    pass 'iand
+                    pass 'ior
+                    pass 'ixor
+                    pass 'ishl
+                    pass 'sshr
+                    pass 'ushr
+                    pass 'ieq
+                    pass 'ine
+                    pass 'slt
+                    pass 'sle
+                    pass 'sgt
+                    pass 'sge
+                    pass 'ult
+                    pass 'ule
+                    pass 'ugt
+                    pass 'uge
+                    do
+                        a := getarg 0 Const
+                        b := getarg 1 Const
+                        aptr asz := 'data ('constof builder a)
+                        bptr bsz := 'data ('constof builder b)
+                        if (asz != bsz)
+                            continue;
+                        if (asz > 16)
+                            continue;
+                        ptr := alloca-array u8 asz
+                        f := inline "#hidden" (T op)
+                            (@ (ptr as ~@T)) = op (@ (aptr as @T)) (@ (bptr as @T))
+                            asz
+                        bf := inline "#hidden" (T op)
+                            (@ (ptr as ~@bool)) = op (@ (aptr as @T)) (@ (bptr as @T))
+                            1:usize
+                        sf := inline "#hidden" (f ...)
+                            switch asz
+                            case 1
+                                f i8 ...
+                            case 2
+                                f i16 ...
+                            case 4
+                                f i32 ...
+                            case 8
+                                f i64 ...
+                            case 16
+                                f i128 ...
+                            default
+                                continue;
+                        uf := inline "#hidden" (f ...)
+                            switch asz
+                            case 1
+                                f u8 ...
+                            case 2
+                                f u16 ...
+                            case 4
+                                f u32 ...
+                            case 8
+                                f u64 ...
+                            case 16
+                                f u128 ...
+                            default
+                                continue;
+                        csz := switch row.op
+                        case 'iadd
+                            uf f add
+                        case 'isub
+                            uf f sub
+                        case 'imul
+                            uf f mul
+                        case 'sdiv
+                            sf f sdiv
+                        case 'udiv
+                            uf f udiv
+                        case 'srem
+                            sf f srem
+                        case 'urem
+                            uf f urem
+                        case 'iand
+                            uf f band
+                        case 'ior
+                            uf f bor
+                        case 'ixor
+                            uf f bxor
+                        case 'ishl
+                            uf f shl
+                        case 'sshr
+                            uf f ashr
+                        case 'ushr
+                            uf f lshr
+                        case 'ieq
+                            uf bf icmp==
+                        case 'ine
+                            uf bf icmp!=
+                        case 'slt
+                            sf bf icmp<s
+                        case 'sle
+                            sf bf icmp<=s
+                        case 'sgt
+                            sf bf icmp>s
+                        case 'sge
+                            sf bf icmp>=s
+                        case 'ult
+                            uf bf icmp<u
+                        case 'ule
+                            uf bf icmp<=u
+                        case 'ugt
+                            uf bf icmp>u
+                        case 'uge
+                            uf bf icmp>=u
+                        default
+                            continue;
+                        updates += 1
+                        value := 'intern-byte-data builder ptr csz
+                        row := getrow& ()
+                        if (empty? row.deps)
+                            row.op = Operation.ALIAS
+                        else
+                            row.op = Operation.pass
+                        row.operands = typeinit value
                     case 'TRACE # ...
                         if (prev_updates != updates)
                             print2 "trace (2):"

          
M testing/noir/test.noir +36 -38
@@ 123,49 123,47 @@ test_comp_partial_update = export 'test_
 
 #######################
 
-#
-    INT = 0
+INT = 0
 
-    gen-int-type = proc bitcount signed? :
-        kind = INT
+gen-int-type = proc bitcount signed? :
+    kind = INT
 
-    type-s32 = gen-int-type 32 true
-    type-s64 = gen-int-type 64 true
+type-s32 = gen-int-type 32 true
+type-s64 = gen-int-type 64 true
 
-    type-u32 = gen-int-type 32 false
-    type-u64 = gen-int-type 64 false
+type-u32 = gen-int-type 32 false
+type-u64 = gen-int-type 64 false
 
-    proc+ gen-int-type
-        __+ = proc A B :
-            _ok = iand
-                ieq A.kind INT
-                ieq B.kind INT
-            _ok = iand _ok
-                ieq A.bitcount B.bitcount
-            _signed? = iand A.signed? B.signed?
-            apply = proc a b :
-                type = gen-int-type A.bitcount _signed?
-                value = iadd a.value b.value
+proc+ gen-int-type
+    __+ = proc A B :
+        _ok = iand
+            ieq A.kind INT
+            ieq B.kind INT
+        _ok = iand _ok
+            ieq A.bitcount B.bitcount
+        _signed? = iand A.signed? B.signed?
+        apply = proc a b :
+            type = gen-int-type A.bitcount _signed?
+            value = iadd a.value b.value
 
-    type:i32 = proc value :
-        type = type-s32
-    type:u32 = proc value :
-        type = type-u32
++ = proc a b :
+    f = a.type.__+ a.type b.type
+    v = f.apply a b
+    type = v.type
+    value = v.value
 
-    + = proc a b :
-        f = a.type.__+ a.type b.type
-        v = f.apply a b
-        type = v.type
-        value = v.value
-
-    test4 = export 'test4
-        fntype auto void
-        proc :
-            a = 137:u32
-            b = -1
-            c = + a b
-            _ = pcall printf_ printf "computing:\n"
-            _ = _ ? pcall printf_s32_s32_s32 printf "%i + %i = %i\n" a.value b.value c.value
+test4 = export 'test4
+    fntype auto void
+    proc :
+        type:i32 = proc value :
+            type = type-s32
+        type:u32 = proc value :
+            type = type-u32
+        a = 137:u32
+        b = -1
+        c = + a b
+        _ = pcall printf_ printf "computing:\n"
+        _ = _ ? pcall printf_s32_s32_s32 printf "%i + %i = %i\n" a.value b.value c.value
 
 export 'main
     fntype auto s32 s32 ptr

          
@@ 174,6 172,6 @@ export 'main
         _ = _ ? call test_fib
         _ = _ ? call test_array_fill_iter
         _ = _ ? call test_comp_partial_update
-        #_ = _ ? call test4
+        _ = _ ? call test4
 
         return = pass 0