001/*
002 * Copyright (c) 2012, 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.loop;
024
025import java.util.*;
026
027import com.oracle.graal.debug.*;
028import com.oracle.graal.debug.Debug.*;
029
030import com.oracle.graal.compiler.common.*;
031import com.oracle.graal.compiler.common.cfg.*;
032import com.oracle.graal.graph.*;
033import com.oracle.graal.nodes.*;
034import com.oracle.graal.nodes.cfg.*;
035
036public class LoopsData {
037
038    private Map<Loop<Block>, LoopEx> loopToEx = CollectionsFactory.newIdentityMap();
039    private Map<LoopBeginNode, LoopEx> loopBeginToEx = Node.newIdentityMap();
040    private ControlFlowGraph cfg;
041
042    public LoopsData(final StructuredGraph graph) {
043        try (Scope s = Debug.scope("ControlFlowGraph")) {
044            cfg = ControlFlowGraph.compute(graph, true, true, true, true);
045        } catch (Throwable e) {
046            throw Debug.handle(e);
047        }
048
049        for (Loop<Block> loop : cfg.getLoops()) {
050            LoopEx ex = new LoopEx(loop, this);
051            loopToEx.put(loop, ex);
052            loopBeginToEx.put(ex.loopBegin(), ex);
053        }
054    }
055
056    public LoopEx loop(Loop<?> loop) {
057        return loopToEx.get(loop);
058    }
059
060    public LoopEx loop(LoopBeginNode loopBegin) {
061        return loopBeginToEx.get(loopBegin);
062    }
063
064    public Collection<LoopEx> loops() {
065        return loopToEx.values();
066    }
067
068    public List<LoopEx> outerFirst() {
069        ArrayList<LoopEx> loops = new ArrayList<>(loops());
070        Collections.sort(loops, new Comparator<LoopEx>() {
071
072            @Override
073            public int compare(LoopEx o1, LoopEx o2) {
074                return o1.loop().getDepth() - o2.loop().getDepth();
075            }
076        });
077        return loops;
078    }
079
080    public List<LoopEx> innerFirst() {
081        ArrayList<LoopEx> loops = new ArrayList<>(loops());
082        Collections.sort(loops, new Comparator<LoopEx>() {
083
084            @Override
085            public int compare(LoopEx o1, LoopEx o2) {
086                return o2.loop().getDepth() - o1.loop().getDepth();
087            }
088        });
089        return loops;
090    }
091
092    public Collection<LoopEx> countedLoops() {
093        List<LoopEx> counted = new LinkedList<>();
094        for (LoopEx loop : loops()) {
095            if (loop.isCounted()) {
096                counted.add(loop);
097            }
098        }
099        return counted;
100    }
101
102    public void detectedCountedLoops() {
103        for (LoopEx loop : loops()) {
104            loop.detectCounted();
105        }
106    }
107
108    public ControlFlowGraph getCFG() {
109        return cfg;
110    }
111
112    public InductionVariable getInductionVariable(ValueNode value) {
113        InductionVariable match = null;
114        for (LoopEx loop : loops()) {
115            InductionVariable iv = loop.getInductionVariables().get(value);
116            if (iv != null) {
117                if (match != null) {
118                    return null;
119                }
120                match = iv;
121            }
122        }
123        return match;
124    }
125
126    /**
127     * Deletes any nodes created within the scope of this object that have no usages.
128     */
129    public void deleteUnusedNodes() {
130        for (LoopEx loop : loops()) {
131            loop.deleteUnusedNodes();
132        }
133    }
134}