use of org.jikesrvm.compilers.opt.ir.Instruction in project JikesRVM by JikesRVM.
the class RewriteMemoryOperandsWithOversizedDisplacements method perform.
@Override
public void perform(IR ir) {
for (Instruction inst = ir.firstInstructionInCodeOrder(); inst != null; inst = inst.nextInstructionInCodeOrder()) {
for (int i = 0; i < inst.getNumberOfOperands(); i++) {
Operand op = inst.getOperand(i);
if (op instanceof MemoryOperand) {
MemoryOperand mo = (MemoryOperand) op;
disp64MemOperandConversion(ir, inst, mo);
}
}
}
}
use of org.jikesrvm.compilers.opt.ir.Instruction in project JikesRVM by JikesRVM.
the class StackManager method insertSpillBefore.
@Override
public void insertSpillBefore(Instruction s, Register r, Register type, int location) {
Operator move = getMoveOperator(type);
byte size = getSizeOfType(type);
RegisterOperand rOp;
if (type.isFloat()) {
rOp = F(r);
} else if (type.isDouble()) {
rOp = D(r);
} else {
if (VM.BuildFor64Addr && type.isInteger()) {
rOp = new RegisterOperand(r, TypeReference.Int);
} else {
rOp = new RegisterOperand(r, PRIMITIVE_TYPE_FOR_WORD);
}
}
StackLocationOperand spillLoc = new StackLocationOperand(true, -location, size);
Instruction spillOp = MIR_Move.create(move, spillLoc, rOp);
if (VERBOSE_DEBUG) {
System.out.println("INSERT_SPILL_BEFORE: " + "Inserting " + spillOp + " before " + s);
}
s.insertBefore(spillOp);
}
use of org.jikesrvm.compilers.opt.ir.Instruction in project JikesRVM by JikesRVM.
the class StackManager method rewriteStackLocations.
/**
* Walks through the IR. For each StackLocationOperand, replace the
* operand with the appropriate MemoryOperand.
*/
private void rewriteStackLocations() {
// ESP is initially WORDSIZE above where the framepointer is going to be.
ESPOffset = getFrameFixedSize() + WORDSIZE;
Register ESP = ((PhysicalRegisterSet) ir.regpool.getPhysicalRegisterSet()).getESP();
boolean seenReturn = false;
for (Enumeration<Instruction> e = ir.forwardInstrEnumerator(); e.hasMoreElements(); ) {
Instruction s = e.nextElement();
if (s.isReturn()) {
seenReturn = true;
continue;
}
if (s.isBranch()) {
// restore ESP to home location at end of basic block.
moveESPBefore(s, 0);
continue;
}
if (s.operator() == BBEND) {
if (seenReturn) {
// at a return ESP will be at FrameFixedSize,
seenReturn = false;
ESPOffset = 0;
} else {
moveESPBefore(s, 0);
}
continue;
}
if (s.operator() == ADVISE_ESP) {
ESPOffset = MIR_UnaryNoRes.getVal(s).asIntConstant().value;
continue;
}
if (s.operator() == REQUIRE_ESP) {
// ESP is required to be at the given offset from the bottom of the frame
moveESPBefore(s, MIR_UnaryNoRes.getVal(s).asIntConstant().value);
continue;
}
if (s.operator() == YIELDPOINT_PROLOGUE || s.operator() == YIELDPOINT_BACKEDGE || s.operator() == YIELDPOINT_EPILOGUE) {
moveESPBefore(s, 0);
continue;
}
if (s.operator() == IA32_MOV) {
rewriteMoveInstruction(s);
}
// stacklocation and memory operands.
if (s.operator() == IA32_POP) {
ESPOffset += WORDSIZE;
}
for (Enumeration<Operand> ops = s.getOperands(); ops.hasMoreElements(); ) {
Operand op = ops.nextElement();
if (op instanceof StackLocationOperand) {
StackLocationOperand sop = (StackLocationOperand) op;
int offset = sop.getOffset();
if (sop.isFromTop()) {
offset = FPOffset2SPOffset(offset);
}
offset -= ESPOffset;
byte size = sop.getSize();
MemoryOperand M = MemoryOperand.BD(new RegisterOperand(ESP, PRIMITIVE_TYPE_FOR_WORD), Offset.fromIntSignExtend(offset), size, null, null);
s.replaceOperand(op, M);
} else if (op instanceof MemoryOperand) {
MemoryOperand M = op.asMemory();
if ((M.base != null && M.base.getRegister() == ESP) || (M.index != null && M.index.getRegister() == ESP)) {
M.disp = M.disp.minus(ESPOffset);
}
}
}
// stacklocation and memory operands.
if (s.operator() == IA32_PUSH) {
ESPOffset -= WORDSIZE;
}
}
}
use of org.jikesrvm.compilers.opt.ir.Instruction 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);
}
use of org.jikesrvm.compilers.opt.ir.Instruction in project JikesRVM by JikesRVM.
the class RegisterPreferences method initialize.
/**
* Set up register preferences based on instructions in an IR.
*/
@Override
public void initialize(IR ir) {
for (Enumeration<Instruction> e = ir.forwardInstrEnumerator(); e.hasMoreElements(); ) {
Instruction s = e.nextElement();
switch(s.getOpcode()) {
case PPC_MOVE_opcode:
// add affinities produced by MOVE instructions
Operand result = MIR_Move.getResult(s);
Operand value = MIR_Move.getValue(s);
if (result.isRegister() && value.isRegister()) {
Register r1 = result.asRegister().getRegister();
Register r2 = value.asRegister().getRegister();
addAffinity(1, r2, r1);
// above.
if (SYMBOLIC_SYMBOLIC_HEURISTIC && r1.isSymbolic() && r2.isSymbolic()) {
addAffinity(1, r2, r1);
}
}
break;
default:
break;
}
}
}
Aggregations