/* * This file is part of the Jikes RVM project (http://jikesrvm.org). * * This file is licensed to You under the Common Public License (CPL); * You may not use this file except in compliance with the License. You * may obtain a copy of the License at * * http://www.opensource.org/licenses/cpl1.0.php * * See the COPYRIGHT.txt file distributed with this work for information * regarding copyright ownership. */ package org.jikesrvm.compilers.opt; import java.util.HashSet; import org.jikesrvm.compilers.opt.ir.Move; import org.jikesrvm.compilers.opt.ir.OPT_IR; import org.jikesrvm.compilers.opt.ir.OPT_Instruction; import org.jikesrvm.compilers.opt.ir.OPT_InstructionEnumeration; import org.jikesrvm.compilers.opt.ir.OPT_Operand; import org.jikesrvm.compilers.opt.ir.OPT_Register; /** * Coalesce registers in move instructions where possible. */ class OPT_CoalesceMoves extends OPT_CompilerPhase { /** * verbose debugging flag */ static final boolean DEBUG = false; /** * Return this instance of this phase. This phase contains no * per-compilation instance fields. * @param ir not used * @return this */ public OPT_CompilerPhase newExecution(OPT_IR ir) { return this; } /** * Should we perform this phase? * @param options controlling compiler options */ public final boolean shouldPerform(OPT_Options options) { return options.COALESCE_AFTER_SSA; } /** * Return a string name for this phase. * @return "Coalesce Moves" */ public final String getName() { return "Coalesce Moves"; } /** * perform the transformation * @param ir the governing IR */ public final void perform(OPT_IR ir) { // Compute liveness. OPT_LiveAnalysis live = new OPT_LiveAnalysis(false /* GC Maps */, false /* don't skip local propagation */); live.perform(ir); // Compute def-use information. OPT_DefUse.computeDU(ir); // Number the instructions ir.numberInstructions(); // Maintain a set of dead move instructions. HashSet<OPT_Instruction> dead = new HashSet<OPT_Instruction>(5); // for each Move instruction ... for (OPT_InstructionEnumeration e = ir.forwardInstrEnumerator(); e.hasMoreElements();) { OPT_Instruction s = e.nextElement(); if (s.operator.isMove()) { OPT_Register r = Move.getResult(s).asRegister().getRegister(); if (r.isSymbolic()) { OPT_Operand val = Move.getVal(s); if (val != null && val.isRegister()) { OPT_Register r2 = val.asRegister().getRegister(); if (r2.isSymbolic()) { if (OPT_Coalesce.attempt(ir, live, r, r2)) { if (DEBUG) System.out.println("COALESCED " + r + " " + r2); dead.add(s); } } } } } } // Now remove all dead Move instructions. for (OPT_Instruction s : dead) { OPT_DefUse.removeInstructionAndUpdateDU(s); } } }