예제 #1
0
파일: Forest.cpp 프로젝트: robfinch/Cores
void Forest::Color()
{
	int nn, m;
	int c;
	int j, k = 17;
	int *p;
	CSet used;
	Tree *t;

	if (pass == 1) {
		for (c = 0; c < treecount; c++) {
			trees[c]->spill = false;
			trees[c]->color = k;
			if (trees[c]->var < 3)
				trees[c]->color = trees[c]->var;
			if (trees[c]->var >= regFirstArg && trees[c]->var <= regLastArg) {
				trees[c]->color = trees[c]->var - regFirstArg + 18;
			}
			if (trees[c]->var == regFP
				|| trees[c]->var == regLR
				|| trees[c]->var == regXLR
				|| trees[c]->var == regSP) {
				trees[c]->color = trees[c]->var - regXLR + 28;
			}
		}
	}
	used.clear();
	used.add(0);	// reg0 is a constant 0
	used.add(1);	// these two are return value
	used.add(2);
	while (!stk->IsEmpty()) {
		t = trees[m=pop()];
		if (pass == 1 && !t->infinite && t->cost < 0.0f) {	// was <= 0.0f
			t->spill = true;
		}
		else {
			p = iGraph.GetNeighbours(m, &nn);
			for (j = 0; j < nn; j++)
				used.add(trees[p[j]]->color);
			for (c = 0; used.isMember(c) && c < k; c++);
			if (c < k && t->color == k) {	// The tree may have been colored already
				t->color = c;
				used.add(c);
			}
			else if (t->color <= k)		// Don't need to spill args
				t->spill = true;
		}
	}
}
예제 #2
0
파일: Forest.cpp 프로젝트: robfinch/Cores
bool Forest::SpillCode()
{
	int c, m, n;
	Var *v;
	Tree *t;
	BasicBlock *bb;
	int64_t spillOffset;
	OCODE *cd;
	CSet spilled;
	bool ret;

	ret = false;
	cd = currentFn->spAdjust;
	if (cd == nullptr)
		return (ret);
	spillOffset = cd->oper3->offset->i;
	spilled.clear();
	for (c = 0; c < treecount; c++) {
		t = trees[c];	// convenience
		// Tree couldn't be colored that means there are no available registers.
		// So, spill one of the registers. The register to spill should be one
		// that isn't live at the same time as this tree.
		if (t->spill) {
			ret = true;
			v = Var::Find(t->var);
			v = v->GetVarToSpill(&spilled);
			if (v == nullptr)
				continue;
			// The var is spilled at the head of the tree, and restored later
			t->blocks->resetPtr();
			m = t->blocks->nextMember();
			if (m >= 0) {	// should always be true, otherwise no code
				bb = basicBlocks[m];
				if (!spilled.isMember(v->num)) {
					v->spillOffset = spillOffset;
					spillOffset += sizeOfWord;
					spilled.add(v->num);
				}
				bb->InsertSpillCode(v->num, -v->spillOffset);
				while(1) {
					n = m;
					m = t->blocks->nextMember();
					if (m < 0)
						break;
					// Detect when a different branch is present. The node
					// number will jump by more than 1 between branches.
					// *** suspect this won't work, should just pick last block in tree
					if (m - n > 1) {
						bb = basicBlocks[n];
						bb->InsertFillCode(v->num, -v->spillOffset);
					}
				}
				bb = basicBlocks[n];
				bb->InsertFillCode(v->num, -v->spillOffset);
			}
			t->spill = false;
		}
	}
	cd->oper3->offset->i = spillOffset;
	return (ret);
}