#include <iostream>
#include <fstream>
#include <iomanip>
#include <cstring>
#include <cmath>
#include <stdlib.h>
#include<sys/time.h>

using namespace std;

//-----------------------DO NOT CHANGE NAMES, ONLY MODIFY VALUES--------------------------------------------

//Final Values that will be compared for correctness
//You may change the function prototypes and definitions, but you need to present final results in these arrays
//-----------------------------Structures for correctness check-------------------
int **SA_Final_student;
int **L_counts_student;
char *L_student;
int F_counts_student[]={0,0,0,0};
//--------------------------------------------------------------------------------

//----------------------------------------------------------------------------------------------------------


//-----------------------DO NOT CHANGE--------------------------------------------

int read_count = 0;
int read_length = 0;

int **SA_Final;
int **L_counts;
char *L;
int F_counts[]={0,0,0,0};


//Read file to get reads
char** inputReads(char *file_path, int *read_count, int *length){
    FILE *read_file = fopen(file_path, "r");
    int ch, lines=0;
    char **reads;
    do                                                                                                 
    {                                                                                                  
        ch = fgetc(read_file);                                                                            
        if (ch == '\n')                                                                                
            lines++;                                                                                   
    } while (ch != EOF);
    rewind(read_file);
    reads=(char**)malloc(lines*sizeof(char*));
    *read_count = lines;
    int i = 0;                                                                                         
    size_t len = 0;                                                                                    
    for(i = 0; i < lines; i++)                                                                         
    {
        reads[i] = NULL;
        len = 0;                                                                                
        getline(&reads[i], &len, read_file);
    }                                                                                                  
    fclose(read_file);
    int j=0;
    while(reads[0][j]!='\n')
        j++;
    *length = j+1;
    for(i=0;i<lines;i++)
        reads[i][j]='$';
    return reads;
}

//Check correctness of values
int checker(){
    int correct = 1;
    for(int i=0; i<read_count*read_length;i++){
        if(L_student[i]!=L[i])
            correct = 0;
        for(int j=0;j<2;j++){
            if(SA_Final_student[i][j]!=SA_Final[i][j])
                correct = 0;
        }
        for(int j=0;j<4;j++){
            if(L_counts_student[i][j]!=L_counts[i][j])
                correct = 0;
        }
    }
    for(int i=0;i<4;i++){
        if(F_counts_student[i]!=F_counts[i])
            correct = 0;
    }
    return correct;
}

//Rotate read by 1 character
void rotateRead(char *read, char *rotatedRead, int length){
    for(int i=0;i<length-1;i++)
        rotatedRead[i]=read[i+1];
    rotatedRead[length-1]=read[0];
}

//Generate Sufixes and their SA's for a read
char** generateSuffixes(char *read, int length, int read_id){
    char **suffixes=(char**)malloc(length*sizeof(char*));
    suffixes[0]=(char*)malloc(length*sizeof(char));
    for(int j=0;j<length;j++)
        suffixes[0][j]=read[j];
    for(int i=1;i<length;i++){
        suffixes[i]=(char*)malloc(length*sizeof(char));
        rotateRead(suffixes[i-1], suffixes[i], length);
    }
    return suffixes;
}

//Comparator for Suffixes
int compSuffixes(char *suffix1, char *suffix2, int length){
    int ret = 0;
    for(int i=0;i<length;i++){
        if(suffix1[i]>suffix2[i])
            return 1;
        else if(suffix1[i]<suffix2[i])
            return -1;
    }
    return ret;
}


//Calculates the final FM-Index
int** makeFMIndex(char ***suffixes, int read_count, int read_length, int F_count[], char *L){
    int i, j;

    SA_Final=(int**)malloc(read_count*read_length*sizeof(int*));
    for(i=0;i<read_count*read_length;i++)
        SA_Final[i]=(int*)malloc(2*sizeof(int));

    //Temporary storage for collecting together all suffixes
    char **temp_suffixes=(char**)malloc(read_count*read_length*sizeof(char*));

    //Initalization of temporary storage
    for(i=0;i<read_count;i++){
        for(j=0;j<read_length;j++){
            temp_suffixes[i*read_length+j]=(char*)malloc(read_length*sizeof(char));
            memcpy(&temp_suffixes[i*read_length+j], &suffixes[i][j],read_length*sizeof(char));
            SA_Final[i*read_length+j][0]=j;
            SA_Final[i*read_length+j][1]=i;
        }
    }
    
    char *temp=(char*)malloc(read_length*sizeof(char));
    
    int **L_count=(int**)malloc(read_length*read_count*sizeof(int*));
    for(i=0;i<read_length*read_count;i++){
        L_count[i]=(int*)malloc(4*sizeof(int));
        for(j=0;j<4;j++){
            L_count[i][j]=0;
        }
    }

    //Focus on improving this for evaluation purpose
    //Sorting of suffixes
    for(i=0;i<read_count*read_length-1;i++){
        for(j=0;j<read_count*read_length-i-1;j++){
            if(compSuffixes(temp_suffixes[j], temp_suffixes[j+1], read_length)>0){
                memcpy(temp, temp_suffixes[j], read_length*sizeof(char));
                memcpy(temp_suffixes[j], temp_suffixes[j+1], read_length*sizeof(char));
                memcpy(temp_suffixes[j+1], temp, read_length*sizeof(char));
                int temp_int = SA_Final[j][0];
                SA_Final[j][0]=SA_Final[j+1][0];
                SA_Final[j+1][0]=temp_int;
                temp_int = SA_Final[j][1];
                SA_Final[j][1]=SA_Final[j+1][1];
                SA_Final[j+1][1]=temp_int;
            }
        }
    }

    free(temp);
    char this_F = '$';
    j=0;
    
    //Calculation of F_count's
    for(i=0;i<read_count*read_length;i++){
        int count=0;
        while(temp_suffixes[i][0]==this_F){
            count++;i++;
        }
        F_count[j++]=j==0?count:count+1;
        this_F = temp_suffixes[i][0];
        if(temp_suffixes[i][0]=='T')
            break;
    }
    
    //Calculation of L's and L_count's
    for(i=0;i<read_count*read_length;i++){
        char ch = temp_suffixes[i][read_length-1];
        L[i]=ch;
        if(i>0){
            for(int k=0;k<4;k++)
                L_count[i][k]=L_count[i-1][k];
        }
        if(ch=='A')
            L_count[i][0]++;
        else if(ch=='C')
            L_count[i][1]++;
        else if(ch=='G')
            L_count[i][2]++;
        else if(ch=='T')
            L_count[i][3]++;
    }

    return L_count;
}

//-----------------------DO NOT CHANGE--------------------------------------------

int main(int argc, char *argv[]){

    char **reads = inputReads(argv[1], &read_count, &read_length);//Input reads from file
    char ***suffixes=(char***)malloc(read_count*sizeof(char**));//Storage for read-wise suffixes
        
    //-----------------------------Structures for correctness check----------------------------------------------
    L=(char*)malloc(read_count*read_length*sizeof(char*));//Final storage for last column of sorted suffixes
    //-----------------------------Structures for correctness check----------------------------------------------
    
    //-----------Default implementation----------------
    //-----------Time capture start--------------------
    struct timeval  TimeValue_Start;
    struct timeval  TimeValue_Final;
    struct timezone TimeZone_Start;
    struct timezone TimeZone_Final;
    long time_start, time_end;
    double time_overhead_default, time_overhead_student;

    gettimeofday(&TimeValue_Start, &TimeZone_Start);

    //Generate read-wise suffixes
    for(int i=0;i<read_count;i++){
        suffixes[i]=generateSuffixes(reads[i], read_length, i);
    }
    
    //Calculate finl FM-Index
    L_counts = makeFMIndex(suffixes, read_count, read_length, F_counts, L);
    
    gettimeofday(&TimeValue_Final, &TimeZone_Final);
    time_start = TimeValue_Start.tv_sec * 1000000 + TimeValue_Start.tv_usec;
    time_end = TimeValue_Final.tv_sec * 1000000 + TimeValue_Final.tv_usec;
    time_overhead_default = (time_end - time_start)/1000000.0;
    //------------Time capture end----------------------
    //--------------------------------------------------

    //-----------Your implementations------------------
    gettimeofday(&TimeValue_Final, &TimeZone_Final);
    time_start = TimeValue_Start.tv_sec * 1000000 + TimeValue_Start.tv_usec;
    //-----------Call your functions here--------------------

    //-----------Call your functions here--------------------
    time_end = TimeValue_Final.tv_sec * 1000000 + TimeValue_Final.tv_usec;
    time_overhead_student = (time_end - time_start)/1000000.0;
    //--------------------------------------------------


    //----------------For debug purpose only-----------------
    //for(int i=0;i<read_count*read_length;i++)        
    //    cout<<L[i]<<"\t"<<SA_Final[i][0]<<","<<SA_Final[i][1]<<"\t"<<L_counts[i][0]<<","<<L_counts[i][1]<<","<<L_counts[i][2]<<","<<L_counts[i][3]<<endl;
    //--------------------------------------------------

    //---------------Correction check and speedup calculation----------------------
    float speedup=0.0;
    //if(checker()==1)
    //    speedup = time_overhead_default/time_overhead_student;
    cout<<"Speedup="<<speedup<<endl;
    //-----------------------------------------------------------------------------
    return 0;
}

	.file	"tmpxft_003a9852_00000000-6_FMIndex.cudafe1.cpp"
	.text
#APP
	.globl _ZSt21ios_base_library_initv

#NO_APP
	.type	_ZL26__cudaUnregisterBinaryUtilv, @function
_ZL26__cudaUnregisterBinaryUtilv:
.LFB4014:
	.cfi_startproc
	endbr64
	movq	_ZL20__cudaFatCubinHandle(%rip), %rdi
	jmp	__cudaUnregisterFatBinary@PLT
	.cfi_endproc
.LFE4014:
	.size	_ZL26__cudaUnregisterBinaryUtilv, .-_ZL26__cudaUnregisterBinaryUtilv
	.section	.rodata.str1.1,"aMS",@progbits,1
.LC0:
	.string	"r"
	.text
	.globl	_Z10inputReadsPcPiS0_
	.type	_Z10inputReadsPcPiS0_, @function
_Z10inputReadsPcPiS0_:
.LFB4005:
	.cfi_startproc
	endbr64
	pushq	%r15
	.cfi_def_cfa_offset 16
	.cfi_offset 15, -16
	pushq	%r14
	.cfi_def_cfa_offset 24
	.cfi_offset 14, -24
	movq	%rdx, %r14
	pushq	%r13
	.cfi_def_cfa_offset 32
	.cfi_offset 13, -32
	movq	%rsi, %r13
	leaq	.LC0(%rip), %rsi
	pushq	%r12
	.cfi_def_cfa_offset 40
	.cfi_offset 12, -40
	pushq	%rbp
	.cfi_def_cfa_offset 48
	.cfi_offset 6, -48
	xorl	%ebp, %ebp
	pushq	%rbx
	.cfi_def_cfa_offset 56
	.cfi_offset 3, -56
	subq	$40, %rsp
	.cfi_def_cfa_offset 96
	movq	%fs:40, %rax
	movq	%rax, 24(%rsp)
	xorl	%eax, %eax
	call	fopen@PLT
	movq	%rax, 8(%rsp)
.L6:
	movq	8(%rsp), %rdi
	call	fgetc@PLT
	cmpl	$10, %eax
	jne	.L3
	incl	%ebp
	jmp	.L6
.L3:
	incl	%eax
	jne	.L6
	movq	8(%rsp), %rdi
	xorl	%r12d, %r12d
	leaq	16(%rsp), %r15
	call	rewind@PLT
	movslq	%ebp, %rdi
	salq	$3, %rdi
	call	malloc@PLT
	xorl	%edx, %edx
	movl	%ebp, 0(%r13)
	movq	%rdx, 16(%rsp)
	movq	%rax, %rbx
	movq	%rax, %r13
.L7:
	cmpl	%r12d, %ebp
	jle	.L16
	xorl	%eax, %eax
	movq	8(%rsp), %rdx
	movq	%r13, %rdi
	movq	%r15, %rsi
	movq	%rax, 0(%r13)
	incl	%r12d
	addq	$8, %r13
	movq	%rax, 16(%rsp)
	call	getline@PLT
	jmp	.L7
.L16:
	movq	8(%rsp), %rdi
	call	fclose@PLT
	movq	(%rbx), %rsi
	xorl	%eax, %eax
.L9:
	movb	(%rsi,%rax), %cl
	movq	%rax, %rdx
	leaq	1(%rax), %rax
	cmpb	$10, %cl
	jne	.L9
	leal	1(%rdx), %eax
	movl	%eax, (%r14)
	xorl	%eax, %eax
.L10:
	cmpl	%eax, %ebp
	jle	.L17
	movq	(%rbx,%rax,8), %rcx
	incq	%rax
	movb	$36, (%rcx,%rdx)
	jmp	.L10
.L17:
	movq	24(%rsp), %rax
	subq	%fs:40, %rax
	je	.L12
	call	__stack_chk_fail@PLT
.L12:
	addq	$40, %rsp
	.cfi_def_cfa_offset 56
	movq	%rbx, %rax
	popq	%rbx
	.cfi_def_cfa_offset 48
	popq	%rbp
	.cfi_def_cfa_offset 40
	popq	%r12
	.cfi_def_cfa_offset 32
	popq	%r13
	.cfi_def_cfa_offset 24
	popq	%r14
	.cfi_def_cfa_offset 16
	popq	%r15
	.cfi_def_cfa_offset 8
	ret
	.cfi_endproc
.LFE4005:
	.size	_Z10inputReadsPcPiS0_, .-_Z10inputReadsPcPiS0_
	.globl	_Z7checkerv
	.type	_Z7checkerv, @function
_Z7checkerv:
.LFB4006:
	.cfi_startproc
	endbr64
	movl	read_count(%rip), %edi
	pushq	%r14
	.cfi_def_cfa_offset 16
	.cfi_offset 14, -16
	xorl	%edx, %edx
	movl	$1, %eax
	imull	read_length(%rip), %edi
	pushq	%r13
	.cfi_def_cfa_offset 24
	.cfi_offset 13, -24
	xorl	%esi, %esi
	movq	L_student(%rip), %r9
	movq	L(%rip), %r10
	pushq	%r12
	.cfi_def_cfa_offset 32
	.cfi_offset 12, -32
	movq	L_counts_student(%rip), %r11
	movq	SA_Final(%rip), %r12
	pushq	%rbp
	.cfi_def_cfa_offset 40
	.cfi_offset 6, -40
	movq	SA_Final_student(%rip), %rbp
	pushq	%rbx
	.cfi_def_cfa_offset 48
	.cfi_offset 3, -48
	movq	L_counts(%rip), %rbx
.L19:
	cmpl	%edx, %edi
	jle	.L35
	movq	0(%rbp,%rdx,8), %r8
	movb	(%r10,%rdx), %cl
	cmpb	%cl, (%r9,%rdx)
	movq	(%r12,%rdx,8), %rcx
	cmovne	%esi, %eax
	movl	(%rcx), %r13d
	cmpl	%r13d, (%r8)
	cmovne	%esi, %eax
	movl	4(%rcx), %ecx
	movq	(%r11,%rdx,8), %r13
	cmpl	%ecx, 4(%r8)
	movq	(%rbx,%rdx,8), %r8
	cmovne	%esi, %eax
	xorl	%ecx, %ecx
.L24:
	movl	(%r8,%rcx), %r14d
	cmpl	%r14d, 0(%r13,%rcx)
	cmovne	%esi, %eax
	addq	$4, %rcx
	cmpq	$16, %rcx
	jne	.L24
	incq	%rdx
	jmp	.L19
.L35:
	xorl	%edx, %edx
	leaq	F_counts_student(%rip), %rdi
	leaq	F_counts(%rip), %rsi
	xorl	%ecx, %ecx
.L27:
	movl	(%rsi,%rdx), %ebx
	cmpl	%ebx, (%rdi,%rdx)
	cmovne	%ecx, %eax
	addq	$4, %rdx
	cmpq	$16, %rdx
	jne	.L27
	popq	%rbx
	.cfi_def_cfa_offset 40
	popq	%rbp
	.cfi_def_cfa_offset 32
	popq	%r12
	.cfi_def_cfa_offset 24
	popq	%r13
	.cfi_def_cfa_offset 16
	popq	%r14
	.cfi_def_cfa_offset 8
	ret
	.cfi_endproc
.LFE4006:
	.size	_Z7checkerv, .-_Z7checkerv
	.globl	_Z10rotateReadPcS_i
	.type	_Z10rotateReadPcS_i, @function
_Z10rotateReadPcS_i:
.LFB4007:
	.cfi_startproc
	endbr64
	xorl	%eax, %eax
	leal	-1(%rdx), %ecx
.L37:
	cmpl	%eax, %ecx
	jle	.L39
	movb	1(%rdi,%rax), %r8b
	movb	%r8b, (%rsi,%rax)
	incq	%rax
	jmp	.L37
.L39:
	movb	(%rdi), %al
	movslq	%edx, %rdx
	movb	%al, -1(%rsi,%rdx)
	ret
	.cfi_endproc
.LFE4007:
	.size	_Z10rotateReadPcS_i, .-_Z10rotateReadPcS_i
	.globl	_Z16generateSuffixesPcii
	.type	_Z16generateSuffixesPcii, @function
_Z16generateSuffixesPcii:
.LFB4008:
	.cfi_startproc
	endbr64
	pushq	%r13
	.cfi_def_cfa_offset 16
	.cfi_offset 13, -16
	movslq	%esi, %r13
	pushq	%r12
	.cfi_def_cfa_offset 24
	.cfi_offset 12, -24
	movq	%rdi, %r12
	leaq	0(,%r13,8), %rdi
	pushq	%rbp
	.cfi_def_cfa_offset 32
	.cfi_offset 6, -32
	movq	%r13, %rbp
	pushq	%rbx
	.cfi_def_cfa_offset 40
	.cfi_offset 3, -40
	pushq	%rcx
	.cfi_def_cfa_offset 48
	call	malloc@PLT
	movq	%r13, %rdi
	movq	%rax, %rbx
	call	malloc@PLT
	xorl	%edx, %edx
	movq	%rax, (%rbx)
.L41:
	cmpl	%edx, %ebp
	jle	.L46
	movb	(%r12,%rdx), %cl
	movb	%cl, (%rax,%rdx)
	incq	%rdx
	jmp	.L41
.L46:
	xorl	%r12d, %r12d
.L43:
	incq	%r12
	cmpl	%r12d, %ebp
	jle	.L47
	movq	%r13, %rdi
	call	malloc@PLT
	movq	-8(%rbx,%r12,8), %rdi
	movl	%ebp, %edx
	movq	%rax, (%rbx,%r12,8)
	movq	%rax, %rsi
	call	_Z10rotateReadPcS_i
	jmp	.L43
.L47:
	popq	%rdx
	.cfi_def_cfa_offset 40
	movq	%rbx, %rax
	popq	%rbx
	.cfi_def_cfa_offset 32
	popq	%rbp
	.cfi_def_cfa_offset 24
	popq	%r12
	.cfi_def_cfa_offset 16
	popq	%r13
	.cfi_def_cfa_offset 8
	ret
	.cfi_endproc
.LFE4008:
	.size	_Z16generateSuffixesPcii, .-_Z16generateSuffixesPcii
	.globl	_Z12compSuffixesPcS_i
	.type	_Z12compSuffixesPcS_i, @function
_Z12compSuffixesPcS_i:
.LFB4009:
	.cfi_startproc
	endbr64
	xorl	%eax, %eax
.L49:
	cmpl	%eax, %edx
	jle	.L54
	movb	(%rdi,%rax), %r8b
	movb	(%rsi,%rax), %cl
	cmpb	%cl, %r8b
	jg	.L52
	incq	%rax
	cmpb	%cl, %r8b
	jge	.L49
	orl	$-1, %eax
	ret
.L54:
	xorl	%eax, %eax
	ret
.L52:
	movl	$1, %eax
	ret
	.cfi_endproc
.LFE4009:
	.size	_Z12compSuffixesPcS_i, .-_Z12compSuffixesPcS_i
	.globl	_Z11makeFMIndexPPPciiPiS_
	.type	_Z11makeFMIndexPPPciiPiS_, @function
_Z11makeFMIndexPPPciiPiS_:
.LFB4010:
	.cfi_startproc
	endbr64
	pushq	%r15
	.cfi_def_cfa_offset 16
	.cfi_offset 15, -16
	pushq	%r14
	.cfi_def_cfa_offset 24
	.cfi_offset 14, -24
	pushq	%r13
	.cfi_def_cfa_offset 32
	.cfi_offset 13, -32
	pushq	%r12
	.cfi_def_cfa_offset 40
	.cfi_offset 12, -40
	movl	%esi, %r12d
	imull	%edx, %r12d
	pushq	%rbp
	.cfi_def_cfa_offset 48
	.cfi_offset 6, -48
	movl	%edx, %ebp
	pushq	%rbx
	.cfi_def_cfa_offset 56
	.cfi_offset 3, -56
	xorl	%ebx, %ebx
	movslq	%r12d, %rax
	subq	$88, %rsp
	.cfi_def_cfa_offset 144
	salq	$3, %rax
	movq	%rdi, 40(%rsp)
	movq	%rax, %rdi
	movl	%esi, 16(%rsp)
	movq	%rcx, 48(%rsp)
	movq	%r8, 56(%rsp)
	movq	%rax, 8(%rsp)
	call	malloc@PLT
	movq	%rax, SA_Final(%rip)
	movq	%rax, %r13
.L56:
	cmpl	%ebx, %r12d
	jle	.L90
	movl	$8, %edi
	call	malloc@PLT
	movq	%rax, 0(%r13,%rbx,8)
	incq	%rbx
	jmp	.L56
.L90:
	movq	8(%rsp), %rdi
	call	malloc@PLT
	xorl	%r11d, %r11d
	xorl	%r10d, %r10d
	movq	%rax, %rbx
	movslq	%ebp, %rax
	movq	%rax, 24(%rsp)
.L58:
	movl	%r10d, 32(%rsp)
	cmpl	%r10d, 16(%rsp)
	jle	.L60
	movslq	%r11d, %r8
	xorl	%r14d, %r14d
	leaq	0(,%r8,8), %r15
.L61:
	cmpl	%r14d, %ebp
	jle	.L91
	movq	24(%rsp), %rdi
	movl	%r11d, 72(%rsp)
	movq	%r10, 64(%rsp)
	call	malloc@PLT
	movq	64(%rsp), %r10
	movq	8(%rsp), %rcx
	leaq	(%rbx,%r15), %rdi
	cmpq	%r15, 8(%rsp)
	movq	24(%rsp), %rdx
	movq	%rax, (%rbx,%r15)
	movq	40(%rsp), %rax
	cmovb	%r15, %rcx
	movq	(%rax,%r10,8), %rax
	subq	%r15, %rcx
	leaq	(%rax,%r14,8), %rsi
	call	__memcpy_chk@PLT
	movq	0(%r13,%r15), %rax
	movl	32(%rsp), %edi
	addq	$8, %r15
	movl	72(%rsp), %r11d
	movq	64(%rsp), %r10
	movl	%r14d, (%rax)
	incq	%r14
	movl	%edi, 4(%rax)
	jmp	.L61
.L91:
	incq	%r10
	addl	%ebp, %r11d
	jmp	.L58
.L60:
	movslq	%ebp, %rax
	xorl	%r14d, %r14d
	movq	%rax, %rdi
	movq	%rax, 16(%rsp)
	call	malloc@PLT
	movq	8(%rsp), %rdi
	movq	%rax, 32(%rsp)
	call	malloc@PLT
	movq	%rax, %r15
.L62:
	cmpl	%r14d, %r12d
	jle	.L92
	movl	$16, %edi
	call	malloc@PLT
	xorl	%edx, %edx
	movq	%rax, (%r15,%r14,8)
	incq	%r14
	movq	%rdx, (%rax)
	movq	%rdx, 8(%rax)
	jmp	.L62
.L92:
	leal	-1(%r12), %eax
	movl	$1, %r14d
	movl	%eax, 64(%rsp)
.L64:
	leal	-1(%r14), %eax
	cmpl	%eax, 64(%rsp)
	jle	.L93
	movl	%r12d, %eax
	xorl	%r13d, %r13d
	subl	%r14d, %eax
	movl	%eax, 40(%rsp)
.L67:
	cmpl	%r13d, 40(%rsp)
	jle	.L94
	movq	8(%rbx,%r13,8), %rax
	movl	%ebp, %edx
	movq	%rax, 8(%rsp)
	movq	(%rbx,%r13,8), %rax
	movq	8(%rsp), %rsi
	movq	%rax, %rdi
	movq	%rax, 24(%rsp)
	call	_Z12compSuffixesPcS_i
	testl	%eax, %eax
	jle	.L65
	movq	16(%rsp), %rcx
	movq	%rdi, %rsi
	movq	32(%rsp), %rdi
	leaq	0(,%r13,8), %r11
	movq	%r11, 72(%rsp)
	movq	%rcx, %rdx
	call	__memcpy_chk@PLT
	movq	24(%rsp), %rdi
	movq	8(%rsp), %rsi
	movq	16(%rsp), %rcx
	movq	72(%rsp), %r11
	rep movsb
	movq	8(%rsp), %rdi
	movq	32(%rsp), %rsi
	movq	16(%rsp), %rcx
	rep movsb
	movq	SA_Final(%rip), %rax
	movq	(%rax,%r13,8), %rdx
	movq	8(%rax,%r11), %rax
	movl	(%rdx), %ecx
	movl	(%rax), %esi
	movl	%esi, (%rdx)
	movl	4(%rax), %esi
	movl	%ecx, (%rax)
	movl	4(%rdx), %ecx
	movl	%esi, 4(%rdx)
	movl	%ecx, 4(%rax)
.L65:
	incq	%r13
	jmp	.L67
.L94:
	incl	%r14d
	jmp	.L64
.L93:
	movq	32(%rsp), %rdi
	call	free@PLT
	xorl	%ecx, %ecx
	movb	$36, %sil
	xorl	%edx, %edx
.L68:
	cmpl	%edx, %r12d
	jg	.L95
.L73:
	xorl	%eax, %eax
	jmp	.L72
.L95:
	movslq	%edx, %rax
.L74:
	movq	(%rbx,%rax,8), %rdi
	cmpb	%sil, (%rdi)
	jne	.L96
	incq	%rax
	jmp	.L74
.L96:
	movl	%eax, %esi
	subl	%edx, %esi
	cmpq	$1, %rcx
	movq	48(%rsp), %rdx
	sbbl	$-1, %esi
	movl	%esi, (%rdx,%rcx,4)
	movb	(%rdi), %sil
	incq	%rcx
	cmpb	$84, %sil
	je	.L73
	leal	1(%rax), %edx
	jmp	.L68
.L83:
	movq	(%rbx,%rax,8), %rdx
	movq	16(%rsp), %rsi
	movq	56(%rsp), %rcx
	movb	-1(%rdx,%rsi), %dl
	movb	%dl, (%rcx,%rax)
	testq	%rax, %rax
	jne	.L75
.L79:
	cmpb	$65, %dl
	jne	.L88
	movq	(%r15,%rax,8), %rdx
	incl	(%rdx)
.L80:
	incq	%rax
.L72:
	cmpl	%eax, %r12d
	jg	.L83
	jmp	.L97
.L75:
	movq	-8(%r15,%rax,8), %r9
	movq	(%r15,%rax,8), %rsi
	xorl	%ecx, %ecx
.L78:
	movl	(%r9,%rcx), %edi
	movl	%edi, (%rsi,%rcx)
	addq	$4, %rcx
	cmpq	$16, %rcx
	jne	.L78
	jmp	.L79
.L88:
	cmpb	$67, %dl
	jne	.L81
	movq	(%r15,%rax,8), %rdx
	incl	4(%rdx)
	jmp	.L80
.L81:
	cmpb	$71, %dl
	jne	.L82
	movq	(%r15,%rax,8), %rdx
	incl	8(%rdx)
	jmp	.L80
.L82:
	cmpb	$84, %dl
	jne	.L80
	movq	(%r15,%rax,8), %rdx
	incl	12(%rdx)
	jmp	.L80
.L97:
	addq	$88, %rsp
	.cfi_def_cfa_offset 56
	movq	%r15, %rax
	popq	%rbx
	.cfi_def_cfa_offset 48
	popq	%rbp
	.cfi_def_cfa_offset 40
	popq	%r12
	.cfi_def_cfa_offset 32
	popq	%r13
	.cfi_def_cfa_offset 24
	popq	%r14
	.cfi_def_cfa_offset 16
	popq	%r15
	.cfi_def_cfa_offset 8
	ret
	.cfi_endproc
.LFE4010:
	.size	_Z11makeFMIndexPPPciiPiS_, .-_Z11makeFMIndexPPPciiPiS_
	.section	.rodata.str1.1
.LC1:
	.string	"Speedup="
	.section	.text.startup,"ax",@progbits
	.globl	main
	.type	main, @function
main:
.LFB4011:
	.cfi_startproc
	endbr64
	pushq	%r12
	.cfi_def_cfa_offset 16
	.cfi_offset 12, -16
	leaq	read_length(%rip), %rdx
	pushq	%rbp
	.cfi_def_cfa_offset 24
	.cfi_offset 6, -24
	pushq	%rbx
	.cfi_def_cfa_offset 32
	.cfi_offset 3, -32
	subq	$64, %rsp
	.cfi_def_cfa_offset 96
	movq	8(%rsi), %rdi
	leaq	read_count(%rip), %rsi
	movq	%fs:40, %rax
	movq	%rax, 56(%rsp)
	xorl	%eax, %eax
	call	_Z10inputReadsPcPiS0_
	movslq	read_count(%rip), %rdi
	movq	%rax, %r12
	movq	%rdi, %rbx
	salq	$3, %rdi
	call	malloc@PLT
	imull	read_length(%rip), %ebx
	movq	%rax, %rbp
	movslq	%ebx, %rdi
	xorl	%ebx, %ebx
	salq	$3, %rdi
	call	malloc@PLT
	leaq	8(%rsp), %rsi
	leaq	24(%rsp), %rdi
	movq	%rax, L(%rip)
	call	gettimeofday@PLT
.L99:
	movl	read_count(%rip), %esi
	movl	read_length(%rip), %eax
	movl	%ebx, %edx
	cmpl	%ebx, %esi
	jle	.L103
	movq	(%r12,%rbx,8), %rdi
	movl	%eax, %esi
	call	_Z16generateSuffixesPcii
	movq	%rax, 0(%rbp,%rbx,8)
	incq	%rbx
	jmp	.L99
.L103:
	movq	L(%rip), %r8
	leaq	F_counts(%rip), %rcx
	movl	%eax, %edx
	movq	%rbp, %rdi
	leaq	40(%rsp), %rbx
	leaq	16(%rsp), %rbp
	call	_Z11makeFMIndexPPPciiPiS_
	movq	%rbp, %rsi
	movq	%rbx, %rdi
	movq	%rax, L_counts(%rip)
	call	gettimeofday@PLT
	movq	%rbp, %rsi
	movq	%rbx, %rdi
	call	gettimeofday@PLT
	leaq	.LC1(%rip), %rsi
	leaq	_ZSt4cout(%rip), %rdi
	call	_ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc@PLT
	xorps	%xmm0, %xmm0
	movq	%rax, %rdi
	call	_ZNSo9_M_insertIdEERSoT_@PLT
	movq	%rax, %rdi
	call	_ZSt4endlIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_@PLT
	movq	56(%rsp), %rax
	subq	%fs:40, %rax
	je	.L101
	call	__stack_chk_fail@PLT
.L101:
	addq	$64, %rsp
	.cfi_def_cfa_offset 32
	xorl	%eax, %eax
	popq	%rbx
	.cfi_def_cfa_offset 24
	popq	%rbp
	.cfi_def_cfa_offset 16
	popq	%r12
	.cfi_def_cfa_offset 8
	ret
	.cfi_endproc
.LFE4011:
	.size	main, .-main
	.type	_ZL24__sti____cudaRegisterAllv, @function
_ZL24__sti____cudaRegisterAllv:
.LFB4037:
	.cfi_startproc
	endbr64
	pushq	%rax
	.cfi_def_cfa_offset 16
	leaq	_ZL15__fatDeviceText(%rip), %rdi
	call	__cudaRegisterFatBinary@PLT
	movq	%rax, %rdi
	movq	%rax, _ZL20__cudaFatCubinHandle(%rip)
	call	__cudaRegisterFatBinaryEnd@PLT
	leaq	_ZL26__cudaUnregisterBinaryUtilv(%rip), %rdi
	popq	%rdx
	.cfi_def_cfa_offset 8
	jmp	atexit@PLT
	.cfi_endproc
.LFE4037:
	.size	_ZL24__sti____cudaRegisterAllv, .-_ZL24__sti____cudaRegisterAllv
	.section	.init_array,"aw"
	.align 8
	.quad	_ZL24__sti____cudaRegisterAllv
	.section	.nvFatBinSegment,"aw"
	.align 8
	.type	_ZL15__fatDeviceText, @object
	.size	_ZL15__fatDeviceText, 24
_ZL15__fatDeviceText:
	.long	1180844977
	.long	1
	.quad	fatbinData
	.quad	0
	.local	_ZL20__cudaFatCubinHandle
	.comm	_ZL20__cudaFatCubinHandle,8,8
	.globl	F_counts
	.bss
	.align 16
	.type	F_counts, @object
	.size	F_counts, 16
F_counts:
	.zero	16
	.globl	L
	.align 8
	.type	L, @object
	.size	L, 8
L:
	.zero	8
	.globl	L_counts
	.align 8
	.type	L_counts, @object
	.size	L_counts, 8
L_counts:
	.zero	8
	.globl	SA_Final
	.align 8
	.type	SA_Final, @object
	.size	SA_Final, 8
SA_Final:
	.zero	8
	.globl	read_length
	.align 4
	.type	read_length, @object
	.size	read_length, 4
read_length:
	.zero	4
	.globl	read_count
	.align 4
	.type	read_count, @object
	.size	read_count, 4
read_count:
	.zero	4
	.globl	F_counts_student
	.align 16
	.type	F_counts_student, @object
	.size	F_counts_student, 16
F_counts_student:
	.zero	16
	.globl	L_student
	.align 8
	.type	L_student, @object
	.size	L_student, 8
L_student:
	.zero	8
	.globl	L_counts_student
	.align 8
	.type	L_counts_student, @object
	.size	L_counts_student, 8
L_counts_student:
	.zero	8
	.globl	SA_Final_student
	.align 8
	.type	SA_Final_student, @object
	.size	SA_Final_student, 8
SA_Final_student:
	.zero	8
	.ident	"GCC: (Ubuntu 13.3.0-6ubuntu2~24.04) 13.3.0"
	.section	.note.GNU-stack,"",@progbits
	.section	.note.gnu.property,"a"
	.align 8
	.long	1f - 0f
	.long	4f - 1f
	.long	5
0:
	.string	"GNU"
1:
	.align 8
	.long	0xc0000002
	.long	3f - 2f
2:
	.long	0x3
3:
	.align 8
4:


#include <hip/hip_runtime.h>
#include <iostream>
#include <fstream>
#include <iomanip>
#include <cstring>
#include <cmath>
#include <stdlib.h>
#include<sys/time.h>

using namespace std;

//-----------------------DO NOT CHANGE NAMES, ONLY MODIFY VALUES--------------------------------------------

//Final Values that will be compared for correctness
//You may change the function prototypes and definitions, but you need to present final results in these arrays
//-----------------------------Structures for correctness check-------------------
int **SA_Final_student;
int **L_counts_student;
char *L_student;
int F_counts_student[]={0,0,0,0};
//--------------------------------------------------------------------------------

//----------------------------------------------------------------------------------------------------------


//-----------------------DO NOT CHANGE--------------------------------------------

int read_count = 0;
int read_length = 0;

int **SA_Final;
int **L_counts;
char *L;
int F_counts[]={0,0,0,0};


//Read file to get reads
char** inputReads(char *file_path, int *read_count, int *length){
    FILE *read_file = fopen(file_path, "r");
    int ch, lines=0;
    char **reads;
    do                                                                                                 
    {                                                                                                  
        ch = fgetc(read_file);                                                                            
        if (ch == '\n')                                                                                
            lines++;                                                                                   
    } while (ch != EOF);
    rewind(read_file);
    reads=(char**)malloc(lines*sizeof(char*));
    *read_count = lines;
    int i = 0;                                                                                         
    size_t len = 0;                                                                                    
    for(i = 0; i < lines; i++)                                                                         
    {
        reads[i] = NULL;
        len = 0;                                                                                
        getline(&reads[i], &len, read_file);
    }                                                                                                  
    fclose(read_file);
    int j=0;
    while(reads[0][j]!='\n')
        j++;
    *length = j+1;
    for(i=0;i<lines;i++)
        reads[i][j]='$';
    return reads;
}

//Check correctness of values
int checker(){
    int correct = 1;
    for(int i=0; i<read_count*read_length;i++){
        if(L_student[i]!=L[i])
            correct = 0;
        for(int j=0;j<2;j++){
            if(SA_Final_student[i][j]!=SA_Final[i][j])
                correct = 0;
        }
        for(int j=0;j<4;j++){
            if(L_counts_student[i][j]!=L_counts[i][j])
                correct = 0;
        }
    }
    for(int i=0;i<4;i++){
        if(F_counts_student[i]!=F_counts[i])
            correct = 0;
    }
    return correct;
}

//Rotate read by 1 character
void rotateRead(char *read, char *rotatedRead, int length){
    for(int i=0;i<length-1;i++)
        rotatedRead[i]=read[i+1];
    rotatedRead[length-1]=read[0];
}

//Generate Sufixes and their SA's for a read
char** generateSuffixes(char *read, int length, int read_id){
    char **suffixes=(char**)malloc(length*sizeof(char*));
    suffixes[0]=(char*)malloc(length*sizeof(char));
    for(int j=0;j<length;j++)
        suffixes[0][j]=read[j];
    for(int i=1;i<length;i++){
        suffixes[i]=(char*)malloc(length*sizeof(char));
        rotateRead(suffixes[i-1], suffixes[i], length);
    }
    return suffixes;
}

//Comparator for Suffixes
int compSuffixes(char *suffix1, char *suffix2, int length){
    int ret = 0;
    for(int i=0;i<length;i++){
        if(suffix1[i]>suffix2[i])
            return 1;
        else if(suffix1[i]<suffix2[i])
            return -1;
    }
    return ret;
}


//Calculates the final FM-Index
int** makeFMIndex(char ***suffixes, int read_count, int read_length, int F_count[], char *L){
    int i, j;

    SA_Final=(int**)malloc(read_count*read_length*sizeof(int*));
    for(i=0;i<read_count*read_length;i++)
        SA_Final[i]=(int*)malloc(2*sizeof(int));

    //Temporary storage for collecting together all suffixes
    char **temp_suffixes=(char**)malloc(read_count*read_length*sizeof(char*));

    //Initalization of temporary storage
    for(i=0;i<read_count;i++){
        for(j=0;j<read_length;j++){
            temp_suffixes[i*read_length+j]=(char*)malloc(read_length*sizeof(char));
            memcpy(&temp_suffixes[i*read_length+j], &suffixes[i][j],read_length*sizeof(char));
            SA_Final[i*read_length+j][0]=j;
            SA_Final[i*read_length+j][1]=i;
        }
    }
    
    char *temp=(char*)malloc(read_length*sizeof(char));
    
    int **L_count=(int**)malloc(read_length*read_count*sizeof(int*));
    for(i=0;i<read_length*read_count;i++){
        L_count[i]=(int*)malloc(4*sizeof(int));
        for(j=0;j<4;j++){
            L_count[i][j]=0;
        }
    }

    //Focus on improving this for evaluation purpose
    //Sorting of suffixes
    for(i=0;i<read_count*read_length-1;i++){
        for(j=0;j<read_count*read_length-i-1;j++){
            if(compSuffixes(temp_suffixes[j], temp_suffixes[j+1], read_length)>0){
                memcpy(temp, temp_suffixes[j], read_length*sizeof(char));
                memcpy(temp_suffixes[j], temp_suffixes[j+1], read_length*sizeof(char));
                memcpy(temp_suffixes[j+1], temp, read_length*sizeof(char));
                int temp_int = SA_Final[j][0];
                SA_Final[j][0]=SA_Final[j+1][0];
                SA_Final[j+1][0]=temp_int;
                temp_int = SA_Final[j][1];
                SA_Final[j][1]=SA_Final[j+1][1];
                SA_Final[j+1][1]=temp_int;
            }
        }
    }

    free(temp);
    char this_F = '$';
    j=0;
    
    //Calculation of F_count's
    for(i=0;i<read_count*read_length;i++){
        int count=0;
        while(temp_suffixes[i][0]==this_F){
            count++;i++;
        }
        F_count[j++]=j==0?count:count+1;
        this_F = temp_suffixes[i][0];
        if(temp_suffixes[i][0]=='T')
            break;
    }
    
    //Calculation of L's and L_count's
    for(i=0;i<read_count*read_length;i++){
        char ch = temp_suffixes[i][read_length-1];
        L[i]=ch;
        if(i>0){
            for(int k=0;k<4;k++)
                L_count[i][k]=L_count[i-1][k];
        }
        if(ch=='A')
            L_count[i][0]++;
        else if(ch=='C')
            L_count[i][1]++;
        else if(ch=='G')
            L_count[i][2]++;
        else if(ch=='T')
            L_count[i][3]++;
    }

    return L_count;
}

//-----------------------DO NOT CHANGE--------------------------------------------

int main(int argc, char *argv[]){

    char **reads = inputReads(argv[1], &read_count, &read_length);//Input reads from file
    char ***suffixes=(char***)malloc(read_count*sizeof(char**));//Storage for read-wise suffixes
        
    //-----------------------------Structures for correctness check----------------------------------------------
    L=(char*)malloc(read_count*read_length*sizeof(char*));//Final storage for last column of sorted suffixes
    //-----------------------------Structures for correctness check----------------------------------------------
    
    //-----------Default implementation----------------
    //-----------Time capture start--------------------
    struct timeval  TimeValue_Start;
    struct timeval  TimeValue_Final;
    struct timezone TimeZone_Start;
    struct timezone TimeZone_Final;
    long time_start, time_end;
    double time_overhead_default, time_overhead_student;

    gettimeofday(&TimeValue_Start, &TimeZone_Start);

    //Generate read-wise suffixes
    for(int i=0;i<read_count;i++){
        suffixes[i]=generateSuffixes(reads[i], read_length, i);
    }
    
    //Calculate finl FM-Index
    L_counts = makeFMIndex(suffixes, read_count, read_length, F_counts, L);
    
    gettimeofday(&TimeValue_Final, &TimeZone_Final);
    time_start = TimeValue_Start.tv_sec * 1000000 + TimeValue_Start.tv_usec;
    time_end = TimeValue_Final.tv_sec * 1000000 + TimeValue_Final.tv_usec;
    time_overhead_default = (time_end - time_start)/1000000.0;
    //------------Time capture end----------------------
    //--------------------------------------------------

    //-----------Your implementations------------------
    gettimeofday(&TimeValue_Final, &TimeZone_Final);
    time_start = TimeValue_Start.tv_sec * 1000000 + TimeValue_Start.tv_usec;
    //-----------Call your functions here--------------------

    //-----------Call your functions here--------------------
    time_end = TimeValue_Final.tv_sec * 1000000 + TimeValue_Final.tv_usec;
    time_overhead_student = (time_end - time_start)/1000000.0;
    //--------------------------------------------------


    //----------------For debug purpose only-----------------
    //for(int i=0;i<read_count*read_length;i++)        
    //    cout<<L[i]<<"\t"<<SA_Final[i][0]<<","<<SA_Final[i][1]<<"\t"<<L_counts[i][0]<<","<<L_counts[i][1]<<","<<L_counts[i][2]<<","<<L_counts[i][3]<<endl;
    //--------------------------------------------------

    //---------------Correction check and speedup calculation----------------------
    float speedup=0.0;
    //if(checker()==1)
    //    speedup = time_overhead_default/time_overhead_student;
    cout<<"Speedup="<<speedup<<endl;
    //-----------------------------------------------------------------------------
    return 0;
}

	.text
	.file	"FMIndex.hip"
                                        # Start of file scope inline assembly
	.globl	_ZSt21ios_base_library_initv

                                        # End of file scope inline assembly
	.globl	_Z10inputReadsPcPiS0_           # -- Begin function _Z10inputReadsPcPiS0_
	.type	_Z10inputReadsPcPiS0_,@function
_Z10inputReadsPcPiS0_:                  # @_Z10inputReadsPcPiS0_
	.cfi_startproc
# %bb.0:
	pushq	%rbp
	.cfi_def_cfa_offset 16
	pushq	%r15
	.cfi_def_cfa_offset 24
	pushq	%r14
	.cfi_def_cfa_offset 32
	pushq	%r13
	.cfi_def_cfa_offset 40
	pushq	%r12
	.cfi_def_cfa_offset 48
	pushq	%rbx
	.cfi_def_cfa_offset 56
	subq	$24, %rsp
	.cfi_def_cfa_offset 80
	.cfi_offset %rbx, -56
	.cfi_offset %r12, -48
	.cfi_offset %r13, -40
	.cfi_offset %r14, -32
	.cfi_offset %r15, -24
	.cfi_offset %rbp, -16
	movq	%rdx, 16(%rsp)                  # 8-byte Spill
	movq	%rsi, %r12
	movl	$.L.str, %esi
	callq	fopen
	movq	%rax, %r15
	xorl	%ebp, %ebp
.LBB0_1:                                # =>This Inner Loop Header: Depth=1
	movl	%ebp, %ebx
	movq	%r15, %rdi
	callq	fgetc
	xorl	%ebp, %ebp
	cmpl	$10, %eax
	sete	%bpl
	addl	%ebx, %ebp
	cmpl	$-1, %eax
	jne	.LBB0_1
# %bb.2:
	movq	%r15, %rdi
	callq	rewind
	movl	%ebx, %edi
	shlq	$3, %rdi
	callq	malloc
	movq	%rax, %r14
	movl	%ebx, (%r12)
	movq	$0, 8(%rsp)
	movl	%ebp, %eax
	movq	%rax, (%rsp)                    # 8-byte Spill
	testl	%ebp, %ebp
	je	.LBB0_5
# %bb.3:                                # %.lr.ph.preheader
	xorl	%r12d, %r12d
	movq	(%rsp), %rbx                    # 8-byte Reload
	movq	%r14, %r13
.LBB0_4:                                # %.lr.ph
                                        # =>This Inner Loop Header: Depth=1
	movq	%r12, (%r13)
	movq	%r12, 8(%rsp)
	movq	%r13, %rdi
	leaq	8(%rsp), %rsi
	movq	%r15, %rdx
	callq	getline
	addq	$8, %r13
	decq	%rbx
	jne	.LBB0_4
.LBB0_5:                                # %._crit_edge
	movq	%r15, %rdi
	callq	fclose
	movq	(%r14), %rcx
	xorl	%eax, %eax
.LBB0_6:                                # =>This Inner Loop Header: Depth=1
	cmpb	$10, (%rcx,%rax)
	leaq	1(%rax), %rax
	jne	.LBB0_6
# %bb.7:
	movq	16(%rsp), %rcx                  # 8-byte Reload
	movl	%eax, (%rcx)
	testl	%ebp, %ebp
	movq	(%rsp), %rsi                    # 8-byte Reload
	je	.LBB0_10
# %bb.8:                                # %.lr.ph36.preheader
	xorl	%ecx, %ecx
.LBB0_9:                                # %.lr.ph36
                                        # =>This Inner Loop Header: Depth=1
	movq	(%r14,%rcx,8), %rdx
	movb	$36, -1(%rdx,%rax)
	incq	%rcx
	cmpq	%rcx, %rsi
	jne	.LBB0_9
.LBB0_10:                               # %._crit_edge37
	movq	%r14, %rax
	addq	$24, %rsp
	.cfi_def_cfa_offset 56
	popq	%rbx
	.cfi_def_cfa_offset 48
	popq	%r12
	.cfi_def_cfa_offset 40
	popq	%r13
	.cfi_def_cfa_offset 32
	popq	%r14
	.cfi_def_cfa_offset 24
	popq	%r15
	.cfi_def_cfa_offset 16
	popq	%rbp
	.cfi_def_cfa_offset 8
	retq
.Lfunc_end0:
	.size	_Z10inputReadsPcPiS0_, .Lfunc_end0-_Z10inputReadsPcPiS0_
	.cfi_endproc
                                        # -- End function
	.globl	_Z7checkerv                     # -- Begin function _Z7checkerv
	.type	_Z7checkerv,@function
_Z7checkerv:                            # @_Z7checkerv
	.cfi_startproc
# %bb.0:
	pushq	%rbp
	.cfi_def_cfa_offset 16
	pushq	%r15
	.cfi_def_cfa_offset 24
	pushq	%r14
	.cfi_def_cfa_offset 32
	pushq	%r13
	.cfi_def_cfa_offset 40
	pushq	%r12
	.cfi_def_cfa_offset 48
	pushq	%rbx
	.cfi_def_cfa_offset 56
	.cfi_offset %rbx, -56
	.cfi_offset %r12, -48
	.cfi_offset %r13, -40
	.cfi_offset %r14, -32
	.cfi_offset %r15, -24
	.cfi_offset %rbp, -16
	movl	read_length(%rip), %eax
	imull	read_count(%rip), %eax
	testl	%eax, %eax
	jle	.LBB1_1
# %bb.5:                                # %.lr.ph
	movq	L_student(%rip), %rcx
	movq	%rcx, -8(%rsp)                  # 8-byte Spill
	movq	L(%rip), %rdx
	movq	SA_Final_student(%rip), %rsi
	movq	SA_Final(%rip), %rdi
	movq	L_counts_student(%rip), %r8
	movq	L_counts(%rip), %r9
	movl	%eax, %r10d
	movl	$1, %eax
	xorl	%r11d, %r11d
	xorl	%ebx, %ebx
.LBB1_6:                                # =>This Loop Header: Depth=1
                                        #     Child Loop BB1_7 Depth 2
                                        #     Child Loop BB1_9 Depth 2
	movq	-8(%rsp), %rcx                  # 8-byte Reload
	movb	(%rcx,%rbx), %bpl
	cmpb	(%rdx,%rbx), %bpl
	cmovnel	%r11d, %eax
	movq	(%rsi,%rbx,8), %r14
	movq	(%rdi,%rbx,8), %r15
	movb	$1, %bpl
	xorl	%r12d, %r12d
.LBB1_7:                                #   Parent Loop BB1_6 Depth=1
                                        # =>  This Inner Loop Header: Depth=2
	movl	(%r14,%r12,4), %r13d
	xorl	%ecx, %ecx
	cmpl	(%r15,%r12,4), %r13d
	cmovnel	%ecx, %eax
	movl	$1, %r12d
	testb	$1, %bpl
	movl	$0, %ebp
	jne	.LBB1_7
# %bb.8:                                # %.preheader31
                                        #   in Loop: Header=BB1_6 Depth=1
	movq	(%r8,%rbx,8), %r14
	movq	(%r9,%rbx,8), %r15
	xorl	%r12d, %r12d
.LBB1_9:                                #   Parent Loop BB1_6 Depth=1
                                        # =>  This Inner Loop Header: Depth=2
	movl	(%r14,%r12,4), %ecx
	cmpl	(%r15,%r12,4), %ecx
	cmovnel	%r11d, %eax
	incq	%r12
	cmpq	$4, %r12
	jne	.LBB1_9
# %bb.10:                               #   in Loop: Header=BB1_6 Depth=1
	incq	%rbx
	cmpq	%r10, %rbx
	jne	.LBB1_6
	jmp	.LBB1_2
.LBB1_1:
	movl	$1, %eax
.LBB1_2:                                # %.preheader.preheader
	movq	$-16, %rcx
	xorl	%edx, %edx
.LBB1_3:                                # %.preheader
                                        # =>This Inner Loop Header: Depth=1
	movl	F_counts_student+16(%rcx), %esi
	cmpl	F_counts+16(%rcx), %esi
	cmovnel	%edx, %eax
	addq	$4, %rcx
	jne	.LBB1_3
# %bb.4:
	popq	%rbx
	.cfi_def_cfa_offset 48
	popq	%r12
	.cfi_def_cfa_offset 40
	popq	%r13
	.cfi_def_cfa_offset 32
	popq	%r14
	.cfi_def_cfa_offset 24
	popq	%r15
	.cfi_def_cfa_offset 16
	popq	%rbp
	.cfi_def_cfa_offset 8
	retq
.Lfunc_end1:
	.size	_Z7checkerv, .Lfunc_end1-_Z7checkerv
	.cfi_endproc
                                        # -- End function
	.globl	_Z10rotateReadPcS_i             # -- Begin function _Z10rotateReadPcS_i
	.type	_Z10rotateReadPcS_i,@function
_Z10rotateReadPcS_i:                    # @_Z10rotateReadPcS_i
	.cfi_startproc
# %bb.0:
                                        # kill: def $edx killed $edx def $rdx
	leal	-1(%rdx), %eax
	cmpl	$2, %edx
	jl	.LBB2_3
# %bb.1:                                # %.lr.ph.preheader
	movl	%eax, %ecx
	xorl	%edx, %edx
.LBB2_2:                                # %.lr.ph
                                        # =>This Inner Loop Header: Depth=1
	movb	1(%rdi,%rdx), %r8b
	movb	%r8b, (%rsi,%rdx)
	leaq	1(%rdx), %r8
	movq	%r8, %rdx
	cmpq	%r8, %rcx
	jne	.LBB2_2
.LBB2_3:                                # %._crit_edge
	movb	(%rdi), %cl
	cltq
	movb	%cl, (%rsi,%rax)
	retq
.Lfunc_end2:
	.size	_Z10rotateReadPcS_i, .Lfunc_end2-_Z10rotateReadPcS_i
	.cfi_endproc
                                        # -- End function
	.globl	_Z16generateSuffixesPcii        # -- Begin function _Z16generateSuffixesPcii
	.type	_Z16generateSuffixesPcii,@function
_Z16generateSuffixesPcii:               # @_Z16generateSuffixesPcii
	.cfi_startproc
# %bb.0:
	pushq	%r15
	.cfi_def_cfa_offset 16
	pushq	%r14
	.cfi_def_cfa_offset 24
	pushq	%r13
	.cfi_def_cfa_offset 32
	pushq	%r12
	.cfi_def_cfa_offset 40
	pushq	%rbx
	.cfi_def_cfa_offset 48
	.cfi_offset %rbx, -48
	.cfi_offset %r12, -40
	.cfi_offset %r13, -32
	.cfi_offset %r14, -24
	.cfi_offset %r15, -16
	movl	%esi, %ebx
	movq	%rdi, %r13
	movslq	%esi, %r14
	leaq	(,%r14,8), %rdi
	callq	malloc
	movq	%rax, %r15
	movq	%r14, %rdi
	callq	malloc
	movq	%rax, (%r15)
	testl	%r14d, %r14d
	jle	.LBB3_6
# %bb.1:                                # %.preheader
	movl	%ebx, %r12d
	movq	%rax, %rdi
	movq	%r13, %rsi
	movq	%r12, %rdx
	callq	memcpy@PLT
	cmpl	$1, %ebx
	je	.LBB3_6
# %bb.2:                                # %.lr.ph25
	decl	%ebx
	movl	$1, %r13d
.LBB3_3:                                # %.lr.ph.i.preheader
                                        # =>This Loop Header: Depth=1
                                        #     Child Loop BB3_4 Depth 2
	movq	%r14, %rdi
	callq	malloc
	movq	%rax, (%r15,%r13,8)
	movq	-8(%r15,%r13,8), %rcx
	xorl	%edx, %edx
.LBB3_4:                                # %.lr.ph.i
                                        #   Parent Loop BB3_3 Depth=1
                                        # =>  This Inner Loop Header: Depth=2
	movb	1(%rcx,%rdx), %sil
	movb	%sil, (%rax,%rdx)
	leaq	1(%rdx), %rsi
	movq	%rsi, %rdx
	cmpq	%rsi, %rbx
	jne	.LBB3_4
# %bb.5:                                # %_Z10rotateReadPcS_i.exit
                                        #   in Loop: Header=BB3_3 Depth=1
	movb	(%rcx), %cl
	movb	%cl, (%rax,%rbx)
	incq	%r13
	cmpq	%r12, %r13
	jne	.LBB3_3
.LBB3_6:                                # %._crit_edge
	movq	%r15, %rax
	popq	%rbx
	.cfi_def_cfa_offset 40
	popq	%r12
	.cfi_def_cfa_offset 32
	popq	%r13
	.cfi_def_cfa_offset 24
	popq	%r14
	.cfi_def_cfa_offset 16
	popq	%r15
	.cfi_def_cfa_offset 8
	retq
.Lfunc_end3:
	.size	_Z16generateSuffixesPcii, .Lfunc_end3-_Z16generateSuffixesPcii
	.cfi_endproc
                                        # -- End function
	.globl	_Z12compSuffixesPcS_i           # -- Begin function _Z12compSuffixesPcS_i
	.type	_Z12compSuffixesPcS_i,@function
_Z12compSuffixesPcS_i:                  # @_Z12compSuffixesPcS_i
	.cfi_startproc
# %bb.0:
	testl	%edx, %edx
	jle	.LBB4_1
# %bb.3:                                # %.lr.ph.preheader
	movl	%edx, %eax
	xorl	%ecx, %ecx
.LBB4_4:                                # %.lr.ph
                                        # =>This Inner Loop Header: Depth=1
	movb	(%rsi,%rcx), %dl
	cmpb	%dl, (%rdi,%rcx)
	jg	.LBB4_5
# %bb.6:                                #   in Loop: Header=BB4_4 Depth=1
	jl	.LBB4_7
# %bb.2:                                #   in Loop: Header=BB4_4 Depth=1
	incq	%rcx
	cmpq	%rcx, %rax
	jne	.LBB4_4
.LBB4_1:
	xorl	%eax, %eax
	retq
.LBB4_5:
	movl	$1, %eax
	retq
.LBB4_7:
	movl	$-1, %eax
	retq
.Lfunc_end4:
	.size	_Z12compSuffixesPcS_i, .Lfunc_end4-_Z12compSuffixesPcS_i
	.cfi_endproc
                                        # -- End function
	.globl	_Z11makeFMIndexPPPciiPiS_       # -- Begin function _Z11makeFMIndexPPPciiPiS_
	.type	_Z11makeFMIndexPPPciiPiS_,@function
_Z11makeFMIndexPPPciiPiS_:              # @_Z11makeFMIndexPPPciiPiS_
	.cfi_startproc
# %bb.0:
	pushq	%rbp
	.cfi_def_cfa_offset 16
	pushq	%r15
	.cfi_def_cfa_offset 24
	pushq	%r14
	.cfi_def_cfa_offset 32
	pushq	%r13
	.cfi_def_cfa_offset 40
	pushq	%r12
	.cfi_def_cfa_offset 48
	pushq	%rbx
	.cfi_def_cfa_offset 56
	subq	$104, %rsp
	.cfi_def_cfa_offset 160
	.cfi_offset %rbx, -56
	.cfi_offset %r12, -48
	.cfi_offset %r13, -40
	.cfi_offset %r14, -32
	.cfi_offset %r15, -24
	.cfi_offset %rbp, -16
	movq	%r8, %r15
	movq	%rcx, 88(%rsp)                  # 8-byte Spill
	movl	%esi, %r12d
	movq	%rdi, 40(%rsp)                  # 8-byte Spill
	movl	%edx, 4(%rsp)                   # 4-byte Spill
	movl	%edx, %r14d
	imull	%esi, %r14d
	movslq	%r14d, %rbx
	leaq	(,%rbx,8), %rbp
	movq	%rbp, %rdi
	callq	malloc
	movq	%rax, SA_Final(%rip)
	movq	%r14, 8(%rsp)                   # 8-byte Spill
	movl	%r14d, %r14d
	testl	%ebx, %ebx
	jle	.LBB5_3
# %bb.1:                                # %.lr.ph.preheader
	xorl	%ebx, %ebx
.LBB5_2:                                # %.lr.ph
                                        # =>This Inner Loop Header: Depth=1
	movl	$8, %edi
	callq	malloc
	movq	SA_Final(%rip), %rcx
	movq	%rax, (%rcx,%rbx,8)
	incq	%rbx
	cmpq	%rbx, %r14
	jne	.LBB5_2
.LBB5_3:                                # %._crit_edge
	movq	%rbp, %rdi
	callq	malloc
	movq	%rax, 48(%rsp)                  # 8-byte Spill
	testl	%r12d, %r12d
	movq	%r15, 96(%rsp)                  # 8-byte Spill
	movq	%r14, 80(%rsp)                  # 8-byte Spill
	jle	.LBB5_4
# %bb.5:                                # %.preheader153.lr.ph
	movq	%rbp, 56(%rsp)                  # 8-byte Spill
	movl	4(%rsp), %ecx                   # 4-byte Reload
	movslq	%ecx, %rax
	movq	%rax, 24(%rsp)                  # 8-byte Spill
	movq	SA_Final(%rip), %rax
	movq	%rax, 64(%rsp)                  # 8-byte Spill
	movl	%r12d, %eax
	movq	%rax, 72(%rsp)                  # 8-byte Spill
	movl	%ecx, %r14d
	xorl	%eax, %eax
	movq	%rax, 16(%rsp)                  # 8-byte Spill
	xorl	%ebx, %ebx
	movq	24(%rsp), %rbp                  # 8-byte Reload
.LBB5_6:                                # %.preheader153
                                        # =>This Loop Header: Depth=1
                                        #     Child Loop BB5_8 Depth 2
	testl	%ecx, %ecx
	jle	.LBB5_9
# %bb.7:                                # %.lr.ph156
                                        #   in Loop: Header=BB5_6 Depth=1
	movl	16(%rsp), %eax                  # 4-byte Reload
	movq	64(%rsp), %rcx                  # 8-byte Reload
	leaq	(%rcx,%rax,8), %rcx
	movq	%rcx, 32(%rsp)                  # 8-byte Spill
	movq	48(%rsp), %rcx                  # 8-byte Reload
	leaq	(%rcx,%rax,8), %r12
	movq	40(%rsp), %rax                  # 8-byte Reload
	movq	(%rax,%rbx,8), %r13
	xorl	%r15d, %r15d
.LBB5_8:                                #   Parent Loop BB5_6 Depth=1
                                        # =>  This Inner Loop Header: Depth=2
	movq	%rbp, %rdi
	callq	malloc
	leaq	(%r12,%r15,8), %rdi
	movq	%rax, (%rdi)
	leaq	(,%r15,8), %rsi
	addq	%r13, %rsi
	movq	%rbp, %rdx
	callq	memcpy@PLT
	movq	32(%rsp), %rax                  # 8-byte Reload
	movq	(%rax,%r15,8), %rax
	movl	%r15d, (%rax)
	movl	%ebx, 4(%rax)
	incq	%r15
	cmpq	%r15, %r14
	jne	.LBB5_8
.LBB5_9:                                # %._crit_edge157
                                        #   in Loop: Header=BB5_6 Depth=1
	incq	%rbx
	movl	4(%rsp), %ecx                   # 4-byte Reload
	movq	16(%rsp), %rax                  # 8-byte Reload
	addl	%ecx, %eax
	movq	%rax, 16(%rsp)                  # 8-byte Spill
	cmpq	72(%rsp), %rbx                  # 8-byte Folded Reload
	jne	.LBB5_6
# %bb.10:
	movq	80(%rsp), %r14                  # 8-byte Reload
	movq	24(%rsp), %rbx                  # 8-byte Reload
	movq	56(%rsp), %rbp                  # 8-byte Reload
	jmp	.LBB5_11
.LBB5_4:                                # %._crit_edge.._crit_edge159_crit_edge
	movslq	4(%rsp), %rbx                   # 4-byte Folded Reload
.LBB5_11:                               # %._crit_edge159
	movq	%rbx, %rdi
	callq	malloc
	movq	%rax, %r13
	movq	%rbp, %rdi
	callq	malloc
	movq	%rax, %r12
	cmpl	$0, 8(%rsp)                     # 4-byte Folded Reload
	jle	.LBB5_12
# %bb.22:                               # %.lr.ph163.preheader
	movq	%r13, 32(%rsp)                  # 8-byte Spill
	movq	%rbx, 24(%rsp)                  # 8-byte Spill
	xorl	%ebx, %ebx
.LBB5_23:                               # %.lr.ph163
                                        # =>This Inner Loop Header: Depth=1
	movl	$1, %edi
	movl	$16, %esi
	callq	calloc@PLT
	movq	%rax, (%r12,%rbx,8)
	incq	%rbx
	cmpq	%rbx, %r14
	jne	.LBB5_23
# %bb.13:                               # %.preheader152
	movq	%r12, 56(%rsp)                  # 8-byte Spill
	cmpl	$1, 8(%rsp)                     # 4-byte Folded Reload
	movq	48(%rsp), %rdi                  # 8-byte Reload
	movl	4(%rsp), %esi                   # 4-byte Reload
	je	.LBB5_27
# %bb.14:                               # %.preheader151.lr.ph
	movq	8(%rsp), %rax                   # 8-byte Reload
	decl	%eax
	movl	%esi, %r14d
	decq	%r14
	xorl	%ecx, %ecx
	movl	%eax, 64(%rsp)                  # 4-byte Spill
	movl	%eax, 40(%rsp)                  # 4-byte Spill
	movq	24(%rsp), %r15                  # 8-byte Reload
.LBB5_15:                               # %.preheader151
                                        # =>This Loop Header: Depth=1
                                        #     Child Loop BB5_17 Depth 2
                                        #       Child Loop BB5_19 Depth 3
	movq	%rcx, 72(%rsp)                  # 8-byte Spill
	movl	%ecx, %eax
	subl	8(%rsp), %eax                   # 4-byte Folded Reload
	cmpl	$-2, %eax
	jg	.LBB5_26
# %bb.16:                               # %.lr.ph165.preheader
                                        #   in Loop: Header=BB5_15 Depth=1
	movl	40(%rsp), %r8d                  # 4-byte Reload
	movq	(%rdi), %r13
	xorl	%ebx, %ebx
	movq	%r8, 16(%rsp)                   # 8-byte Spill
.LBB5_17:                               # %.lr.ph165
                                        #   Parent Loop BB5_15 Depth=1
                                        # =>  This Loop Header: Depth=2
                                        #       Child Loop BB5_19 Depth 3
	movq	%rbx, %rbp
	movq	%r13, %r12
	incq	%rbx
	movq	8(%rdi,%rbp,8), %r13
	testl	%esi, %esi
	jle	.LBB5_25
# %bb.18:                               # %.lr.ph.i.preheader
                                        #   in Loop: Header=BB5_17 Depth=2
	xorl	%eax, %eax
.LBB5_19:                               # %.lr.ph.i
                                        #   Parent Loop BB5_15 Depth=1
                                        #     Parent Loop BB5_17 Depth=2
                                        # =>    This Inner Loop Header: Depth=3
	movb	(%r12,%rax), %cl
	movb	(%r13,%rax), %dl
	cmpb	%dl, %cl
	jg	.LBB5_24
# %bb.20:                               #   in Loop: Header=BB5_19 Depth=3
	jl	.LBB5_25
# %bb.21:                               #   in Loop: Header=BB5_19 Depth=3
	leaq	1(%rax), %rcx
	cmpq	%rax, %r14
	movq	%rcx, %rax
	jne	.LBB5_19
	jmp	.LBB5_25
.LBB5_24:                               # %_Z12compSuffixesPcS_i.exit
                                        #   in Loop: Header=BB5_17 Depth=2
	movq	32(%rsp), %rdi                  # 8-byte Reload
	movq	%r12, %rsi
	movq	%r15, %rdx
	callq	memcpy@PLT
	movq	%r12, %rdi
	movq	%r13, %rsi
	movq	%r15, %rdx
	callq	memcpy@PLT
	movq	%r13, %rdi
	movq	32(%rsp), %rsi                  # 8-byte Reload
	movq	%r15, %rdx
	callq	memcpy@PLT
	movq	16(%rsp), %r8                   # 8-byte Reload
	movq	48(%rsp), %rdi                  # 8-byte Reload
	movq	SA_Final(%rip), %rax
	movq	(%rax,%rbp,8), %rcx
	movl	(%rcx), %edx
	movq	(%rax,%rbx,8), %rax
	movl	(%rax), %esi
	movl	%esi, (%rcx)
	movl	%edx, (%rax)
	movl	4(%rcx), %edx
	movl	4(%rax), %esi
	movl	%esi, 4(%rcx)
	movl	4(%rsp), %esi                   # 4-byte Reload
	movl	%edx, 4(%rax)
.LBB5_25:                               # %_Z12compSuffixesPcS_i.exit.thread
                                        #   in Loop: Header=BB5_17 Depth=2
	cmpq	%r8, %rbx
	jne	.LBB5_17
.LBB5_26:                               # %._crit_edge166
                                        #   in Loop: Header=BB5_15 Depth=1
	movq	72(%rsp), %rcx                  # 8-byte Reload
	incl	%ecx
	decl	40(%rsp)                        # 4-byte Folded Spill
	cmpl	64(%rsp), %ecx                  # 4-byte Folded Reload
	jne	.LBB5_15
.LBB5_27:                               # %._crit_edge168
	movq	32(%rsp), %rdi                  # 8-byte Reload
	callq	free
	movq	48(%rsp), %r11                  # 8-byte Reload
	cmpl	$0, 8(%rsp)                     # 4-byte Folded Reload
	movq	80(%rsp), %r10                  # 8-byte Reload
	movq	24(%rsp), %rbx                  # 8-byte Reload
	movq	96(%rsp), %r14                  # 8-byte Reload
	movq	56(%rsp), %r12                  # 8-byte Reload
	jle	.LBB5_52
# %bb.28:                               # %.preheader150.preheader
	movq	%r11, %rax
	addq	$8, %rax
	movb	$36, %sil
	xorl	%ecx, %ecx
	xorl	%edx, %edx
	movq	88(%rsp), %r15                  # 8-byte Reload
.LBB5_29:                               # %.preheader150
                                        # =>This Loop Header: Depth=1
                                        #     Child Loop BB5_32 Depth 2
	movslq	%edx, %r8
	movq	(%r11,%r8,8), %rdi
	cmpb	%sil, (%rdi)
	jne	.LBB5_30
# %bb.31:                               # %.lr.ph171.preheader
                                        #   in Loop: Header=BB5_29 Depth=1
	leaq	(%rax,%r8,8), %r9
	xorl	%r8d, %r8d
.LBB5_32:                               # %.lr.ph171
                                        #   Parent Loop BB5_29 Depth=1
                                        # =>  This Inner Loop Header: Depth=2
	movq	(%r9,%r8,8), %rdi
	incq	%r8
	cmpb	%sil, (%rdi)
	je	.LBB5_32
# %bb.33:                               # %._crit_edge172.loopexit
                                        #   in Loop: Header=BB5_29 Depth=1
	addl	%r8d, %edx
	jmp	.LBB5_34
.LBB5_30:                               #   in Loop: Header=BB5_29 Depth=1
	xorl	%r8d, %r8d
.LBB5_34:                               # %._crit_edge172
                                        #   in Loop: Header=BB5_29 Depth=1
	cmpq	$1, %rcx
	sbbl	$-1, %r8d
	movl	%r8d, (%r15,%rcx,4)
	movb	(%rdi), %sil
	cmpb	$84, %sil
	je	.LBB5_36
# %bb.35:                               #   in Loop: Header=BB5_29 Depth=1
	incq	%rcx
	incl	%edx
	cmpl	8(%rsp), %edx                   # 4-byte Folded Reload
	jl	.LBB5_29
.LBB5_36:                               # %._crit_edge178
	cmpl	$0, 8(%rsp)                     # 4-byte Folded Reload
	jle	.LBB5_52
# %bb.37:                               # %.lr.ph183.preheader
	xorl	%eax, %eax
.LBB5_38:                               # %.lr.ph183
                                        # =>This Loop Header: Depth=1
                                        #     Child Loop BB5_40 Depth 2
	movq	(%r11,%rax,8), %rcx
	movzbl	-1(%rcx,%rbx), %ecx
	movb	%cl, (%r14,%rax)
	testq	%rax, %rax
	je	.LBB5_41
# %bb.39:                               # %.preheader
                                        #   in Loop: Header=BB5_38 Depth=1
	movq	-8(%r12,%rax,8), %rdx
	movq	(%r12,%rax,8), %rsi
	xorl	%edi, %edi
.LBB5_40:                               #   Parent Loop BB5_38 Depth=1
                                        # =>  This Inner Loop Header: Depth=2
	movl	(%rdx,%rdi,4), %r8d
	movl	%r8d, (%rsi,%rdi,4)
	incq	%rdi
	cmpq	$4, %rdi
	jne	.LBB5_40
.LBB5_41:                               # %.loopexit
                                        #   in Loop: Header=BB5_38 Depth=1
	cmpl	$70, %ecx
	jg	.LBB5_45
# %bb.42:                               # %.loopexit
                                        #   in Loop: Header=BB5_38 Depth=1
	cmpl	$65, %ecx
	je	.LBB5_48
# %bb.43:                               # %.loopexit
                                        #   in Loop: Header=BB5_38 Depth=1
	cmpl	$67, %ecx
	jne	.LBB5_51
# %bb.44:                               #   in Loop: Header=BB5_38 Depth=1
	movq	(%r12,%rax,8), %rcx
	addq	$4, %rcx
	jmp	.LBB5_50
.LBB5_45:                               # %.loopexit
                                        #   in Loop: Header=BB5_38 Depth=1
	cmpl	$71, %ecx
	je	.LBB5_49
# %bb.46:                               # %.loopexit
                                        #   in Loop: Header=BB5_38 Depth=1
	cmpl	$84, %ecx
	jne	.LBB5_51
# %bb.47:                               #   in Loop: Header=BB5_38 Depth=1
	movq	(%r12,%rax,8), %rcx
	addq	$12, %rcx
	jmp	.LBB5_50
.LBB5_48:                               #   in Loop: Header=BB5_38 Depth=1
	movq	(%r12,%rax,8), %rcx
	jmp	.LBB5_50
.LBB5_49:                               #   in Loop: Header=BB5_38 Depth=1
	movq	(%r12,%rax,8), %rcx
	addq	$8, %rcx
.LBB5_50:                               # %.sink.split
                                        #   in Loop: Header=BB5_38 Depth=1
	incl	(%rcx)
.LBB5_51:                               #   in Loop: Header=BB5_38 Depth=1
	incq	%rax
	cmpq	%r10, %rax
	jne	.LBB5_38
	jmp	.LBB5_52
.LBB5_12:                               # %._crit_edge168.thread
	movq	%r13, %rdi
	callq	free
.LBB5_52:                               # %._crit_edge184
	movq	%r12, %rax
	addq	$104, %rsp
	.cfi_def_cfa_offset 56
	popq	%rbx
	.cfi_def_cfa_offset 48
	popq	%r12
	.cfi_def_cfa_offset 40
	popq	%r13
	.cfi_def_cfa_offset 32
	popq	%r14
	.cfi_def_cfa_offset 24
	popq	%r15
	.cfi_def_cfa_offset 16
	popq	%rbp
	.cfi_def_cfa_offset 8
	retq
.Lfunc_end5:
	.size	_Z11makeFMIndexPPPciiPiS_, .Lfunc_end5-_Z11makeFMIndexPPPciiPiS_
	.cfi_endproc
                                        # -- End function
	.globl	main                            # -- Begin function main
	.type	main,@function
main:                                   # @main
	.cfi_startproc
# %bb.0:
	pushq	%r15
	.cfi_def_cfa_offset 16
	pushq	%r14
	.cfi_def_cfa_offset 24
	pushq	%rbx
	.cfi_def_cfa_offset 32
	subq	$48, %rsp
	.cfi_def_cfa_offset 80
	.cfi_offset %rbx, -32
	.cfi_offset %r14, -24
	.cfi_offset %r15, -16
	movq	8(%rsi), %rdi
	movl	$read_count, %esi
	movl	$read_length, %edx
	callq	_Z10inputReadsPcPiS0_
	movq	%rax, %r14
	movslq	read_count(%rip), %r15
	leaq	(,%r15,8), %rdi
	callq	malloc
	movq	%rax, %rbx
	movslq	read_length(%rip), %rdi
	imulq	%r15, %rdi
	shlq	$3, %rdi
	callq	malloc
	movq	%rax, L(%rip)
	leaq	32(%rsp), %rdi
	leaq	8(%rsp), %rsi
	callq	gettimeofday
	movl	read_count(%rip), %esi
	testl	%esi, %esi
	jle	.LBB6_3
# %bb.1:                                # %.lr.ph.preheader
	xorl	%r15d, %r15d
.LBB6_2:                                # %.lr.ph
                                        # =>This Inner Loop Header: Depth=1
	movq	(%r14,%r15,8), %rdi
	movl	read_length(%rip), %esi
	callq	_Z16generateSuffixesPcii
	movq	%rax, (%rbx,%r15,8)
	incq	%r15
	movslq	read_count(%rip), %rsi
	cmpq	%rsi, %r15
	jl	.LBB6_2
.LBB6_3:                                # %._crit_edge
	movl	read_length(%rip), %edx
	movq	L(%rip), %r8
	movl	$F_counts, %ecx
	movq	%rbx, %rdi
                                        # kill: def $esi killed $esi killed $rsi
	callq	_Z11makeFMIndexPPPciiPiS_
	movq	%rax, L_counts(%rip)
	leaq	16(%rsp), %rbx
	movq	%rsp, %r14
	movq	%rbx, %rdi
	movq	%r14, %rsi
	callq	gettimeofday
	movq	%rbx, %rdi
	movq	%r14, %rsi
	callq	gettimeofday
	movl	$_ZSt4cout, %edi
	movl	$.L.str.1, %esi
	movl	$8, %edx
	callq	_ZSt16__ostream_insertIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_PKS3_l
	movl	$_ZSt4cout, %edi
	xorps	%xmm0, %xmm0
	callq	_ZNSo9_M_insertIdEERSoT_
	movq	%rax, %rbx
	movq	(%rax), %rax
	movq	-24(%rax), %rdi
	addq	%rbx, %rdi
	movl	$10, %esi
	callq	_ZNKSt9basic_iosIcSt11char_traitsIcEE5widenEc
	movsbl	%al, %esi
	movq	%rbx, %rdi
	callq	_ZNSo3putEc
	movq	%rax, %rdi
	callq	_ZNSo5flushEv
	xorl	%eax, %eax
	addq	$48, %rsp
	.cfi_def_cfa_offset 32
	popq	%rbx
	.cfi_def_cfa_offset 24
	popq	%r14
	.cfi_def_cfa_offset 16
	popq	%r15
	.cfi_def_cfa_offset 8
	retq
.Lfunc_end6:
	.size	main, .Lfunc_end6-main
	.cfi_endproc
                                        # -- End function
	.type	SA_Final_student,@object        # @SA_Final_student
	.bss
	.globl	SA_Final_student
	.p2align	3, 0x0
SA_Final_student:
	.quad	0
	.size	SA_Final_student, 8

	.type	L_counts_student,@object        # @L_counts_student
	.globl	L_counts_student
	.p2align	3, 0x0
L_counts_student:
	.quad	0
	.size	L_counts_student, 8

	.type	L_student,@object               # @L_student
	.globl	L_student
	.p2align	3, 0x0
L_student:
	.quad	0
	.size	L_student, 8

	.type	F_counts_student,@object        # @F_counts_student
	.globl	F_counts_student
	.p2align	4, 0x0
F_counts_student:
	.zero	16
	.size	F_counts_student, 16

	.type	read_count,@object              # @read_count
	.globl	read_count
	.p2align	2, 0x0
read_count:
	.long	0                               # 0x0
	.size	read_count, 4

	.type	read_length,@object             # @read_length
	.globl	read_length
	.p2align	2, 0x0
read_length:
	.long	0                               # 0x0
	.size	read_length, 4

	.type	SA_Final,@object                # @SA_Final
	.globl	SA_Final
	.p2align	3, 0x0
SA_Final:
	.quad	0
	.size	SA_Final, 8

	.type	L_counts,@object                # @L_counts
	.globl	L_counts
	.p2align	3, 0x0
L_counts:
	.quad	0
	.size	L_counts, 8

	.type	L,@object                       # @L
	.globl	L
	.p2align	3, 0x0
L:
	.quad	0
	.size	L, 8

	.type	F_counts,@object                # @F_counts
	.globl	F_counts
	.p2align	4, 0x0
F_counts:
	.zero	16
	.size	F_counts, 16

	.type	.L.str,@object                  # @.str
	.section	.rodata.str1.1,"aMS",@progbits,1
.L.str:
	.asciz	"r"
	.size	.L.str, 2

	.type	.L.str.1,@object                # @.str.1
.L.str.1:
	.asciz	"Speedup="
	.size	.L.str.1, 9

	.type	__hip_cuid_,@object             # @__hip_cuid_
	.bss
	.globl	__hip_cuid_
__hip_cuid_:
	.byte	0                               # 0x0
	.size	__hip_cuid_, 1

	.ident	"AMD clang version 18.0.0git (https://github.com/RadeonOpenCompute/llvm-project roc-6.3.2 25012 e5bf7e55c91490b07c49d8960fa7983d864936c4)"
	.section	".note.GNU-stack","",@progbits
	.addrsig
	.addrsig_sym read_count
	.addrsig_sym read_length
	.addrsig_sym F_counts
	.addrsig_sym _ZSt4cout
	.addrsig_sym __hip_cuid_

	.text
	.p2alignl 7, 3214868480
	.fill 96, 4, 3214868480
	.type	__hip_cuid_,@object             ; @__hip_cuid_
	.section	.bss,"aw",@nobits
	.globl	__hip_cuid_
__hip_cuid_:
	.byte	0                               ; 0x0
	.size	__hip_cuid_, 1

	.ident	"AMD clang version 18.0.0git (https://github.com/RadeonOpenCompute/llvm-project roc-6.3.2 25012 e5bf7e55c91490b07c49d8960fa7983d864936c4)"
	.section	".note.GNU-stack","",@progbits
	.addrsig
	.addrsig_sym __hip_cuid_
	.amdgcn_target "amdgcn-amd-amdhsa--gfx1100"
	.amdgpu_metadata
---
amdhsa.kernels:  []
amdhsa.target:   amdgcn-amd-amdhsa--gfx1100
amdhsa.version:
  - 1
  - 2
...

	.end_amdgpu_metadata
