Search in sources :

Example 36 with BasicBlock

use of org.jikesrvm.compilers.opt.ir.BasicBlock in project JikesRVM by JikesRVM.

the class LoopVersioning method modifyOriginalLoop.

/*
   * TODO Convert to JavaDoc and add missing tags.
   * <p>
   * Remove loop and replace register definitions in the original loop
   * with phi instructions
   */
private void modifyOriginalLoop(AnnotatedLSTNode loop, ArrayList<Instruction> phiInstructions, ArrayList<Instruction> definingInstrInOriginalLoop, HashMap<Register, Register> subOptimalRegMap, HashMap<Register, Register> optimalRegMap) {
    // Remove instructions from loop header and exit, remove other
    // loop body blocks
    Enumeration<BasicBlock> blocks = loop.getBasicBlocks();
    while (blocks.hasMoreElements()) {
        BasicBlock block = blocks.nextElement();
        if ((block == loop.header) || (block == loop.exit)) {
            IREnumeration.AllInstructionsEnum instructions = new IREnumeration.AllInstructionsEnum(ir, block);
            while (instructions.hasMoreElements()) {
                Instruction instruction = instructions.nextElement();
                if (!BBend.conforms(instruction) && !Label.conforms(instruction)) {
                    instruction.remove();
                }
            }
        } else {
            ir.cfg.removeFromCFGAndCodeOrder(block);
        }
    }
    // Place phi instructions in loop header
    for (int i = 0; i < phiInstructions.size(); i++) {
        Instruction origInstr = definingInstrInOriginalLoop.get(i);
        // Did the original instructions value escape the loop?
        if (origInstr != null) {
            // Was this a phi of a phi?
            if (Phi.conforms(origInstr)) {
                Instruction phi = phiInstructions.get(i);
                boolean phiHasUnoptimizedArg = Phi.getNumberOfValues(phi) == 2;
                // Phi of a phi - so make sure that we get the value to escape the loop, not the value at the loop header
                boolean fixed = false;
                for (int index = 0; index < Phi.getNumberOfPreds(origInstr); index++) {
                    BasicBlockOperand predOp = Phi.getPred(origInstr, index);
                    // Only worry about values who are on the backward branch
                    if (predOp.block == loop.exit) {
                        if (fixed) {
                            // We've tried to do 2 replaces => something wrong
                            SSA.printInstructions(ir);
                            OptimizingCompilerException.UNREACHABLE("LoopVersioning", "Phi node in loop header with multiple in loop predecessors");
                        }
                        Operand rval = Phi.getValue(origInstr, index);
                        if (rval.isRegister()) {
                            // Sort out registers
                            Register origRegPhiRval = rval.asRegister().getRegister();
                            Register subOptRegPhiRval;
                            Register optRegPhiRval;
                            if (!subOptimalRegMap.containsKey(origRegPhiRval)) {
                                // Register comes from loop exit but it wasn't defined in the loop
                                subOptRegPhiRval = origRegPhiRval;
                                optRegPhiRval = origRegPhiRval;
                            } else {
                                subOptRegPhiRval = subOptimalRegMap.get(origRegPhiRval);
                                optRegPhiRval = optimalRegMap.get(origRegPhiRval);
                            }
                            if (phiHasUnoptimizedArg) {
                                Phi.getValue(phi, UNOPTIMIZED_LOOP_OPERAND).asRegister().setRegister(subOptRegPhiRval);
                            }
                            Phi.getValue(phi, OPTIMIZED_LOOP_OPERAND).asRegister().setRegister(optRegPhiRval);
                        } else if (rval.isConstant()) {
                            // Sort out constants
                            if (phiHasUnoptimizedArg) {
                                Phi.setValue(phi, UNOPTIMIZED_LOOP_OPERAND, rval.copy());
                            }
                            Phi.setValue(phi, OPTIMIZED_LOOP_OPERAND, rval.copy());
                        } else if (rval instanceof HeapOperand) {
                            // Sort out heap variables
                            // Cast to generic type
                            @SuppressWarnings("unchecked") HeapVariable<Object> origPhiRval = ((HeapOperand) rval).value;
                            HeapVariable<Object> subOptPhiRval;
                            HeapVariable<Object> optPhiRval;
                            if (true) /*subOptimalRegMap.containsKey(origPhiRval) == false*/
                            {
                                // currently we only expect to optimise scalar SSA
                                // form
                                subOptPhiRval = origPhiRval;
                                optPhiRval = origPhiRval;
                            } else {
                            /*
                  subOptPhiRval   = (HeapVariable)subOptimalRegMap.get(origPhiRval);
                  optPhiRval      = (HeapVariable)optimalRegMap.get(origPhiRval);
                  */
                            }
                            if (phiHasUnoptimizedArg) {
                                Phi.setValue(phi, UNOPTIMIZED_LOOP_OPERAND, new HeapOperand<Object>(subOptPhiRval));
                            }
                            Phi.setValue(phi, OPTIMIZED_LOOP_OPERAND, new HeapOperand<Object>(optPhiRval));
                        } else {
                            OptimizingCompilerException.UNREACHABLE("LoopVersioning", "Unknown operand type", rval.toString());
                        }
                        fixed = true;
                    }
                }
            }
            // Add back to loop
            loop.header.appendInstruction(phiInstructions.get(i));
        }
    }
    // Remove original loop and branch to loop successor
    Instruction tempInstr;
    if (loop.header != loop.exit) {
        tempInstr = Goto.create(GOTO, loop.exit.makeJumpTarget());
        tempInstr.setBytecodeIndex(SYNTH_LOOP_VERSIONING_BCI);
        loop.header.appendInstruction(tempInstr);
        loop.header.deleteNormalOut();
        loop.header.insertOut(loop.exit);
    }
    tempInstr = Goto.create(GOTO, loop.successor.makeJumpTarget());
    tempInstr.setBytecodeIndex(SYNTH_LOOP_VERSIONING_BCI);
    loop.exit.appendInstruction(tempInstr);
    loop.exit.deleteNormalOut();
    loop.exit.insertOut(loop.successor);
}
Also used : BasicBlockOperand(org.jikesrvm.compilers.opt.ir.operand.BasicBlockOperand) BasicBlockOperand(org.jikesrvm.compilers.opt.ir.operand.BasicBlockOperand) RegisterOperand(org.jikesrvm.compilers.opt.ir.operand.RegisterOperand) ConditionOperand(org.jikesrvm.compilers.opt.ir.operand.ConditionOperand) Operand(org.jikesrvm.compilers.opt.ir.operand.Operand) NullConstantOperand(org.jikesrvm.compilers.opt.ir.operand.NullConstantOperand) BranchProfileOperand(org.jikesrvm.compilers.opt.ir.operand.BranchProfileOperand) HeapOperand(org.jikesrvm.compilers.opt.ir.operand.HeapOperand) IntConstantOperand(org.jikesrvm.compilers.opt.ir.operand.IntConstantOperand) BasicBlock(org.jikesrvm.compilers.opt.ir.BasicBlock) Instruction(org.jikesrvm.compilers.opt.ir.Instruction) HeapOperand(org.jikesrvm.compilers.opt.ir.operand.HeapOperand) Register(org.jikesrvm.compilers.opt.ir.Register) IREnumeration(org.jikesrvm.compilers.opt.ir.IREnumeration)

Example 37 with BasicBlock

use of org.jikesrvm.compilers.opt.ir.BasicBlock in project JikesRVM by JikesRVM.

the class LoopVersioning method createCloneLoop.

/**
 * Create a clone of the loop replacing definitions in the cloned
 * loop with those found in the register map
 * @param loop - loop to clone
 * @param regMap - mapping of original definition to new
 * definition
 * @param regToBlockMap mapping of registers to new, unoptimized blocks. This starts
 *  empty and will be filled during execution of the method.
 * @return a mapping from original BBs to created BBs
 */
private HashMap<BasicBlock, BasicBlock> createCloneLoop(AnnotatedLSTNode loop, HashMap<Register, Register> regMap, HashMap<Register, BasicBlock> regToBlockMap) {
    HashMap<BasicBlock, BasicBlock> originalToCloneBBMap = new HashMap<BasicBlock, BasicBlock>();
    // After the newly created loop goto the old loop header
    originalToCloneBBMap.put(loop.successor, loop.header);
    // Create an empty block to be the loop predecessor
    BasicBlock new_pred = loop.header.createSubBlock(SYNTH_LOOP_VERSIONING_BCI, ir);
    ir.cfg.linkInCodeOrder(ir.cfg.lastInCodeOrder(), new_pred);
    originalToCloneBBMap.put(loop.predecessor, new_pred);
    // Create copy blocks
    Enumeration<BasicBlock> blocks = loop.getBasicBlocks();
    while (blocks.hasMoreElements()) {
        BasicBlock block = blocks.nextElement();
        // get rid of fall through edges to aid recomputeNormalOuts
        block.killFallThrough();
        // Create copy and register mapping
        BasicBlock copy = block.copyWithoutLinks(ir);
        originalToCloneBBMap.put(block, copy);
        // Link into code order
        ir.cfg.linkInCodeOrder(ir.cfg.lastInCodeOrder(), copy);
        // Alter register definitions and uses in copy
        IREnumeration.AllInstructionsEnum instructions = new IREnumeration.AllInstructionsEnum(ir, copy);
        while (instructions.hasMoreElements()) {
            Instruction instruction = instructions.nextElement();
            Enumeration<Operand> operands = instruction.getDefs();
            while (operands.hasMoreElements()) {
                Operand operand = operands.nextElement();
                if (operand.isRegister()) {
                    Register register = operand.asRegister().getRegister();
                    if (regMap.containsKey(register)) {
                        instruction.replaceRegister(register, regMap.get(register));
                        regToBlockMap.put(regMap.get(register), copy);
                    }
                }
            }
            operands = instruction.getUses();
            while (operands.hasMoreElements()) {
                Operand operand = operands.nextElement();
                if (operand instanceof RegisterOperand) {
                    Register register = operand.asRegister().getRegister();
                    if (regMap.containsKey(register)) {
                        instruction.replaceRegister(register, regMap.get(register));
                    }
                }
            }
        }
    }
    // Fix up outs
    // loop predecessor
    new_pred.redirectOuts(loop.header, originalToCloneBBMap.get(loop.header), ir);
    // loop blocks
    blocks = loop.getBasicBlocks();
    while (blocks.hasMoreElements()) {
        BasicBlock block = blocks.nextElement();
        BasicBlock copy = originalToCloneBBMap.get(block);
        Enumeration<BasicBlock> outs = block.getOutNodes();
        while (outs.hasMoreElements()) {
            BasicBlock out = outs.nextElement();
            if (originalToCloneBBMap.containsKey(out)) {
                copy.redirectOuts(out, originalToCloneBBMap.get(out), ir);
            }
        }
    }
    // Fix up phis
    blocks = loop.getBasicBlocks();
    while (blocks.hasMoreElements()) {
        BasicBlock block = blocks.nextElement();
        BasicBlock copy = originalToCloneBBMap.get(block);
        IREnumeration.AllInstructionsEnum instructions = new IREnumeration.AllInstructionsEnum(ir, copy);
        while (instructions.hasMoreElements()) {
            Instruction instruction = instructions.nextElement();
            if (Phi.conforms(instruction)) {
                for (int i = 0; i < Phi.getNumberOfValues(instruction); i++) {
                    BasicBlock phi_predecessor = Phi.getPred(instruction, i).block;
                    if (originalToCloneBBMap.containsKey(phi_predecessor)) {
                        Phi.setPred(instruction, i, new BasicBlockOperand(originalToCloneBBMap.get(phi_predecessor)));
                    } else {
                        dumpIR(ir, "Error when optimising" + ir.getMethod());
                        throw new Error("There's > 1 route to this phi node " + instruction + " from outside the loop: " + phi_predecessor);
                    }
                }
            }
        }
    }
    return originalToCloneBBMap;
}
Also used : BasicBlockOperand(org.jikesrvm.compilers.opt.ir.operand.BasicBlockOperand) HashMap(java.util.HashMap) BasicBlockOperand(org.jikesrvm.compilers.opt.ir.operand.BasicBlockOperand) RegisterOperand(org.jikesrvm.compilers.opt.ir.operand.RegisterOperand) ConditionOperand(org.jikesrvm.compilers.opt.ir.operand.ConditionOperand) Operand(org.jikesrvm.compilers.opt.ir.operand.Operand) NullConstantOperand(org.jikesrvm.compilers.opt.ir.operand.NullConstantOperand) BranchProfileOperand(org.jikesrvm.compilers.opt.ir.operand.BranchProfileOperand) HeapOperand(org.jikesrvm.compilers.opt.ir.operand.HeapOperand) IntConstantOperand(org.jikesrvm.compilers.opt.ir.operand.IntConstantOperand) BasicBlock(org.jikesrvm.compilers.opt.ir.BasicBlock) Instruction(org.jikesrvm.compilers.opt.ir.Instruction) RegisterOperand(org.jikesrvm.compilers.opt.ir.operand.RegisterOperand) Register(org.jikesrvm.compilers.opt.ir.Register) IREnumeration(org.jikesrvm.compilers.opt.ir.IREnumeration)

Example 38 with BasicBlock

use of org.jikesrvm.compilers.opt.ir.BasicBlock in project JikesRVM by JikesRVM.

the class LoopVersioning method createBranchBlocks.

/*
   * TODO better JavaDoc comment.
   * <p>
   * Create the block containing explict branches to either the
   * optimized or unoptimized loops
   * @param optimalRegMap - mapping used to map eliminated bound and
   * null check guards to
   */
private boolean createBranchBlocks(AnnotatedLSTNode loop, BasicBlock block, ArrayList<Instruction> checksToEliminate, BasicBlock unoptimizedLoopEntry, BasicBlock optimizedLoopEntry, HashMap<Register, Register> optimalRegMap) {
    BasicBlock blockOnEntry = block;
    // 1) generate null check guards
    block = generateNullCheckBranchBlocks(loop, checksToEliminate, optimalRegMap, block, unoptimizedLoopEntry);
    // 2) generate bound check guards
    if (loop.isMonotonic()) {
        // create new operands for values beyond initial and terminal iterator values
        Operand terminal;
        Operand terminalLessStrideOnce;
        Operand terminalPlusStrideOnce;
        // it does create dead code though
        if (loop.terminalIteratorValue.isIntConstant()) {
            terminal = loop.terminalIteratorValue;
            int terminalAsInt = terminal.asIntConstant().value;
            int stride = loop.strideValue.asIntConstant().value;
            terminalLessStrideOnce = new IntConstantOperand(terminalAsInt - stride);
            terminalPlusStrideOnce = new IntConstantOperand(terminalAsInt + stride);
        } else {
            Instruction tempInstr;
            terminal = loop.generateLoopInvariantOperand(block, loop.terminalIteratorValue);
            terminalLessStrideOnce = ir.regpool.makeTempInt();
            terminalPlusStrideOnce = ir.regpool.makeTempInt();
            tempInstr = Binary.create(INT_SUB, terminalLessStrideOnce.asRegister(), terminal.copy(), loop.strideValue.copy());
            tempInstr.setBytecodeIndex(SYNTH_LOOP_VERSIONING_BCI);
            block.appendInstruction(tempInstr);
            DefUse.updateDUForNewInstruction(tempInstr);
            tempInstr = Binary.create(INT_ADD, terminalPlusStrideOnce.asRegister(), terminal.copy(), loop.strideValue.copy());
            tempInstr.setBytecodeIndex(SYNTH_LOOP_VERSIONING_BCI);
            block.appendInstruction(tempInstr);
            DefUse.updateDUForNewInstruction(tempInstr);
        }
        // Determine maximum and minimum index values for different loop types
        Operand phiMinIndexValue;
        Operand phiMaxIndexValue;
        if (loop.isMonotonicIncreasing()) {
            phiMinIndexValue = loop.initialIteratorValue;
            if ((loop.condition.isLESS() || loop.condition.isLOWER() || loop.condition.isNOT_EQUAL())) {
                phiMaxIndexValue = terminal;
            } else if ((loop.condition.isLESS_EQUAL() || loop.condition.isLOWER_EQUAL() || loop.condition.isEQUAL())) {
                phiMaxIndexValue = terminalPlusStrideOnce;
            } else {
                throw new Error("Unrecognised loop for fission " + loop);
            }
        } else if (loop.isMonotonicDecreasing()) {
            phiMaxIndexValue = loop.initialIteratorValue;
            if ((loop.condition.isGREATER() || loop.condition.isHIGHER() || loop.condition.isNOT_EQUAL())) {
                phiMinIndexValue = terminalPlusStrideOnce;
            } else if ((loop.condition.isGREATER_EQUAL() || loop.condition.isHIGHER_EQUAL() || loop.condition.isEQUAL())) {
                phiMinIndexValue = terminalLessStrideOnce;
            } else {
                throw new Error("Unrecognised loop for fission " + loop);
            }
        } else {
            throw new Error("Unrecognised loop for fission " + loop);
        }
        // Generate tests
        for (int i = 0; i < checksToEliminate.size(); i++) {
            Instruction instr = checksToEliminate.get(i);
            if (BoundsCheck.conforms(instr)) {
                // Have we already generated these tests?
                boolean alreadyChecked = false;
                for (int j = 0; j < i; j++) {
                    Instruction old_instr = checksToEliminate.get(j);
                    if (BoundsCheck.conforms(old_instr) && (BoundsCheck.getRef(old_instr).similar(BoundsCheck.getRef(instr))) && (BoundsCheck.getIndex(old_instr).similar(BoundsCheck.getIndex(instr)))) {
                        // yes - just create a guard move
                        alreadyChecked = true;
                        RegisterOperand guardResult = BoundsCheck.getGuardResult(instr).copyRO();
                        guardResult.setRegister(optimalRegMap.get(guardResult.getRegister()));
                        RegisterOperand guardSource = BoundsCheck.getGuardResult(old_instr).copyRO();
                        guardSource.setRegister(optimalRegMap.get(guardSource.getRegister()));
                        Instruction tempInstr = Move.create(GUARD_MOVE, guardResult, guardSource);
                        tempInstr.setBytecodeIndex(SYNTH_LOOP_VERSIONING_BCI);
                        block.appendInstruction(tempInstr);
                        break;
                    }
                }
                if (!alreadyChecked) {
                    // no - generate tests
                    Operand index = BoundsCheck.getIndex(instr);
                    int distance = loop.getFixedDistanceFromPhiIterator(index);
                    if (distance == 0) {
                        block = generateExplicitBoundCheck(instr, phiMinIndexValue, phiMaxIndexValue, optimalRegMap, block, unoptimizedLoopEntry);
                    } else {
                        Instruction tempInstr;
                        RegisterOperand minIndex = ir.regpool.makeTempInt();
                        RegisterOperand maxIndex = ir.regpool.makeTempInt();
                        tempInstr = Binary.create(INT_ADD, minIndex, phiMinIndexValue.copy(), new IntConstantOperand(distance));
                        tempInstr.setBytecodeIndex(SYNTH_LOOP_VERSIONING_BCI);
                        block.appendInstruction(tempInstr);
                        DefUse.updateDUForNewInstruction(tempInstr);
                        tempInstr = Binary.create(INT_ADD, maxIndex, phiMaxIndexValue.copy(), new IntConstantOperand(distance));
                        tempInstr.setBytecodeIndex(SYNTH_LOOP_VERSIONING_BCI);
                        block.appendInstruction(tempInstr);
                        DefUse.updateDUForNewInstruction(tempInstr);
                        block = generateExplicitBoundCheck(instr, minIndex, maxIndex, optimalRegMap, block, unoptimizedLoopEntry);
                    }
                }
            }
        }
    }
    // Have we had to create a new basic block since entry => we
    // generated a branch to the unoptimized loop
    boolean isUnoptimizedLoopReachable = (blockOnEntry != block);
    // 3) Finish up with goto and generate true guard value
    {
        // the generated branch instruction
        Instruction branch;
        branch = Goto.create(GOTO, optimizedLoopEntry.makeJumpTarget());
        branch.setBytecodeIndex(SYNTH_LOOP_VERSIONING_BCI);
        block.appendInstruction(branch);
        block.deleteNormalOut();
        block.insertOut(optimizedLoopEntry);
    }
    return isUnoptimizedLoopReachable;
}
Also used : IntConstantOperand(org.jikesrvm.compilers.opt.ir.operand.IntConstantOperand) RegisterOperand(org.jikesrvm.compilers.opt.ir.operand.RegisterOperand) BasicBlockOperand(org.jikesrvm.compilers.opt.ir.operand.BasicBlockOperand) RegisterOperand(org.jikesrvm.compilers.opt.ir.operand.RegisterOperand) ConditionOperand(org.jikesrvm.compilers.opt.ir.operand.ConditionOperand) Operand(org.jikesrvm.compilers.opt.ir.operand.Operand) NullConstantOperand(org.jikesrvm.compilers.opt.ir.operand.NullConstantOperand) BranchProfileOperand(org.jikesrvm.compilers.opt.ir.operand.BranchProfileOperand) HeapOperand(org.jikesrvm.compilers.opt.ir.operand.HeapOperand) IntConstantOperand(org.jikesrvm.compilers.opt.ir.operand.IntConstantOperand) BasicBlock(org.jikesrvm.compilers.opt.ir.BasicBlock) Instruction(org.jikesrvm.compilers.opt.ir.Instruction)

Example 39 with BasicBlock

use of org.jikesrvm.compilers.opt.ir.BasicBlock in project JikesRVM by JikesRVM.

the class PiNodes method insertPiIfNodes.

/**
 *  Insert PI nodes corresponding to compare operations.
 *  Pi-nodes are represented as dummy assignments with a single
 *  argument inserted along each outedge of the conditional.
 *
 *  @param ir the governing IR
 */
private void insertPiIfNodes(IR ir) {
    Enumeration<Instruction> e = ir.forwardInstrEnumerator();
    while (e.hasMoreElements()) {
        Instruction instr = e.nextElement();
        // TODO: what other compareops generate useful assertions?
        if (IfCmp.conforms(instr) || InlineGuard.conforms(instr)) {
            BasicBlock thisbb = instr.getBasicBlock();
            // only handle the "normal" case
            if (thisbb.getNumberOfNormalOut() != 2) {
                continue;
            }
            // insert new basic blocks on each edge out of thisbb
            Enumeration<BasicBlock> outBB = thisbb.getNormalOut();
            BasicBlock out1 = outBB.nextElement();
            BasicBlock new1 = IRTools.makeBlockOnEdge(thisbb, out1, ir);
            BasicBlock out2 = outBB.nextElement();
            BasicBlock new2 = IRTools.makeBlockOnEdge(thisbb, out2, ir);
            // blocks made on the outgoing edges.
            if (InlineGuard.conforms(instr))
                continue;
            RegisterOperand ifGuard = IfCmp.getGuardResult(instr);
            if (VM.VerifyAssertions) {
                VM._assert(ifGuard != null);
            }
            // get compared variables
            Operand a = IfCmp.getVal1(instr);
            Operand b = IfCmp.getVal2(instr);
            // determine which block is "taken" on the branch
            BasicBlock takenBlock = IfCmp.getTarget(instr).target.getBasicBlock();
            boolean new1IsTaken = false;
            if (takenBlock == new1) {
                new1IsTaken = true;
            }
            // insert the PI-node instructions for a and b
            if (a.isRegister() && !a.asRegister().getRegister().isPhysical() && (a.asRegister().getRegister().isInteger() || a.asRegister().getRegister().isAddress())) {
                // insert pi-nodes only for variables, not constants
                Instruction s = GuardedUnary.create(PI, (RegisterOperand) a.copy(), a.copy(), null);
                RegisterOperand sGuard = (RegisterOperand) ifGuard.copy();
                if (new1IsTaken) {
                    sGuard.setTaken();
                } else {
                    sGuard.setNotTaken();
                }
                GuardedUnary.setGuard(s, sGuard);
                new1.prependInstruction(s);
                s = s.copyWithoutLinks();
                sGuard = (RegisterOperand) ifGuard.copy();
                if (new1IsTaken) {
                    sGuard.setNotTaken();
                } else {
                    sGuard.setTaken();
                }
                GuardedUnary.setGuard(s, sGuard);
                new2.prependInstruction(s);
            }
            if (b.isRegister() && !b.asRegister().getRegister().isPhysical() && (b.asRegister().getRegister().isInteger() || b.asRegister().getRegister().isAddress())) {
                Instruction s = GuardedUnary.create(PI, (RegisterOperand) b.copy(), b.copy(), null);
                RegisterOperand sGuard = (RegisterOperand) ifGuard.copy();
                if (new1IsTaken) {
                    sGuard.setTaken();
                } else {
                    sGuard.setNotTaken();
                }
                GuardedUnary.setGuard(s, sGuard);
                new1.prependInstruction(s);
                s = s.copyWithoutLinks();
                sGuard = (RegisterOperand) ifGuard.copy();
                if (new1IsTaken) {
                    sGuard.setNotTaken();
                } else {
                    sGuard.setTaken();
                }
                GuardedUnary.setGuard(s, sGuard);
                new2.prependInstruction(s);
            }
        }
    }
}
Also used : RegisterOperand(org.jikesrvm.compilers.opt.ir.operand.RegisterOperand) Operand(org.jikesrvm.compilers.opt.ir.operand.Operand) RegisterOperand(org.jikesrvm.compilers.opt.ir.operand.RegisterOperand) BasicBlock(org.jikesrvm.compilers.opt.ir.BasicBlock) Instruction(org.jikesrvm.compilers.opt.ir.Instruction)

Example 40 with BasicBlock

use of org.jikesrvm.compilers.opt.ir.BasicBlock in project JikesRVM by JikesRVM.

the class SSA method printInstructions.

/**
 * Print the instructions in SSA form.
 *
 * @param ir the IR, assumed to be in SSA form
 */
public static void printInstructions(IR ir) {
    SSADictionary dictionary = ir.HIRInfo.dictionary;
    System.out.println("********* START OF IR DUMP in SSA FOR " + ir.method);
    for (Enumeration<BasicBlock> be = ir.forwardBlockEnumerator(); be.hasMoreElements(); ) {
        BasicBlock bb = be.nextElement();
        // print the explicit instructions for basic block bb
        for (Enumeration<Instruction> e = dictionary.getAllInstructions(bb); e.hasMoreElements(); ) {
            Instruction s = e.nextElement();
            System.out.print(s.getBytecodeIndex() + "\t" + s);
            if (dictionary.defsHeapVariable(s) && s.operator() != PHI) {
                System.out.print("  (Implicit Defs: ");
                HeapOperand<?>[] defs = dictionary.getHeapDefs(s);
                if (defs != null) {
                    for (HeapOperand<?> def : defs) System.out.print(def + " ");
                }
                System.out.print(" )");
            }
            if (dictionary.usesHeapVariable(s) && s.operator() != PHI) {
                System.out.print("  (Implicit Uses: ");
                HeapOperand<?>[] uses = dictionary.getHeapUses(s);
                if (uses != null) {
                    for (HeapOperand<?> use : uses) System.out.print(use + " ");
                }
                System.out.print(" )");
            }
            System.out.println();
        }
    }
    System.out.println("*********   END OF IR DUMP in SSA FOR " + ir.method);
}
Also used : HeapOperand(org.jikesrvm.compilers.opt.ir.operand.HeapOperand) BasicBlock(org.jikesrvm.compilers.opt.ir.BasicBlock) Instruction(org.jikesrvm.compilers.opt.ir.Instruction)

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