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.regalloc; 014 015 import java.util.HashMap; 016 017 import org.jikesrvm.compilers.opt.ir.Register; 018 import org.jikesrvm.compilers.opt.util.GraphEdge; 019 import org.jikesrvm.compilers.opt.util.SpaceEffGraph; 020 import org.jikesrvm.compilers.opt.util.SpaceEffGraphEdge; 021 import org.jikesrvm.compilers.opt.util.SpaceEffGraphNode; 022 import org.jikesrvm.compilers.opt.util.SpaceEffGraphNode.GraphEdgeEnumeration; 023 024 /** 025 * This class represents a graph, where 026 * <ul> 027 * <li> the nodes are registers 028 * <li> the edge weights represent affinities between registers. 029 * </ul> 030 * <p> 031 * This graph is used to drive coalescing during register allocation. 032 * <p> 033 * Implementation: this is meant to be an undirected graph. By 034 * convention, we enforce that the register with the lower number is the 035 * source of an edge. 036 */ 037 class CoalesceGraph extends SpaceEffGraph { 038 039 /** 040 * Mapping register -> Node 041 */ 042 final HashMap<Register, Node> nodeMap = new HashMap<Register, Node>(); 043 044 /** 045 * find or create a node in the graph corresponding to a register. 046 */ 047 private Node findOrCreateNode(Register r) { 048 Node n = nodeMap.get(r); 049 if (n == null) { 050 n = new Node(r); 051 nodeMap.put(r, n); 052 addGraphNode(n); 053 } 054 return n; 055 } 056 057 /** 058 * Find the node corresponding to a regsiter. 059 */ 060 Node findNode(Register r) { 061 return nodeMap.get(r); 062 } 063 064 /** 065 * find or create an edge in the graph 066 */ 067 private Edge findOrCreateEdge(Node src, Node dest) { 068 Edge edge = null; 069 for (GraphEdgeEnumeration<GraphEdge> e = src.outEdges(); e.hasMoreElements();) { 070 Edge candidate = (Edge)e.next(); 071 if (candidate.toNode() == dest) { 072 edge = candidate; 073 break; 074 } 075 } 076 if (edge == null) { 077 edge = new Edge(src, dest); 078 addGraphEdge(edge); 079 } 080 return edge; 081 } 082 083 /** 084 * Add an affinity of weight w between registers r1 and r2 085 */ 086 void addAffinity(int w, Register r1, Register r2) { 087 Node src; 088 Node dest; 089 if (r1.getNumber() == r2.getNumber()) return; 090 091 // the register with the smaller number is the source of the edge. 092 if (r1.getNumber() < r2.getNumber()) { 093 src = findOrCreateNode(r1); 094 dest = findOrCreateNode(r2); 095 } else { 096 src = findOrCreateNode(r2); 097 dest = findOrCreateNode(r1); 098 } 099 100 Edge edge = findOrCreateEdge(src, dest); 101 102 edge.addWeight(w); 103 } 104 105 static class Node extends SpaceEffGraphNode { 106 final Register r; 107 108 Node(Register r) { 109 this.r = r; 110 } 111 112 Register getRegister() { 113 return r; 114 } 115 } 116 117 static class Edge extends SpaceEffGraphEdge { 118 private int w; 119 120 Edge(Node src, Node dest) { 121 super(src, dest); 122 } 123 124 void addWeight(int x) { 125 w += x; 126 } 127 128 int getWeight() { 129 return w; 130 } 131 } 132 }