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