// File: /workspace/github_c_makefile_star2_O2/cbouilla[P]AES-attacks-finder/SysEqLin.c
// Function: TailleE
int TailleE(int * __restrict const X, const int N, SysEqLin E) // Renvoi N - dim(E(X)),  N = |X|
{
	//return TailleE(X,N,E);
	/* Beaucoup de variables */
	static int AlloueN = 0;
	static LigneCreuse * __restrict L = NULL;
	static int * __restrict nombre_nnz_colonne = NULL;
	static int AlloueCOL = 0;
	static int AlloueNCOL = 0;
	static int AlloueLIGNE_mat = 0;
	static unsigned char ** __restrict m = NULL;
	static int * __restrict nouvelle_colonne = NULL;
	static int * __restrict colonne_changer = NULL;
	//static int compteur1 = 0, compteur2 = 0, compteur3 = 0, compteur4 = 0;

	
	if (!E->initialise) InitialiseSousMat(E);
		
	if (N*E->gen>AlloueN)
	{
		free(L);
		AlloueN=N*E->gen;
		//printf("AlloueN : %d\n",AlloueN);
		L=malloc(AlloueN*sizeof(LigneCreuse));
	}

	if (E->col_max>AlloueCOL)
	{
		nouvelle_colonne=realloc(nouvelle_colonne,E->col_max*sizeof(int));
		int i;
		for (i = AlloueCOL; i < E->col_max; i++) nouvelle_colonne[i]=-1;
		free(nombre_nnz_colonne);
		AlloueCOL=E->col_max;
		//printf("AlloueCOL : %d\n",AlloueCOL);
		nombre_nnz_colonne=calloc(AlloueCOL,sizeof(int));
	}

	int NombreDeLignes =  0;
	int taille=0,i;
	for (i = 0; i < N; i++)
	{
		if (E->lignevar[X[i]]*E->gen<E->a)
		{
			int j;
			for (j = 0; j < E->sousmat[X[i]]->nombre_de_lignes; j++) L[NombreDeLignes++]=E->sousmat[X[i]]->ligne[j];
			taille++;
		}
	}

	/* 
	 * On compte le nombre d'éléments non-nuls sur chaque colonne
	 */
	int NombreDeColonnes = 0;
	for (i = 0; i < NombreDeLignes; i++)
	{
		int j;
		for (j = 0; j < L[i]->nnz; j++)
		{
			if (!nombre_nnz_colonne[L[i]->elements[j].colonne]) NombreDeColonnes++;
			nombre_nnz_colonne[L[i]->elements[j].colonne]++;
		}
	}

	/*
	 * On va essayer de faire une partie du pivot sur la matrice creuse
	 * (c'est rentable de part la forme des sous-mat)
	 */
	int dim = (1-E->gen)*taille;
	//int cpt=NombreDeLignes;
	int ligne = 0;
	//while (cpt)
	while (ligne<NombreDeLignes)
	{
		//if (ligne==NombreDeLignes) ligne=0;
		int nombre_element_ligne = 0;
		int colonne_a_enlever;
		int j;
		for (j = 0; j < L[ligne]->nnz; j++)
		{
			if (nombre_nnz_colonne[L[ligne]->elements[j].colonne])
			{
				if (nombre_nnz_colonne[L[ligne]->elements[j].colonne]==1) // 1 seul élément non nul sur la colonne -> très bon pivot pour matrice creuse
				{
					int l;
					for (l = 0; l < L[ligne]->nnz; l++)
					{
						if (nombre_nnz_colonne[L[ligne]->elements[l].colonne])
						{
							if (nombre_nnz_colonne[L[ligne]->elements[l].colonne] == 1) NombreDeColonnes--;
							nombre_nnz_colonne[L[ligne]->elements[l].colonne]--; // On met à jour le nombre d'éléments dans les colonnes
						}
					}
					goto suppr_ligne;
				}
				else
				{
					nombre_element_ligne++;
					colonne_a_enlever = j;
				}
			}
		}
		if (nombre_element_ligne<=1)
		{
			if (nombre_element_ligne==1) // 1 seul élément sur la ligne
			{
				nombre_nnz_colonne[L[ligne]->elements[colonne_a_enlever].colonne] = 0; // on supprime la colonne
				NombreDeColonnes--;
				suppr_ligne: // on met à jour la dim et on supprime la ligne
				dim++;
				//cpt=NombreDeLignes;
			}
			NombreDeLignes--;
			L[ligne]=L[NombreDeLignes];
		}
		else ligne++;
		//cpt--;
	}
	
	if (NombreDeColonnes>AlloueNCOL)
	{
		AlloueNCOL=NombreDeColonnes;
		for (i = 0; i < AlloueLIGNE_mat; i++)
		{
			free(m[i]);
			m[i]=malloc(AlloueNCOL*sizeof(unsigned char));
		}
		free(colonne_changer);
		colonne_changer=malloc((AlloueNCOL+1)*sizeof(int));
	}
	if (NombreDeLignes>AlloueLIGNE_mat)
	{
		m = realloc(m,NombreDeLignes*sizeof(unsigned char *));
		for (i = AlloueLIGNE_mat; i < NombreDeLignes; i++) m[i] = malloc(AlloueNCOL*sizeof(unsigned char));
		AlloueLIGNE_mat = NombreDeLignes;
		//printf("AlloueLIGNE_mat : %d\n",AlloueLIGNE_mat);
	}
	
	int pos=0;
	int DerniereColonne = NombreDeColonnes-1;
	int Ncol = 0;
	for (i = 0; i < NombreDeLignes; i++)
	{
		int k;
		unsigned char * __restrict ligne_matrice = m[i];
		for (k = 0; k < NombreDeColonnes; k++) ligne_matrice[k]=0;
		int premier = 1;
		for (k = 0; k < L[i]->nnz; k++)
		{
			if (nombre_nnz_colonne[L[i]->elements[k].colonne])
			{
				nombre_nnz_colonne[L[i]->elements[k].colonne]--;
				colonne_changer[pos]=L[i]->elements[k].colonne;
				int colonne;
				if (nouvelle_colonne[colonne_changer[pos]]>=0) colonne=nouvelle_colonne[colonne_changer[pos]];
				else
				{
					if (!premier)
					{
						nouvelle_colonne[colonne_changer[pos++]]=DerniereColonne;
						colonne=DerniereColonne--;
					}
					else
					{
						nouvelle_colonne[colonne_changer[pos++]]=Ncol;
						colonne=Ncol++;
						premier=0;
					}
				}
				ligne_matrice[colonne]=L[i]->elements[k].coeff;								
			}
		}
	}
			
	for (i = 0; i < pos; i++) nouvelle_colonne[colonne_changer[i]]=-1; // on remet le tableau à zero pour la prochaine execution

	//compteur4++;
	//printf("cpt1 = %d, cpt2 = %d, cpt3 = %d, cpt4 = %d\n",compteur1,compteur2,compteur3,compteur4);
															
	return dim+Dimension_tmp(m,NombreDeLignes,NombreDeColonnes);
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x38, %rsp
movq %rdx, %r15
movl %esi, %r14d
movq %rdi, %r12
cmpb $0x0, 0x28(%rdx)
jne 0x96f4
movq %r15, %rdi
callq 0x9638
movl 0x10(%r15), %eax
imull %r14d, %eax
cmpl 0x26c02(%rip), %eax     # 0x30304
jle 0x9731
movq 0x26bfd(%rip), %rdi     # 0x30308
callq 0x2030
movslq 0x10(%r15), %rax
movslq %r14d, %rdi
imulq %rax, %rdi
movl %edi, 0x26be3(%rip)     # 0x30304
shlq $0x3, %rdi
callq 0x21c0
movq %rax, 0x26bd7(%rip)     # 0x30308
movslq 0x38(%r15), %rsi
movslq 0x26bdc(%rip), %rbx     # 0x30318
cmpl %ebx, %esi
jle 0x978e
movq 0x26be9(%rip), %rdi     # 0x30330
shlq $0x2, %rsi
callq 0x21f0
movq %rax, 0x26bd9(%rip)     # 0x30330
movslq 0x38(%r15), %rcx
cmpq %rcx, %rbx
jge 0x9769
orl $-0x1, (%rax,%rbx,4)
incq %rbx
jmp 0x975b
movq 0x26ba0(%rip), %rdi     # 0x30310
callq 0x2030
movslq 0x38(%r15), %rdi
movl %edi, 0x26b99(%rip)     # 0x30318
pushq $0x4
popq %rsi
callq 0x2150
movq %rax, 0x26b82(%rip)     # 0x30310
movq 0x26b73(%rip), %rax     # 0x30308
movq %rax, 0x10(%rsp)
xorl %ecx, %ecx
testl %r14d, %r14d
cmovlel %ecx, %r14d
xorl %r10d, %r10d
xorl %eax, %eax
cmpq %r14, %rcx
je 0x97fc
movq 0x18(%r15), %rsi
movslq (%r12,%rcx,4), %rdx
movl 0x10(%r15), %edi
imull (%rsi,%rdx,4), %edi
cmpl 0x8(%r15), %edi
jge 0x97f7
movslq %r10d, %rsi
movq 0x10(%rsp), %rdi
leaq (%rdi,%rsi,8), %rdi
xorl %esi, %esi
movq 0x30(%r15), %r8
movq (%r8,%rdx,8), %r8
movslq (%r8), %r9
cmpq %r9, %rsi
jge 0x97f2
movq 0x8(%r8), %r8
movq (%r8,%rsi,8), %r8
movq %r8, (%rdi,%rsi,8)
incq %rsi
jmp 0x97d1
addl %esi, %r10d
incl %eax
incq %rcx
jmp 0x97a8
movq 0x26b0d(%rip), %rbp     # 0x30310
xorl %ecx, %ecx
testl %r10d, %r10d
movl $0x0, %edx
movl %r10d, 0xc(%rsp)
cmovgl %r10d, %edx
xorl %r14d, %r14d
cmpq %rdx, %rcx
je 0x9859
movq 0x10(%rsp), %rsi
movq (%rsi,%rcx,8), %rsi
xorl %edi, %edi
movslq (%rsi), %r8
cmpq %r8, %rdi
jge 0x9854
movq 0x8(%rsi), %r8
movslq 0x4(%r8,%rdi,8), %r8
movl (%rbp,%r8,4), %r9d
cmpl $0x1, %r9d
adcl $0x0, %r14d
incl %r9d
movl %r9d, (%rbp,%r8,4)
incq %rdi
jmp 0x9829
incq %rcx
jmp 0x9819
pushq $0x1
popq %rcx
subl 0x10(%r15), %ecx
imull %eax, %ecx
movl %ecx, 0x2c(%rsp)
xorl %eax, %eax
movl 0xc(%rsp), %edx
movslq %edx, %rbx
cmpl %edx, %eax
jge 0x993f
movslq %eax, %rsi
movq 0x10(%rsp), %rdx
movq (%rdx,%rsi,8), %rdx
movl (%rdx), %edi
xorl %r9d, %r9d
testl %edi, %edi
movl $0x0, %r10d
cmovgl %edi, %r10d
xorl %r11d, %r11d
cmpq %r9, %r10
je 0x98c1
movq 0x8(%rdx), %r8
movslq 0x4(%r8,%r9,8), %r15
movl (%rbp,%r15,4), %r15d
testl %r15d, %r15d
je 0x98bc
cmpl $0x1, %r15d
je 0x98cb
incl %r11d
movl %r9d, %ecx
incq %r9
jmp 0x9898
cmpl $0x1, %r11d
jle 0x9906
incl %eax
jmp 0x9869
movq 0x10(%rsp), %r9
leaq (%r9,%rsi,8), %rsi
xorl %r9d, %r9d
movslq %edi, %r10
cmpq %r10, %r9
jge 0x9925
movslq 0x4(%r8,%r9,8), %r10
movl (%rbp,%r10,4), %r11d
testl %r11d, %r11d
je 0x9901
cmpl $0x1, %r11d
jne 0x98f7
decl %r14d
decl %r11d
movl %r11d, (%rbp,%r10,4)
movl (%rdx), %edi
incq %r9
jmp 0x98d7
movq 0x10(%rsp), %rdi
leaq (%rdi,%rsi,8), %rsi
jne 0x9929
movq 0x8(%rdx), %rdx
movslq %ecx, %rdi
movslq 0x4(%rdx,%rdi,8), %rdx
andl $0x0, (%rbp,%rdx,4)
decl %r14d
incl 0x2c(%rsp)
decl 0xc(%rsp)
movq 0x10(%rsp), %rdx
movq -0x8(%rdx,%rbx,8), %rdx
movq %rdx, (%rsi)
jmp 0x9869
movl 0x269d6(%rip), %r12d    # 0x3031c
movslq 0x269d3(%rip), %r15     # 0x30320
movq 0x269d4(%rip), %rax     # 0x30328
movq %rax, 0x18(%rsp)
cmpl %r12d, %r14d
jle 0x99d3
movl %r14d, 0x269b7(%rip)    # 0x3031c
movl %r14d, %eax
movq %rax, 0x20(%rsp)
xorl %r12d, %r12d
testl %r15d, %r15d
movl $0x0, %eax
cmovgl %r15d, %eax
movq %rax, 0x30(%rsp)
movq 0x18(%rsp), %r13
cmpq %r12, 0x30(%rsp)
je 0x99ab
movq (%r13,%r12,8), %rdi
callq 0x2030
movq 0x20(%rsp), %rdi
callq 0x21c0
movq %rax, (%r13,%r12,8)
incq %r12
jmp 0x9986
movq 0x26986(%rip), %rdi     # 0x30338
callq 0x2030
movq 0x20(%rsp), %rax
leaq 0x4(,%rax,4), %rdi
callq 0x21c0
movq %rax, 0x26968(%rip)     # 0x30338
movl %r14d, %r12d
movl 0xc(%rsp), %eax
cmpl %r15d, %eax
jle 0x9a20
movl %eax, %esi
shlq $0x3, %rsi
movq 0x18(%rsp), %rdi
callq 0x21f0
movq %rax, 0x18(%rsp)
movq %rax, 0x26930(%rip)     # 0x30328
movl %r12d, %r12d
cmpq %rbx, %r15
jge 0x9a16
movq %r12, %rdi
callq 0x21c0
movq 0x18(%rsp), %rcx
movq %rax, (%rcx,%r15,8)
incq %r15
jmp 0x99fb
movl 0xc(%rsp), %eax
movl %eax, 0x26900(%rip)     # 0x30320
leal -0x1(%r14), %r9d
movq 0x2690d(%rip), %rcx     # 0x30338
movq %rcx, 0x20(%rsp)
movq 0x268f9(%rip), %rcx     # 0x30330
xorl %esi, %esi
testl %r14d, %r14d
movl $0x0, %edi
cmovgl %r14d, %edi
testl %eax, %eax
movl $0x0, %edx
cmovgl %eax, %edx
movq %rdx, 0x30(%rsp)
xorl %edx, %edx
xorl %r11d, %r11d
cmpq 0x30(%rsp), %rsi
je 0x9b23
movq 0x18(%rsp), %rax
movq (%rax,%rsi,8), %r10
xorl %r8d, %r8d
cmpq %r8, %rdi
je 0x9a7f
movb $0x0, (%r10,%r8)
incq %r8
jmp 0x9a70
xorl %ebx, %ebx
pushq $0x1
popq %r15
movq 0x10(%rsp), %rax
movq (%rax,%rsi,8), %rax
movslq (%rax), %r8
cmpq %r8, %rbx
jge 0x9b1b
movq 0x8(%rax), %r12
movslq 0x4(%r12,%rbx,8), %rax
movl (%rbp,%rax,4), %r8d
testl %r8d, %r8d
je 0x9b13
decl %r8d
movl %r8d, (%rbp,%rax,4)
movslq 0x4(%r12,%rbx,8), %r8
movslq %edx, %rax
movq 0x20(%rsp), %r13
movl %r8d, (%r13,%rax,4)
movl (%rcx,%r8,4), %eax
testl %eax, %eax
js 0x9ada
movl %r9d, %r8d
movl %r11d, %r13d
movl %eax, %r9d
jmp 0x9b02
incl %edx
testl %r15d, %r15d
jne 0x9af1
movl %r9d, (%rcx,%r8,4)
leal -0x1(%r9), %r8d
xorl %r15d, %r15d
movl %r11d, %r13d
jmp 0x9b02
movl %r11d, (%rcx,%r8,4)
leal 0x1(%r11), %r13d
xorl %r15d, %r15d
movl %r9d, %r8d
movl %r11d, %r9d
movb (%r12,%rbx,8), %al
movslq %r9d, %r9
movb %al, (%r10,%r9)
movl %r8d, %r9d
movl %r13d, %r11d
incq %rbx
jmp 0x9a85
incq %rsi
jmp 0x9a59
xorl %edi, %edi
testl %edx, %edx
cmovlel %edi, %edx
movl 0xc(%rsp), %esi
cmpq %rdi, %rdx
je 0x9b45
movq 0x20(%rsp), %rax
movslq (%rax,%rdi,4), %rax
orl $-0x1, (%rcx,%rax,4)
incq %rdi
jmp 0x9b2e
movq 0x18(%rsp), %rdi
movl %r14d, %edx
callq 0x2d2d
addl 0x2c(%rsp), %eax
addq $0x38, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq