use of org.jikesrvm.compilers.opt.ir.operand.HeapOperand in project JikesRVM by JikesRVM.
the class LICM method replaceUses.
/*
* In the consumers of `inst', replace uses of `inst's result
* with uses of `replacement'
*/
private boolean replaceUses(Instruction inst, HeapOperand<?> replacement, BasicBlockOperand replacementBlock, boolean onlyPEIs) {
if (VM.VerifyAssertions)
VM._assert(Phi.conforms(inst));
boolean changed = false;
// Cast to generic HeapOperand
@SuppressWarnings("unchecked") HeapOperand<Object> hop = (HeapOperand) Phi.getResult(inst);
HeapVariable<Object> H = hop.value;
Iterator<HeapOperand<Object>> it = ssad.iterateHeapUses(H);
while (it.hasNext()) {
hop = it.next();
Instruction user = hop.instruction;
if (onlyPEIs && !user.isPEI())
continue;
if (Phi.conforms(user)) {
for (int i = 0; i < Phi.getNumberOfValues(user); i++) {
if (Phi.getValue(user, i) == hop) {
Phi.setValue(user, i, replacement.copy());
Phi.setPred(user, i, (BasicBlockOperand) replacementBlock.copy());
}
}
changed |= replacement.value != H;
} else {
HeapOperand<?>[] uses = ssad.getHeapUses(user);
for (int i = uses.length - 1; i >= 0; --i) {
if (uses[i].value == H) {
changed |= replacement.value != H;
uses[i] = replacement.copy();
uses[i].setInstruction(user);
}
}
}
if (DEBUG && changed) {
VM.sysWriteln(" changing dependency of " + user + "\n" + "from " + H + " to " + replacement);
}
}
if (!onlyPEIs) {
for (int i = Phi.getNumberOfValues(inst) - 1; i >= 0; --i) {
Phi.setValue(inst, i, replacement.copy());
}
}
return changed;
}
use of org.jikesrvm.compilers.opt.ir.operand.HeapOperand in project JikesRVM by JikesRVM.
the class LICM method scheduleHeapUsesLate.
BasicBlock scheduleHeapUsesLate(Instruction inst, BasicBlock lateBlock) {
// VM.sysWriteln (" scheduleHeapUsesLate");
Operand[] defs = ssad.getHeapDefs(inst);
if (defs == null)
return lateBlock;
// VM.sysWriteln (" defs: " + defs.length);
for (Operand def : defs) {
// Cast to generic HeapOperand
@SuppressWarnings("unchecked") HeapOperand<Object> dhop = (HeapOperand) def;
HeapVariable<Object> H = dhop.value;
if (DEBUG)
VM.sysWriteln("H: " + H);
Iterator<HeapOperand<Object>> it = ssad.iterateHeapUses(H);
// VM.sysWriteln (" H: " + H + " (" + ssad.getNumberOfUses (H) + ")");
while (it.hasNext()) {
HeapOperand<Object> uhop = it.next();
// VM.sysWriteln (" uhop: " + uhop):
Instruction use = uhop.instruction;
// VM.sysWriteln ("use: " + use);
BasicBlock _block = useBlock(use, uhop);
lateBlock = commonDominator(_block, lateBlock);
}
}
return lateBlock;
}
use of org.jikesrvm.compilers.opt.ir.operand.HeapOperand in project JikesRVM by JikesRVM.
the class LoadElimination method replaceDefs.
/**
* Perform scalar replacement actions for a Def of a heap variable.
* <p>
* NOTE: Even loads can def a heap variable.
*
* @param ir the governing IR
* @param UseRepSet stores the uses(loads) that have been eliminated
* @param registers mapping from valueNumber -> temporary register
*/
static void replaceDefs(IR ir, UseRecordSet UseRepSet, HashMap<UseRecord, Register> registers) {
SSADictionary ssa = ir.HIRInfo.dictionary;
for (Enumeration<Instruction> e = ir.forwardInstrEnumerator(); e.hasMoreElements(); ) {
Instruction s = e.nextElement();
if (!GetField.conforms(s) && !GetStatic.conforms(s) && !PutField.conforms(s) && !PutStatic.conforms(s) && !ALoad.conforms(s) && !AStore.conforms(s)) {
continue;
}
if (!ssa.defsHeapVariable(s)) {
continue;
}
// this instruction is a DEF of heap variable H.
// Check if UseRepSet needs the scalar assigned by this def
HeapOperand<?>[] H = ssa.getHeapDefs(s);
if (H.length != 1) {
throw new OptimizingCompilerException("LoadElimination: encountered a store with more than one def? " + s);
}
int valueNumber = -1;
Object index = null;
if (AStore.conforms(s)) {
Object address = AStore.getArray(s);
index = AStore.getIndex(s);
valueNumber = ir.HIRInfo.valueNumbers.getValueNumber(address);
} else if (GetField.conforms(s)) {
Object address = GetField.getRef(s);
valueNumber = ir.HIRInfo.valueNumbers.getValueNumber(address);
} else if (PutField.conforms(s)) {
Object address = PutField.getRef(s);
valueNumber = ir.HIRInfo.valueNumbers.getValueNumber(address);
} else if (GetStatic.conforms(s)) {
valueNumber = 0;
} else if (PutStatic.conforms(s)) {
valueNumber = 0;
} else if (ALoad.conforms(s)) {
Object address = ALoad.getArray(s);
valueNumber = ir.HIRInfo.valueNumbers.getValueNumber(address);
index = ALoad.getIndex(s);
}
if (index == null) {
// Load/Store
if (UseRepSet.containsMatchingUse(H[0].getHeapVariable(), valueNumber)) {
Operand value = null;
if (PutField.conforms(s)) {
value = PutField.getValue(s);
} else if (PutStatic.conforms(s)) {
value = PutStatic.getValue(s);
} else if (GetField.conforms(s) || GetStatic.conforms(s)) {
value = ResultCarrier.getResult(s);
}
TypeReference type = value.getType();
Register r = findOrCreateRegister(H[0].getHeapType(), valueNumber, registers, ir.regpool, type);
appendMove(r, value, s);
}
} else {
// ALoad / AStore
int v1 = valueNumber;
int v2 = ir.HIRInfo.valueNumbers.getValueNumber(index);
if (UseRepSet.containsMatchingUse(H[0].getHeapVariable(), v1, v2)) {
Operand value = null;
if (AStore.conforms(s)) {
value = AStore.getValue(s);
} else if (ALoad.conforms(s)) {
value = ALoad.getResult(s);
}
TypeReference type = value.getType();
Register r = findOrCreateRegister(H[0].getHeapType(), v1, v2, registers, ir.regpool, type);
appendMove(r, value, s);
}
}
}
}
use of org.jikesrvm.compilers.opt.ir.operand.HeapOperand in project JikesRVM by JikesRVM.
the class LoadElimination method replaceLoads.
/**
* Walk over each instruction. If its a USE (load) of a heap
* variable and the value is available, then replace the load
* with a move from a register.
* <p>
* POSTCONDITION: sets up the mapping 'registers' from value number
* to temporary register
* @param ir the IR
* @param available information on which values are available
* @param registers a place to store information about temp registers
* @return mapping from heap variables to value numbers
*/
static UseRecordSet replaceLoads(IR ir, DF_Solution available, HashMap<UseRecord, Register> registers) {
UseRecordSet result = new UseRecordSet();
SSADictionary ssa = ir.HIRInfo.dictionary;
GlobalValueNumberState valueNumbers = ir.HIRInfo.valueNumbers;
for (Enumeration<Instruction> e = ir.forwardInstrEnumerator(); e.hasMoreElements(); ) {
Instruction s = e.nextElement();
if (!GetField.conforms(s) && !GetStatic.conforms(s) && !ALoad.conforms(s)) {
continue;
}
// this instruction is a USE of heap variable H.
// get the lattice cell that holds the available indices
// for this heap variable
HeapOperand<?>[] H = ssa.getHeapUses(s);
if (H == null) {
// TODO: clean up HIR representation of these magics
continue;
}
if (H.length != 1) {
throw new OptimizingCompilerException("LoadElimination: load with wrong number of heap uses");
}
if (GetField.conforms(s) || GetStatic.conforms(s)) {
int valueNumber = -1;
if (GetField.conforms(s)) {
Object address = GetField.getRef(s);
valueNumber = valueNumbers.getValueNumber(address);
} else {
// for getStatic, always use the value number 0
valueNumber = 0;
}
ObjectCell cell = (ObjectCell) available.lookup(H[0].getHeapVariable());
if (cell == null) {
// nothing available
continue;
}
// .. if H{valueNumber} is available ...
if (cell.contains(valueNumber)) {
result.add(H[0].getHeapVariable(), valueNumber);
TypeReference type = ResultCarrier.getResult(s).getType();
Register r = findOrCreateRegister(H[0].getHeapType(), valueNumber, registers, ir.regpool, type);
if (DEBUG) {
System.out.println("ELIMINATING LOAD " + s);
}
replaceLoadWithMove(r, s);
}
} else {
// ALoad.conforms(s)
Object array = ALoad.getArray(s);
Object index = ALoad.getIndex(s);
ArrayCell cell = (ArrayCell) available.lookup(H[0].getHeapVariable());
if (cell == null) {
// nothing available
continue;
}
int v1 = valueNumbers.getValueNumber(array);
int v2 = valueNumbers.getValueNumber(index);
// .. if H{<v1,v2>} is available ...
if (cell.contains(v1, v2)) {
result.add(H[0].getHeapVariable(), v1, v2);
TypeReference type = ALoad.getResult(s).getType();
Register r = findOrCreateRegister(H[0].getHeapVariable().getHeapType(), v1, v2, registers, ir.regpool, type);
if (DEBUG) {
System.out.println("ELIMINATING LOAD " + s);
}
replaceLoadWithMove(r, s);
}
}
}
return result;
}
use of org.jikesrvm.compilers.opt.ir.operand.HeapOperand in project JikesRVM by JikesRVM.
the class EnterSSA method renameHeapVariables.
/**
* Rename the implicit heap variables in the SSA form so that
* each heap variable has only one definition.
*
* <p> Algorithm: Cytron et. al 91 (see renameSymbolicRegisters)
*
* @param ir the governing IR
*/
private void renameHeapVariables(IR ir) {
int n = ir.HIRInfo.dictionary.getNumberOfHeapVariables();
if (n == 0) {
return;
}
// we maintain a stack of names for each type of heap variable
// stacks implements a mapping from type to Stack.
// Example: to get the stack of names for HEAP<int> variables,
// use stacks.get(ClassLoaderProxy.IntType);
HashMap<Object, Stack<HeapOperand<Object>>> stacks = new HashMap<Object, Stack<HeapOperand<Object>>>(n);
// names, currently stored in the SSADictionary
for (Iterator<HeapVariable<Object>> e = ir.HIRInfo.dictionary.getHeapVariables(); e.hasNext(); ) {
HeapVariable<Object> H = e.next();
Stack<HeapOperand<Object>> S = new Stack<HeapOperand<Object>>();
S.push(new HeapOperand<Object>(H));
Object heapType = H.getHeapType();
stacks.put(heapType, S);
}
BasicBlock entry = ir.cfg.entry();
numPredProcessed = new int[ir.getMaxBasicBlockNumber()];
search2(entry, stacks);
// registerRenamedHeapPhis(ir);
}
Aggregations