<commit_before>/*
 * BuildControlFlow.cpp
 *
 *  Created on: 29 nov. 2016
 *      Author: <NAME>
 */

#include <stdio.h>

#include <dbt/dbtPlateform.h>
#include <dbt/insertions.h>
#include <dbt/profiling.h>

#include <isa/irISA.h>
#include <isa/vexISA.h>

#include <stdlib.h>
#include <string.h>

#include <types.h>
#include <lib/endianness.h>

#include <transformation/irGenerator.h>

#define TEMP_PROCEDURE_STORAGE_SIZE 50
#define TEMP_BLOCK_STORAGE_SIZE 900


void buildBasicControlFlow(DBTPlateform *dbtPlateform, int section, int mipsStartAddress, int sectionStartAddress, int startAddress, int endAddress, IRApplication *application, Profiler *profiler){

	int sizeNewlyTranslated = endAddress-startAddress;
	mipsStartAddress = mipsStartAddress>>2;


	//This first step consists of mapping insertions in order to easily say if isntr n is an insertion or not.

	char* insertionMap = (char*) malloc(sizeNewlyTranslated);
	for (int oneInstruction = 0; oneInstruction < sizeNewlyTranslated; oneInstruction++)
		insertionMap[oneInstruction] = 0;

	int** insertions = (int**) malloc (sizeof(int**));
	int numberInsertions = getInsertionList((sectionStartAddress>>2) - mipsStartAddress, insertions); //TODO
	for (int oneInsertion = 0; oneInsertion < numberInsertions; oneInsertion++){
		//We mark the destination as an insertion
		int index = (*insertions)[oneInsertion];
		insertionMap[index] = 1;
	}
	free(insertions);

	//We declare a temporary storage for storing procedures.
	application->blocksInSections[section] = (IRBlock**) malloc(TEMP_BLOCK_STORAGE_SIZE * sizeof(IRBlock**));
	application->numbersAllocatedBlockInSections[section] = TEMP_BLOCK_STORAGE_SIZE;

	int blockCounter = 0;

	int indexInMipsBinaries = 0;
	int indexInVLIWBinaries = 0;
	int previousBlockStart = 0;
	int previousBlockStartSource = 0;

	//Online resolution of jumps
	unsigned int unresolvedJumpIndex = 0;



	for (int oneInstruction = 0; oneInstruction <= sizeNewlyTranslated; oneInstruction++){
		int offset = (indexInMipsBinaries + ((sectionStartAddress>>2) - mipsStartAddress));
		char blockBoundary = 1;
		if (oneInstruction != sizeNewlyTranslated)
			blockBoundary = (dbtPlateform->blockBoundaries[offset]);
		char isInsertion = (oneInstruction == sizeNewlyTranslated) ? 0 : insertionMap[oneInstruction];

		if (blockBoundary && !isInsertion & previousBlockStart<indexInVLIWBinaries){


			/******************************************************************************************
			 ******************************  Creation and insertion of the block
			 ******************************************************************************************
			 * A new boundary has been reached, we have to create the IRBlock, to give him its values
			 * (eg. vliwStartAddress, vliwEndAddress, sourceStartAddress, sourceEndAddress etc...) and
			 * we insert it in the IRApplication
			 *
			 ******************************************************************************************/

			//We reach the end of a block: we create the block and mark this place as a new start
			IRBlock *newBlock = new IRBlock(previousBlockStart+startAddress, indexInVLIWBinaries+startAddress, section);
			newBlock->sourceStartAddress = previousBlockStartSource + (sectionStartAddress>>2);
			newBlock->sourceEndAddress = indexInMipsBinaries + (sectionStartAddress>>2);
			newBlock->sourceDestination = -1;


			application->addBlock(newBlock, section);


			/******************************************************************************************
			 ******************************  Branch resolution
			 ******************************************************************************************
			 * If we find that there is an unresolved jump in this block, we find the correct location and
			 * solve it if possible (eg. if the destination has already been translated.
			 *
			 ******************************************************************************************/
			unsigned int oneJumpSource = dbtPlateform->unresolvedJumps_src[unresolvedJumpIndex];
			unsigned int oneJumpInitialDestination = dbtPlateform->unresolvedJumps[unresolvedJumpIndex];
			unsigned int oneJumpType = dbtPlateform->unresolvedJumps_type[unresolvedJumpIndex];

			if (newBlock->vliwEndAddress - 2 == oneJumpSource){

				//We save the destination
				newBlock->sourceDestination = oneJumpInitialDestination+(sectionStartAddress>>2);

				unsigned char isAbsolute = ((oneJumpType & 0x7f) != VEX_BR) && ((oneJumpType & 0x7f) != VEX_BRF);
				unsigned int destinationInVLIWFromNewMethod = solveUnresolvedJump(oneJumpInitialDestination+((sectionStartAddress>>2)-mipsStartAddress));
				if (destinationInVLIWFromNewMethod == -1){
					//In this case, the jump cannot be resolved because the destination block is not translated yet.
					//We store information concerning the destination and it will be resolved later

					int numberUnresolvedJumps = unresolvedJumpsArray[0];
					unresolvedJumpsArray[1+numberUnresolvedJumps] = oneJumpInitialDestination+((sectionStartAddress>>2)-mipsStartAddress);
					unresolvedJumpsTypeArray[1+numberUnresolvedJumps] = oneJumpType;
					unresolvedJumpsSourceArray[1+numberUnresolvedJumps] = oneJumpSource;

					unresolvedJumpsArray[0] = numberUnresolvedJumps+1;
				}
				else{
					//The jump can be resolved
					int immediateValue = (isAbsolute) ? (destinationInVLIWFromNewMethod << 2) : ((destinationInVLIWFromNewMethod  - oneJumpSource)<<2);
					writeInt(dbtPlateform->vliwBinaries, 16*(oneJumpSource), oneJumpType + ((immediateValue & 0x7ffff)<<7));

					unsigned int instructionBeforePreviousDestination = readInt(dbtPlateform->vliwBinaries, 16*(destinationInVLIWFromNewMethod-1)+12);
					if (instructionBeforePreviousDestination != 0)
						writeInt(dbtPlateform->vliwBinaries, 16*(oneJumpSource+1)+12, instructionBeforePreviousDestination);
				}

				unresolvedJumpIndex++;
			}

			//If the block is big enough, we profile it
			if (newBlock->vliwEndAddress - newBlock->vliwStartAddress > 7)
				profiler->profileBlock(application->blocksInSections[section][application->numbersBlockInSections[section] - 1]);


			/******************************************************************************************/
			// We update interLoop values
			previousBlockStart = indexInVLIWBinaries;
			previousBlockStartSource = indexInMipsBinaries;

		}


		//We increase counters: both if we are not in an insertion, only the VLIW if we are
		indexInVLIWBinaries++;
		if (!isInsertion)
			indexInMipsBinaries++;
	}
<commit_msg>Correction of a problem on block construction<commit_after>/*
 * BuildControlFlow.cpp
 *
 *  Created on: 29 nov. 2016
 *      Author: <NAME>
 */

#include <stdio.h>

#include <dbt/dbtPlateform.h>
#include <dbt/insertions.h>
#include <dbt/profiling.h>

#include <isa/irISA.h>
#include <isa/vexISA.h>

#include <stdlib.h>
#include <string.h>

#include <types.h>
#include <lib/endianness.h>

#include <transformation/irGenerator.h>

#define TEMP_PROCEDURE_STORAGE_SIZE 50
#define TEMP_BLOCK_STORAGE_SIZE 900


void buildBasicControlFlow(DBTPlateform *dbtPlateform, int section, int mipsStartAddress, int sectionStartAddress, int startAddress, int endAddress, IRApplication *application, Profiler *profiler){

	int sizeNewlyTranslated = endAddress-startAddress;
	mipsStartAddress = mipsStartAddress>>2;


	//This first step consists of mapping insertions in order to easily say if isntr n is an insertion or not.

	char* insertionMap = (char*) malloc(sizeNewlyTranslated);
	for (int oneInstruction = 0; oneInstruction < sizeNewlyTranslated; oneInstruction++)
		insertionMap[oneInstruction] = 0;

	int** insertions = (int**) malloc (sizeof(int**));
	int numberInsertions = getInsertionList((sectionStartAddress>>2) - mipsStartAddress, insertions); //TODO
	for (int oneInsertion = 0; oneInsertion < numberInsertions; oneInsertion++){
		//We mark the destination as an insertion
		int index = (*insertions)[oneInsertion];
		insertionMap[index] = 1;
	}
	free(insertions);

	//We declare a temporary storage for storing procedures.
	application->blocksInSections[section] = (IRBlock**) malloc(TEMP_BLOCK_STORAGE_SIZE * sizeof(IRBlock**));
	application->numbersAllocatedBlockInSections[section] = TEMP_BLOCK_STORAGE_SIZE;

	int blockCounter = 0;

	int indexInMipsBinaries = 0;
	int indexInVLIWBinaries = 0;
	int previousBlockStart = 0;
	int previousBlockStartSource = 0;

	//Online resolution of jumps
	unsigned int unresolvedJumpIndex = 0;



	for (int oneInstruction = 0; oneInstruction <= sizeNewlyTranslated; oneInstruction++){
		int offset = (indexInMipsBinaries + ((sectionStartAddress>>2) - mipsStartAddress));
		char blockBoundary = 1;
		if (oneInstruction != sizeNewlyTranslated)
			blockBoundary = (dbtPlateform->blockBoundaries[offset]);
		char isInsertion = (oneInstruction == sizeNewlyTranslated) ? 0 : insertionMap[oneInstruction];

		if (blockBoundary && !isInsertion & previousBlockStart<indexInVLIWBinaries){


			/******************************************************************************************
			 ******************************  Creation and insertion of the block
			 ******************************************************************************************
			 * A new boundary has been reached, we have to create the IRBlock, to give him its values
			 * (eg. vliwStartAddress, vliwEndAddress, sourceStartAddress, sourceEndAddress etc...) and
			 * we insert it in the IRApplication
			 *
			 ******************************************************************************************/

			//We reach the end of a block: we create the block and mark this place as a new start
			IRBlock *newBlock = new IRBlock(previousBlockStart+startAddress, indexInVLIWBinaries+startAddress, section);
			newBlock->sourceStartAddress = previousBlockStartSource + (sectionStartAddress>>2);
			newBlock->sourceEndAddress = indexInMipsBinaries + (sectionStartAddress>>2);
			newBlock->sourceDestination = -1;


			application->addBlock(newBlock, section);


			/******************************************************************************************
			 ******************************  Branch resolution
			 ******************************************************************************************
			 * If we find that there is an unresolved jump in this block, we find the correct location and
			 * solve it if possible (eg. if the destination has already been translated.
			 *
			 ******************************************************************************************/
			unsigned int oneJumpSource = dbtPlateform->unresolvedJumps_src[unresolvedJumpIndex];
			unsigned int oneJumpInitialDestination = dbtPlateform->unresolvedJumps[unresolvedJumpIndex];
			unsigned int oneJumpType = dbtPlateform->unresolvedJumps_type[unresolvedJumpIndex];

			if (newBlock->vliwEndAddress - 2 == oneJumpSource){

				//We save the destination
				newBlock->sourceDestination = oneJumpInitialDestination+(sectionStartAddress>>2);

				unsigned char isAbsolute = ((oneJumpType & 0x7f) != VEX_BR) && ((oneJumpType & 0x7f) != VEX_BRF);
				unsigned int destinationInVLIWFromNewMethod = solveUnresolvedJump(oneJumpInitialDestination+((sectionStartAddress>>2)-mipsStartAddress));
				if (destinationInVLIWFromNewMethod == -1){
					//In this case, the jump cannot be resolved because the destination block is not translated yet.
					//We store information concerning the destination and it will be resolved later

					int numberUnresolvedJumps = unresolvedJumpsArray[0];
					unresolvedJumpsArray[1+numberUnresolvedJumps] = oneJumpInitialDestination+((sectionStartAddress>>2)-mipsStartAddress);
					unresolvedJumpsTypeArray[1+numberUnresolvedJumps] = oneJumpType;
					unresolvedJumpsSourceArray[1+numberUnresolvedJumps] = oneJumpSource;

					unresolvedJumpsArray[0] = numberUnresolvedJumps+1;
				}
				else{
					//The jump can be resolved
					int immediateValue = (isAbsolute) ? (destinationInVLIWFromNewMethod << 2) : ((destinationInVLIWFromNewMethod  - oneJumpSource)<<2);
					writeInt(dbtPlateform->vliwBinaries, 16*(oneJumpSource), oneJumpType + ((immediateValue & 0x7ffff)<<7));

					unsigned int instructionBeforePreviousDestination = readInt(dbtPlateform->vliwBinaries, 16*(destinationInVLIWFromNewMethod-1)+12);
					if (instructionBeforePreviousDestination != 0)
						writeInt(dbtPlateform->vliwBinaries, 16*(oneJumpSource+1)+12, instructionBeforePreviousDestination);
				}

				unresolvedJumpIndex++;

				//We check if the boundary was already marked

				int offsetForDestination = (oneJumpInitialDestination + ((sectionStartAddress>>2) - mipsStartAddress));
				int sectionOfDestination = offsetForDestination>>10;


				if (sectionOfDestination < section){
					bool isDestinationAlreadyMarked = false;
					IRBlock *blockToSplit;

					for (int oneBlockForSucc = 0; oneBlockForSucc<application->numbersBlockInSections[sectionOfDestination]; oneBlockForSucc++){
						IRBlock* blockForSucc = application->blocksInSections[sectionOfDestination][oneBlockForSucc];
						fprintf(stderr, "Looking in block %x\n", blockForSucc->sourceStartAddress);

						if (blockForSucc->sourceStartAddress == newBlock->sourceDestination){
							isDestinationAlreadyMarked = true;
						}
						if (blockForSucc->sourceStartAddress<newBlock->sourceDestination && blockForSucc->sourceEndAddress>newBlock->sourceDestination){
							blockToSplit = blockForSucc;
							fprintf(stderr, "Found the block\n");
						}
					}

					if (!isDestinationAlreadyMarked){
						fprintf(stderr, "Solving block definition for %x\n", newBlock->sourceDestination);


						IRBlock *splittedBlock = new IRBlock(destinationInVLIWFromNewMethod, blockToSplit->vliwEndAddress, sectionOfDestination);
						application->addBlock(splittedBlock, sectionOfDestination);

						//We set metainfo for new block
						splittedBlock->sourceStartAddress = newBlock->sourceDestination;
						splittedBlock->sourceEndAddress = blockToSplit->sourceEndAddress;

						//We set meta info for old block
						blockToSplit->sourceEndAddress = newBlock->sourceDestination;
						blockToSplit->sourceDestination = newBlock->sourceDestination;
						blockToSplit->vliwEndAddress = destinationInVLIWFromNewMethod;
					}

				}

			}



			//If the block is big enough, we profile it
			if (newBlock->vliwEndAddress - newBlock->vliwStartAddress > 7)
				profiler->profileBlock(application->blocksInSections[section][application->numbersBlockInSections[section] - 1]);


			/******************************************************************************************/
			// We update interLoop values
			previousBlockStart = indexInVLIWBinaries;
			previousBlockStartSource = indexInMipsBinaries;

		}


		//We increase counters: both if we are not in an insertion, only the VLIW if we are
		indexInVLIWBinaries++;
		if (!isInsertion)
			indexInMipsBinaries++;
	}

{'fraction_non_alphanumeric': 0.17911754799595825, 'fraction_numerical': 0.009026608285618054, 'mean_word_length': 5.5400881057268725, 'pattern_counts': {'":': 0, '<': 50, '<?xml version=': 0, '>': 127, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1997125', 'n_tokens_mistral': 4775, 'n_tokens_neox': 4080, 'n_words': 989}