@@ -554,13 +554,62 @@ def _add_to_adjacency_list(self, src_node_ptr, tgt_node_ptr):
554554        adj_cap_ptr  =  self .builder .gep (src_node_ptr , [ir .Constant (self .int_type , 0 ), ir .Constant (self .int_type , 5 )])
555555
556556        current_count  =  self .builder .load (adj_count_ptr )
557-         current_capacity  =  self .builder .load (adj_cap_ptr )
557+         tgt_node_name_ptr  =  self .builder .gep (tgt_node_ptr , [ir .Constant (self .int_type , 0 ), ir .Constant (self .int_type , 1 )])
558+         tgt_node_name  =  self .builder .load (tgt_node_name_ptr )
559+         tgt_node_name_len_ptr  =  self .builder .gep (tgt_node_ptr , [ir .Constant (self .int_type , 0 ), ir .Constant (self .int_type , 2 )])
560+         tgt_node_name_len  =  self .builder .load (tgt_node_name_len_ptr )
558561
559-         needs_resize  =  self .builder .icmp_signed ('>=' , current_count , current_capacity )
562+         adj_list_void  =  self .builder .load (adj_list_ptr )
563+         adj_list_exists  =  self .builder .icmp_signed ('!=' , adj_list_void , ir .Constant (self .void_ptr , None ))
564+ 
565+         check_duplicates_block  =  self .builder .block .parent .append_basic_block (name = "check_duplicates" )
566+         proceed_add_block  =  self .builder .block .parent .append_basic_block (name = "proceed_add" )
567+         self .builder .cbranch (adj_list_exists , check_duplicates_block , proceed_add_block )
568+ 
569+         self .builder .position_at_end (check_duplicates_block )
570+         adj_list_typed  =  self .builder .bitcast (adj_list_void , self .node_type .as_pointer ().as_pointer ())
571+         dup_i  =  self .builder .alloca (self .int_type , name = "dup_check_i" )
572+         self .builder .store (ir .Constant (self .int_type , 0 ), dup_i )
573+ 
574+         dup_loop_block  =  self .builder .block .parent .append_basic_block (name = "dup_check_loop" )
575+         dup_check_block  =  self .builder .block .parent .append_basic_block (name = "dup_check_node" )
576+         dup_next_block  =  self .builder .block .parent .append_basic_block (name = "dup_next" )
577+         self .builder .branch (dup_loop_block )
578+ 
579+         self .builder .position_at_end (dup_loop_block )
580+         dup_i_val  =  self .builder .load (dup_i )
581+         current_count_loop  =  self .builder .load (adj_count_ptr )
582+         dup_loop_condition  =  self .builder .icmp_signed ('<' , dup_i_val , current_count_loop )
583+         self .builder .cbranch (dup_loop_condition , dup_check_block , proceed_add_block )
584+ 
585+         self .builder .position_at_end (dup_check_block )
586+         existing_node_ptr  =  self .builder .gep (adj_list_typed , [dup_i_val ])
587+         existing_node  =  self .builder .load (existing_node_ptr )
588+         existing_name_ptr  =  self .builder .gep (existing_node , [ir .Constant (self .int_type , 0 ), ir .Constant (self .int_type , 1 )])
589+         existing_name  =  self .builder .load (existing_name_ptr )
590+         existing_name_len_ptr  =  self .builder .gep (existing_node , [ir .Constant (self .int_type , 0 ), ir .Constant (self .int_type , 2 )])
591+         existing_name_len  =  self .builder .load (existing_name_len_ptr )
592+ 
593+         len_match  =  self .builder .icmp_signed ('==' , existing_name_len , tgt_node_name_len )
594+         dup_content_check_block  =  self .builder .block .parent .append_basic_block (name = "dup_content_check" )
595+         self .builder .cbranch (len_match , dup_content_check_block , dup_next_block )
596+ 
597+         self .builder .position_at_end (dup_content_check_block )
598+         names_match  =  self ._compare_strings (existing_name , tgt_node_name , tgt_node_name_len )
599+         self .builder .cbranch (names_match , proceed_add_block , dup_next_block )
600+ 
601+         self .builder .position_at_end (dup_next_block )
602+         next_dup_i  =  self .builder .add (dup_i_val , ir .Constant (self .int_type , 1 ))
603+         self .builder .store (next_dup_i , dup_i )
604+         self .builder .branch (dup_loop_block )
605+ 
606+         self .builder .position_at_end (proceed_add_block )
607+         current_capacity  =  self .builder .load (adj_cap_ptr )
608+         current_count_final  =  self .builder .load (adj_count_ptr )
609+         needs_resize  =  self .builder .icmp_signed ('>=' , current_count_final , current_capacity )
560610
561611        resize_adj_block  =  self .builder .block .parent .append_basic_block (name = "resize_adj" )
562612        add_adj_block  =  self .builder .block .parent .append_basic_block (name = "add_adj" )
563- 
564613        self .builder .cbranch (needs_resize , resize_adj_block , add_adj_block )
565614
566615        self .builder .position_at_end (resize_adj_block )
@@ -569,24 +618,18 @@ def _add_to_adjacency_list(self, src_node_ptr, tgt_node_ptr):
569618            ir .Constant (self .int_type , 1 ),
570619            self .builder .mul (current_capacity , ir .Constant (self .int_type , 2 ))
571620        )
572- 
573-         target_data  =  self ._get_target_data ()
574-         ptr_type  =  self .node_type .as_pointer ()
575621        ptr_size  =  ir .Constant (self .int64_type , self ._get_pointer_size ())
576- 
577622        new_size_bytes  =  self .builder .mul (self .builder .zext (new_capacity , self .int64_type ), ptr_size )
578623        new_array_mem  =  self .builder .call (self .malloc_func , [new_size_bytes ])
579624
580625        old_adj_list  =  self .builder .load (adj_list_ptr )
581-         copy_needed  =  self .builder .icmp_signed ('>' , current_count , ir .Constant (self .int_type , 0 ))
582- 
626+         copy_needed  =  self .builder .icmp_signed ('>' , current_count_final , ir .Constant (self .int_type , 0 ))
583627        copy_block  =  self .builder .block .parent .append_basic_block (name = "copy_existing" )
584628        store_block  =  self .builder .block .parent .append_basic_block (name = "store_new_array" )
585- 
586629        self .builder .cbranch (copy_needed , copy_block , store_block )
587630
588631        self .builder .position_at_end (copy_block )
589-         old_size_bytes  =  self .builder .mul (self .builder .zext (current_count , self .int64_type ), ptr_size )
632+         old_size_bytes  =  self .builder .mul (self .builder .zext (current_count_final , self .int64_type ), ptr_size )
590633        self .builder .call (self .memcpy_func , [new_array_mem , old_adj_list , old_size_bytes ])
591634        self .builder .call (self .free_func , [old_adj_list ])
592635        self .builder .branch (store_block )
@@ -599,11 +642,8 @@ def _add_to_adjacency_list(self, src_node_ptr, tgt_node_ptr):
599642        self .builder .position_at_end (add_adj_block )
600643        adj_array  =  self .builder .load (adj_list_ptr )
601644        adj_array_typed  =  self .builder .bitcast (adj_array , self .node_type .as_pointer ().as_pointer ())
602- 
603-         current_count_final  =  self .builder .load (adj_count_ptr )
604645        target_addr  =  self .builder .gep (adj_array_typed , [current_count_final ])
605646        self .builder .store (tgt_node_ptr , target_addr )
606- 
607647        new_count  =  self .builder .add (current_count_final , ir .Constant (self .int_type , 1 ))
608648        self .builder .store (new_count , adj_count_ptr )
609649
@@ -640,29 +680,32 @@ def _create_hash_insert(self):
640680        self .builder .ret (ir .Constant (self .int_type , 0 ))
641681
642682    def  _create_is_adjacent (self ):
643-         is_adj_type  =  ir .FunctionType (self .bool_type ,
644-             [self .graph_type .as_pointer (), self .char_ptr , self .int_type , self .char_ptr , self .int_type ])
683+         is_adj_type  =  ir .FunctionType (
684+             self .bool_type ,
685+             [self .graph_type .as_pointer (), self .char_ptr , self .int_type ,
686+             self .char_ptr , self .int_type ]
687+         )
645688        self .is_adjacent  =  ir .Function (self .module , is_adj_type , name = "is_adjacent" )
646689
647-         entry_block  =  self .is_adjacent .append_basic_block (name = "entry" )
648-         node1_found_block  =  self .is_adjacent .append_basic_block (name = "node1_found" )
649-         check_adjacency_block  =  self .is_adjacent .append_basic_block (name = "check_adjacency" )
650-         search_adj_block  =  self .is_adjacent .append_basic_block (name = "search_adjacency" )
651-         adj_loop_block  =  self .is_adjacent .append_basic_block (name = "adj_search_loop" )
652-         adj_check_block  =  self .is_adjacent .append_basic_block (name = "adj_check_node" )
653-         adj_next_block  =  self .is_adjacent .append_basic_block (name = "adj_next" )
654-         adj_loop_end_block  =  self .is_adjacent .append_basic_block (name = "adj_loop_end" )
655-         true_block  =  self .is_adjacent .append_basic_block (name = "return_true" )
656-         false_block  =  self .is_adjacent .append_basic_block (name = "return_false" )
690+         entry_block  =  self .is_adjacent .append_basic_block ("entry" )
691+         node1_found_block  =  self .is_adjacent .append_basic_block ("node1_found" )
692+         check_adjacency_block  =  self .is_adjacent .append_basic_block ("check_adjacency" )
693+         search_adj_block  =  self .is_adjacent .append_basic_block ("search_adj" )
694+         adj_loop_block  =  self .is_adjacent .append_basic_block ("adj_loop" )
695+         adj_check_block  =  self .is_adjacent .append_basic_block ("adj_check" )
696+         adj_next_block  =  self .is_adjacent .append_basic_block ("adj_next" )
697+         content_check_block  =  self .is_adjacent .append_basic_block ("content_check" )
698+         adj_loop_end_block  =  self .is_adjacent .append_basic_block ("adj_loop_end" )
699+         true_block  =  self .is_adjacent .append_basic_block ("return_true" )
700+         false_block  =  self .is_adjacent .append_basic_block ("return_false" )
657701
658702        self .builder .position_at_end (entry_block )
659- 
660703        graph_ptr , node1_name , node1_name_len , node2_name , node2_name_len  =  self .is_adjacent .args 
661704
662705        node_map_ptr  =  self .builder .gep (graph_ptr , [ir .Constant (self .int_type , 0 ), ir .Constant (self .int_type , 3 )])
663706        node_map  =  self .builder .load (node_map_ptr )
664-         node1_void  =  self .builder .call (self .hash_lookup , [node_map , node1_name , node1_name_len ])
665707
708+         node1_void  =  self .builder .call (self .hash_lookup , [node_map , node1_name , node1_name_len ])
666709        node1_exists  =  self .builder .icmp_signed ('!=' , node1_void , ir .Constant (self .void_ptr , None ))
667710        self .builder .cbranch (node1_exists , node1_found_block , false_block )
668711
@@ -684,40 +727,50 @@ def _create_is_adjacent(self):
684727        adj_exists  =  self .builder .icmp_signed ('!=' , adj_list_void , ir .Constant (self .void_ptr , None ))
685728        count_positive  =  self .builder .icmp_signed ('>' , adj_count , ir .Constant (self .int_type , 0 ))
686729        should_search  =  self .builder .and_ (adj_exists , count_positive )
687- 
688730        self .builder .cbranch (should_search , search_adj_block , false_block )
689731
690732        self .builder .position_at_end (search_adj_block )
691733        adj_array_typed  =  self .builder .bitcast (adj_list_void , self .node_type .as_pointer ().as_pointer ())
692-         i  =  self .builder .alloca (self .int_type , name = "adj_search_i " )
734+         i  =  self .builder .alloca (self .int_type , name = "i " )
693735        self .builder .store (ir .Constant (self .int_type , 0 ), i )
694736        self .builder .branch (adj_loop_block )
695737
696738        self .builder .position_at_end (adj_loop_block )
697739        i_val  =  self .builder .load (i )
698-         loop_condition  =  self .builder .icmp_signed ('<' , i_val , adj_count )
699-         self .builder .cbranch (loop_condition , adj_check_block , adj_loop_end_block )
740+         loop_cond  =  self .builder .icmp_signed ('<' , i_val , adj_count )
741+         self .builder .cbranch (loop_cond , adj_check_block , adj_loop_end_block )
700742
701743        self .builder .position_at_end (adj_check_block )
702744        entry_ptr  =  self .builder .gep (adj_array_typed , [i_val ])
703745        adj_node  =  self .builder .load (entry_ptr )
704-         nodes_match  =  self .builder .icmp_signed ('==' , adj_node , node2_ptr )
705-         self .builder .cbranch (nodes_match , true_block , adj_next_block )
746+ 
747+         adj_node_name_ptr  =  self .builder .gep (adj_node , [ir .Constant (self .int_type , 0 ), ir .Constant (self .int_type , 1 )])
748+         adj_node_name  =  self .builder .load (adj_node_name_ptr )
749+         adj_node_name_len_ptr  =  self .builder .gep (adj_node , [ir .Constant (self .int_type , 0 ), ir .Constant (self .int_type , 2 )])
750+         adj_node_name_len  =  self .builder .load (adj_node_name_len_ptr )
751+ 
752+         len_match  =  self .builder .icmp_signed ('==' , adj_node_name_len , node2_name_len )
753+         self .builder .cbranch (len_match , content_check_block , adj_next_block )
754+ 
755+         self .builder .position_at_end (content_check_block )
756+         names_match  =  self ._compare_strings (adj_node_name , node2_name , node2_name_len )
757+         self .builder .cbranch (names_match , true_block , adj_next_block )
706758
707759        self .builder .position_at_end (adj_next_block )
708760        next_i  =  self .builder .add (i_val , ir .Constant (self .int_type , 1 ))
709761        self .builder .store (next_i , i )
710762        self .builder .branch (adj_loop_block )
711763
712-         self .builder .position_at_end (true_block )
713-         self .builder .ret (ir .Constant (self .bool_type , 1 ))
714- 
715764        self .builder .position_at_end (adj_loop_end_block )
716765        self .builder .ret (ir .Constant (self .bool_type , 0 ))
717766
767+         self .builder .position_at_end (true_block )
768+         self .builder .ret (ir .Constant (self .bool_type , 1 ))
769+ 
718770        self .builder .position_at_end (false_block )
719771        self .builder .ret (ir .Constant (self .bool_type , 0 ))
720772
773+ 
721774    def  _create_remove_vertex (self ):
722775
723776        remove_vertex_type  =  ir .FunctionType (self .int_type ,
@@ -964,6 +1017,11 @@ def _remove_from_all_adjacency_lists(self, graph_ptr, vertex_name, vertex_name_l
9641017        self .builder .position_at_end (done_adj_cleanup )
9651018
9661019    def  _remove_from_adjacency_list (self , src_node_ptr , tgt_node_ptr ):
1020+         tgt_node_name_ptr  =  self .builder .gep (tgt_node_ptr , [ir .Constant (self .int_type , 0 ), ir .Constant (self .int_type , 1 )])
1021+         tgt_node_name  =  self .builder .load (tgt_node_name_ptr )
1022+         tgt_node_name_len_ptr  =  self .builder .gep (tgt_node_ptr , [ir .Constant (self .int_type , 0 ), ir .Constant (self .int_type , 2 )])
1023+         tgt_node_name_len  =  self .builder .load (tgt_node_name_len_ptr )
1024+ 
9671025        adj_list_ptr  =  self .builder .gep (src_node_ptr , [ir .Constant (self .int_type , 0 ), ir .Constant (self .int_type , 3 )])
9681026        adj_count_ptr  =  self .builder .gep (src_node_ptr , [ir .Constant (self .int_type , 0 ), ir .Constant (self .int_type , 4 )])
9691027
@@ -993,8 +1051,20 @@ def _remove_from_adjacency_list(self, src_node_ptr, tgt_node_ptr):
9931051        adj_entry_ptr  =  self .builder .gep (adj_list_typed , [i_val ])
9941052        adj_node  =  self .builder .load (adj_entry_ptr )
9951053
996-         is_target  =  self .builder .icmp_signed ('==' , adj_node , tgt_node_ptr )
997-         self .builder .cbranch (is_target , adj_found_block , adj_next_block )
1054+         adj_node_name_ptr  =  self .builder .gep (adj_node , [ir .Constant (self .int_type , 0 ), ir .Constant (self .int_type , 1 )])
1055+         adj_node_name  =  self .builder .load (adj_node_name_ptr )
1056+         adj_node_name_len_ptr  =  self .builder .gep (adj_node , [ir .Constant (self .int_type , 0 ), ir .Constant (self .int_type , 2 )])
1057+         adj_node_name_len  =  self .builder .load (adj_node_name_len_ptr )
1058+ 
1059+         len_match  =  self .builder .icmp_signed ('==' , adj_node_name_len , tgt_node_name_len )
1060+ 
1061+         content_check_block  =  self .builder .block .parent .append_basic_block (name = "adj_content_check" )
1062+ 
1063+         self .builder .cbranch (len_match , content_check_block , adj_next_block )
1064+ 
1065+         self .builder .position_at_end (content_check_block )
1066+         names_match  =  self ._compare_strings (adj_node_name , tgt_node_name , tgt_node_name_len )
1067+         self .builder .cbranch (names_match , adj_found_block , adj_next_block )
9981068
9991069        self .builder .position_at_end (adj_found_block )
10001070        shift_i  =  self .builder .alloca (self .int_type , name = "adj_shift_i" )
0 commit comments