// File: /workspace/github_cpp_makefile_star2_O2/CMU-SAFARI[P]Register-Interval/./src/implementation/RegisterIntervalCreation.cpp
// Function: RegisterIntervalCreationPass::traverse(basicBlock*, int)
void RegisterIntervalCreationPass::traverse(basicBlock* BB, int N){
	set<string> temp_list;
	vector<basicBlock*> V;
	auto register_list = BB->get_input_list();

	basicBlock* BB1;
	registerInterval* temp;
        string new_name, old_name;
        
        //set<string> register_list;//register_list is a list that will be updated after processing each instruction and the new registers will be added to it
        //register_list.clear();
        set<string> temporary_register_list;//temporary_register_list contains is like register_list but it can have more than N registers and it is checked at each iteration
        temporary_register_list.clear();
        
        string code = BB->get_code();//code is the string of instruction sequence
        
	int found1 = 0; //points to the beginning of the instruction string
	int found2 = code.find(";", found1, 1); //points to the end of instructions string
	while (found2 != string::npos){//This loop continues until all instructions of the basic block are processed
		
                /* this loop updates register_list for the current instruction (in other words it finds the register operands of the instruction)*/
		for (int i = found1; i < found2; i++){
			if (code[i] == 'R'){
				string str = "";
				if (code[i + 1]>47 && code[i + 1] < 58){
					str.push_back('R');
					str.push_back(code[i + 1]);
					if (code[i + 2]>47 && code[i + 2] < 58){
						str.push_back(code[i + 2]);
					}
					temporary_register_list.insert(str);
				}
			}
		}

		/*after cheching the size of temporary_register_list, we decide to split the basic block or not */
		if (temporary_register_list.size() > N){
                        /*At this point the basic block will be splited and the current instruction will reside in the second baisc basicBlock*/
			string code1, code2;//code1 and code2 contain the instructions of two basic blocks after splitting
                        code1.append(code, 0, found1); 
			code2.append(code, found1 + 1, code.size() - found1);


			//introducing a new basic block BB1:
			BB1 = new basicBlock();
			basic_blocks.push_back(BB1);
			
			old_name = BB->get_name();
			string new_name = old_name + std::to_string(BB->getID() + 1);
			BB1->set_name(new_name);//sets the name of the new basic blcok
			
                        int found = 0;
			found = code2.find(old_name, found+1);
			while(found != string::npos){//in thils loop finds points of code that uses the old name and replaces with the new name
				code2.replace(found, old_name.size(), new_name);
				
				found = code2.find(old_name, found+1);
			}
			BB1->set_code(code2);

			/*At this point the register set of the new basic block will be set*/
			found = 0;
			found = code2.find("R", found + 1, 1);
			while (found != string::npos){
				string str = "R";
				if (code2[found + 1] > 47 && code2[found + 1] < 58){
					for (int j = found + 1; code2[j] >47 && code2[j] < 58; j++){
						str = str + code2[j];
					}
					BB1->add_register(str);
				}

				found = code2.find("R", found + 1, 1);
			}
                        
                        //The BB will be splitted and its code and register list are updated
			BB->set_code(code1);
			BB->set_output_list(register_list);

			/*setting successors of old and new basic blocks*/
			BB1->set_successors(BB->get_successors()); //the successors of the new basic block is just like the original basic block
                        vector<basicBlock*> S;
                        S.clear();
                        S.push_back(BB1);
                        BB->set_successors(S); //the only successor of the old basic block is the new one

			/*setting predecessors of new and old basic blocks*/
			BB1->add_predecessor(BB); //the only predecessor of the new basic block is the old one (also the predecessors of the old basic block won't change)
			

			auto temp = new registerInterval();
			RegisterIntervals.push_back(temp);
			BB1->set_registerInterval(temp);
			BB1->clear_input_list();
			WS.push(BB1);//the new basic block has been assigned to a new register-interval

			return;
		}
		else{
			register_list = temporary_register_list;
			BB->set_output_list(register_list);
		}

		register_list = temporary_register_list;
		found1 = found2 + 1;
		found2 = code.find(";", found1, 1);
	}

	return;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x2e8, %rsp            # imm = 0x2E8
leaq -0x2d8(%rbp), %rax
andl $0x0, (%rax)
andq $0x0, 0x8(%rax)
movq %rax, 0x10(%rax)
movq %rax, 0x18(%rax)
andq $0x0, 0x20(%rax)
movl %esi, %ebx
movq %rdi, %r14
xorps %xmm0, %xmm0
movaps %xmm0, -0x130(%rbp)
andq $0x0, -0x120(%rbp)
leaq 0x90(%rdi), %rsi
leaq -0x220(%rbp), %rdi
callq 0x6ef4
leaq -0x250(%rbp), %rax
movq %rax, -0x10(%rax)
andq $0x0, -0x8(%rax)
xorl %r13d, %r13d
movb %r13b, (%rax)
leaq -0x108(%rbp), %rax
movq %rax, -0x10(%rax)
andq $0x0, -0x8(%rax)
movb %r13b, (%rax)
leaq -0x188(%rbp), %rax
andl $0x0, (%rax)
andq $0x0, 0x8(%rax)
movq %rax, 0x10(%rax)
movq %rax, 0x18(%rax)
andq $0x0, 0x20(%rax)
leaq -0x190(%rbp), %rdi
callq 0x75c8
leaq 0x28(%r14), %rsi
leaq -0x80(%rbp), %rdi
callq 0x2270
leaq 0x596a(%rip), %rsi      # 0x912d
leaq -0x80(%rbp), %rdi
pushq $0x1
popq %r15
xorl %edx, %edx
movq %r15, %rcx
callq 0x2330
movq %rax, %rcx
movslq %ebx, %rax
movq %rax, -0xb0(%rbp)
movq %r14, -0x38(%rbp)
leaq 0xc0(%r14), %rax
movq %rax, -0x40(%rbp)
leaq -0xf8(%rbp), %r14
cmpl $-0x1, %ecx
je 0x3d53
movslq %r13d, %rbx
movq %rcx, -0xb8(%rbp)
movslq %ecx, %r13
movq %rbx, -0xa8(%rbp)
cmpq %r13, %rbx
jge 0x38ab
movq -0x80(%rbp), %rax
cmpb $0x52, (%rax,%rbx)
jne 0x38a3
movq %r14, %rdi
leaq 0x5884(%rip), %rsi      # 0x90b6
leaq -0x60(%rbp), %rdx
callq 0x20c0
leaq 0x1(%rbx), %r12
movq -0x80(%rbp), %rax
movb 0x1(%rax,%rbx), %al
addb $-0x30, %al
cmpb $0x9, %al
ja 0x3893
movq %r14, %rdi
pushq $0x52
popq %rsi
callq 0x2170
movq -0x80(%rbp), %rax
movsbl (%rax,%r12), %esi
movq %r14, %rdi
callq 0x2170
movq -0x80(%rbp), %rax
movb 0x2(%rax,%rbx), %al
leal -0x30(%rax), %ecx
cmpb $0x9, %cl
ja 0x3884
movsbl %al, %esi
movq %r14, %rdi
callq 0x2170
leaq -0x190(%rbp), %rdi
movq %r14, %rsi
callq 0x7ee6
movq %r14, %rdi
callq 0x2100
movq %r12, %rbx
jmp 0x3815
incq %rbx
jmp 0x3815
movq -0xb0(%rbp), %rax
cmpq %rax, -0x168(%rbp)
ja 0x3930
leaq -0x220(%rbp), %rbx
movq %rbx, %rdi
leaq -0x190(%rbp), %rsi
callq 0x7194
movq -0xb8(%rbp), %r12
leaq -0x310(%rbp), %r13
movq %r13, %rdi
movq %rbx, %rsi
callq 0x6ef4
movq -0x40(%rbp), %rdi
movq %r13, %rsi
callq 0x7194
movq %r13, %rdi
callq 0x6e7c
movq %rbx, %rdi
leaq -0x190(%rbp), %rsi
callq 0x7194
leal 0x1(%r12), %r13d
movslq %r13d, %rdx
leaq -0x80(%rbp), %rdi
leaq 0x580d(%rip), %rsi      # 0x912d
movq %r15, %rcx
callq 0x2330
movq %rax, %rcx
jmp 0x37f8
leaq -0xe8(%rbp), %rax
movq %rax, -0x10(%rax)
andq $0x0, -0x8(%rax)
xorl %ecx, %ecx
movb %cl, (%rax)
leaq -0x50(%rbp), %rax
movq %rax, -0x10(%rax)
andq $0x0, -0x8(%rax)
movb %cl, (%rax)
leaq -0xf8(%rbp), %rdi
leaq -0x80(%rbp), %rsi
xorl %edx, %edx
movq -0xa8(%rbp), %rbx
movq %rbx, %rcx
callq 0x2280
leal 0x1(%rbx), %eax
movslq %eax, %rdx
leaq -0x80(%rbp), %rsi
movq 0x8(%rsi), %rcx
subq %rbx, %rcx
leaq -0x60(%rbp), %rdi
callq 0x2280
movl $0xf8, %edi
callq 0x21c0
movq %rax, %rbx
movq %rax, %rdi
callq 0x291e
leaq -0x30(%rbp), %rsi
movq %rbx, (%rsi)
leaq 0xa85c(%rip), %rdi      # 0xe208
callq 0x6ab2
movq -0x38(%rbp), %r14
leaq 0x8(%r14), %rsi
leaq -0xd8(%rbp), %rdi
callq 0x2270
leaq -0x118(%rbp), %rdi
leaq -0xd8(%rbp), %rbx
movq %rbx, %rsi
callq 0x2220
movq %rbx, %rdi
callq 0x2100
movl (%r14), %esi
incl %esi
leaq -0xa0(%rbp), %rdi
callq 0x6cac
leaq -0xd8(%rbp), %rdi
leaq -0x118(%rbp), %rsi
leaq -0xa0(%rbp), %rdx
callq 0x6c5e
leaq -0xa0(%rbp), %rdi
callq 0x2100
movq -0x30(%rbp), %rbx
leaq -0x1f0(%rbp), %rdi
leaq -0xd8(%rbp), %rsi
callq 0x2270
addq $0x8, %rbx
leaq -0x1f0(%rbp), %rsi
movq %rbx, %rdi
callq 0x2130
leaq -0x1f0(%rbp), %rdi
callq 0x2100
leaq -0x60(%rbp), %rbx
leaq -0x118(%rbp), %r14
movabsq $-0x100000000, %r13     # imm = 0xFFFFFFFF00000000
leaq -0xd8(%rbp), %r12
movq %rbx, %rdi
movq %r14, %rsi
movq %r15, %rdx
callq 0x23a0
movq %rax, %r15
shlq $0x20, %r15
cmpq %r13, %r15
je 0x3ab2
movq %r15, %rsi
sarq $0x20, %rsi
movq -0x110(%rbp), %rdx
movq %rbx, %rdi
movq %r12, %rcx
callq 0x20b0
movabsq $0x100000000, %rax      # imm = 0x100000000
addq %rax, %r15
sarq $0x20, %r15
jmp 0x3a6c
movq -0x30(%rbp), %rbx
leaq -0x1d0(%rbp), %rdi
leaq -0x60(%rbp), %rsi
callq 0x2270
movq -0x38(%rbp), %r15
leaq -0x1d0(%rbp), %rsi
movq %rbx, %rdi
callq 0x2c08
leaq -0x1d0(%rbp), %rdi
callq 0x2100
leaq 0x5534(%rip), %rbx      # 0x9020
leaq -0x60(%rbp), %rdi
pushq $0x1
popq %rcx
movq %rbx, %rsi
movq %rcx, %rdx
callq 0x2330
movq %rax, %r14
leaq -0xa0(%rbp), %r12
leaq -0x240(%rbp), %r13
cmpl $-0x1, %r14d
je 0x3be3
movq %r12, %rdi
movq %rbx, %rsi
movq %r13, %rdx
callq 0x20c0
shlq $0x20, %r14
movabsq $0x100000000, %rax      # imm = 0x100000000
addq %rax, %r14
sarq $0x20, %r14
movq -0x60(%rbp), %rax
movb (%rax,%r14), %al
leal -0x30(%rax), %ecx
cmpb $0x9, %cl
ja 0x3bc1
leaq 0x1(%r14), %r15
leal -0x30(%rax), %ecx
cmpb $0xa, %cl
jae 0x3b86
movsbl %al, %edx
movq %r13, %rdi
movq %r12, %rsi
callq 0x6d0c
movq %r12, %rdi
movq %r13, %rsi
callq 0x2220
movq %r13, %rdi
callq 0x2100
movq -0x60(%rbp), %rax
movb (%rax,%r15), %al
incq %r15
jmp 0x3b50
movq -0x30(%rbp), %r15
leaq -0x2b0(%rbp), %rbx
movq %rbx, %rdi
movq %r12, %rsi
callq 0x2270
addq $0xc0, %r15
movq %r15, %rdi
movq %rbx, %rsi
callq 0x7ee6
movq %rbx, %rdi
callq 0x2100
movq -0x38(%rbp), %r15
leaq 0x545f(%rip), %rbx      # 0x9020
leaq -0x60(%rbp), %rdi
movq %rbx, %rsi
movq %r14, %rdx
pushq $0x1
popq %rcx
callq 0x2330
movq %rax, %r14
movq %r12, %rdi
callq 0x2100
jmp 0x3b0f
leaq -0x1b0(%rbp), %rdi
leaq -0xf8(%rbp), %rsi
callq 0x2270
leaq -0x1b0(%rbp), %rsi
movq %r15, %rdi
callq 0x2c08
leaq -0x1b0(%rbp), %rdi
callq 0x2100
leaq -0x290(%rbp), %rdi
leaq -0x220(%rbp), %rsi
callq 0x6ef4
leaq -0x290(%rbp), %rsi
movq -0x40(%rbp), %rdi
callq 0x7194
leaq -0x290(%rbp), %rdi
callq 0x6e7c
movq -0x30(%rbp), %r14
leaq 0x78(%r15), %rbx
leaq -0x160(%rbp), %rdi
movq %rbx, %rsi
callq 0x6bdc
addq $0x78, %r14
leaq -0x160(%rbp), %rsi
movq %r14, %rdi
callq 0x6ad6
leaq -0x160(%rbp), %rdi
callq 0x7ed2
xorps %xmm0, %xmm0
leaq -0xa0(%rbp), %rdi
movaps %xmm0, (%rdi)
andq $0x0, 0x10(%rdi)
leaq -0x30(%rbp), %rsi
callq 0x6ab2
leaq -0x148(%rbp), %rdi
leaq -0xa0(%rbp), %rsi
callq 0x6bdc
leaq -0x148(%rbp), %rsi
movq %rbx, %rdi
callq 0x6ad6
leaq -0x148(%rbp), %rdi
callq 0x7ed2
movq -0x30(%rbp), %rdi
movq %r15, %rsi
callq 0x2c76
movl $0xc0, %edi
callq 0x21c0
movq %rax, %rbx
movq %rax, %rdi
callq 0x25cc
leaq -0x240(%rbp), %rsi
movq %rbx, (%rsi)
leaq 0xa52f(%rip), %rdi      # 0xe220
callq 0x6a2c
leaq -0x30(%rbp), %rbx
movq (%rbx), %rdi
movq -0x240(%rbp), %rax
movq %rax, 0xf0(%rdi)
addq $0x90, %rdi
callq 0x75c8
leaq 0xa51a(%rip), %rdi      # 0xe238
movq %rbx, %rsi
callq 0x83c0
leaq -0xa0(%rbp), %rdi
callq 0x7ed2
leaq -0xd8(%rbp), %rdi
callq 0x2100
leaq -0x60(%rbp), %rdi
callq 0x2100
leaq -0xf8(%rbp), %rdi
callq 0x2100
leaq -0x80(%rbp), %rdi
callq 0x2100
leaq -0x190(%rbp), %rdi
callq 0x6e7c
leaq -0x118(%rbp), %rdi
callq 0x2100
leaq -0x260(%rbp), %rdi
callq 0x2100
leaq -0x220(%rbp), %rdi
callq 0x6e7c
leaq -0x130(%rbp), %rdi
callq 0x7ed2
leaq -0x2e0(%rbp), %rdi
callq 0x6e7c
addq $0x2e8, %rsp            # imm = 0x2E8
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq %rax, %rbx
leaq -0x148(%rbp), %rdi
callq 0x7ed2
jmp 0x3e35
movq %rax, %rbx
leaq -0x160(%rbp), %rdi
jmp 0x3e3c
movq %rax, %rbx
leaq -0x290(%rbp), %rdi
callq 0x6e7c
jmp 0x3e86
movq %rax, %rbx
leaq -0x1b0(%rbp), %rdi
jmp 0x3e81
movq %rax, %rbx
leaq -0x1d0(%rbp), %rdi
jmp 0x3e81
movq %rax, %rbx
leaq -0x1f0(%rbp), %rdi
jmp 0x3e81
jmp 0x3e5f
movq %rax, %rbx
leaq -0xa0(%rbp), %rdi
jmp 0x3e8d
jmp 0x3e45
jmp 0x3e45
movq %rax, %rbx
jmp 0x3eba
movq %rax, %rbx
jmp 0x3eea
jmp 0x3e32
movq %rax, %rbx
leaq -0xa0(%rbp), %rdi
callq 0x7ed2
jmp 0x3e86
jmp 0x3e5f
movq %rax, %rbx
jmp 0x3e92
movq %rax, %rbx
leaq -0x2b0(%rbp), %rdi
callq 0x2100
jmp 0x3e7a
jmp 0x3e77
jmp 0x3e5f
movq %rax, %rbx
jmp 0x3e86
movq %rax, %rbx
leaq -0x310(%rbp), %rdi
callq 0x6e7c
jmp 0x3eb1
jmp 0x3e9d
movq %rax, %rbx
leaq -0xa0(%rbp), %rdi
callq 0x2100
leaq -0xd8(%rbp), %rdi
callq 0x2100
leaq -0x60(%rbp), %rdi
callq 0x2100
jmp 0x3ea5
movq %rax, %rbx
jmp 0x3eb1
movq %rax, %rbx
leaq -0xf8(%rbp), %rdi
callq 0x2100
leaq -0x80(%rbp), %rdi
callq 0x2100
leaq -0x190(%rbp), %rdi
callq 0x6e7c
leaq -0x118(%rbp), %rdi
callq 0x2100
leaq -0x260(%rbp), %rdi
callq 0x2100
leaq -0x220(%rbp), %rdi
callq 0x6e7c
leaq -0x130(%rbp), %rdi
callq 0x7ed2
leaq -0x2e0(%rbp), %rdi
callq 0x6e7c
movq %rbx, %rdi
callq 0x2340