Skip to content

Commit 7590e68

Browse files
Prerak SinghPrerak Singh
authored andcommitted
bug fix
1 parent 182df75 commit 7590e68

File tree

1 file changed

+109
-39
lines changed

1 file changed

+109
-39
lines changed

pydatastructs/graphs/_backend/cpp/llvm_adjacency_list.py

Lines changed: 109 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)