src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/alloc/trace/TraceUtil.java
branchJDK-8200758-branch
changeset 57069 b8385a806d2b
parent 57068 eb6d315c4e39
parent 52934 8deeb7bba516
child 57070 42783e8e73de
equal deleted inserted replaced
57068:eb6d315c4e39 57069:b8385a806d2b
     1 /*
       
     2  * Copyright (c) 2015, 2015, 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.lir.alloc.trace;
       
    26 
       
    27 import java.util.ArrayList;
       
    28 
       
    29 import org.graalvm.compiler.core.common.alloc.Trace;
       
    30 import org.graalvm.compiler.core.common.alloc.TraceBuilderResult;
       
    31 import org.graalvm.compiler.core.common.cfg.AbstractBlockBase;
       
    32 import org.graalvm.compiler.lir.LIR;
       
    33 import org.graalvm.compiler.lir.LIRInstruction;
       
    34 import org.graalvm.compiler.lir.StandardOp.JumpOp;
       
    35 import org.graalvm.compiler.lir.StandardOp.LabelOp;
       
    36 
       
    37 import jdk.vm.ci.meta.Value;
       
    38 
       
    39 public class TraceUtil {
       
    40 
       
    41     public static boolean isShadowedRegisterValue(Value value) {
       
    42         assert value != null;
       
    43         return value instanceof ShadowedRegisterValue;
       
    44     }
       
    45 
       
    46     public static ShadowedRegisterValue asShadowedRegisterValue(Value value) {
       
    47         assert isShadowedRegisterValue(value);
       
    48         return (ShadowedRegisterValue) value;
       
    49     }
       
    50 
       
    51     public static boolean isTrivialTrace(LIR lir, Trace trace) {
       
    52         if (trace.size() != 1) {
       
    53             return false;
       
    54         }
       
    55         ArrayList<LIRInstruction> instructions = lir.getLIRforBlock(trace.getBlocks()[0]);
       
    56         if (instructions.size() != 2) {
       
    57             return false;
       
    58         }
       
    59         assert instructions.get(0) instanceof LabelOp : "First instruction not a LabelOp: " + instructions.get(0);
       
    60         if (((LabelOp) instructions.get(0)).isPhiIn()) {
       
    61             /*
       
    62              * Merge blocks are in general not trivial block because variables defined by a PHI
       
    63              * always need a location. If the outgoing value of the predecessor is a constant we
       
    64              * need to find an appropriate location (register or stack).
       
    65              *
       
    66              * Note that this case should not happen in practice since the trace containing the
       
    67              * merge block should also contain one of the predecessors. For non-standard trace
       
    68              * builders (e.g. the single block trace builder) this is not the true, though.
       
    69              */
       
    70             return false;
       
    71         }
       
    72         /*
       
    73          * Now we need to check if the BlockEndOp has no special operand requirements (i.e.
       
    74          * stack-slot, register). For now we just check for JumpOp because we know that it doesn't.
       
    75          */
       
    76         return instructions.get(1) instanceof JumpOp;
       
    77     }
       
    78 
       
    79     public static boolean hasInterTracePredecessor(TraceBuilderResult result, Trace trace, AbstractBlockBase<?> block) {
       
    80         assert result.getTraceForBlock(block).equals(trace);
       
    81         if (block.getPredecessorCount() == 0) {
       
    82             // start block
       
    83             return false;
       
    84         }
       
    85         if (block.getPredecessorCount() == 1) {
       
    86             return !result.getTraceForBlock(block.getPredecessors()[0]).equals(trace);
       
    87         }
       
    88         return true;
       
    89     }
       
    90 
       
    91     public static boolean hasInterTraceSuccessor(TraceBuilderResult result, Trace trace, AbstractBlockBase<?> block) {
       
    92         assert result.getTraceForBlock(block).equals(trace);
       
    93         if (block.getSuccessorCount() == 0) {
       
    94             // method end block
       
    95             return false;
       
    96         }
       
    97         if (block.getSuccessorCount() == 1) {
       
    98             return !result.getTraceForBlock(block.getSuccessors()[0]).equals(trace);
       
    99         }
       
   100         return true;
       
   101     }
       
   102 }