use of org.jikesrvm.compilers.opt.ir.BasicBlock in project JikesRVM by JikesRVM.
the class ComplexLIR2MIRExpansion method threeValueCmp.
/**
* compare to values and set result to -1, 0, 1 for <, =, >, respectively
* @param s the compare instruction
* @param ir the governing IR
*/
private static void threeValueCmp(Instruction s, IR ir) {
PowerPCConditionOperand firstCond = PowerPCConditionOperand.LESS_EQUAL();
int firstConst = 1;
switch(s.getOpcode()) {
case DOUBLE_CMPG_opcode:
case FLOAT_CMPG_opcode:
firstCond = PowerPCConditionOperand.GREATER_EQUAL();
firstConst = -1;
break;
case DOUBLE_CMPL_opcode:
case FLOAT_CMPL_opcode:
break;
default:
if (VM.VerifyAssertions)
VM._assert(VM.NOT_REACHED);
break;
}
Register res = Binary.getClearResult(s).getRegister();
RegisterOperand one = (RegisterOperand) Binary.getClearVal1(s);
RegisterOperand two = (RegisterOperand) Binary.getClearVal2(s);
res.setSpansBasicBlock();
BasicBlock BB1 = s.getBasicBlock();
BasicBlock BB6 = BB1.splitNodeAt(s, ir);
s = s.remove();
BasicBlock BB2 = BB1.createSubBlock(0, ir);
BasicBlock BB3 = BB1.createSubBlock(0, ir);
BasicBlock BB4 = BB1.createSubBlock(0, ir);
BasicBlock BB5 = BB1.createSubBlock(0, ir);
RegisterOperand t = ir.regpool.makeTempInt();
t.getRegister().setCondition();
BB1.appendInstruction(MIR_Binary.create(PPC_FCMPU, t, one, two));
BB1.appendInstruction(MIR_CondBranch.create(PPC_BCOND, t.copyD2U(), firstCond, BB3.makeJumpTarget(), new BranchProfileOperand(0.5f)));
BB2.appendInstruction(MIR_Unary.create(PPC_LDI, I(res), IC(firstConst)));
BB2.appendInstruction(MIR_Branch.create(PPC_B, BB6.makeJumpTarget()));
BB3.appendInstruction(MIR_CondBranch.create(PPC_BCOND, t.copyD2U(), PowerPCConditionOperand.EQUAL(), BB5.makeJumpTarget(), BranchProfileOperand.unlikely()));
BB4.appendInstruction(MIR_Unary.create(PPC_LDI, I(res), IC(-firstConst)));
BB4.appendInstruction(MIR_Branch.create(PPC_B, BB6.makeJumpTarget()));
BB5.appendInstruction(MIR_Unary.create(PPC_LDI, I(res), IC(0)));
// fix CFG
BB1.insertOut(BB2);
BB1.insertOut(BB3);
BB2.insertOut(BB6);
BB3.insertOut(BB4);
BB3.insertOut(BB5);
BB4.insertOut(BB6);
BB5.insertOut(BB6);
ir.cfg.linkInCodeOrder(BB1, BB2);
ir.cfg.linkInCodeOrder(BB2, BB3);
ir.cfg.linkInCodeOrder(BB3, BB4);
ir.cfg.linkInCodeOrder(BB4, BB5);
ir.cfg.linkInCodeOrder(BB5, BB6);
}
use of org.jikesrvm.compilers.opt.ir.BasicBlock in project JikesRVM by JikesRVM.
the class ComplexLIR2MIRExpansion method attempt.
private static void attempt(Instruction s, IR ir, boolean isAddress, boolean isLong) {
BasicBlock BB1 = s.getBasicBlock();
BasicBlock BB4 = BB1.splitNodeAt(s, ir);
BasicBlock BB2 = BB1.createSubBlock(0, ir);
BasicBlock BB3 = BB2.createSubBlock(0, ir);
BB1.insertOut(BB2);
BB1.insertOut(BB3);
BB2.insertOut(BB4);
BB3.insertOut(BB4);
ir.cfg.linkInCodeOrder(BB1, BB2);
ir.cfg.linkInCodeOrder(BB2, BB3);
ir.cfg.linkInCodeOrder(BB3, BB4);
// mutate ATTEMPT into a STWCX
RegisterOperand newValue = (RegisterOperand) Attempt.getNewValue(s);
RegisterOperand address = (RegisterOperand) Attempt.getAddress(s);
Operand offset = Attempt.getOffset(s);
LocationOperand location = Attempt.getLocation(s);
Operand guard = Attempt.getGuard(s);
RegisterOperand result = Attempt.getResult(s);
MIR_Store.mutate(s, (isAddress || isLong ? PPC_STAddrCXr : PPC_STWCXr), newValue, address, offset, location, guard);
// Branch to BB3 iff the STWXC succeeds (CR(0) is EQUAL)
// Else fall through to BB2
PhysicalRegisterSet phys = ir.regpool.getPhysicalRegisterSet().asPPC();
BB1.appendInstruction(MIR_CondBranch.create(PPC_BCOND, I(phys.getConditionRegister(0)), PowerPCConditionOperand.EQUAL(), BB3.makeJumpTarget(), new BranchProfileOperand()));
// BB2 sets result to FALSE and jumps to BB4
BB2.appendInstruction(MIR_Unary.create(PPC_LDI, result.copyRO(), IC(0)));
BB2.appendInstruction(MIR_Branch.create(PPC_B, BB4.makeJumpTarget()));
// BB3 sets result to TRUE and falls through to BB4
BB3.appendInstruction(MIR_Unary.create(PPC_LDI, result.copyRO(), IC(1)));
}
use of org.jikesrvm.compilers.opt.ir.BasicBlock in project JikesRVM by JikesRVM.
the class ComplexLIR2MIRExpansion method get_time_base.
private static void get_time_base(Instruction s, IR ir) {
if (VM.BuildFor32Addr) {
BasicBlock BB1 = s.getBasicBlock();
BB1 = BB1.segregateInstruction(s, ir);
Register defHigh = Nullary.getResult(s).getRegister();
Register defLow = ir.regpool.getSecondReg(defHigh);
Register t0 = ir.regpool.getInteger();
Register cr = ir.regpool.getCondition();
defLow.setSpansBasicBlock();
defHigh.setSpansBasicBlock();
// Try to get the base
Register TU = ir.regpool.getPhysicalRegisterSet().asPPC().getTU();
Register TL = ir.regpool.getPhysicalRegisterSet().asPPC().getTL();
s.insertBefore(MIR_Move.create(PPC_MFTBU, I(defHigh), I(TU)));
s.insertBefore(MIR_Move.create(PPC_MFTB, I(defLow), I(TL)));
// Try again to see if it changed
s.insertBefore(MIR_Move.create(PPC_MFTBU, I(t0), I(TU)));
s.insertBefore(MIR_Binary.create(PPC_CMP, I(cr), I(t0), I(defHigh)));
MIR_CondBranch.mutate(s, PPC_BCOND, I(cr), PowerPCConditionOperand.NOT_EQUAL(), BB1.makeJumpTarget(), new BranchProfileOperand());
// fix up CFG
BB1.insertOut(BB1);
} else {
// We read the 64-bit time base register atomically
Register def = Nullary.getResult(s).getRegister();
// See PowerPC Architecture, Book II, pp.352-353
Register TL = ir.regpool.getPhysicalRegisterSet().asPPC().getTL();
MIR_Move.mutate(s, PPC_MFTB, L(def), L(TL));
}
}
use of org.jikesrvm.compilers.opt.ir.BasicBlock in project JikesRVM by JikesRVM.
the class LiveAnalysis method perform.
/**
* The entry point into this class
* Perform live variable analysis on this IR, constructing live
* range info and (optionally) GC map info as we go.
*
* @param ir the ir
*/
@Override
public void perform(IR ir) {
liveIntervals = new LiveInterval();
// Debugging information
// Live Intervals, GC Maps, and fixed-point results
final boolean dumpFinalLiveIntervals = DEBUG || ir.options.PRINT_GC_MAPS && (!ir.options.hasMETHOD_TO_PRINT() || (ir.options.hasMETHOD_TO_PRINT() && ir.options.fuzzyMatchMETHOD_TO_PRINT(ir.method.toString())));
final boolean dumpFinalMaps = dumpFinalLiveIntervals;
final boolean dumpFixedPointResults = dumpFinalLiveIntervals;
// make sure IR info is up-to-date
DefUse.recomputeSpansBasicBlock(ir);
debugBegining(ir, createGCMaps, dumpFinalLiveIntervals, dumpFinalMaps, dumpFixedPointResults);
bbLiveInfo = new BBLiveElement[ir.cfg.numberOfNodes()];
for (int i = 0; i < ir.cfg.numberOfNodes(); i++) {
bbLiveInfo[i] = new BBLiveElement();
}
// allocate the "currentSet" which is used to cache the current results
currentSet = new LiveSet();
boolean reuseCurrentSet = false;
// make sure reverse top sort order is built
// currentBlock is the first node in the list
BasicBlock currentBlock = (BasicBlock) ir.cfg.buildRevTopSort();
// 2nd param: true means forward analysis; false means backward analysis
SortedGraphIterator bbIter = new SortedGraphIterator(currentBlock, false);
while (currentBlock != null) {
boolean changed = processBlock(currentBlock, reuseCurrentSet, ir);
// mark this block as processed and get the next one
BasicBlock nextBlock = (BasicBlock) bbIter.markAndGetNextTopSort(changed);
// check to see if nextBlock has only one successor, currentBlock.
// If so, we can reuse the current set and avoid performing a meet.
reuseCurrentSet = nextBlock != null && bbIter.isSinglePredecessor(currentBlock, nextBlock);
currentBlock = nextBlock;
}
debugPostGlobal(ir, dumpFinalLiveIntervals, dumpFinalMaps, dumpFixedPointResults);
// created, so we can't print them.
if (!skipLocal) {
performLocalPropagation(ir, createGCMaps);
if (createGCMaps && dumpFinalMaps) {
System.out.println("**** START OF IR for method: " + ir.method.getName() + " in class: " + ir.method.getDeclaringClass());
ir.printInstructions();
System.out.println("**** END OF IR INSTRUCTION DUMP ****");
printFinalMaps(ir);
}
if (dumpFinalLiveIntervals) {
printFinalLiveIntervals(ir);
}
// If we performed the local propagation, live interval information
// lives off of each basic block.
// Thus, we no longer need bbLiveInfo (the fixed points results)
// When we don't perform the local propagation, such as translating
// out of SSA, then we need to keep bbLiveInfo around
bbLiveInfo = null;
// compute the mapping from registers to live interval elements
computeRegisterMap(ir);
}
// No longer need currentSet, which is simply a cache of a LiveSet).
currentSet = null;
// This will be null if createGCMaps is false
if (createGCMaps) {
ir.MIRInfo.gcIRMap = map;
ir.MIRInfo.osrVarMap = osrMap;
}
// record whether or not we stored liveness information for handlers.
ir.setHandlerLivenessComputed(storeLiveAtHandlers);
ir.setLivenessInformation(liveIntervals);
}
use of org.jikesrvm.compilers.opt.ir.BasicBlock in project JikesRVM by JikesRVM.
the class LiveAnalysis method processBlock.
/**
* Computes the in set for this block given the out, gen, and kill set
* @param block the block of interest
* @param reuseCurrentSet whether we can reuse the "currentSet" or else
* clear it out and recompute the meet of our succs
* @param ir the governing ir
*
* @return {@code true} if something changed
*/
private boolean processBlock(BasicBlock block, boolean reuseCurrentSet, IR ir) {
if (VERBOSE) {
System.out.println(" *** processing block " + block + " # out edges: " + block.getNumberOfOut());
block.printExtended();
}
// summary information about the block (eg getContainsPEIWithHandler).
if (bbLiveInfo[block.getNumber()].BBKillSet() == null) {
bbLiveInfo[block.getNumber()].createKillAndGen();
computeBlockGenAndKill(block, ir);
}
// A summary of the IN sets of all exception handlers for the block
LiveSet exceptionBlockSummary = new LiveSet();
boolean blockHasHandlers = bbLiveInfo[block.getNumber()].getContainsPEIWithHandler();
//
if (!reuseCurrentSet) {
currentSet.clear();
// ExceptionBlockSummary.
for (Enumeration<BasicBlock> bbEnum = block.getOut(); bbEnum.hasMoreElements(); ) {
BasicBlock succ = bbEnum.nextElement();
// conditions in the following test.
if (blockHasHandlers && succ.isExceptionHandlerBasicBlock()) {
exceptionBlockSummary.add(bbLiveInfo[succ.getNumber()].getIn());
} else {
currentSet.add(bbLiveInfo[succ.getNumber()].getIn());
}
}
}
if (VERBOSE) {
System.out.println("\t Before applying transfor function:");
System.out.println("\t currentSet: " + currentSet);
System.out.println("\t exceptionBlockSummary: " + exceptionBlockSummary);
}
// At this point, currentSet contains the union of our normal successors'
// IN sets.
// Compute: In = currentSet - BBKillSet
// U (exceptionBlockSummary - firstPEIKillSet) (1)
// U Gen
// Since firstPEIKillSet is a subset of BBKillSet, we don't need the
// the parenthesis (and the intermediate set)
//
// If there are no handlers than exceptionBlockSummary is empty and
// we don't need to perform line (1)
// currentSet = currentSet - BBKillSet
// first kill off variables that are killed anywhere in the block
currentSet.remove(bbLiveInfo[block.getNumber()].BBKillSet());
if (blockHasHandlers) {
// currentSet = currentSet U exceptionBlockSummary
// add in the IN sets for the handlers
currentSet.add(exceptionBlockSummary);
// currentSet = currentSet - firstPEIKillSet
// kill off variables that are definitely killed, i.e., killed before
// the first PEI
currentSet.remove(bbLiveInfo[block.getNumber()].firstPEIKillSet());
}
// currentSet = currentSet U gen
// add in the GEN set
currentSet.add(bbLiveInfo[block.getNumber()].getGen());
// a change and return true, otherwise return false.
if (bbLiveInfo[block.getNumber()].getIn().add(currentSet)) {
if (VERBOSE) {
System.out.println(" *** processBlock returning true, currentSet: " + currentSet);
}
return true;
} else {
if (VERBOSE) {
System.out.println(" *** processBlock returning false, currentSet: " + currentSet);
}
return false;
}
}
Aggregations