001/*
002 * Copyright (c) 2015, 2015, Oracle and/or its affiliates. All rights reserved.
003 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
004 *
005 * This code is free software; you can redistribute it and/or modify it
006 * under the terms of the GNU General Public License version 2 only, as
007 * published by the Free Software Foundation.
008 *
009 * This code is distributed in the hope that it will be useful, but WITHOUT
010 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
011 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
012 * version 2 for more details (a copy is included in the LICENSE file that
013 * accompanied this code).
014 *
015 * You should have received a copy of the GNU General Public License version
016 * 2 along with this work; if not, write to the Free Software Foundation,
017 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
018 *
019 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
020 * or visit www.oracle.com if you need additional information or have any
021 * questions.
022 */
023package com.oracle.graal.nodes.cfg;
024
025import java.util.*;
026
027import jdk.internal.jvmci.meta.*;
028
029public class LocationSet {
030    private LocationIdentity firstLocation;
031    private List<LocationIdentity> list;
032
033    public LocationSet() {
034        list = null;
035    }
036
037    public LocationSet(LocationSet other) {
038        this.firstLocation = other.firstLocation;
039        if (other.list != null && other.list.size() > 0) {
040            list = new ArrayList<>(other.list);
041        }
042    }
043
044    private void initList() {
045        if (list == null) {
046            list = new ArrayList<>(4);
047        }
048    }
049
050    public boolean isEmpty() {
051        return firstLocation == null;
052    }
053
054    public boolean isAny() {
055        return firstLocation != null && firstLocation.isAny();
056    }
057
058    public void add(LocationIdentity location) {
059        if (this.isAny()) {
060            return;
061        } else if (location.isAny()) {
062            firstLocation = location;
063            list = null;
064        } else if (location.isImmutable()) {
065            return;
066        } else {
067            assert location.isMutable() && location.isSingle();
068            if (firstLocation == null) {
069                firstLocation = location;
070            } else if (location.equals(firstLocation)) {
071                return;
072            } else {
073                initList();
074                for (int i = 0; i < list.size(); ++i) {
075                    LocationIdentity value = list.get(i);
076                    if (location.equals(value)) {
077                        return;
078                    }
079                }
080                list.add(location);
081            }
082        }
083    }
084
085    public void addAll(LocationSet other) {
086        if (other.firstLocation != null) {
087            add(other.firstLocation);
088        }
089        List<LocationIdentity> otherList = other.list;
090        if (otherList != null) {
091            for (LocationIdentity l : otherList) {
092                add(l);
093            }
094        }
095    }
096
097    public boolean contains(LocationIdentity locationIdentity) {
098        assert locationIdentity.isSingle();
099        assert locationIdentity.isMutable();
100        if (LocationIdentity.any().equals(firstLocation)) {
101            return true;
102        }
103        if (locationIdentity.equals(firstLocation)) {
104            return true;
105        }
106        if (list != null) {
107            for (int i = 0; i < list.size(); ++i) {
108                LocationIdentity value = list.get(i);
109                if (locationIdentity.equals(value)) {
110                    return true;
111                }
112            }
113        }
114        return false;
115    }
116
117    public List<LocationIdentity> getCopyAsList() {
118        ArrayList<LocationIdentity> result = new ArrayList<>();
119        if (firstLocation != null) {
120            result.add(firstLocation);
121        }
122        if (list != null) {
123            result.addAll(list);
124        }
125        return result;
126    }
127
128    @Override
129    public String toString() {
130        if (this.isAny()) {
131            return "ANY";
132        } else if (this.isEmpty()) {
133            return "EMPTY";
134        } else {
135            List<LocationIdentity> copyAsList = getCopyAsList();
136            return Arrays.toString(copyAsList.toArray(new LocationIdentity[0]));
137        }
138    }
139}