1 /*
2  * Copyright (c) 2012, 2012, Oracle and/or its affiliates. All rights reserved.
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * This code is free software; you can redistribute it and/or modify it
6  * under the terms of the GNU General Public License version 2 only, as
7  * published by the Free Software Foundation.
8  *
9  * This code is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12  * version 2 for more details (a copy is included in the LICENSE file that
13  * accompanied this code).
14  *
15  * You should have received a copy of the GNU General Public License version
16  * 2 along with this work; if not, write to the Free Software Foundation,
17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18  *
19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20  * or visit www.oracle.com if you need additional information or have any
21  * questions.
22  */
23 
24 
25 
26 package org.graalvm.compiler.core.common.cfg;
27 
28 import java.util.ArrayList;
29 import java.util.List;
30 
31 public abstract class Loop<T extends AbstractBlockBase<T>> {
32 
33     private final Loop<T> parent;
34     private final List<Loop<T>> children;
35 
36     private final int depth;
37     private final int index;
38     private final T header;
39     private final List<T> blocks;
40     private final List<T> exits;
41 
Loop(Loop<T> parent, int index, T header)42     protected Loop(Loop<T> parent, int index, T header) {
43         this.parent = parent;
44         if (parent != null) {
45             this.depth = parent.getDepth() + 1;
46         } else {
47             this.depth = 1;
48         }
49         this.index = index;
50         this.header = header;
51         this.blocks = new ArrayList<>();
52         this.children = new ArrayList<>();
53         this.exits = new ArrayList<>();
54     }
55 
numBackedges()56     public abstract long numBackedges();
57 
58     @Override
toString()59     public String toString() {
60         return "loop " + index + " depth " + getDepth() + (parent != null ? " outer " + parent.index : "");
61     }
62 
getParent()63     public Loop<T> getParent() {
64         return parent;
65     }
66 
getChildren()67     public List<Loop<T>> getChildren() {
68         return children;
69     }
70 
getDepth()71     public int getDepth() {
72         return depth;
73     }
74 
getIndex()75     public int getIndex() {
76         return index;
77     }
78 
getHeader()79     public T getHeader() {
80         return header;
81     }
82 
getBlocks()83     public List<T> getBlocks() {
84         return blocks;
85     }
86 
getExits()87     public List<T> getExits() {
88         return exits;
89     }
90 
addExit(T t)91     public void addExit(T t) {
92         exits.add(t);
93     }
94 
95     /**
96      * Determines if one loop is a transitive parent of another loop.
97      *
98      * @param childLoop The loop for which parentLoop might be a transitive parent loop.
99      * @param parentLoop The loop which might be a transitive parent loop of child loop.
100      * @return {@code true} if parentLoop is a (transitive) parent loop of childLoop, {@code false}
101      *         otherwise
102      */
transitiveParentLoop(Loop<T> childLoop, Loop<T> parentLoop)103     public static <T extends AbstractBlockBase<T>> boolean transitiveParentLoop(Loop<T> childLoop, Loop<T> parentLoop) {
104         Loop<T> curr = childLoop;
105         while (curr != null) {
106             if (curr == parentLoop) {
107                 return true;
108             }
109             curr = curr.getParent();
110         }
111         return false;
112     }
113 
114     @Override
hashCode()115     public int hashCode() {
116         return index + depth * 31;
117     }
118 }
119