Пример #1
0
static void BasicBlock_SetJumpAddr(KonohaContext *kctx, BasicBlock *bb, char *vcode)
{
	while(bb != NULL) {
		BasicBlock_SetVisited(bb);
		if(bb->branchid != -1) {
			BasicBlock   *bbJ = BasicBlock_leapJump(kctx, BasicBlock_FindById(kctx, bb->branchid));
			KVirtualCode *op  = (KVirtualCode *)(vcode + bb->lastoffset);

			OPJMP *j = (OPJMP *) op;
			DBG_ASSERT(j->opcode == OPCODE_JMP || j->opcode == OPCODE_JMPF);
			j->jumppc = (KVirtualCode *)(vcode + bbJ->codeoffset);
			if(BasicBlock_size(bb) > 1) {
				KVirtualCode *opPREV = (KVirtualCode *)(vcode + bb->lastoffset - sizeof(KVirtualCode));
				if(opPREV->opcode == OPCODE_JMPF && bb->nextid != -1) {
					BasicBlock *block = BasicBlock_leapJump(kctx, BasicBlock_FindById(kctx, bb->nextid));
					((OPJMPF *)opPREV)->jumppc = (KVirtualCode *)(vcode + block->codeoffset);
				}
			}
			bbJ = BasicBlock_FindById(kctx, bb->branchid);
			if(!BasicBlock_isVisited(bbJ)) {
				BasicBlock_SetVisited(bbJ);
				BasicBlock_SetJumpAddr(kctx, bbJ, vcode);
			}
		}
		bb = BasicBlock_FindById(kctx, bb->nextid);
	}
}
Пример #2
0
static void MiniVMBuilder_setBlock(KonohaContext *kctx, KBuilder *builder, bblock_t labelId)
{
	BasicBlock *labelNode;
	BasicBlock *bb = BasicBlock_FindById(kctx, builder->bbMainId);
	DBG_ASSERT(bb != NULL);
	labelNode = BasicBlock_FindById(kctx, labelId);
	labelNode->incoming += 1;
	builder->bbMainId = BasicBlock_id(kctx, labelNode);
}
Пример #3
0
static void ASM_LABEL(KonohaContext *kctx, KBuilder *builder, bblock_t labelId)
{
	BasicBlock *bb = BasicBlock_FindById(kctx, builder->bbMainId);
	DBG_ASSERT(bb != NULL);
	DBG_ASSERT(bb->nextid == -1);
	BasicBlock *labelNode = BasicBlock_FindById(kctx, labelId);
	labelNode->incoming += 1;
	builder->bbMainId = BasicBlock_id(kctx, labelNode);
	bb->nextid = builder->bbMainId;
}
Пример #4
0
static BasicBlock *BasicBlock_leapJump(KonohaContext *kctx, BasicBlock *bb)
{
	while(bb->nextid != -1) {
		if(BasicBlock_size(bb) != 0) return bb;
		bb = BasicBlock_FindById(kctx, bb->nextid);
	}
	if(bb->nextid == -1 && bb->branchid != -1 && BasicBlock_size(bb) == 1) {
		return BasicBlock_leapJump(kctx, BasicBlock_FindById(kctx, bb->branchid));
	}
	return bb;
}
Пример #5
0
static void MiniVMBuilder_JumpTo(KonohaContext *kctx, KBuilder *builder, bblock_t labelId)
{
	BasicBlock *bb = BasicBlock_FindById(kctx, builder->bbMainId);
	DBG_ASSERT(bb != NULL);
	//DBG_ASSERT(bb->nextid == -1);
	if(bb->branchid == -1) {
		BasicBlock *labelNode;
		ASM(JMP, NULL);
		labelNode = BasicBlock_FindById(kctx, labelId);
		bb = BasicBlock_FindById(kctx, builder->bbMainId);
		bb->branchid = BasicBlock_id(kctx, labelNode);
		labelNode->incoming += 1;
	}
}
Пример #6
0
static BasicBlock *new_BasicBlock(KonohaContext *kctx, size_t max, bblock_t oldId)
{
	BasicBlock *bb;
	KBuffer wb;
	KLIB KBuffer_Init(&(kctx->stack->cwb), &wb);
	bb = (BasicBlock *)KLIB KBuffer_Alloca(kctx, &wb, max);
	if(oldId != -1) {
		BasicBlock *oldbb = BasicBlock_FindById(kctx, oldId);
		if(((char *)oldbb) + oldbb->max == (char *)bb) {
			oldbb->max += (max - sizeof(BasicBlock));
			wb.m->bytesize -= sizeof(BasicBlock);
			return oldbb;
		}
		memcpy(bb, oldbb, oldbb->size);
		oldbb->newid = BasicBlock_id(kctx, bb);
		oldbb->size = 0;
	}
	else {
		bb->size = sizeof(BasicBlock);
		bb->newid    = -1;
		bb->nextid   = -1;
		bb->branchid = -1;
	}
	bb->max = max;
	bb->codeoffset   = -1;
	bb->lastoffset   = -1;
	return bb;
}
Пример #7
0
static bblock_t BasicBlock_id(KonohaContext *kctx, BasicBlock *bb)
{
	while(bb->newid != -1) {
		bb = BasicBlock_FindById(kctx, bb->newid);
	}
	return ((char *)bb) - kctx->stack->cwb.bytebuf;
}
Пример #8
0
static bblock_t AsmJMPF(KonohaContext *kctx, KBuilder *builder, int localStack, bblock_t jumpId)
{
	BasicBlock *bb = BasicBlock_FindById(kctx, builder->bbMainId);
	DBG_ASSERT(bb != NULL);
	DBG_ASSERT(bb->nextid == -1 && bb->branchid == -1);
	bblock_t nextId = new_BasicBlockLABEL(kctx);
	ASM(JMPF, NULL, NC_(localStack));
	bb = BasicBlock_FindById(kctx, builder->bbMainId);
	BasicBlock *jumpBlock = BasicBlock_FindById(kctx, jumpId);
	BasicBlock *nextBlock = BasicBlock_FindById(kctx, nextId);
	bb->branchid = BasicBlock_id(kctx, jumpBlock);
	bb->nextid = nextId;
	nextBlock->incoming += 1;
	jumpBlock->incoming += 1;
	builder->bbMainId = nextId;
	return nextId;
}
Пример #9
0
static void CreateBranch(KonohaContext *kctx, KBuilder *builder, intptr_t src, bblock_t ThenBB, bblock_t ElseBB, bool emitJumpToThenBlock)
{
	BasicBlock *ThenBlock, *ElseBlock;
	BasicBlock *bb = BasicBlock_FindById(kctx, builder->bbMainId);
	DBG_ASSERT(bb != NULL);
	DBG_ASSERT(/*bb->nextid == -1 &&*/ bb->branchid == -1);
	ASM(JMPF, NULL, NC_(src));
	if(emitJumpToThenBlock) {
		ASM(JMP, NULL);
	}
	bb = BasicBlock_FindById(kctx, builder->bbMainId);
	ThenBlock = BasicBlock_FindById(kctx, ThenBB);
	ElseBlock = BasicBlock_FindById(kctx, ElseBB);
	bb->branchid = ElseBB;
	bb->nextid   = ThenBB;
	ThenBlock->incoming += 1;
	ElseBlock->incoming += 1;
}
Пример #10
0
static void BasicBlock_WriteByteCode(KonohaContext *kctx, bblock_t blockId, ByteCodeWriter *writer)
{
	BasicBlock *bb = BasicBlock_FindById(kctx, blockId);
	while(bb != NULL && bb->codeoffset == -1) {
		intptr_t len = bb->size - sizeof(BasicBlock);
		bb->codeoffset = CodeOffset(writer);
		bb->lastoffset = -1; // reset lastoffset
		if(len > 0) {
			bblock_t id = BasicBlock_id(kctx, bb);
			WriteByteCode(writer, ((char *)bb) + sizeof(BasicBlock), len);
			bb = BasicBlock_FindById(kctx, id);  // recheck
			bb->lastoffset = CodeOffset(writer) - sizeof(KVirtualCode);
			DBG_ASSERT(bb->codeoffset + ((len / sizeof(KVirtualCode)) - 1) * sizeof(KVirtualCode) == (size_t) bb->lastoffset);
		}
		else {
			DBG_ASSERT(bb->branchid == -1);
		}
		bb = BasicBlock_FindById(kctx, bb->nextid);
	}
	bb = BasicBlock_FindById(kctx, blockId);
	while(bb != NULL) {
		if(bb->branchid != -1) {
			BasicBlock *bbJ = BasicBlock_FindById(kctx, bb->branchid);
			if(bbJ->codeoffset == -1) {
				BasicBlock_WriteByteCode(kctx, bb->branchid, writer);
			}
		}
		bb = BasicBlock_FindById(kctx, bb->nextid);
	}
}
Пример #11
0
static void BasicBlock_WriteBuffer(KonohaContext *kctx, bblock_t blockId, KBuffer *wb)
{
	BasicBlock *bb = BasicBlock_FindById(kctx, blockId);
	while(bb != NULL && bb->codeoffset == -1) {
		size_t len = bb->size - sizeof(BasicBlock);
		bb->codeoffset = CodeOffset(wb);
		if(bb->nextid == bb->branchid  && bb->nextid != -1) {
			bb->branchid = -1;
			len -= sizeof(KVirtualCode); // remove unnecesarry jump ..
		}
		if(len > 0) {
			bblock_t id = BasicBlock_id(kctx, bb);
			char buf[len];  // bb is growing together with wb.
			memcpy(buf, ((char *)bb) + sizeof(BasicBlock), len);
			KLIB KBuffer_Write(kctx, wb, buf, len);
			bb = BasicBlock_FindById(kctx, id);  // recheck
			bb->lastoffset = CodeOffset(wb) - sizeof(KVirtualCode);
			DBG_ASSERT(bb->codeoffset + ((len / sizeof(KVirtualCode)) - 1) * sizeof(KVirtualCode) == bb->lastoffset);
		}
		else {
			DBG_ASSERT(bb->branchid == -1);
		}
		bb = BasicBlock_FindById(kctx, bb->nextid);
	}
	bb = BasicBlock_FindById(kctx, blockId);
	while(bb != NULL) {
		if(bb->branchid != -1 /*&& bb->branchid != builder->bbReturnId*/) {
			BasicBlock *bbJ = BasicBlock_FindById(kctx, bb->branchid);
			if(bbJ->codeoffset == -1) {
				BasicBlock_WriteBuffer(kctx, bb->branchid, wb);
			}
		}
		bb = BasicBlock_FindById(kctx, bb->nextid);
	}
}
Пример #12
0
static void BasicBlock_Optimize(KonohaContext *kctx, bblock_t blockId, ByteCodeWriter *writer)
{
	BasicBlock *bb = BasicBlock_FindById(kctx, blockId);
	while(bb != NULL && bb->lastoffset == -1) {
		bb->lastoffset = 0;
		if(bb->nextid == bb->branchid  && bb->nextid != -1) {
			//bb->branchid = -1;
			//writer->codesize -= sizeof(KVirtualCode);
			//bb->size -= sizeof(KVirtualCode); // remove unnecesarry jump ..
		}
		bb = BasicBlock_FindById(kctx, bb->nextid);
	}
	bb = BasicBlock_FindById(kctx, blockId);
	while(bb != NULL) {
		if(bb->branchid != -1) {
			BasicBlock *bbJ = BasicBlock_FindById(kctx, bb->branchid);
			if(bbJ->lastoffset == -1) {
				BasicBlock_Optimize(kctx, bb->branchid, writer);
			}
		}
		bb = BasicBlock_FindById(kctx, bb->nextid);
	}
}
Пример #13
0
static bblock_t BasicBlock_Add(KonohaContext *kctx, bblock_t blockId, kfileline_t uline, KVirtualCode *op, size_t size, size_t padding_size)
{
	BasicBlock *bb = BasicBlock_FindById(kctx, blockId);
	DBG_ASSERT(bb->newid == -1);
	DBG_ASSERT(size <= padding_size);
	DBG_ASSERT(bb->nextid == -1 && bb->branchid == -1);
	if(!(bb->size + size < bb->max)) {
		size_t newsize = newsize2(bb->max);
		bb = new_BasicBlock(kctx, newsize, blockId);
	}
	memcpy(((char *)bb) + bb->size, op, size);
	bb->size += padding_size;
	return BasicBlock_id(kctx, bb);
}
Пример #14
0
static struct KVirtualCode *CompileVirtualCode(KonohaContext *kctx, KBuilder *builder, bblock_t beginId, bblock_t returnId)
{
	KVirtualCode *vcode;
	ByteCodeWriter writer = {NULL, 0, builder->InstructionSize * sizeof(KVirtualCode)};
	BasicBlock_Optimize(kctx, beginId, &writer);
	DBG_P(">>>>>> codesize=%d", writer.codesize);
	DBG_ASSERT(writer.codesize != 0);
	vcode = (KVirtualCode *)KCalloc_UNTRACE(writer.codesize, 1);
	writer.current = vcode;
	BasicBlock_WriteByteCode(kctx, beginId, &writer);
	BasicBlock_WriteByteCode(kctx, returnId, &writer);
	BasicBlock_SetJumpAddr(kctx, BasicBlock_FindById(kctx, beginId), (char *)vcode);
	vcode = MakeThreadedCode(kctx, builder, vcode, writer.codesize);
	DumpVirtualCode(kctx, vcode);
	return vcode;
}
Пример #15
0
static bool Block_HasTerminatorInst(KonohaContext *kctx, bblock_t blockId)
{
	BasicBlock *bb = BasicBlock_FindById(kctx, blockId);
	unsigned size = BasicBlock_size(bb);
	KVirtualCode *code, *lastInst;
	if(size == 0)
		return false;
	code = (KVirtualCode *)(((char *)bb) + sizeof(BasicBlock));
	lastInst = code + (size - 1);
	switch(lastInst->opcode) {
#define CASE(OP) case OPCODE_##OP: return true;
		CASE(EXIT);
		CASE(RET);
		CASE(JMP);
		CASE(JMPF);
		CASE(YIELD);
		CASE(ERROR);
#undef CASE
	}
	return false;
}