001/*
002 * Copyright (c) 2012, 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.graph.iterators;
024
025import com.oracle.graal.graph.*;
026
027public abstract class NodePredicates {
028
029    private static final TautologyPredicate TAUTOLOGY = new TautologyPredicate();
030    private static final ContradictionPredicate CONTRADICTION = new ContradictionPredicate();
031    private static final IsNullPredicate IS_NULL = new IsNullPredicate();
032    private static final IsNotNullPredicate IS_NOT_NULL = new IsNotNullPredicate();
033
034    public static NodePredicate alwaysTrue() {
035        return TAUTOLOGY;
036    }
037
038    public static NodePredicate alwaysFalse() {
039        return CONTRADICTION;
040    }
041
042    public static NodePredicate isNull() {
043        return IS_NULL;
044    }
045
046    public static NodePredicate isNotNull() {
047        return IS_NOT_NULL;
048    }
049
050    public static NodePredicate equals(Node n) {
051        return new EqualsPredicate(n);
052    }
053
054    public static NodePredicate not(NodePredicate a) {
055        return a.negate();
056    }
057
058    public static NegativeTypePredicate isNotA(Class<? extends Node> clazz) {
059        return new NegativeTypePredicate(clazz);
060    }
061
062    public static PositiveTypePredicate isA(Class<? extends Node> clazz) {
063        return new PositiveTypePredicate(clazz);
064    }
065
066    public static NodePredicate isAInterface(Class<?> iface) {
067        assert iface.isInterface();
068        return new PositiveTypePredicate(iface);
069    }
070
071    public static NodePredicate isNotAInterface(Class<?> iface) {
072        assert iface.isInterface();
073        return new NegativeTypePredicate(iface);
074    }
075
076    static final class TautologyPredicate implements NodePredicate {
077
078        @Override
079        public boolean apply(Node n) {
080            return true;
081        }
082
083        public NodePredicate and(NodePredicate np) {
084            return np;
085        }
086
087        public NodePredicate negate() {
088            return CONTRADICTION;
089        }
090
091        public NodePredicate or(NodePredicate np) {
092            return this;
093        }
094    }
095
096    static final class ContradictionPredicate implements NodePredicate {
097
098        @Override
099        public boolean apply(Node n) {
100            return false;
101        }
102
103        public NodePredicate and(NodePredicate np) {
104            return this;
105        }
106
107        public NodePredicate negate() {
108            return TAUTOLOGY;
109        }
110
111        public NodePredicate or(NodePredicate np) {
112            return np;
113        }
114    }
115
116    static final class AndPredicate implements NodePredicate {
117
118        private final NodePredicate a;
119        private final NodePredicate b;
120
121        AndPredicate(NodePredicate a, NodePredicate b) {
122            this.a = a;
123            this.b = b;
124        }
125
126        @Override
127        public boolean apply(Node n) {
128            return a.apply(n) && b.apply(n);
129        }
130    }
131
132    static final class NotPredicate implements NodePredicate {
133
134        private final NodePredicate a;
135
136        NotPredicate(NodePredicate n) {
137            this.a = n;
138        }
139
140        @Override
141        public boolean apply(Node n) {
142            return !a.apply(n);
143        }
144
145        public NodePredicate negate() {
146            return a;
147        }
148    }
149
150    static final class OrPredicate implements NodePredicate {
151
152        private final NodePredicate a;
153        private final NodePredicate b;
154
155        OrPredicate(NodePredicate a, NodePredicate b) {
156            this.a = a;
157            this.b = b;
158        }
159
160        @Override
161        public boolean apply(Node n) {
162            return a.apply(n) || b.apply(n);
163        }
164    }
165
166    static final class IsNullPredicate implements NodePredicate {
167
168        @Override
169        public boolean apply(Node n) {
170            return n == null;
171        }
172
173        public NodePredicate negate() {
174            return IS_NOT_NULL;
175        }
176    }
177
178    static final class IsNotNullPredicate implements NodePredicate {
179
180        @Override
181        public boolean apply(Node n) {
182            return n != null;
183        }
184
185        public NodePredicate negate() {
186            return IS_NULL;
187        }
188    }
189
190    static final class EqualsPredicate implements NodePredicate {
191
192        private final Node u;
193
194        EqualsPredicate(Node u) {
195            this.u = u;
196        }
197
198        @Override
199        public boolean apply(Node n) {
200            return u == n;
201        }
202
203        public NodePredicate negate() {
204            return new NotEqualsPredicate(u);
205        }
206    }
207
208    static final class NotEqualsPredicate implements NodePredicate {
209
210        private final Node u;
211
212        NotEqualsPredicate(Node u) {
213            this.u = u;
214        }
215
216        @Override
217        public boolean apply(Node n) {
218            return u != n;
219        }
220
221        public NodePredicate negate() {
222            return new EqualsPredicate(u);
223        }
224    }
225
226    public static final class PositiveTypePredicate implements NodePredicate {
227
228        private final Class<?> type;
229        private PositiveTypePredicate or;
230
231        PositiveTypePredicate(Class<?> type) {
232            this.type = type;
233        }
234
235        public PositiveTypePredicate(NegativeTypePredicate a) {
236            type = a.type;
237            if (a.nor != null) {
238                or = new PositiveTypePredicate(a.nor);
239            }
240        }
241
242        @Override
243        public boolean apply(Node n) {
244            return type.isInstance(n) || (or != null && or.apply(n));
245        }
246
247        public PositiveTypePredicate or(Class<? extends Node> clazz) {
248            if (or == null) {
249                or = new PositiveTypePredicate(clazz);
250            } else {
251                or.or(clazz);
252            }
253            return this;
254        }
255
256        public NodePredicate negate() {
257            return new NegativeTypePredicate(this);
258        }
259    }
260
261    public static final class NegativeTypePredicate implements NodePredicate {
262
263        private final Class<?> type;
264        private NegativeTypePredicate nor;
265
266        NegativeTypePredicate(Class<?> type) {
267            this.type = type;
268        }
269
270        public NegativeTypePredicate(PositiveTypePredicate a) {
271            type = a.type;
272            if (a.or != null) {
273                nor = new NegativeTypePredicate(a.or);
274            }
275        }
276
277        @Override
278        public boolean apply(Node n) {
279            return !type.isInstance(n) && (nor == null || nor.apply(n));
280        }
281
282        public NegativeTypePredicate nor(Class<? extends Node> clazz) {
283            if (nor == null) {
284                nor = new NegativeTypePredicate(clazz);
285            } else {
286                nor.nor(clazz);
287            }
288            return this;
289        }
290
291        public NodePredicate negate() {
292            return new PositiveTypePredicate(this);
293        }
294    }
295}