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; } }
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; } }
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; } }
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; }
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; }