001    /*
002     *  This file is part of the Jikes RVM project (http://jikesrvm.org).
003     *
004     *  This file is licensed to You under the Eclipse Public License (EPL);
005     *  You may not use this file except in compliance with the License. You
006     *  may obtain a copy of the License at
007     *
008     *      http://www.opensource.org/licenses/eclipse-1.0.php
009     *
010     *  See the COPYRIGHT.txt file distributed with this work for information
011     *  regarding copyright ownership.
012     */
013    package org.jikesrvm.compilers.opt.lir2mir;
014    
015    import org.jikesrvm.ArchitectureSpecificOpt.BURS_TreeNode;
016    import org.jikesrvm.VM;
017    import org.jikesrvm.compilers.opt.ir.BasicBlock;
018    import org.jikesrvm.compilers.opt.ir.IR;
019    import org.jikesrvm.compilers.opt.ir.Instruction;
020    import static org.jikesrvm.compilers.opt.ir.Operators.ADDRESS_CONSTANT_opcode;
021    import static org.jikesrvm.compilers.opt.ir.Operators.BRANCH_TARGET_opcode;
022    import static org.jikesrvm.compilers.opt.ir.Operators.LONG_CONSTANT_opcode;
023    import static org.jikesrvm.compilers.opt.ir.Operators.NULL_opcode;
024    import static org.jikesrvm.compilers.opt.ir.Operators.REGISTER_opcode;
025    
026    /**
027     * A few common utilities used for invoking BURS tree-pattern matching
028     * to do instruction selection.  The interesting code is in the
029     * subclasses of this class.
030     */
031    public abstract class BURS {
032    
033      public static final boolean DEBUG = false;
034    
035      protected final BURS_TreeNode NullTreeNode = new BURS_TreeNode(NULL_opcode);
036      protected final BURS_TreeNode LongConstant = new BURS_TreeNode(LONG_CONSTANT_opcode);
037      protected final BURS_TreeNode AddressConstant = new BURS_TreeNode(ADDRESS_CONSTANT_opcode);
038      protected final BURS_TreeNode Register = new BURS_TreeNode(REGISTER_opcode);
039      protected final BURS_TreeNode BranchTarget = new BURS_TreeNode(BRANCH_TARGET_opcode);
040    
041      // initialize scratch field for expression tree labeling.
042      BURS(IR ir) {
043        this.ir = ir;
044        NullTreeNode.setNumRegisters(0);
045        LongConstant.setNumRegisters(0);
046        AddressConstant.setNumRegisters(0);
047        Register.setNumRegisters(1);
048        BranchTarget.setNumRegisters(0);
049      }
050    
051      public final IR ir;
052      protected Instruction lastInstr;
053    
054      /**
055       * Prepare to convert a block. Must be called before invoke.
056       * @param bb
057       */
058      final void prepareForBlock(BasicBlock bb) {
059        if (DEBUG) {
060          VM.sysWrite("FINAL LIR\n");
061          bb.printExtended();
062        }
063        lastInstr = bb.firstInstruction();
064      }
065    
066      /**
067       * Must be called after invoke for all non-empty blocks.
068       * @param bb
069       */
070      final void finalizeBlock(BasicBlock bb) {
071        lastInstr.BURS_backdoor_linkWithNext(bb.lastInstruction());
072        lastInstr = null;
073        if (DEBUG) {
074          VM.sysWrite("INITIAL MIR\n");
075          bb.printExtended();
076        }
077      }
078    
079      /**
080       * Appends an instruction, i.e. emits an MIR instruction.
081       */
082      public final void append(Instruction instruction) {
083        lastInstr.BURS_backdoor_linkWithNext(instruction);
084        lastInstr = instruction;
085      }
086    }
087    
088