Search in sources :

Example 41 with BasicBlock

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

the class MIRSplitRanges method perform.

/**
 * The main method.<p>
 *
 * We split live ranges for registers around PEIs which have catch
 * blocks.  Suppose we have a
 * PEI s which uses a symbolic register r1.  We must ensure that after
 * register allocation, r1 is NOT assigned to a scratch location in s,
 * since this would mess up code in the catch block that uses r1.<p>
 *
 * So, instead, we introduce a new temporary r2 which holds the value of
 * r1.  The live range for r2 spans only the instruction s.  Later, we
 * will ensure that r2 is never spilled.<p>
 *
 * TODO: This could be implemented more efficiently.
 *
 * @param ir the governing IR
 */
@Override
public final void perform(IR ir) {
    java.util.HashMap<Register, Register> newMap = new java.util.HashMap<Register, Register>(5);
    for (Enumeration<BasicBlock> be = ir.getBasicBlocks(); be.hasMoreElements(); ) {
        BasicBlock bb = be.nextElement();
        for (Enumeration<Instruction> ie = bb.forwardInstrEnumerator(); ie.hasMoreElements(); ) {
            Instruction s = ie.nextElement();
            ;
            // clear the cache of register assignments
            newMap.clear();
            // here and in RegisterRestrictions!
            if (s.isPEI() && s.operator() != IR_PROLOGUE) {
                if (bb.hasApplicableExceptionalOut(s) || !RegisterRestrictions.SCRATCH_IN_PEI) {
                    splitAllLiveRanges(s, newMap, ir, false);
                }
            }
            // (1) Some operands must be in registers
            switch(s.getOpcode()) {
                case MIR_LOWTABLESWITCH_opcode:
                    {
                        RegisterOperand rOp = MIR_LowTableSwitch.getIndex(s);
                        RegisterOperand temp = findOrCreateTemp(rOp, newMap, ir);
                        // NOTE: Index as marked as a DU because LowTableSwitch is
                        // going to destroy the value in the register.
                        // By construction (see ConvertToLowLevelIR), no one will
                        // ever read the value computed by a LowTableSwitch.
                        // Therefore, don't insert a move instruction after the
                        // LowTableSwitch (which would cause IR verification
                        // problems anyways, since LowTableSwitch is a branch).
                        // move r into 'temp' before s
                        insertMoveBefore(temp, rOp.copyRO(), s);
                        rOp.setRegister(temp.getRegister());
                    }
                    break;
            }
        }
    }
}
Also used : RegisterOperand(org.jikesrvm.compilers.opt.ir.operand.RegisterOperand) Register(org.jikesrvm.compilers.opt.ir.Register) BasicBlock(org.jikesrvm.compilers.opt.ir.BasicBlock) Instruction(org.jikesrvm.compilers.opt.ir.Instruction)

Example 42 with BasicBlock

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

the class OptExceptionTable method countExceptionTableSize.

/**
 * @param ir the IR with the exception tables
 * @return an upper bound on the size of the exception table for an IR.
 */
private static int countExceptionTableSize(IR ir) {
    int tSize = 0;
    for (BasicBlock bblock = ir.firstBasicBlockInCodeOrder(); bblock != null; bblock = bblock.nextBasicBlockInCodeOrder()) {
        if (bblock.hasExceptionHandlers()) {
            for (Enumeration<BasicBlock> e = bblock.getExceptionHandlers(); e.hasMoreElements(); ) {
                ExceptionHandlerBasicBlock ebb = (ExceptionHandlerBasicBlock) e.nextElement();
                tSize += ebb.getNumberOfExceptionTableEntries();
            }
        }
    }
    return tSize;
}
Also used : BasicBlock(org.jikesrvm.compilers.opt.ir.BasicBlock) ExceptionHandlerBasicBlock(org.jikesrvm.compilers.opt.ir.ExceptionHandlerBasicBlock) ExceptionHandlerBasicBlock(org.jikesrvm.compilers.opt.ir.ExceptionHandlerBasicBlock)

Example 43 with BasicBlock

use of org.jikesrvm.compilers.opt.ir.BasicBlock 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;
}
Also used : BasicBlockOperand(org.jikesrvm.compilers.opt.ir.operand.BasicBlockOperand) RegisterOperand(org.jikesrvm.compilers.opt.ir.operand.RegisterOperand) BasicBlock(org.jikesrvm.compilers.opt.ir.BasicBlock) TypeReference(org.jikesrvm.classloader.TypeReference) Instruction(org.jikesrvm.compilers.opt.ir.Instruction)

Example 44 with BasicBlock

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

the class EnterSSA method renameSymbolicRegisters.

/**
 * Rename the symbolic registers so that each register has only one
 * definition.
 *
 * <p><em> Note </em>: call this after phi functions have been inserted.
 * <p> <b> Algorithm:</b> from Cytron et. al 91
 * <pre>
 *  call search(entry)
 *
 *  search(X):
 *  for each statement A in X do
 *     if A is not-phi
 *       for each r in RHS(A) do
 *            if !r.isSSA, replace r with TOP(S(r))
 *       done
 *     fi
 *    for each r in LHS(A) do
 *            if !r.isSSA
 *                r2 = new temp register
 *                push r2 onto S(r)
 *                replace r in A by r2
 *            fi
 *    done
 *  done (end of first loop)
 *  for each Y in succ(X) do
 *      j &lt;- whichPred(Y,X)
 *      for each phi-function F in Y do
 *       replace the j-th operand (r) in RHS(F) with TOP(S(r))
 *     done
 *  done (end of second loop)
 *  for each Y in Children(X) do
 *    call search(Y)
 *  done (end of third loop)
 *  for each assignment A in X do
 *     for each r in LHS(A) do
 *      pop(S(r))
 *   done
 *  done (end of fourth loop)
 *  end
 * </pre>
 *
 * @param symbolicRegisters mapping from integer to symbolic registers
 */
private void renameSymbolicRegisters(Register[] symbolicRegisters) {
    int n = ir.getNumberOfSymbolicRegisters();
    // the old covariant array-type problem
    @SuppressWarnings("unchecked") Stack<RegisterOperand>[] S = new Stack[n + 1];
    for (int i = 0; i < S.length; i++) {
        S[i] = new Stack<RegisterOperand>();
        // each parameter, and push "null" for other symbolic registers
        if (i >= symbolicRegisters.length)
            continue;
        // Register r = symbolicRegisters[i];
        // If a register's name is "null", that means the
        // register has not yet been defined.
        S[i].push(null);
    }
    BasicBlock entry = ir.cfg.entry();
    DefUse.clearDU(ir);
    numPredProcessed = new int[ir.getMaxBasicBlockNumber()];
    search(entry, S);
    DefUse.recomputeSSA(ir);
    rectifyPhiTypes();
}
Also used : RegisterOperand(org.jikesrvm.compilers.opt.ir.operand.RegisterOperand) BasicBlock(org.jikesrvm.compilers.opt.ir.BasicBlock) Stack(java.util.Stack)

Example 45 with BasicBlock

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

the class EnterSSA method insertHeapPhiFunctions.

/**
 * Insert phi functions for heap array SSA heap variables.
 *
 * @param ir the governing IR
 */
private void insertHeapPhiFunctions(IR ir) {
    Iterator<HeapVariable<Object>> e = ir.HIRInfo.dictionary.getHeapVariables();
    while (e.hasNext()) {
        HeapVariable<Object> H = e.next();
        if (DEBUG)
            System.out.println("Inserting phis for Heap " + H);
        if (DEBUG)
            System.out.println("Start iterated frontier...");
        BitVector defH = H.getDefBlocks();
        if (DEBUG)
            System.out.println(H + " DEFINED IN " + defH);
        BitVector needsPhi = DominanceFrontier.getIteratedDominanceFrontier(ir, defH);
        if (DEBUG)
            System.out.println(H + " NEEDS PHI " + needsPhi);
        if (DEBUG)
            System.out.println("Done.");
        for (int b = 0; b < needsPhi.length(); b++) {
            if (needsPhi.get(b)) {
                BasicBlock bb = ir.getBasicBlock(b);
                ir.HIRInfo.dictionary.createHeapPhiInstruction(bb, H);
            }
        }
    }
}
Also used : BitVector(org.jikesrvm.util.BitVector) 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