use of org.jikesrvm.compilers.opt.ir.GenericPhysicalRegisterSet in project JikesRVM by JikesRVM.
the class UpdateGCMaps2 method perform.
/**
* @param ir the IR
*/
@Override
public void perform(IR ir) {
GenericPhysicalRegisterSet phys = ir.regpool.getPhysicalRegisterSet();
ScratchMap scratchMap = ir.stackManager.getScratchMap();
RegisterAllocatorState regAllocState = ir.MIRInfo.regAllocState;
if (LinearScan.GC_DEBUG) {
System.out.println("SCRATCH MAP:");
System.out.println();
System.out.println(scratchMap);
}
if (scratchMap.isEmpty())
return;
// Walk over each instruction that has a GC point.
for (GCIRMapElement GCelement : ir.MIRInfo.gcIRMap) {
// new elements to add to the gc map
HashSet<RegSpillListElement> newElements = new HashSet<RegSpillListElement>();
Instruction GCinst = GCelement.getInstruction();
int dfn = regAllocState.getDFN(GCinst);
if (LinearScan.GC_DEBUG) {
VM.sysWrite("GCelement at " + dfn + " , " + GCelement);
}
// a set of elements to delete from the GC Map
HashSet<RegSpillListElement> toDelete = new HashSet<RegSpillListElement>(3);
// For each element in the GC Map ...
for (RegSpillListElement elem : GCelement.regSpillList()) {
if (LinearScan.GC_DEBUG) {
VM.sysWriteln("Update " + elem);
}
if (elem.isSpill()) {
// check if the spilled value currently is cached in a scratch
// register
Register r = elem.getSymbolicReg();
Register scratch = scratchMap.getScratch(r, dfn);
if (scratch != null) {
if (LinearScan.GC_DEBUG) {
VM.sysWriteln("cached in scratch register " + scratch);
}
// we will add a new element noting that the scratch register
// also must be including in the GC map
RegSpillListElement newElem = new RegSpillListElement(r);
newElem.setRealReg(scratch);
newElements.add(newElem);
// valid value
if (scratchMap.isDirty(GCinst, r)) {
toDelete.add(elem);
}
}
} else {
// check if the physical register is currently spilled.
int n = elem.getRealRegNumber();
Register r = phys.get(n);
if (scratchMap.isScratch(r, dfn)) {
// spilled.
if (LinearScan.GC_DEBUG) {
VM.sysWriteln("CHANGE to spill location " + regAllocState.getSpill(r));
}
elem.setSpill(regAllocState.getSpill(r));
}
}
}
// delete all obsolete elements
for (RegSpillListElement deadElem : toDelete) {
GCelement.deleteRegSpillElement(deadElem);
}
// add each new Element to the gc map
for (RegSpillListElement newElem : newElements) {
GCelement.addRegSpillElement(newElem);
}
}
}
use of org.jikesrvm.compilers.opt.ir.GenericPhysicalRegisterSet in project JikesRVM by JikesRVM.
the class CallingConvention method saveNonvolatilesBeforeSysCall.
/**
* Save all nonvolatile registers before a syscall.
* We do this in case the sys call does not respect our
* register conventions.<p>
*
* We save/restore all nonvolatiles and the PR, whether
* or not this routine uses them. This may be a tad inefficient, but if
* you're making a system call, you probably don't care.
*
* @param call the sys call
* @param ir the IR that contains the call
*/
static void saveNonvolatilesBeforeSysCall(Instruction call, IR ir) {
GenericPhysicalRegisterSet phys = ir.regpool.getPhysicalRegisterSet();
StackManager sm = (StackManager) ir.stackManager;
// get the offset into the stack frame of where to stash the first
// nonvolatile for this case.
int location = sm.getOffsetForSysCall();
// save each non-volatile
for (Enumeration<Register> e = phys.enumerateNonvolatileGPRs(); e.hasMoreElements(); ) {
Register r = e.nextElement();
Operand M = new StackLocationOperand(true, -location, (byte) WORDSIZE);
call.insertBefore(MIR_Move.create(IA32_MOV, M, new RegisterOperand(r, wordType)));
location += WORDSIZE;
}
// save the thread register
Operand M = new StackLocationOperand(true, -location, (byte) WORDSIZE);
call.insertBefore(MIR_Move.create(IA32_MOV, M, ir.regpool.makeTROp()));
// save the JTOC, if present
if (JTOC_REGISTER != null) {
location += WORDSIZE;
Operand jtocSave = new StackLocationOperand(true, -location, (byte) WORDSIZE);
call.insertBefore(MIR_Move.create(IA32_MOV, jtocSave, ir.regpool.makeTocOp()));
}
}
use of org.jikesrvm.compilers.opt.ir.GenericPhysicalRegisterSet in project JikesRVM by JikesRVM.
the class StackManager method saveFloatingPointState.
/**
* Insert code into the prologue to save the floating point state.
*
* @param inst the first instruction after the prologue.
*/
private void saveFloatingPointState(Instruction inst) {
if (SSE2_FULL) {
GenericPhysicalRegisterSet phys = ir.regpool.getPhysicalRegisterSet();
for (int i = 0; i < 8; i++) {
inst.insertBefore(MIR_Move.create(IA32_MOVQ, new StackLocationOperand(true, -fsaveLocation + (i * BYTES_IN_DOUBLE), BYTES_IN_DOUBLE), new RegisterOperand(phys.getFPR(i), TypeReference.Double)));
}
} else {
Operand M = new StackLocationOperand(true, -fsaveLocation, 4);
inst.insertBefore(MIR_FSave.create(IA32_FNSAVE, M));
}
}
use of org.jikesrvm.compilers.opt.ir.GenericPhysicalRegisterSet in project JikesRVM by JikesRVM.
the class StackManager method computeNonVolatileArea.
@Override
public void computeNonVolatileArea() {
GenericPhysicalRegisterSet phys = ir.regpool.getPhysicalRegisterSet();
if (ir.compiledMethod.isSaveVolatile()) {
// Record that we use every nonvolatile GPR
int numGprNv = PhysicalRegisterSet.getNumberOfNonvolatileGPRs();
ir.compiledMethod.setNumberOfNonvolatileGPRs((short) numGprNv);
// set the frame size
frameSize += numGprNv * WORDSIZE;
frameSize = align(frameSize, STACKFRAME_ALIGNMENT);
// TODO!!
ir.compiledMethod.setNumberOfNonvolatileFPRs((short) 0);
// Record that we need a stack frame.
setFrameRequired();
int fpuStateSaveAreaBegin = spillPointer;
// and saveFloatingPointState(..)
if (SSE2_FULL) {
for (int i = 0; i < 8; i++) {
fsaveLocation = allocateNewSpillLocation(DOUBLE_REG);
}
} else {
// frame, as a place to store the floating-point state with FSAVE
for (int i = 0; i < 27; i++) {
fsaveLocation = allocateNewSpillLocation(INT_REG);
}
}
int fpuStateSaveAreaEnd = spillPointer;
int fpuStateSize = fpuStateSaveAreaEnd - fpuStateSaveAreaBegin;
if (VM.VerifyAssertions) {
VM._assert(fpuStateSize == OPT_SAVE_VOLATILE_SPACE_FOR_FPU_STATE);
}
int volatileGPRSaveAreaBegin = spillPointer;
// Map each volatile register to a spill location.
int i = 0;
for (Enumeration<Register> e = phys.enumerateVolatileGPRs(); e.hasMoreElements(); i++) {
e.nextElement();
// Note that as a side effect, the following call bumps up the
// frame size.
saveVolatileGPRLocation[i] = allocateNewSpillLocation(INT_REG);
}
int volatileGPRSaveAreaEnd = spillPointer;
int volatileGPRSaveAreaSize = volatileGPRSaveAreaEnd - volatileGPRSaveAreaBegin;
if (VM.VerifyAssertions) {
VM._assert(volatileGPRSaveAreaSize == OPT_SAVE_VOLATILE_SPACE_FOR_VOLATILE_GPRS);
VM._assert((volatileGPRSaveAreaSize + fpuStateSize) == OPT_SAVE_VOLATILE_TOTAL_SIZE);
}
// Map each non-volatile register to a spill location.
i = 0;
for (Enumeration<Register> e = phys.enumerateNonvolatileGPRs(); e.hasMoreElements(); i++) {
e.nextElement();
// Note that as a side effect, the following call bumps up the
// frame size.
nonVolatileGPRLocation[i] = allocateNewSpillLocation(INT_REG);
}
// Set the offset to find non-volatiles.
int gprOffset = getNonvolatileGPROffset(0);
ir.compiledMethod.setUnsignedNonVolatileOffset(gprOffset);
} else {
// Count the number of nonvolatiles used.
int numGprNv = 0;
int i = 0;
for (Enumeration<Register> e = phys.enumerateNonvolatileGPRs(); e.hasMoreElements(); ) {
Register r = e.nextElement();
if (r.isTouched()) {
// Note that as a side effect, the following call bumps up the
// frame size.
nonVolatileGPRLocation[i++] = allocateNewSpillLocation(INT_REG);
numGprNv++;
}
}
// Update the OptCompiledMethod object.
ir.compiledMethod.setNumberOfNonvolatileGPRs((short) numGprNv);
if (numGprNv > 0) {
int gprOffset = getNonvolatileGPROffset(0);
ir.compiledMethod.setUnsignedNonVolatileOffset(gprOffset);
// record that we need a stack frame
setFrameRequired();
} else {
ir.compiledMethod.setUnsignedNonVolatileOffset(0);
}
ir.compiledMethod.setNumberOfNonvolatileFPRs((short) 0);
}
}
use of org.jikesrvm.compilers.opt.ir.GenericPhysicalRegisterSet in project JikesRVM by JikesRVM.
the class CallingConvention method prologueExpand.
// ///////////////////
// Implementation
// ///////////////////
/**
* Expand the prologue instruction to make calling convention explicit.
*/
private static void prologueExpand(IR ir) {
// set up register lists for dead code elimination.
boolean useDU = ir.options.getOptLevel() >= 1;
if (useDU) {
DefUse.computeDU(ir);
}
Instruction prologueInstr = ir.firstInstructionInCodeOrder().nextInstructionInCodeOrder();
if (VM.VerifyAssertions)
VM._assert(prologueInstr.operator() == IR_PROLOGUE);
Instruction start = prologueInstr.nextInstructionInCodeOrder();
int int_index = 0;
int double_index = 0;
int spilledArgumentCounter = (-256 - STACKFRAME_HEADER_SIZE) >> LOG_BYTES_IN_ADDRESS;
GenericPhysicalRegisterSet phys = ir.regpool.getPhysicalRegisterSet();
Register FP = phys.getFP();
for (Enumeration<Operand> symParams = prologueInstr.getDefs(); symParams.hasMoreElements(); ) {
RegisterOperand symParamOp = (RegisterOperand) symParams.nextElement();
Register symParam = symParamOp.getRegister();
TypeReference t = symParamOp.getType();
if (t.isFloatType()) {
// Why? TODO: figure this out and remove the 'true' case below
if (true || !useDU || symParam.useList != null) {
if (double_index < NUMBER_DOUBLE_PARAM) {
Register param = phys.get(FIRST_DOUBLE_PARAM + (double_index));
start.insertBefore(MIR_Move.create(PPC_FMR, F(symParam), F(param)));
} else {
// spilled parameter
start.insertBefore(MIR_Load.create(PPC_LFS, F(symParam), A(FP), IC((spilledArgumentCounter << LOG_BYTES_IN_ADDRESS) - BYTES_IN_ADDRESS + BYTES_IN_FLOAT)));
spilledArgumentCounter--;
}
}
double_index++;
} else if (t.isDoubleType()) {
// Why? TODO: figure this out and remove the 'true' case below
if (true || !useDU || symParam.useList != null) {
if (double_index < NUMBER_DOUBLE_PARAM) {
Register param = phys.get(FIRST_DOUBLE_PARAM + (double_index));
start.insertBefore(MIR_Move.create(PPC_FMR, D(symParam), D(param)));
} else {
// spilled parameter
start.insertBefore(MIR_Load.create(PPC_LFD, D(symParam), A(FP), IC(spilledArgumentCounter << LOG_BYTES_IN_ADDRESS)));
spilledArgumentCounter -= BYTES_IN_DOUBLE / BYTES_IN_ADDRESS;
}
}
double_index++;
} else {
// Why? TODO: figure this out and remove the 'true' case below
if (true || !useDU || symParam.useList != null) {
if (int_index < NUMBER_INT_PARAM) {
Register param = phys.get(FIRST_INT_PARAM + (int_index));
start.insertBefore(MIR_Move.create(PPC_MOVE, new RegisterOperand(symParam, t), A(param)));
} else {
// spilled parameter
if (VM.BuildFor64Addr && (t.isIntType() || t.isShortType() || t.isByteType() || t.isCharType() || t.isBooleanType())) {
start.insertBefore(MIR_Load.create(PPC_LInt, new RegisterOperand(symParam, t), A(FP), IC((spilledArgumentCounter << LOG_BYTES_IN_ADDRESS) - BYTES_IN_ADDRESS + BYTES_IN_INT)));
} else {
// same size as addr (ie, either we're in 32 bit mode or we're in 64 bit mode and it's a reference or long)
start.insertBefore(MIR_Load.create(PPC_LAddr, new RegisterOperand(symParam, t), A(FP), IC(spilledArgumentCounter << LOG_BYTES_IN_ADDRESS)));
}
spilledArgumentCounter--;
}
}
int_index++;
}
}
removeDefsFromPrologue(prologueInstr);
}
Aggregations