use of org.jikesrvm.classloader.TypeReference 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.classloader.TypeReference in project JikesRVM by JikesRVM.
the class EnterSSA method makePhiInstruction.
/**
* Create a phi-function instruction
*
* @param r the symbolic register
* @param bb the basic block holding the new phi function
* @return the instruction r = PHI null,null,..,null
*/
private Instruction makePhiInstruction(Register r, BasicBlock bb) {
int n = bb.getNumberOfIn();
Enumeration<BasicBlock> in = bb.getIn();
TypeReference type = null;
Instruction s = Phi.create(PHI, new RegisterOperand(r, type), n);
for (int i = 0; i < n; i++) {
RegisterOperand junk = new RegisterOperand(r, type);
Phi.setValue(s, i, junk);
BasicBlock pred = in.nextElement();
Phi.setPred(s, i, new BasicBlockOperand(pred));
}
s.setSourcePosition(SSA_SYNTH_BCI, ir.getGc().getInlineSequence());
return s;
}
use of org.jikesrvm.classloader.TypeReference in project JikesRVM by JikesRVM.
the class EnterSSA method rectifyPhiTypes.
/*
* Compute type information for operands in each phi instruction.
*
* PRECONDITION: Def-use chains computed.
* SIDE EFFECT: empties the scalarPhis set
*/
private void rectifyPhiTypes() {
if (DEBUG)
System.out.println("Rectify phi types.");
removeAllUnreachablePhis(scalarPhis);
int noRehashCapacity = (int) (scalarPhis.size() * 1.5f);
HashMap<Instruction, PhiTypeInformation> phiTypes = new HashMap<Instruction, PhiTypeInformation>(noRehashCapacity);
while (!scalarPhis.isEmpty()) {
boolean didSomething = false;
for (Iterator<Instruction> i = scalarPhis.iterator(); i.hasNext(); ) {
Instruction phi = i.next();
phiTypes.put(phi, PhiTypeInformation.NO_NULL_TYPE);
if (DEBUG)
System.out.println("PHI: " + phi);
TypeReference meet = meetPhiType(phi, phiTypes);
if (DEBUG)
System.out.println("MEET: " + meet);
if (meet != null) {
didSomething = true;
if (phiTypes.get(phi) == PhiTypeInformation.NO_NULL_TYPE)
i.remove();
RegisterOperand result = (RegisterOperand) Phi.getResult(phi);
result.setType(meet);
for (Enumeration<RegisterOperand> e = DefUse.uses(result.getRegister()); e.hasMoreElements(); ) {
RegisterOperand rop = e.nextElement();
if (rop.getType() != meet) {
rop.clearPreciseType();
rop.setType(meet);
}
}
}
}
if (!didSomething) {
// iteration has bottomed out.
return;
}
}
}
use of org.jikesrvm.classloader.TypeReference in project JikesRVM by JikesRVM.
the class EnterSSA method patchPEIgeneratedValues.
/**
* Work around some problems with PEI-generated values and
* handlers. Namely, if a PEI has a return value, rename the
* result register before and after the PEI in order to reflect the fact
* that the PEI may not actually assign the result register.
*/
private void patchPEIgeneratedValues() {
// this only applies if there are exception handlers
if (!ir.hasReachableExceptionHandlers())
return;
HashSet<Pair<BasicBlock, RegisterOperand>> needed = new HashSet<Pair<BasicBlock, RegisterOperand>>(4);
Enumeration<BasicBlock> blocks = ir.getBasicBlocks();
while (blocks.hasMoreElements()) {
BasicBlock block = blocks.nextElement();
if (block.getExceptionalOut().hasMoreElements()) {
Instruction pei = block.lastRealInstruction();
if (pei != null && pei.isPEI() && ResultCarrier.conforms(pei)) {
boolean copyNeeded = false;
RegisterOperand v = ResultCarrier.getResult(pei);
// void calls and the like... :(
if (v != null) {
Register orig = v.getRegister();
{
Enumeration<BasicBlock> out = block.getApplicableExceptionalOut(pei);
while (out.hasMoreElements()) {
BasicBlock exp = out.nextElement();
LiveSet explive = live.getLiveInfo(exp).getIn();
if (explive.contains(orig)) {
copyNeeded = true;
break;
}
}
}
if (copyNeeded) {
Enumeration<BasicBlock> out = block.getApplicableExceptionalOut(pei);
while (out.hasMoreElements()) {
BasicBlock exp = out.nextElement();
needed.add(new Pair<BasicBlock, RegisterOperand>(exp, v));
}
}
}
}
}
}
// having determine where copies should be inserted, now insert them.
if (!needed.isEmpty()) {
for (Pair<BasicBlock, RegisterOperand> copy : needed) {
BasicBlock inBlock = copy.first;
RegisterOperand registerOp = copy.second;
TypeReference type = registerOp.getType();
Register register = registerOp.getRegister();
Register temp = ir.regpool.getReg(register);
inBlock.prependInstruction(SSA.makeMoveInstruction(ir, register, temp, type));
Enumeration<BasicBlock> outBlocks = inBlock.getIn();
while (outBlocks.hasMoreElements()) {
BasicBlock outBlock = outBlocks.nextElement();
Instruction x = SSA.makeMoveInstruction(ir, temp, register, type);
SSA.addAtEnd(ir, outBlock, x, true);
}
}
// Recompute liveness information. You might be tempted to incrementally
// update it, but it's tricky, so resist.....do the obvious, but easy thing!
prepare();
}
}
use of org.jikesrvm.classloader.TypeReference in project JikesRVM by JikesRVM.
the class EnterSSA method meetPhiType.
/**
* Return the meet of the types on the rhs of a phi instruction
*
* @param s phi instruction
* @param phiTypes TODO
* @return the meet of the types
*/
private static TypeReference meetPhiType(Instruction s, Map<Instruction, PhiTypeInformation> phiTypes) {
TypeReference result = null;
for (int i = 0; i < Phi.getNumberOfValues(s); i++) {
Operand val = Phi.getValue(s, i);
if (val instanceof UnreachableOperand)
continue;
TypeReference t = val.getType();
if (t == null) {
phiTypes.put(s, PhiTypeInformation.FOUND_NULL_TYPE);
} else if (result == null) {
result = t;
} else {
TypeReference meet = ClassLoaderProxy.findCommonSuperclass(result, t);
if (meet == null) {
// TODO: This horrific kludge should go away once we get rid of Address.toInt()
if ((result.isIntLikeType() && (t.isReferenceType() || t.isWordLikeType())) || ((result.isReferenceType() || result.isWordLikeType()) && t.isIntLikeType())) {
meet = TypeReference.Int;
} else if (result.isReferenceType() && t.isWordLikeType()) {
meet = t;
} else if (result.isWordLikeType() && t.isReferenceType()) {
meet = result;
}
}
if (VM.VerifyAssertions && meet == null) {
String msg = result + " and " + t + " meet to null";
VM._assert(VM.NOT_REACHED, msg);
}
result = meet;
}
}
return result;
}
Aggregations