view graal/com.oracle.max.cri/src/com/sun/cri/xir/XirTemplate.java @ 4142:bc8527f3071c

Adjust code base to new level of warnings.
author Thomas Wuerthinger <thomas.wuerthinger@oracle.com>
date Sun, 18 Dec 2011 05:24:06 +0100
parents e233f5660da4
children
line wrap: on
line source

/*
 * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */
package com.sun.cri.xir;

import java.io.*;
import java.util.*;

import com.sun.cri.xir.CiXirAssembler.*;

/**
 * Represents a completed template of XIR code that has been first assembled by
 * the runtime, and then verified and preprocessed by the compiler. An {@code XirTemplate}
 * instance is immutable.
 */
public class XirTemplate {

    /**
     * Flags that indicate key features of the template for quick checking.
     */
    public enum GlobalFlags {
        /**
         * Contains a call to a {@link GlobalFlags#GLOBAL_STUB} template.
         */
        HAS_STUB_CALL,

        /**
         * Contains a call to the runtime.
         */
        HAS_RUNTIME_CALL,

        /**
         * Not simply a linear sequence of instructions, contains control transfers.
         */
        HAS_CONTROL_FLOW,

        /**
         * Is a shared instruction sequence for use by other templates.
         */
        GLOBAL_STUB;

        public final int mask = 1 << ordinal();
    }

    /**
     * Name of the template.
     */
    public final String name;

    public final XirOperand resultOperand;

    /**
     * The sequence of instructions for the fast (inline) path.
     */
    public final CiXirAssembler.XirInstruction[] fastPath;

    /**
     * The sequence of instructions for the slow (out of line) path.
     */
    public final CiXirAssembler.XirInstruction[] slowPath;

    /**
     * Labels used in control transfers.
     */
    public final XirLabel[] labels;

    /**
     * Parameters to the template.
     */
    public final XirParameter[] parameters;

    /**
     * An array of same length as {@link #parameters} where {@code parameterDestroyed[i]} is {@code true}
     * iff {@code parameters[i]} is the {@link XirInstruction#result result} of any {@link XirInstruction} in either
     * {@link #fastPath} or {@link #slowPath}.
     */
    public final boolean[] parameterDestroyed;

    /**
     * Temporary variables used by the template.
     */
    public final XirTemp[] temps;

    /**
     * Constants used in the template.
     */
    public final XirConstant[] constants;

    /**
     * The total number of variables. (relation to temps/parameters???)
     */
    public final int variableCount;

    public final boolean allocateResultOperand;

    public final XirTemplate[] calleeTemplates;

    public final XirMark[] marks;

    public final int outgoingStackSize;

    public final XirOperand[] inputOperands;
    public final XirOperand[] inputTempOperands;
    public final XirOperand[] tempOperands;


    /**
     * The {@link GlobalFlags} associated with the template.
     */
    public final int flags;

    public XirTemplate(String name,
                       int variableCount,
                       boolean allocateResultOperand,
                       XirOperand resultOperand,
                       CiXirAssembler.XirInstruction[] fastPath,
                       CiXirAssembler.XirInstruction[] slowPath,
                       XirLabel[] labels,
                       XirParameter[] parameters,
                       XirTemp[] temps,
                       XirConstant[] constantValues,
                       int flags,
                       XirTemplate[] calleeTemplates,
                       XirMark[] marks,
                       int outgoingStackSize) {
        this.name = name;
        this.variableCount = variableCount;
        this.resultOperand = resultOperand;
        this.fastPath = fastPath;
        this.slowPath = slowPath;
        this.labels = labels;
        this.parameters = parameters;
        this.flags = flags;
        this.temps = temps;
        this.allocateResultOperand = allocateResultOperand;
        this.constants = constantValues;
        this.calleeTemplates = calleeTemplates;
        this.marks = marks;
        this.outgoingStackSize = outgoingStackSize;

        assert fastPath != null;
        assert labels != null;
        assert parameters != null;

        List<XirOperand> inputOperandList = new ArrayList<>(4);
        List<XirOperand> inputTempOperandList = new ArrayList<>(4);
        List<XirOperand> tempOperandList = new ArrayList<>(4);

        parameterDestroyed = new boolean[parameters.length];
        for (int i = 0; i < parameters.length; i++) {
            for (XirInstruction ins : fastPath) {
                if (ins.result == parameters[i]) {
                    parameterDestroyed[i] = true;
                    break;
                }
            }

            if (slowPath != null && !parameterDestroyed[i]) {
                for (XirInstruction ins : slowPath) {
                    if (ins.result == parameters[i]) {
                        parameterDestroyed[i] = true;
                    }
                }
            }

            if (parameterDestroyed[i]) {
                inputTempOperandList.add(parameters[i]);
            } else {
                inputOperandList.add(parameters[i]);
            }
        }

        for (XirTemp temp : temps) {
            if (temp.reserve) {
                tempOperandList.add(temp);
            }
        }

        this.inputOperands = inputOperandList.toArray(new XirOperand[inputOperandList.size()]);
        this.inputTempOperands = inputTempOperandList.toArray(new XirOperand[inputTempOperandList.size()]);
        this.tempOperands = tempOperandList.toArray(new XirOperand[tempOperandList.size()]);
    }

    /**
     * Convenience getter that returns the value at a given index in the {@link #parameterDestroyed} array.
     * @param index
     * @return the value at {@code parameterDestroyed[index]}
     */
    public boolean isParameterDestroyed(int index) {
        return parameterDestroyed[index];
    }

    @Override
    public String toString() {
        return name;
    }

    public void print(PrintStream p) {
        final String indent = "   ";

        p.println();
        p.println("Template " + name);

        p.print("Param:");
        for (XirParameter param : parameters) {
            p.print(" " + param.detailedToString());
        }
        p.println();

        if (temps.length > 0) {
            p.print("Temps:");
            for (XirTemp temp : temps) {
                p.print(" " + temp.detailedToString());
            }
            p.println();
        }

        if (constants.length > 0) {
            p.print("Constants:");
            for (XirConstant c : constants) {
                p.print(" " + c.detailedToString());
            }
            p.println();
        }

        if (flags != 0) {
            p.print("Flags:");
            for (XirTemplate.GlobalFlags flag : XirTemplate.GlobalFlags.values()) {
                if ((this.flags & flag.mask) != 0) {
                    p.print(" " + flag.name());
                }
            }
            p.println();
        }

        p.println("Fast path:");
        for (XirInstruction i : fastPath) {
            p.println(indent + i.toString());
        }

        if (slowPath != null) {
            p.println("Slow path:");
            for (XirInstruction i : slowPath) {
                p.println(indent + i.toString());
            }
        }
    }
}