001/*
002 * Copyright (c) 2011, 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.phases.common.inlining.policy;
024
025import static com.oracle.graal.phases.common.inlining.InliningPhase.Options.*;
026
027import java.util.*;
028
029import jdk.internal.jvmci.meta.*;
030
031import com.oracle.graal.nodes.*;
032import com.oracle.graal.nodes.spi.*;
033import com.oracle.graal.phases.common.inlining.*;
034import com.oracle.graal.phases.common.inlining.info.*;
035import com.oracle.graal.phases.common.inlining.info.elem.*;
036
037public abstract class AbstractInliningPolicy implements InliningPolicy {
038    public static final float RelevanceCapForInlining = 1.0f;
039    public static final float CapInheritedRelevance = 1.0f;
040    protected final Map<Invoke, Double> hints;
041
042    public AbstractInliningPolicy(Map<Invoke, Double> hints) {
043        this.hints = hints;
044    }
045
046    protected double computeMaximumSize(double relevance, int configuredMaximum) {
047        double inlineRatio = Math.min(RelevanceCapForInlining, relevance);
048        return configuredMaximum * inlineRatio;
049    }
050
051    protected double getInliningBonus(InlineInfo info) {
052        if (hints != null && hints.containsKey(info.invoke())) {
053            return hints.get(info.invoke());
054        }
055        return 1;
056    }
057
058    protected boolean isIntrinsic(Replacements replacements, InlineInfo info) {
059        if (AlwaysInlineIntrinsics.getValue()) {
060            return onlyIntrinsics(replacements, info);
061        } else {
062            return onlyForcedIntrinsics(replacements, info);
063        }
064    }
065
066    private static boolean onlyIntrinsics(Replacements replacements, InlineInfo info) {
067        for (int i = 0; i < info.numberOfMethods(); i++) {
068            if (!InliningUtil.canIntrinsify(replacements, info.methodAt(i), info.invoke().bci())) {
069                return false;
070            }
071        }
072        return true;
073    }
074
075    private static boolean onlyForcedIntrinsics(Replacements replacements, InlineInfo info) {
076        for (int i = 0; i < info.numberOfMethods(); i++) {
077            if (!InliningUtil.canIntrinsify(replacements, info.methodAt(i), info.invoke().bci())) {
078                return false;
079            }
080        }
081        return true;
082    }
083
084    protected static int previousLowLevelGraphSize(InlineInfo info) {
085        int size = 0;
086        for (int i = 0; i < info.numberOfMethods(); i++) {
087            ResolvedJavaMethod m = info.methodAt(i);
088            ProfilingInfo profile = m.getProfilingInfo();
089            int compiledGraphSize = profile.getCompilerIRSize(StructuredGraph.class);
090            if (compiledGraphSize > 0) {
091                size += compiledGraphSize;
092            }
093        }
094        return size;
095    }
096
097    protected static double determineInvokeProbability(InlineInfo info) {
098        double invokeProbability = 0;
099        for (int i = 0; i < info.numberOfMethods(); i++) {
100            Inlineable callee = info.inlineableElementAt(i);
101            Iterable<Invoke> invokes = callee.getInvokes();
102            if (invokes.iterator().hasNext()) {
103                for (Invoke invoke : invokes) {
104                    invokeProbability += callee.getProbability(invoke);
105                }
106            }
107        }
108        return invokeProbability;
109    }
110}