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 package org.graalvm.compiler.loop.phases;
26 
27 import java.util.Iterator;
28 import java.util.List;
29 
30 import org.graalvm.compiler.debug.CounterKey;
31 import org.graalvm.compiler.debug.DebugContext;
32 import org.graalvm.compiler.graph.Node;
33 import org.graalvm.compiler.loop.LoopEx;
34 import org.graalvm.compiler.loop.LoopPolicies;
35 import org.graalvm.compiler.loop.LoopsData;
36 import org.graalvm.compiler.nodes.AbstractBeginNode;
37 import org.graalvm.compiler.nodes.ControlSplitNode;
38 import org.graalvm.compiler.nodes.StructuredGraph;
39 
40 public class LoopUnswitchingPhase extends ContextlessLoopPhase<LoopPolicies> {
41     private static final CounterKey UNSWITCHED = DebugContext.counter("Unswitched");
42     private static final CounterKey UNSWITCH_CANDIDATES = DebugContext.counter("UnswitchCandidates");
43     private static final CounterKey UNSWITCH_EARLY_REJECTS = DebugContext.counter("UnswitchEarlyRejects");
44 
LoopUnswitchingPhase(LoopPolicies policies)45     public LoopUnswitchingPhase(LoopPolicies policies) {
46         super(policies);
47     }
48 
49     @Override
run(StructuredGraph graph)50     protected void run(StructuredGraph graph) {
51         DebugContext debug = graph.getDebug();
52         if (graph.hasLoops()) {
53             boolean unswitched;
54             do {
55                 unswitched = false;
56                 final LoopsData dataUnswitch = new LoopsData(graph);
57                 for (LoopEx loop : dataUnswitch.outerFirst()) {
58                     if (getPolicies().shouldTryUnswitch(loop)) {
59                         List<ControlSplitNode> controlSplits = LoopTransformations.findUnswitchable(loop);
60                         if (controlSplits != null) {
61                             UNSWITCH_CANDIDATES.increment(debug);
62                             if (getPolicies().shouldUnswitch(loop, controlSplits)) {
63                                 if (debug.isLogEnabled()) {
64                                     logUnswitch(loop, controlSplits);
65                                 }
66                                 LoopTransformations.unswitch(loop, controlSplits);
67                                 debug.dump(DebugContext.DETAILED_LEVEL, graph, "After unswitch %s", controlSplits);
68                                 UNSWITCHED.increment(debug);
69                                 unswitched = true;
70                                 break;
71                             }
72                         }
73                     } else {
74                         UNSWITCH_EARLY_REJECTS.increment(debug);
75                     }
76                 }
77             } while (unswitched);
78         }
79     }
80 
logUnswitch(LoopEx loop, List<ControlSplitNode> controlSplits)81     private static void logUnswitch(LoopEx loop, List<ControlSplitNode> controlSplits) {
82         StringBuilder sb = new StringBuilder("Unswitching ");
83         sb.append(loop).append(" at ");
84         for (ControlSplitNode controlSplit : controlSplits) {
85             sb.append(controlSplit).append(" [");
86             Iterator<Node> it = controlSplit.successors().iterator();
87             while (it.hasNext()) {
88                 sb.append(controlSplit.probability((AbstractBeginNode) it.next()));
89                 if (it.hasNext()) {
90                     sb.append(", ");
91                 }
92             }
93             sb.append("]");
94         }
95         loop.entryPoint().getDebug().log("%s", sb);
96     }
97 
98     @Override
codeSizeIncrease()99     public float codeSizeIncrease() {
100         return 10.0f;
101     }
102 }
103