📄 jitregman.c
字号:
*/#if 0 if ((oldrmask & con->occupiedRegisters) != oldrmask) { CVMconsolePrintf("****May have spilled\n"); }#endif /* * Issue the move instruction(s) */ if (rp->nregs == 1) { CVMCPUemitMoveRegister(cc, RM_MOV_OPCODE(con), regNo, oldRegNo, CVMJIT_NOSETCC); } else if (regNo == oldRegNo + 1) { CVMCPUemitMoveRegister(cc, RM_MOV_OPCODE(con), regNo+1, oldRegNo+1, CVMJIT_NOSETCC); CVMCPUemitMoveRegister(cc, RM_MOV_OPCODE(con), regNo, oldRegNo, CVMJIT_NOSETCC); } else { CVMCPUemitMoveRegister(cc, RM_MOV_OPCODE(con), regNo, oldRegNo, CVMJIT_NOSETCC); CVMCPUemitMoveRegister(cc, RM_MOV_OPCODE(con), regNo+1, oldRegNo+1, CVMJIT_NOSETCC); } /* The resource no longer occupies the old registers it was in */ con->occupiedRegisters &= ~oldrmask; /* * This is necessary in case there is overlap between the new and old * registers, which of course can only happen with 64-bit resources. */ if (rp->nregs == 2) { /* undo damage done by masking with ~oldrmask */ con->occupiedRegisters |= ((1U << regNo) | (1U << (regNo + 1))); } pinToRegister(con, rp, regNo);}static CVMRMResource*newResource(CVMJITRMContext* con){ CVMJITCompilationContext* cc = con->compilationContext; CVMRMResource *rp = cc->RMcommonContext.freeResourceList; if (rp != NULL) { cc->RMcommonContext.freeResourceList = rp->next; memset(rp, 0, sizeof *rp); } else { rp = CVMJITmemNew(cc, JIT_ALLOC_CGEN_REGMAN, sizeof(CVMRMResource)); } return rp;}static CVMRMResource*CVMRMallocateAndPutOnList(CVMJITRMContext* con){ CVMRMResource* rp = newResource(con); CVMJITidentityInitDecoration(con, &rp->dec, CVMJIT_IDENTITY_DECORATION_RESOURCE); rp->next = con->resourceList; rp->prev = NULL; if (con->resourceList != NULL){ con->resourceList->prev = rp; } con->resourceList = rp;#ifdef CVM_DEBUG_ASSERTS rp->key = con->key;#endif return rp;}/* * Return register preference based on target and avoid sets. * If there is an unsafe register in the target set that is not in * the avoid set, then use SCRATCH preference. Otherwise use PERSISTENT. */static CVMRMRegisterPreferencegetRegisterPreference(CVMJITRMContext* con, CVMRMregset target, CVMRMregset avoid){#ifdef IAI_ROUNDROBIN_REGISTER_ALLOCATION return CVMRM_REGPREF_TARGET;#endif#if 1 return CVMRM_REGPREF_PERSISTENT;#else /* * NOTE: the following code is disabled since it hasn't been determined * to be of any value and may actually hurt performance. This is probably * because the avoid set is not accurate enough (due to TEMP nodes and * IDENTITY nodes). */ if ((~avoid & target & RM_UNSAFE_SET) != CVMRM_EMPTY_SET) { return CVMRM_REGPREF_SCRATCH; } else { return CVMRM_REGPREF_PERSISTENT; }#endif}CVMRMResource*CVMRMgetResource0( CVMJITRMContext* con, CVMRMregset target, CVMRMregset avoid, CVMRMRegisterPreference pref, CVMBool strict, int size){ int regNo; CVMRMResource* rp; int nregs = RM_NREGISTERS(con, size); CVMassert(!con->compilationContext->inConditionalCode); regNo = findAvailableRegister(con, target, avoid, pref, strict, nregs); /* * we have a register (or asserted while trying) * so make up a new resource and return it. */ rp = CVMRMallocateAndPutOnList(con); rp->size = size; rp->nregs = nregs; rp->spillLoc = -1; rp->localNo = CVMRM_INVALID_LOCAL_NUMBER; rp->constant = -1; rp->expr = NULL; rp->regno = -1; pinToRegister(con, rp, regNo); return rp;}/* * For now, ask for any register. * Eventually, we should probably pass in * the expression so we can make a better decision based * on reference counts or other usage information. */CVMRMResource*CVMRMgetResource( CVMJITRMContext* con, CVMRMregset target, CVMRMregset avoid, int size){ return CVMRMgetResource0(con, target, avoid, getRegisterPreference(con, target, avoid), CVM_FALSE, size);}CVMRMResource*CVMRMgetPersistentResource( CVMJITRMContext* con, CVMRMregset target, CVMRMregset avoid, int size){ return CVMRMgetResource0(con, target, avoid, CVMRM_REGPREF_PERSISTENT, CVM_FALSE, size);}CVMRMResource*CVMRMgetResourceStrict( CVMJITRMContext* con, CVMRMregset target, CVMRMregset avoid, int size){ CVMRMResource* r = CVMRMgetResource0(con, target, avoid, CVMRM_REGPREF_TARGET, CVM_TRUE, size); CVMassert(((1U<<r->regno) & target) != 0); return r;}CVMRMResource*CVMRMgetResourceSpecific( CVMJITRMContext* con, int target, int size){ CVMRMregset t = 1U << target; CVMRMResource* r = CVMRMgetResource0(con, t, ~t, CVMRM_REGPREF_TARGET, CVM_TRUE, size); CVMassert(r->regno == target); return r;}/* * Clone a given resource to a target register, and emit move of * source contents to target. The returned clone has a reference count * of 1. */static voidCVMRMcloneResource0( CVMJITRMContext* con, CVMRMResource *rp, CVMRMResource *clonerp){ CVMJITCompilationContext* cc = con->compilationContext; CVMassert(clonerp->flags & CVMRMpinned); CVMRMassertContextMatch(con, rp); /* clone */ clonerp->flags = rp->flags & (CVMRMpinned|CVMRMref); clonerp->flags |= CVMRMclone; clonerp->expr = rp->expr;#ifdef CVM_DEBUG clonerp->originalTag = rp->originalTag;#endif#ifdef CVM_TRACE_JIT clonerp->name = rp->name;#endif CVMRMdecRefCount(con, rp); /* Emit move from original to clone */ CVMCPUemitMoveRegister(cc, RM_MOV_OPCODE(con), clonerp->regno, rp->regno, CVMJIT_NOSETCC); if (rp->nregs > 1) { /* Handle 64-bit values too */ CVMCPUemitMoveRegister(cc, RM_MOV_OPCODE(con), clonerp->regno+1, rp->regno+1, CVMJIT_NOSETCC); }}CVMRMResource*CVMRMcloneResourceStrict( CVMJITRMContext* con, CVMRMResource *rp, CVMRMregset target, CVMRMregset avoid){ CVMRMResource *clonerp; CVMassert(rp->flags & CVMRMpinned); /* Only clone pinned resources */ clonerp = CVMRMgetResourceStrict(con, target, avoid, rp->size); CVMRMcloneResource0(con, rp, clonerp); return clonerp;}static CVMRMResource*CVMRMcloneResourceSpecific( CVMJITRMContext* con, CVMRMResource *rp, int target){ CVMRMResource *clonerp; CVMassert(rp->flags & CVMRMpinned); /* Only clone pinned resources */ CVMassert(rp->regno != target); /* Be sensible */ clonerp = CVMRMgetResourceSpecific(con, target, rp->size); CVMassert(clonerp->regno == target); CVMRMcloneResource0(con, rp, clonerp); return clonerp;} /* DEBUGchar * regByKey[] = { "X", "%r", "%f" }; *//* * Clone a given resource to another resource in the other register bank. * The target pinned and loaded. * The reference count on the spill location is incremented. */extern CVMRMResource *CVMRMcloneResource( CVMJITRMContext* srcCx, CVMRMResource* src, CVMJITRMContext* destCx, CVMRMregset target, CVMRMregset avoid){ CVMRMResource* rnew; int spilloff; CVMRMassertContextMatch(srcCx, src); if (CVMRMisConstant(src)) { CVMassert(src->size == 1); rnew = CVMRMgetResourceForConstant32(destCx, target, avoid, src->constant); return rnew; } /* * Make sure the spill area is consistent with the src register */ if ((src->regno >= 0) && (src->flags & CVMRMdirty)){ flushResource(srcCx, src); src->flags ^= CVMRMdirty; } /* * now clone it. */ rnew = CVMRMgetResource( destCx, target, avoid, src->size); rnew->flags = src->flags | CVMRMclone | CVMRMpinned; rnew->nregs = RM_NREGISTERS(destCx, rnew->size); /* recompute nregs! */ rnew->spillLoc = src->spillLoc; rnew->localNo = src->localNo; rnew->expr = src->expr; rnew->constant = src->constant;#ifdef CVM_DEBUG rnew->originalTag = src->originalTag;#endif#ifdef CVM_TRACE_JIT rnew->name = src->name;#endif /* * Incremement ref count on spill location, if any */ spilloff = src->spillLoc; if (spilloff >= 0){ incrementSpillCount(destCx->compilationContext, spilloff, src->size); } /* * LOAD THE DATA & DISASSOCIATE FROM LOCAL, IF ANY. */ reloadRegister( destCx->compilationContext, destCx, rnew); if (CVMRMisLocal(rnew)){ /* if it has to do a writeback, do it somewhere else */ rnew->flags = (rnew->flags & ~CVMRMLocalVar) | CVMRMdirty; rnew->localNo = CVMRM_INVALID_LOCAL_NUMBER; } /* DEBUG CVMconsolePrintf("CLONING resource 0x%x (%s%d) to resource 0x%x (%s%d)\n", src, regByKey[src->key], src->regno, rnew, regByKey[rnew->key], rnew->regno); */ return rnew;}/* * Allocate a resource to a temporary value which is on the Java stack. * Defer pinning until needed. */CVMRMResource*CVMRMbindStackTempToResource( CVMJITRMContext* con, CVMJITIRNode* expr, int size){ CVMRMResource* rp; rp = CVMRMallocateAndPutOnList(con); /* could probably tell this by looking at node tag */ rp->flags = CVMRMjavaStackTopValue; rp->size = size; rp->nregs = RM_NREGISTERS(con, size); rp->expr = expr; rp->spillLoc = -1; rp->localNo = CVMRM_INVALID_LOCAL_NUMBER; rp->constant = -1; rp->regno = -1; CVMRMsetRefCount(con, rp, CVMJITirnodeGetRefCount(expr)); if (CVMJITirnodeIsReferenceType(expr)) { rp->flags |= CVMRMref; } return rp;}static voiddeleteResource( CVMJITRMContext* con, CVMRMResource* rp ){ if (con->resourceList == rp ) { con->resourceList = rp->next; } if (rp->prev != NULL) { rp->prev->next = rp->next; } if (rp->next != NULL) { rp->next->prev = rp->prev; } rp->flags = CVMRMtrash; if (rp->regno != -1){ con->occupiedRegisters &= ~rp->rmask; con->reg2res[rp->regno] = NULL; if (rp->nregs == 2 ){ con->reg2res[rp->regno + 1] = NULL; }#ifdef CVM_DEBUG rp->regno = 127; /* make it look trashy */#endif } rp->next = con->freeResourceList; con->freeResourceList = rp;}/* * Make sure that a given resource is in a register, in accordance * with 'target' and 'avoid' */static voidensureInRegister(CVMJITRMContext* con, CVMRMregset target, CVMRMregset avoid, CVMRMRegisterPreference pref, CVMBool strict, CVMRMResource* rp){ CVMRMpinResource0(con, rp, target, avoid, pref, strict);}/* * TBD: Constants should get their own list. If constants * get their own table, associateResourceWithConstant32() * also needs to be updated. */CVMRMResource*CVMRMfindResourceConstant32(CVMJITRMContext* con, CVMInt32 constant){ CVMRMResource* rp; for (rp = con->resourceList; rp != NULL; rp = rp->next) { if (CVMRMisConstant(rp) && rp->constant == constant) { break; } } return rp;}/* * This is a no-op currently. If and when constants get their * own table, this has to do something. */static voidassociateResourceWithConstant32(CVMJITRMContext* con, CVMRMResource* rp, CVMInt32 constant){ CVMassert(CVMRMfindResourceConstant32(con, constant) != NULL);}/* * Create a resource for a 32-bit constant. */CVMRMResource*CVMRMbindResourceForConstant32( CVMJITRMContext* con, CVMInt32 constant){ CVMRMResource* rp;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -