# HG changeset patch # User Leonard Ritter # Date 1730289357 -3600 # Wed Oct 30 12:55:57 2024 +0100 # Node ID 241e5727c46bc85509777cbe7e0d8d496e3a70c8 # Parent 0c796946ef40af3eed5d87a730084ec7038b6515 * NOIR: all integer operations are reduced if constant diff --git a/lib/scopes/compiler/noir/Builder.sc b/lib/scopes/compiler/noir/Builder.sc --- a/lib/scopes/compiler/noir/Builder.sc +++ b/lib/scopes/compiler/noir/Builder.sc @@ -177,6 +177,19 @@ '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) diff --git a/lib/scopes/compiler/noir/Index.sc b/lib/scopes/compiler/noir/Index.sc --- a/lib/scopes/compiler/noir/Index.sc +++ b/lib/scopes/compiler/noir/Index.sc @@ -332,6 +332,7 @@ 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 diff --git a/lib/scopes/compiler/noir/reduce.sc b/lib/scopes/compiler/noir/reduce.sc --- a/lib/scopes/compiler/noir/reduce.sc +++ b/lib/scopes/compiler/noir/reduce.sc @@ -119,6 +119,130 @@ 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 icmps + case 'sge + sf bf icmp>=s + case 'ult + uf bf icmpu + 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):" diff --git a/testing/noir/test.noir b/testing/noir/test.noir --- a/testing/noir/test.noir +++ b/testing/noir/test.noir @@ -123,49 +123,47 @@ ####################### -# - 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 @@ _ = _ ? call test_fib _ = _ ? call test_array_fill_iter _ = _ ? call test_comp_partial_update - #_ = _ ? call test4 + _ = _ ? call test4 return = pass 0