Search in sources :

Example 26 with BasicBlock

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);
}
Also used : RegisterOperand(org.jikesrvm.compilers.opt.ir.operand.RegisterOperand) Register(org.jikesrvm.compilers.opt.ir.Register) PowerPCConditionOperand(org.jikesrvm.compilers.opt.ir.operand.ppc.PowerPCConditionOperand) BasicBlock(org.jikesrvm.compilers.opt.ir.BasicBlock) BranchProfileOperand(org.jikesrvm.compilers.opt.ir.operand.BranchProfileOperand)

Example 27 with BasicBlock

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)));
}
Also used : LocationOperand(org.jikesrvm.compilers.opt.ir.operand.LocationOperand) RegisterOperand(org.jikesrvm.compilers.opt.ir.operand.RegisterOperand) BranchProfileOperand(org.jikesrvm.compilers.opt.ir.operand.BranchProfileOperand) PowerPCConditionOperand(org.jikesrvm.compilers.opt.ir.operand.ppc.PowerPCConditionOperand) RegisterOperand(org.jikesrvm.compilers.opt.ir.operand.RegisterOperand) LocationOperand(org.jikesrvm.compilers.opt.ir.operand.LocationOperand) ConditionOperand(org.jikesrvm.compilers.opt.ir.operand.ConditionOperand) Operand(org.jikesrvm.compilers.opt.ir.operand.Operand) IntConstantOperand(org.jikesrvm.compilers.opt.ir.operand.IntConstantOperand) PhysicalRegisterSet(org.jikesrvm.compilers.opt.ir.ppc.PhysicalRegisterSet) BasicBlock(org.jikesrvm.compilers.opt.ir.BasicBlock) BranchProfileOperand(org.jikesrvm.compilers.opt.ir.operand.BranchProfileOperand)

Example 28 with BasicBlock

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));
    }
}
Also used : Register(org.jikesrvm.compilers.opt.ir.Register) BasicBlock(org.jikesrvm.compilers.opt.ir.BasicBlock) BranchProfileOperand(org.jikesrvm.compilers.opt.ir.operand.BranchProfileOperand)

Example 29 with BasicBlock

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);
}
Also used : SortedGraphIterator(org.jikesrvm.compilers.opt.util.SortedGraphIterator) ExceptionHandlerBasicBlock(org.jikesrvm.compilers.opt.ir.ExceptionHandlerBasicBlock) BasicBlock(org.jikesrvm.compilers.opt.ir.BasicBlock) OsrPoint(org.jikesrvm.compilers.opt.ir.OsrPoint)

Example 30 with BasicBlock

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;
    }
}
Also used : ExceptionHandlerBasicBlock(org.jikesrvm.compilers.opt.ir.ExceptionHandlerBasicBlock) BasicBlock(org.jikesrvm.compilers.opt.ir.BasicBlock)

Aggregations

BasicBlock (org.jikesrvm.compilers.opt.ir.BasicBlock)219 Instruction (org.jikesrvm.compilers.opt.ir.Instruction)117 RegisterOperand (org.jikesrvm.compilers.opt.ir.operand.RegisterOperand)93 Operand (org.jikesrvm.compilers.opt.ir.operand.Operand)66 ExceptionHandlerBasicBlock (org.jikesrvm.compilers.opt.ir.ExceptionHandlerBasicBlock)52 Register (org.jikesrvm.compilers.opt.ir.Register)50 BranchProfileOperand (org.jikesrvm.compilers.opt.ir.operand.BranchProfileOperand)48 IntConstantOperand (org.jikesrvm.compilers.opt.ir.operand.IntConstantOperand)37 ConditionOperand (org.jikesrvm.compilers.opt.ir.operand.ConditionOperand)33 MethodOperand (org.jikesrvm.compilers.opt.ir.operand.MethodOperand)27 LocationOperand (org.jikesrvm.compilers.opt.ir.operand.LocationOperand)24 HeapOperand (org.jikesrvm.compilers.opt.ir.operand.HeapOperand)21 BasicBlockOperand (org.jikesrvm.compilers.opt.ir.operand.BasicBlockOperand)20 TrueGuardOperand (org.jikesrvm.compilers.opt.ir.operand.TrueGuardOperand)19 TypeReference (org.jikesrvm.classloader.TypeReference)18 NullConstantOperand (org.jikesrvm.compilers.opt.ir.operand.NullConstantOperand)18 Test (org.junit.Test)17 BranchOperand (org.jikesrvm.compilers.opt.ir.operand.BranchOperand)16 InlineSequence (org.jikesrvm.compilers.opt.inlining.InlineSequence)14 MemoryOperand (org.jikesrvm.compilers.opt.ir.operand.MemoryOperand)14