LoopFragmentWhole.java revision 13264:48566d838608
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 */
23package org.graalvm.compiler.loop;
24
25import org.graalvm.compiler.core.common.cfg.Loop;
26import org.graalvm.compiler.debug.DebugContext;
27import org.graalvm.compiler.graph.Graph;
28import org.graalvm.compiler.graph.Graph.DuplicationReplacement;
29import org.graalvm.compiler.graph.Node;
30import org.graalvm.compiler.graph.NodeBitMap;
31import org.graalvm.compiler.nodes.EndNode;
32import org.graalvm.compiler.nodes.FixedNode;
33import org.graalvm.compiler.nodes.LoopBeginNode;
34import org.graalvm.compiler.nodes.LoopExitNode;
35import org.graalvm.compiler.nodes.StructuredGraph;
36import org.graalvm.compiler.nodes.ValueNode;
37import org.graalvm.compiler.nodes.cfg.Block;
38import org.graalvm.util.EconomicSet;
39
40public class LoopFragmentWhole extends LoopFragment {
41
42    public LoopFragmentWhole(LoopEx loop) {
43        super(loop);
44    }
45
46    public LoopFragmentWhole(LoopFragmentWhole original) {
47        super(null, original);
48    }
49
50    @Override
51    public LoopFragmentWhole duplicate() {
52        LoopFragmentWhole loopFragmentWhole = new LoopFragmentWhole(this);
53        loopFragmentWhole.reify();
54        return loopFragmentWhole;
55    }
56
57    private void reify() {
58        assert this.isDuplicate();
59
60        patchNodes(null);
61
62        mergeEarlyExits();
63    }
64
65    @Override
66    public NodeBitMap nodes() {
67        if (nodes == null) {
68            Loop<Block> loop = loop().loop();
69            nodes = LoopFragment.computeNodes(graph(), LoopFragment.toHirBlocks(loop.getBlocks()), LoopFragment.toHirExits(loop.getExits()));
70        }
71        return nodes;
72    }
73
74    @Override
75    protected ValueNode prim(ValueNode b) {
76        return getDuplicatedNode(b);
77    }
78
79    @Override
80    protected DuplicationReplacement getDuplicationReplacement() {
81        final FixedNode entry = loop().entryPoint();
82        final Graph graph = this.graph();
83        return new DuplicationReplacement() {
84
85            private EndNode endNode;
86
87            @Override
88            public Node replacement(Node o) {
89                if (o == entry) {
90                    if (endNode == null) {
91                        endNode = graph.add(new EndNode());
92                    }
93                    return endNode;
94                }
95                return o;
96            }
97        };
98    }
99
100    public FixedNode entryPoint() {
101        if (isDuplicate()) {
102            LoopBeginNode newLoopBegin = getDuplicatedNode(original().loop().loopBegin());
103            return newLoopBegin.forwardEnd();
104        }
105        return loop().entryPoint();
106    }
107
108    @Override
109    protected void finishDuplication() {
110        // TODO (gd) ?
111    }
112
113    void cleanupLoopExits() {
114        LoopBeginNode loopBegin = original().loop().loopBegin();
115        assert nodes == null || nodes.contains(loopBegin);
116        StructuredGraph graph = loopBegin.graph();
117        if (graph.getGuardsStage() == StructuredGraph.GuardsStage.AFTER_FSA) {
118            // After FrameStateAssignment ControlFlowGraph treats loop exits differently which means
119            // that the LoopExitNodes can be in a block which post dominates the true loop exit. For
120            // cloning to work right they must agree.
121            EconomicSet<LoopExitNode> exits = EconomicSet.create();
122            for (Block exitBlock : original().loop().loop().getExits()) {
123                LoopExitNode exitNode = exitBlock.getLoopExit();
124                if (exitNode == null) {
125                    exitNode = graph.add(new LoopExitNode(loopBegin));
126                    graph.addAfterFixed(exitBlock.getBeginNode(), exitNode);
127                    if (nodes != null) {
128                        nodes.mark(exitNode);
129                    }
130                    graph.getDebug().dump(DebugContext.VERBOSE_LEVEL, graph, "Adjusting loop exit node for %s", loopBegin);
131                }
132                exits.add(exitNode);
133            }
134            for (LoopExitNode exitNode : loopBegin.loopExits()) {
135                if (!exits.contains(exitNode)) {
136                    if (nodes != null) {
137                        nodes.clear(exitNode);
138                    }
139                    graph.removeFixed(exitNode);
140                }
141            }
142        }
143
144    }
145
146    @Override
147    protected void beforeDuplication() {
148        cleanupLoopExits();
149    }
150
151    @Override
152    public void insertBefore(LoopEx loop) {
153        // TODO Auto-generated method stub
154
155    }
156}
157