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 */ 013package org.jikesrvm.compilers.opt.regalloc; 014 015import java.util.Enumeration; 016 017import org.jikesrvm.compilers.opt.ir.BasicBlock; 018import org.jikesrvm.compilers.opt.ir.IR; 019import org.jikesrvm.compilers.opt.ir.Instruction; 020import org.jikesrvm.compilers.opt.ir.Register; 021import org.jikesrvm.compilers.opt.ir.operand.MemoryOperand; 022import org.jikesrvm.compilers.opt.ir.operand.Operand; 023 024/** 025 * An object that returns an estimate of the relative cost of spilling a 026 * symbolic register, based on basic block frequencies. 027 */ 028final class BlockCountSpillCost extends SpillCostEstimator { 029 030 BlockCountSpillCost(IR ir) { 031 calculate(ir); 032 } 033 034 @Override 035 void calculate(IR ir) { 036 final double moveFactor = ir.options.REGALLOC_SIMPLE_SPILL_COST_MOVE_FACTOR; 037 final double memoryOperandFactor = ir.options.REGALLOC_SIMPLE_SPILL_COST_MEMORY_OPERAND_FACTOR; 038 for (Enumeration<BasicBlock> blocks = ir.getBasicBlocks(); blocks.hasMoreElements();) { 039 BasicBlock bb = blocks.nextElement(); 040 float freq = bb.getExecutionFrequency(); 041 for (Enumeration<Instruction> e = bb.forwardInstrEnumerator(); e.hasMoreElements();) { 042 Instruction s = e.nextElement(); 043 double factor = freq; 044 045 if (s.isMove()) factor *= moveFactor; 046 double baseFactor = factor; 047 if (SimpleSpillCost.hasBadSizeMemoryOperand(s)) { 048 baseFactor *= memoryOperandFactor; 049 } 050 051 // first deal with non-memory operands 052 for (Enumeration<Operand> e2 = s.getRootOperands(); e2.hasMoreElements();) { 053 Operand op = e2.nextElement(); 054 if (op.isRegister()) { 055 Register r = op.asRegister().getRegister(); 056 if (r.isSymbolic()) { 057 update(r, baseFactor); 058 } 059 } 060 } 061 // now handle memory operands 062 factor *= memoryOperandFactor; 063 for (Enumeration<Operand> e2 = s.getMemoryOperands(); e2.hasMoreElements();) { 064 MemoryOperand M = (MemoryOperand) e2.nextElement(); 065 if (M.base != null) { 066 Register r = M.base.getRegister(); 067 if (r.isSymbolic()) { 068 update(r, factor); 069 } 070 } 071 if (M.index != null) { 072 Register r = M.index.getRegister(); 073 if (r.isSymbolic()) { 074 update(r, factor); 075 } 076 } 077 } 078 } 079 } 080 } 081}