@@ -40,12 +40,41 @@ void ir_consistency_check(void)
4040	IR_ASSERT (IR_ADD  +  1  ==  IR_SUB );
4141}
4242
43- static  bool  ir_check_use_list (const  ir_ctx  * ctx , ir_ref  from , ir_ref  to )
43+ typedef  struct  {
44+ 	ir_arena   * arena ;
45+ 	ir_bitset  * use_set ;
46+ 	ir_bitset  * input_set ;
47+ } ir_check_ctx ;
48+ 
49+ static  bool  ir_check_use_list (ir_check_ctx  * check_ctx , const  ir_ctx  * ctx , ir_ref  from , ir_ref  to )
4450{
4551	ir_ref  n , * p ;
4652	ir_use_list  * use_list  =  & ctx -> use_lists [from ];
4753
4854	n  =  use_list -> count ;
55+ 	if  (n  >  16 ) {
56+ 		/* Avoid quadratic complexity by maintaining a temporary bit-set */ 
57+ 		ir_bitset  set ;
58+ 
59+ 		if  (!check_ctx -> use_set  ||  !(set  =  check_ctx -> use_set [from ])) {
60+ 			if  (!check_ctx -> arena ) {
61+ 				check_ctx -> arena  =  ir_arena_create (sizeof (ir_arena ) + 
62+ 					ctx -> insns_count  *  sizeof (ir_bitset ) + 
63+ 					ir_bitset_len (ctx -> insns_count ) *  sizeof (ir_bitset_base_t ));
64+ 			}
65+ 			if  (!check_ctx -> use_set ) {
66+ 				check_ctx -> use_set  =  ir_arena_alloc (& check_ctx -> arena , ctx -> insns_count  *  sizeof (ir_bitset ));
67+ 				memset (check_ctx -> use_set , 0 , ctx -> insns_count  *  sizeof (ir_bitset ));
68+ 			}
69+ 			check_ctx -> use_set [from ] =  set  =  (ir_bitset )ir_arena_alloc (& check_ctx -> arena ,
70+ 				ir_bitset_len (ctx -> insns_count ) *  sizeof (ir_bitset_base_t ));
71+ 			memset (set , 0 , ir_bitset_len (ctx -> insns_count ) *  sizeof (ir_bitset_base_t ));
72+ 			for  (p  =  & ctx -> use_edges [use_list -> refs ]; n  >  0 ; p ++ , n -- ) {
73+ 				ir_bitset_incl (set , * p );
74+ 			}
75+ 		}
76+ 		return  ir_bitset_in (set , to );
77+ 	}
4978	for  (p  =  & ctx -> use_edges [use_list -> refs ]; n  >  0 ; p ++ , n -- ) {
5079		if  (* p  ==  to ) {
5180			return  1 ;
@@ -54,12 +83,35 @@ static bool ir_check_use_list(const ir_ctx *ctx, ir_ref from, ir_ref to)
5483	return  0 ;
5584}
5685
57- static  bool  ir_check_input_list (const  ir_ctx  * ctx , ir_ref  from , ir_ref  to )
86+ static  bool  ir_check_input_list (ir_check_ctx   * check_ctx ,  const  ir_ctx  * ctx , ir_ref  from , ir_ref  to )
5887{
5988	ir_insn  * insn  =  & ctx -> ir_base [to ];
6089	ir_ref  n , j , * p ;
6190
6291	n  =  ir_input_edges_count (ctx , insn );
92+ 	if  (n  >  16 ) {
93+ 		/* Avoid quadratic complexity by maintaining a temporary bit-set */ 
94+ 		ir_bitset  set ;
95+ 
96+ 		if  (!check_ctx -> input_set  ||  !(set  =  check_ctx -> input_set [to ])) {
97+ 			if  (!check_ctx -> arena ) {
98+ 				check_ctx -> arena  =  ir_arena_create (sizeof (ir_arena ) + 
99+ 					ctx -> insns_count  *  sizeof (ir_bitset ) + 
100+ 					ir_bitset_len (ctx -> insns_count ) *  sizeof (ir_bitset_base_t ));
101+ 			}
102+ 			if  (!check_ctx -> input_set ) {
103+ 				check_ctx -> input_set  =  ir_arena_alloc (& check_ctx -> arena , ctx -> insns_count  *  sizeof (ir_bitset ));
104+ 				memset (check_ctx -> input_set , 0 , ctx -> insns_count  *  sizeof (ir_bitset ));
105+ 			}
106+ 			check_ctx -> input_set [to ] =  set  =  (ir_bitset )ir_arena_alloc (& check_ctx -> arena ,
107+ 				ir_bitset_len (ctx -> insns_count ) *  sizeof (ir_bitset_base_t ));
108+ 			memset (set , 0 , ir_bitset_len (ctx -> insns_count ) *  sizeof (ir_bitset_base_t ));
109+ 			for  (j  =  1 , p  =  insn -> ops  +  1 ; j  <= n ; j ++ , p ++ ) {
110+ 				if  (* p  >  0 ) ir_bitset_incl (set , * p );
111+ 			}
112+ 		}
113+ 		return  ir_bitset_in (set , from );
114+ 	}
63115	for  (j  =  1 , p  =  insn -> ops  +  1 ; j  <= n ; j ++ , p ++ ) {
64116		if  (* p  ==  from ) {
65117			return  1 ;
@@ -93,6 +145,11 @@ bool ir_check(const ir_ctx *ctx)
93145	ir_type  type ;
94146	uint32_t  flags ;
95147	bool  ok  =  1 ;
148+ 	ir_check_ctx  check_ctx ;
149+ 
150+ 	check_ctx .arena  =  NULL ;
151+ 	check_ctx .use_set  =  NULL ;
152+ 	check_ctx .input_set  =  NULL ;
96153
97154	for  (i  =  IR_UNUSED  +  1 , insn  =  ctx -> ir_base  +  i ; i  <  ctx -> insns_count ;) {
98155		if  (insn -> op  >= IR_LAST_OP ) {
@@ -255,7 +312,7 @@ bool ir_check(const ir_ctx *ctx)
255312			}
256313			if  (ctx -> use_lists 
257314			 &&  use  >  0 
258- 			 &&  !ir_check_use_list (ctx , use , i )) {
315+ 			 &&  !ir_check_use_list (& check_ctx ,  ctx , use , i )) {
259316				fprintf (stderr , "ir_base[%d].ops[%d] is not in use list (%d)\n" , i , j , use );
260317				ok  =  0 ;
261318			}
@@ -313,7 +370,7 @@ bool ir_check(const ir_ctx *ctx)
313370
314371			for  (p  =  & ctx -> use_edges [use_list -> refs ]; n  >  0 ; p ++ , n -- ) {
315372				use  =  * p ;
316- 				if  (!ir_check_input_list (ctx , i , use )) {
373+ 				if  (!ir_check_input_list (& check_ctx ,  ctx , i , use )) {
317374					fprintf (stderr , "ir_base[%d] is in use list of ir_base[%d]\n" , use , i );
318375					ok  =  0 ;
319376				}
@@ -393,6 +450,10 @@ bool ir_check(const ir_ctx *ctx)
393450		insn  +=  n ;
394451	}
395452
453+ 	if  (check_ctx .arena ) {
454+ 		ir_arena_free (check_ctx .arena );
455+ 	}
456+ 
396457//	if (!ok) { 
397458//		ir_dump_codegen(ctx, stderr); 
398459//	} 
0 commit comments