/* * 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.Enumeration; import java.util.HashMap; import org.jikesrvm.compilers.opt.ir.OPT_Register; /** * This class represents a graph, where * - the nodes are registers * - the edge weights represent affinities between registers. * * This graph is used to drive coalescing during register allocation. * * Implementation: this is meant to be an undirected graph. By * convention, we enforce that the register with the lower number is the * source of an edge. */ class OPT_CoalesceGraph extends OPT_SpaceEffGraph { /** * Mapping register -> Node */ final HashMap<OPT_Register, Node> nodeMap = new HashMap<OPT_Register, Node>(); /** * find or create a node in the graph corresponding to a register. */ private Node findOrCreateNode(OPT_Register r) { Node n = nodeMap.get(r); if (n == null) { n = new Node(r); nodeMap.put(r, n); addGraphNode(n); } return n; } /** * Find the node corresponding to a regsiter. */ Node findNode(OPT_Register r) { return nodeMap.get(r); } /** * find or create an edge in the graph */ private Edge findOrCreateEdge(Node src, Node dest) { Edge edge = null; for (Enumeration<OPT_VisEdge> e = src.edges(); e.hasMoreElements();) { Edge candidate = (Edge) e.nextElement(); if (candidate.toNode() == dest) { edge = candidate; break; } } if (edge == null) { edge = new Edge(src, dest); addGraphEdge(edge); } return edge; } /** * Add an affinity of weight w between registers r1 and r2 */ void addAffinity(int w, OPT_Register r1, OPT_Register r2) { Node src; Node dest; if (r1.getNumber() == r2.getNumber()) return; // the register with the smaller number is the source of the edge. if (r1.getNumber() < r2.getNumber()) { src = findOrCreateNode(r1); dest = findOrCreateNode(r2); } else { src = findOrCreateNode(r2); dest = findOrCreateNode(r1); } Edge edge = findOrCreateEdge(src, dest); edge.addWeight(w); } static class Node extends OPT_SpaceEffGraphNode { OPT_Register r; Node(OPT_Register r) { this.r = r; } OPT_Register getRegister() { return r; } } static class Edge extends OPT_SpaceEffGraphEdge { private int w; Edge(Node src, Node dest) { super(src, dest); } void addWeight(int x) { w += x; } int getWeight() { return w; } } }