1- import TempNode from '../core/TempNode.js' ;
21import { addMethodChaining , Fn , nodeProxyIntent , uint } from '../tsl/TSLCore.js' ;
32import { bitcast } from './BitcastNode.js' ;
43import MathNode from './MathNode.js' ;
4+
5+ const registeredBitcountFunctions = { } ;
6+
57/**
68 * This node represents an operation that reinterprets the bit representation of a value
79 * in one type as a value in another type.
@@ -61,13 +63,10 @@ class BitcountNode extends MathNode {
6163
6264 }
6365
64- const inputType = this . getInputType ( ) ;
66+ const inputType = this . getInputType ( builder ) ;
6567 const elementType = builder . getElementType ( inputType ) ;
6668
67- const typeLength = builder . getTypeLength ( ) ;
68-
69- console . log ( inputType , elementType , typeLength ) ;
70-
69+ const typeLength = builder . getTypeLength ( inputType ) ;
7170
7271 if ( method === BitcountNode . COUNT_LEADING_ZEROS ) {
7372
@@ -80,79 +79,98 @@ class BitcountNode extends MathNode {
8079
8180 } else if ( method === BitcountNode . COUNT_ONE_BITS ) {
8281
83- const bitCountBase = Fn ( ( [ value ] ) => {
82+ const bitcountBaseMethod = `bitcount_base_ ${ elementType } ` ;
8483
85- const v = uint ( 0.0 ) ;
84+ let bitCountBaseFn = registeredBitcountFunctions [ bitcountBaseMethod ] ;
8685
87- if ( elementType === 'int' ) {
86+ if ( bitCountBaseFn === undefined ) {
8887
89- v . assign ( bitcast ( value , 'uint' ) ) ;
88+ bitCountBaseFn = Fn ( ( [ value ] ) => {
9089
91- }
90+ const v = uint ( 0.0 ) ;
9291
93- v . assign ( v . sub ( v . shiftRight ( uint ( 1 ) ) . bitAnd ( uint ( 0x55555555 ) ) ) ) ;
94- v . assign ( v . bitAnd ( uint ( 0x33333333 ) ) . add ( v . shiftRight ( uint ( 2 ) ) . bitAnd ( uint ( 0x33333333 ) ) ) ) ;
92+ if ( elementType === 'int' ) {
9593
96- return v . add ( v . shiftRight ( uint ( 4 ) ) ) . bitAnd ( uint ( 0xF0F0F0F ) ) . mul ( uint ( 0x1010101 ) ) . shiftRight ( uint ( 24 ) ) ;
94+ v . assign ( bitcast ( value , ' uint' ) ) ;
9795
98- } ) . setLayout ( {
99- name : `bitcount_${ elementType } ` ,
100- type : 'uint' ,
101- inputs : [
102- { name : 'value' , type : elementType }
103- ]
104- } ) ;
96+ } else {
10597
98+ v . assign ( value ) ;
10699
107- const bitCountFn = Fn ( ( [ value ] ) => {
100+ }
108101
109- const v = uint ( 0.0 ) ;
102+ v . assign ( v . sub ( v . shiftRight ( uint ( 1 ) ) . bitAnd ( uint ( 0x55555555 ) ) ) ) ;
103+ v . assign ( v . bitAnd ( uint ( 0x33333333 ) ) . add ( v . shiftRight ( uint ( 2 ) ) . bitAnd ( uint ( 0x33333333 ) ) ) ) ;
110104
111- if ( typeLength === 1 ) {
105+ return v . add ( v . shiftRight ( uint ( 4 ) ) ) . bitAnd ( uint ( 0xF0F0F0F ) ) . mul ( uint ( 0x1010101 ) ) . shiftRight ( uint ( 24 ) ) ;
112106
113- v . addAssign ( bitCountBase ( value ) ) ;
107+ } ) . setLayout ( {
108+ name : bitcountBaseMethod ,
109+ type : 'uint' ,
110+ inputs : [
111+ { name : 'value' , type : elementType }
112+ ]
113+ } ) ;
114114
115- } else {
116115
117- const components = [ 'x' , 'y' , 'z' , 'w' ] ;
116+ registeredBitcountFunctions [ bitcountBaseMethod ] = bitCountBaseFn ;
118117
119- for ( let i = 0 ; i < typeLength ; i ++ ) {
118+ }
120119
121- const component = components [ i ] ;
120+ const bitCountMethod = `bitcount_ ${ inputType } ` ;
122121
123- v . addAssign ( bitCountBase ( value [ component ] ) ) ;
122+ let bitCountFn = registeredBitcountFunctions [ bitCountMethod ] ;
124123
125- }
124+ if ( bitCountFn === undefined ) {
126125
127- }
126+ bitCountFn = Fn ( ( [ value ] ) => {
128127
129- return v ;
128+ const v = uint ( 0.0 ) ;
130129
131- } ) . setLayout ( {
132- name : `bitcount_main_${ this . nodeType } ` ,
133- type : 'uint' ,
134- inputs : [
135- { name : 'value' , type : inputType }
136- ]
137- } ) ;
130+ if ( typeLength === 1 ) {
138131
139- console . log ( 'test' ) ;
132+ v . addAssign ( bitCountBaseFn ( value ) ) ;
140133
141- const exec = bitCountFn ( aNode ) . toVar ( 'testVar' ) ;
134+ } else {
142135
143- return exec ;
136+ const components = [ 'x' , 'y' , 'z' , 'w' ] ;
144137
145- }
138+ for ( let i = 0 ; i < typeLength ; i ++ ) {
146139
147- }
140+ const component = components [ i ] ;
148141
149- generate ( builder ) {
142+ v . addAssign ( bitCountBaseFn ( value [ component ] ) ) ;
150143
151- this . method += 'test' ;
144+ }
152145
153- super . generate ( builder ) ;
146+ }
154147
148+ return v ;
155149
150+ } ) . setLayout ( {
151+ name : bitCountMethod ,
152+ type : 'uint' ,
153+ inputs : [
154+ { name : 'value' , type : inputType }
155+ ]
156+ } ) ;
157+
158+ registeredBitcountFunctions [ bitCountMethod ] = bitCountFn ;
159+
160+
161+ }
162+
163+ const methodFn = Fn ( ( ) => {
164+
165+ return bitCountFn (
166+ aNode ,
167+ ) ;
168+
169+ } ) ;
170+
171+ return methodFn ( ) ;
172+
173+ }
156174
157175 }
158176
0 commit comments