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.phases; 024 025import java.util.*; 026 027import com.oracle.graal.debug.*; 028 029import com.oracle.graal.graph.*; 030import com.oracle.graal.loop.*; 031import com.oracle.graal.nodes.*; 032import com.oracle.graal.phases.*; 033 034public class LoopUnswitchingPhase extends Phase { 035 036 private static final DebugMetric UNSWITCHED = Debug.metric("Unswitched"); 037 private static final DebugMetric UNSWITCH_CANDIDATES = Debug.metric("UnswitchCandidates"); 038 private static final DebugMetric UNSWITCH_EARLY_REJECTS = Debug.metric("UnswitchEarlyRejects"); 039 040 @Override 041 protected void run(StructuredGraph graph) { 042 if (graph.hasLoops()) { 043 boolean unswitched; 044 do { 045 unswitched = false; 046 final LoopsData dataUnswitch = new LoopsData(graph); 047 for (LoopEx loop : dataUnswitch.outerFirst()) { 048 if (LoopPolicies.shouldTryUnswitch(loop)) { 049 List<ControlSplitNode> controlSplits = LoopTransformations.findUnswitchable(loop); 050 if (controlSplits != null) { 051 UNSWITCH_CANDIDATES.increment(); 052 if (LoopPolicies.shouldUnswitch(loop, controlSplits)) { 053 if (Debug.isLogEnabled()) { 054 logUnswitch(loop, controlSplits); 055 } 056 LoopTransformations.unswitch(loop, controlSplits); 057 UNSWITCHED.increment(); 058 unswitched = true; 059 break; 060 } 061 } 062 } else { 063 UNSWITCH_EARLY_REJECTS.increment(); 064 } 065 } 066 } while (unswitched); 067 } 068 } 069 070 private static void logUnswitch(LoopEx loop, List<ControlSplitNode> controlSplits) { 071 StringBuilder sb = new StringBuilder("Unswitching "); 072 sb.append(loop).append(" at "); 073 for (ControlSplitNode controlSplit : controlSplits) { 074 sb.append(controlSplit).append(" ["); 075 NodePosIterator it = controlSplit.successors().iterator(); 076 while (it.hasNext()) { 077 sb.append(controlSplit.probability((AbstractBeginNode) it.next())); 078 if (it.hasNext()) { 079 sb.append(", "); 080 } 081 } 082 sb.append("]"); 083 } 084 Debug.log("%s", sb); 085 } 086}