Пример #1
0
void LinearScan::spill(SSATmp* tmp) {
  if (RuntimeOption::EvalDumpIR > 4) {
    std::cout << "--- spilling ";
    tmp->print(std::cout);
    std::cout << "\n";
  }
  // If we're spilling, we better actually have registers allocated.
  ASSERT(tmp->numAllocatedRegs() > 0);
  ASSERT(tmp->numAllocatedRegs() == tmp->numNeededRegs());

  // Free the registers used by <tmp>.
  // Need call freeReg and modify <m_allocatedRegs>.
  for (std::list<RegState*>::iterator it = m_allocatedRegs.begin();
       it != m_allocatedRegs.end(); ) {
    std::list<RegState*>::iterator next = it; ++next;
    RegState* reg = *it;
    if (reg->m_ssaTmp == tmp) {
      freeReg(reg);
      m_allocatedRegs.erase(it);
    }
    it = next;
  }

  if (tmp->getSpillSlot() == -1) {
    // <tmp> hasn't been spilled before.
    // We need to create a new spill slot for it.
    uint32 slotId = createSpillSlot(tmp);
    // createSpillSlot sets the latest reloaded value of slotId to tmp.
    // Here, we need reset this value because tmp is spilled and no longer
    // synced with memory.
    m_slots[slotId].m_latestTmp = NULL;
  }
}
Пример #2
0
void LinearScan::freeRegsAtId(uint32_t id) {
  // free all registers whose lifetime ends at this id
  // Note that we free registers before we allocate a register
  // to this instruction, so we have to be careful to finish using
  // a register before over-writing it.
  for (std::list<RegState*>::iterator it = m_allocatedRegs.begin();
       it != m_allocatedRegs.end(); ) {
    std::list<RegState*>::iterator next = it; ++next;
    RegState* reg = *it;
    ASSERT(reg->m_ssaTmp);
    if (reg->m_ssaTmp->getLastUseId() <= id) {
      m_allocatedRegs.erase(it);
      freeReg(reg);
    }
    it = next;
  }
}
Пример #3
0
int codeGenerate(Tnode *root)
{
	int loc,r,r1,r2;
	int lbl1,lbl2;
	struct Gsymbol *TEMP;
	
	if(root==NULL)
		return;

	switch(root->NODETYPE)
	{
		case CONTINUE		:	codeGenerate(root->Ptr1);
								codeGenerate(root->Ptr2);
								
								return;
		
		case ITERATIVE		:	fprintf(fp,"\n*** ITERATION ***\n");
								lbl1 = getLabel();
								lbl2 = getLabel();
								fprintf(fp,"Label%d:\n",lbl1);
								r = codeGenerate(root ->Ptr1);
								fprintf(fp,"JZ R%d Label%d\n",r,lbl2);
								freeReg();
								codeGenerate(root ->Ptr2);
								fprintf(fp,"JMP Label%d\n",lbl1);
								fprintf(fp,"Label%d:\n",lbl2);
								
								return;
		
		case CONDITIONAL	:	fprintf(fp,"\n*** CONDITIONAL ***\n");
								r = codeGenerate(root->Ptr1);
								lbl1 = getLabel();
								lbl2 = getLabel();
								
								fprintf(fp,"JZ R%d Label%d\n",r,lbl1);
								freeReg();
								codeGenerate(root->Ptr2);
								fprintf(fp,"JMP Label%d\n",lbl2);
								fprintf(fp,"Label%d:\n",lbl1);
								codeGenerate(root->Ptr3);
								fprintf(fp,"Label%d:\n",lbl2);
								
								return;
		
		case RD				:	fprintf(fp,"\n*** READ ***\n");
								loc = Glookup(root->NAME)->LOCATION;
								r = getReg();
								fprintf(fp,"IN R%d\n",r);
								fprintf(fp,"MOV [%d] R%d\n",loc,r);
								freeReg();
								
								return -1;
		
		case ARRAYRD		:	fprintf(fp,"\n*** ARRAY READ ***\n");
								r = getReg();
								fprintf(fp,"IN R%d\n",r);
								loc = Glookup(root->NAME)->LOCATION;
								r1 = codeGenerate(root->Ptr1);
								r2 = getReg();
								fprintf(fp,"MOV R%d %d\n",r2,loc);
								fprintf(fp,"ADD R%d R%d\n",r1,r2);
								freeReg();
								fprintf(fp,"MOV [R%d] R%d\n",r1,r);
								freeReg();
								freeReg();
								
								return -1;
		
		case WRIT			:	fprintf(fp,"\n*** WRITE ***\n");
								r = codeGenerate(root->Ptr1);
								fprintf(fp,"OUT R%d\n",r);
								freeReg();
								
								return -1;
		
		case ASSIGN			:	fprintf(fp,"\n*** ASSIGNMENT ***\n");
								loc = Glookup(root->NAME)->LOCATION;
								r = codeGenerate(root->Ptr1);
								fprintf(fp,"MOV [%d] R%d\n",loc,r);
								freeReg();
								
								return;
		
		case GT				:	r = codeGenerate(root->Ptr1);
								codeGenerate(root->Ptr2);
								fprintf(fp,"GT R%d R%d\n",r,r+1);
								freeReg();
								
								return r;
		
		case LT				:	r = codeGenerate(root->Ptr1);
								codeGenerate(root->Ptr2);
								fprintf(fp,"LT R%d R%d\n",r,r+1);
								freeReg();
								
								return r;
		
		case EQ				:	r = codeGenerate(root->Ptr1);
								codeGenerate(root->Ptr2);
								fprintf(fp,"EQ R%d R%d\n",r,r+1);
								freeReg();
								
								return r;
		
		case NE				:	r = codeGenerate(root->Ptr1);
								codeGenerate(root->Ptr2);
								fprintf(fp,"NE R%d R%d\n",r,r+1);
								freeReg();
								
								return r;
		
		case NUM			:	r=getReg();
								fprintf(fp,"MOV R%d %d \n",r,root->VALUE);
								
								return r;
		
		case ADD			:	r=codeGenerate(root->Ptr1);
								r1=codeGenerate(root->Ptr2);
								fprintf(fp,"ADD R%d R%d\n",r,r1);
								freeReg();
								
								return r;
		
		case SUB			:	r=codeGenerate(root->Ptr1);
								r1=codeGenerate(root->Ptr2);
								fprintf(fp,"SUB R%d R%d\n",r,r1);
								freeReg();
								
								return r;
		
		case MUL			:	r=codeGenerate(root->Ptr1);
								r1=codeGenerate(root->Ptr2);
								fprintf(fp,"MUL R%d R%d\n",r,r1);
								freeReg();
								
								return r;
		
		case DIV			:	r=codeGenerate(root->Ptr1);
								r1=codeGenerate(root->Ptr2);
								fprintf(fp,"DIV R%d R%d\n",r,r1);
								freeReg();
								
								return r;
		
		case IDFR			:	loc = Glookup(root->NAME)->LOCATION;
								r=getReg();
								fprintf(fp,"MOV R%d [%d]\n",r,loc);
								
								return r;
		
		case ARRAYIDFR		:	r = codeGenerate(root->Ptr1);
								loc = Glookup(root->NAME)->LOCATION;
								r1 = getReg();
								fprintf(fp,"MOV R%d %d\n",r1,loc);
								fprintf(fp,"ADD R%d R%d\n",r,r1);
								fprintf(fp,"MOV R%d [R%d]\n",r1,r);
								freeReg();
								
								return r1;
	}
}
int CodeGen(tnode* t)
{
	int r,r1,r2;
	int value;
	int loc,l1,l2;
	//r is the root of AST
	//returntype of CodeGen is int that is it returns the register Number
	switch(t->NODETYPE)
	{

		case NUM:
			value=t->val;
			r=getReg();
			fprintf(fp,"MOV R%d, %d\n",r,value);
			return r;
			break;

		case ID:
			loc=t->var-'a';
			r=getReg();
			fprintf(fp, "MOV R%d, [%d]\n",r,loc);
			return r;
			break;

		case PLUS:
			r1=CodeGen(t->left);
			r2=CodeGen(t->right);
			fprintf(fp, "ADD R%d, R%d\n",r1,r2);
			freeReg();
			return r1;
			break;

		case MINUS:
			r1=CodeGen(t->left);
			r2=CodeGen(t->right);
			fprintf(fp, "SUB R%d, R%d\n",r1,r2);
			freeReg();
			return r1;
			break;

		case MUL:
			r1=CodeGen(t->left);
			r2=CodeGen(t->right);
			fprintf(fp, "MUL R%d, R%d\n",r1,r2);
			freeReg();
			return r1;
			break;

		case DIV:
			r1=CodeGen(t->left);
			r2=CodeGen(t->right);
			fprintf(fp, "DIV R%d, R%d\n",r1,r2);
			freeReg();
			return r1;
			break;

		case MOD:
			r1=CodeGen(t->left);
			r2=CodeGen(t->right);
			fprintf(fp, "MOD R%d, R%d\n",r1,r2);
			freeReg();
			return r1;
			break;

		case LT:
			r1=CodeGen(t->left);
			r2=CodeGen(t->right);
			fprintf(fp, "LT R%d, R%d\n",r1,r2);
			freeReg();
			return r1;
			break;

		case GT:
			r1=CodeGen(t->left);
			r2=CodeGen(t->right);
			fprintf(fp, "GT R%d, R%d\n",r1,r2);
			freeReg();
			return r1;
			break;

		case EQ:
			r1=CodeGen(t->left);
			r2=CodeGen(t->right);
			fprintf(fp, "EQ R%d, R%d\n",r1,r2);
			freeReg();
			return r1;
			break;

		case EQUALS:
			r1=getBinding(t->left);
			r2=CodeGen(t->right);
			fprintf(fp, "MOV [R%d], R%d\n",r1,r2);
			freeReg();
			freeReg();
			return 0;
			break;

		case READ:
			r=getBinding(t->left);
			r1=getReg();
			fprintf(fp, "IN R%d\n",r1);
			fprintf(fp, "MOV [R%d], R%d\n",r,r1);
			freeReg();
			freeReg();
			return 0;
			break;

		case WRITE:
			r=CodeGen(t->left);
			fprintf(fp, "OUT R%d\n",r);
			freeReg();
			return 0;
			break;
		case IF:
				l1=getLabel();
				r=CodeGen(t->left);
				r1=getReg();
				fprintf(fp, "MOV R%d, 0\n",r1);
				fprintf(fp, "NE R%d, R%d\n",r,r1);
				fprintf(fp, "JZ R%d, L%d\n",r,l1);
				freeReg();
				freeReg();
				CodeGen(t->right);
				fprintf(fp, "L%d:\n",l1);
				return 0;
				break;

		case WHILE:
			{
				l1=getLabel();
				l2=getLabel();
				fprintf(fp, "L%d:\n",l1);
				r=CodeGen(t->left);
				r1=getReg();
				fprintf(fp, "MOV R%d, 0\n",r1);
				fprintf(fp, "NE R%d, R%d\n",r,r1);
				fprintf(fp, "JZ R%d, L%d\n",r,l2);
				freeReg();
				freeReg();
				CodeGen(t->right);
				fprintf(fp, "JMP L%d\n",l1);
				fprintf(fp, "L%d:\n",l2);
				return 0;
			}
				break;

		case CONNECT:
			CodeGen(t->left);
			CodeGen(t->right);
			return 0;
			break;
	}


}
Пример #5
0
int allocateCTEParamsFast(CTEParamsFast * pars)
{
    PtrRegister ptrReg;
    initPtrRegister(&ptrReg);

    void * tmp = NULL;
    tmp = newAndZero((void*)&pars->iz_data, pars->nScaleTableColumns, sizeof(*pars->iz_data));
    addPtr(&ptrReg, tmp, &free);
    if (!tmp)
    {
        freeOnExit(&ptrReg);
        trlerror ("Out of memory.\n");
        return OUT_OF_MEMORY;
    }
    tmp = newAndZero((void*)&pars->scale512, pars->nScaleTableColumns, sizeof(*pars->scale512));
    addPtr(&ptrReg, tmp, &free);
    if (!tmp)
    {
        freeOnExit(&ptrReg);
        trlerror ("Out of memory.\n");
        return OUT_OF_MEMORY;
    }
    tmp = newAndZero((void*)&pars->scale1024, pars->nScaleTableColumns, sizeof(*pars->scale1024));
    addPtr(&ptrReg, tmp, &free);
    if (!tmp)
    {
        freeOnExit(&ptrReg);
        trlerror ("Out of memory.\n");
        return OUT_OF_MEMORY;
    }
    tmp = newAndZero((void*)&pars->scale1536, pars->nScaleTableColumns, sizeof(*pars->scale1536));
    addPtr(&ptrReg, tmp, &free);
    if (!tmp)
    {
        freeOnExit(&ptrReg);
        trlerror ("Out of memory.\n");
        return OUT_OF_MEMORY;
    }
    tmp = newAndZero((void*)&pars->scale2048, pars->nScaleTableColumns, sizeof(*pars->scale2048));
    addPtr(&ptrReg, tmp, &free);
    if (!tmp)
    {
        freeOnExit(&ptrReg);
        trlerror ("Out of memory.\n");
        return OUT_OF_MEMORY;
    }
    tmp = newAndZero((void*)&pars->wcol_data, pars->nTraps, sizeof(*pars->wcol_data));
    addPtr(&ptrReg, tmp, &free);
    if (!tmp)
    {
        freeOnExit(&ptrReg);
        trlerror ("Out of memory.\n");
        return OUT_OF_MEMORY;
    }
    tmp = newAndZero((void*)&pars->qlevq_data, pars->nTraps, sizeof(*pars->qlevq_data));
    addPtr(&ptrReg, tmp, &free);
    if (!tmp)
    {
        freeOnExit(&ptrReg);
        trlerror ("Out of memory.\n");
        return OUT_OF_MEMORY;
    }
    tmp = newAndZero((void*)& pars->dpdew_data, pars->nTraps, sizeof(*pars->dpdew_data));
    addPtr(&ptrReg, tmp, &free);
    if (!tmp)
    {
        freeOnExit(&ptrReg);
        trlerror ("Out of memory.\n");
        return OUT_OF_MEMORY;
    }

    freeReg(&ptrReg);
    return 0;
}
Пример #6
0
int Tile::eval(int want)
{
	//save any hit registers
	int spill = hits;
	if (want_l)
		spill |= 1 << want_l;
	if (want_r)
		spill |= 1 << want_r;
	if (spill) {
		for (int n = 1; n <= NUM_REGS; ++n) {
			if (spill & (1 << n)) {
				if (regUsed[n])
					pushReg(n);
				else
					spill &= ~(1 << n);
			}
		}
	}

	//if tile needs an argFrame...
	if (argFrame) {
		codeFrags.push_back("-" + itoa(argFrame));
	}

	int got_l = 0, got_r = 0;
	if (want_l)
		want = want_l;

	std::string* as = &assem;

	if (!l) {
		got_l = allocReg(want);
	} else if (!r) {
		got_l = l->eval(want);
	} else {
		if (l->need >= NUM_REGS && r->need >= NUM_REGS) {
			got_r = r->eval(0);
			pushReg(got_r);
			freeReg(got_r);
			got_l = l->eval(want);
			got_r = allocReg(want_r);
			popReg(got_r);
		} else if (r->need > l->need) {
			got_r = r->eval(want_r);
			got_l = l->eval(want);
		} else {
			got_l = l->eval(want);
			got_r = r->eval(want_r);
			if (assem2.size())
				as = &assem2;
		}
		if (want_l == got_r || want_r == got_l) {
			swapRegs(got_l, got_r);
			int t = got_l;
			got_l = got_r;
			got_r = t;
		}
	}

	if (!want_l)
		want_l = got_l;
	else if (want_l != got_l)
		moveReg(want_l, got_l);

	if (!want_r)
		want_r = got_r;
	else if (want_r != got_r)
		moveReg(want_r, got_r);

	int i;
	while ((i = as->find("%l")) != std::string::npos)
		as->replace(i, 2, regs[want_l]);
	while ((i = as->find("%r")) != std::string::npos)
		as->replace(i, 2, regs[want_r]);

	codeFrags.push_back(*as);

	freeReg(got_r);
	if (want_l != got_l)
		moveReg(got_l, want_l);

	//cleanup argFrame
	if (argFrame) {
		//***** Not needed for STDCALL *****
		//		codeFrags.push_back( "+"+itoa(argFrame) );
	}

	//restore spilled regs
	if (spill) {
		for (int n = NUM_REGS; n >= 1; --n) {
			if (spill & (1 << n))
				popReg(n);
		}
	}
	return got_l;
}