Skip to content

Commit 9924f2c

Browse files
committed
feat: implement merge sort for jCC lists to ensure chronological dump order
1 parent c9593ee commit 9924f2c

3 files changed

Lines changed: 62 additions & 4 deletions

File tree

callgrind/dump.c

Lines changed: 57 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -739,6 +739,54 @@ static void fprint_jcc(VgFile *fp, jCC* jcc, AddrPos* curr, AddrPos* last,
739739
static AddrCost ccSum[2];
740740
static int currSum;
741741

742+
/*
743+
* Merge sort implementation for jCC lists to ensure chronological dump order.
744+
* Sorts by creation_seq field to preserve execution order.
745+
*/
746+
747+
/* Merge two sorted jCC lists */
748+
static jCC* merge_jcc_lists(jCC* left, jCC* right) {
749+
if (!left) return right;
750+
if (!right) return left;
751+
752+
jCC* result = NULL;
753+
754+
if (left->creation_seq <= right->creation_seq) {
755+
result = left;
756+
result->next_from = merge_jcc_lists(left->next_from, right);
757+
} else {
758+
result = right;
759+
result->next_from = merge_jcc_lists(left, right->next_from);
760+
}
761+
762+
return result;
763+
}
764+
765+
/* Sort jCC list using merge sort */
766+
static jCC* merge_sort_jcc_list(jCC* head) {
767+
if (!head || !head->next_from) return head;
768+
769+
/* Split list into two halves using slow/fast pointer technique */
770+
jCC* slow = head;
771+
jCC* fast = head->next_from;
772+
773+
while (fast && fast->next_from) {
774+
slow = slow->next_from;
775+
fast = fast->next_from->next_from;
776+
}
777+
778+
/* Split at midpoint */
779+
jCC* mid = slow->next_from;
780+
slow->next_from = NULL;
781+
782+
/* Recursively sort both halves */
783+
jCC* left = merge_sort_jcc_list(head);
784+
jCC* right = merge_sort_jcc_list(mid);
785+
786+
/* Merge sorted halves */
787+
return merge_jcc_lists(left, right);
788+
}
789+
742790
/*
743791
* Print all costs of a BBCC:
744792
* - FCCs of instructions
@@ -818,7 +866,10 @@ static Bool fprint_bbcc(VgFile *fp, BBCC* bbcc, AddrPos* last)
818866
get_debug_pos(bbcc, bb_addr(bb)+instr_info->instr_offset, &(currCost->p));
819867
fprint_apos(fp, &(currCost->p), last, bbcc->cxt->fn[0]->file, bbcc);
820868
something_written = True;
821-
for(jcc=bbcc->jmp[jmp].jcc_list; jcc; jcc=jcc->next_from) {
869+
870+
// Sort jcc_list by creation sequence to ensure chronological order
871+
jCC* sorted_list = merge_sort_jcc_list(bbcc->jmp[jmp].jcc_list);
872+
for(jcc=sorted_list; jcc; jcc=jcc->next_from) {
822873
if (((jcc->jmpkind != jk_Call) && (jcc->call_counter >0)) ||
823874
(!CLG_(is_zero_cost)( CLG_(sets).full, jcc->cost )))
824875
fprint_jcc(fp, jcc, &(currCost->p), last, ecounter);
@@ -868,15 +919,17 @@ static Bool fprint_bbcc(VgFile *fp, BBCC* bbcc, AddrPos* last)
868919
fprint_fcost(fp, currCost, last);
869920
}
870921

871-
if (jcc_count > 0)
872-
for(jcc=bbcc->jmp[jmp].jcc_list; jcc; jcc=jcc->next_from) {
922+
if (jcc_count > 0) {
923+
// Sort jcc_list by creation sequence to ensure chronological order
924+
jCC* sorted_list = merge_sort_jcc_list(bbcc->jmp[jmp].jcc_list);
925+
for(jcc=sorted_list; jcc; jcc=jcc->next_from) {
873926
CLG_ASSERT(jcc->jmp == jmp);
874927
if ( ((jcc->jmpkind != jk_Call) && (jcc->call_counter >0)) ||
875928
(!CLG_(is_zero_cost)( CLG_(sets).full, jcc->cost )))
876929

877930
fprint_jcc(fp, jcc, &(currCost->p), last, ecounter);
878931
}
879-
}
932+
}
880933

881934
if (CLG_(clo).dump_bbs || CLG_(clo).dump_bb) {
882935
if (!CLG_(is_zero_cost)( CLG_(sets).full, currCost->cost )) {

callgrind/global.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -244,6 +244,7 @@ struct _jCC {
244244
UInt jmp; /* jump no. in source */
245245

246246
ULong call_counter; /* no wraparound with 64 bit */
247+
ULong creation_seq; /* creation order sequence number for correct dump order */
247248

248249
FullCost cost; /* simulator + user counters */
249250
};

callgrind/jumps.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,9 @@
3434

3535
static jcc_hash current_jccs;
3636

37+
/* Global counter for jCC creation sequence to preserve chronological order */
38+
static ULong jcc_creation_counter = 0;
39+
3740
void CLG_(init_jcc_hash)(jcc_hash* jccs)
3841
{
3942
Int i;
@@ -148,6 +151,7 @@ static jCC* new_jcc(BBCC* from, UInt jmp, BBCC* to)
148151
jcc->to = to;
149152
jcc->jmpkind = jk_Call;
150153
jcc->call_counter = 0;
154+
jcc->creation_seq = jcc_creation_counter++;
151155
jcc->cost = 0;
152156

153157
/* insert into JCC chain of calling BBCC.

0 commit comments

Comments
 (0)