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.ir; 014 015import java.util.List; 016 017/** 018 * This class holds each element in the GCIRMap 019 */ 020public final class GCIRMapElement { 021 022 /** 023 * The instruction, i.e., GC point 024 */ 025 private final Instruction inst; 026 027 /** 028 * The list of references (either symbolic regs or physical regs & spills) 029 */ 030 private final List<RegSpillListElement> regSpillList; 031 032 /** 033 * @param inst the instruction of interest 034 * @param regSpillList the list of references either symbolic (before regalloc) 035 * or physical/spill location (after regalloc) 036 */ 037 public GCIRMapElement(Instruction inst, List<RegSpillListElement> regSpillList) { 038 this.inst = inst; 039 this.regSpillList = regSpillList; 040 } 041 042 /** 043 * Creates a twin entry: required when the same MIR GC point 044 * is split into two instructions, both of which are PEIs 045 * after register allocation/GCIRMap creation. 046 * 047 * @param inst the instruction which needs a twin element 048 * @return the twin entry 049 */ 050 public GCIRMapElement createTwin(Instruction inst) { 051 return new GCIRMapElement(inst, this.regSpillList); 052 } 053 054 /** 055 * @return the instruction with this entry 056 */ 057 public Instruction getInstruction() { 058 return inst; 059 } 060 061 /** 062 * returns an enumerator to access the registers/spills for this entry 063 * @return an enumerator to access the registers/spills for this entry 064 */ 065 public List<RegSpillListElement> regSpillList() { 066 return regSpillList; 067 } 068 069 public void addRegSpillElement(RegSpillListElement e) { 070 regSpillList.add(e); 071 } 072 073 public void deleteRegSpillElement(RegSpillListElement e) { 074 regSpillList.remove(e); 075 } 076 077 /** 078 * Counts and returns the number of references for this map 079 * @return the number of references, either regs or spills for this map 080 */ 081 public int countNumElements() { 082 return regSpillList.size(); 083 } 084 085 /** 086 * Counts and returns the number of register elements (not spills) 087 * for this entry 088 * @return the number of register elements for this entry 089 */ 090 public int countNumRegElements() { 091 int count = 0; 092 093 for (RegSpillListElement elem : regSpillList) { 094 if (!elem.isSpill()) { 095 count++; 096 } 097 } 098 return count; 099 } 100 101 /** 102 * Counts and returns the number of spill for this entry 103 * @return the number of spill for this entry 104 */ 105 public int countNumSpillElements() { 106 int count = 0; 107 // traverse the list and compute how many spills exist 108 for (RegSpillListElement elem : regSpillList) { 109 if (elem.isSpill()) { 110 count++; 111 } 112 } 113 return count; 114 } 115 116 /** 117 * Return a string version of this object 118 * @return a string version of this object 119 */ 120 @Override 121 public String toString() { 122 StringBuilder buf = new StringBuilder(); 123 buf.append(" Instruction: ").append(inst.bcIndex).append(", ").append(inst); 124 for (RegSpillListElement elem : regSpillList) { 125 buf.append(elem).append(" "); 126 } 127 buf.append("\n"); 128 return buf.toString(); 129 } 130}