/*
 * Copyright (c) 2016, 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 org.graalvm.compiler.hotspot.phases.profiling;

import static org.graalvm.compiler.hotspot.nodes.profiling.ProfileInvokeNode.getProfileInvokeNodes;
import static org.graalvm.compiler.hotspot.nodes.profiling.ProfileNode.getProfileNodes;

import java.util.HashMap;
import java.util.Map;

import org.graalvm.compiler.core.common.cfg.Loop;
import org.graalvm.compiler.hotspot.nodes.profiling.ProfileInvokeNode;
import org.graalvm.compiler.hotspot.nodes.profiling.ProfileNode;
import org.graalvm.compiler.hotspot.nodes.profiling.RandomSeedNode;
import org.graalvm.compiler.nodes.ConstantNode;
import org.graalvm.compiler.nodes.InvokeNode;
import org.graalvm.compiler.nodes.LoopBeginNode;
import org.graalvm.compiler.nodes.PhiNode;
import org.graalvm.compiler.nodes.ValuePhiNode;
import org.graalvm.compiler.nodes.StructuredGraph;
import org.graalvm.compiler.nodes.ValueNode;
import org.graalvm.compiler.nodes.calc.AddNode;
import org.graalvm.compiler.nodes.calc.MulNode;
import org.graalvm.compiler.nodes.cfg.Block;
import org.graalvm.compiler.nodes.cfg.ControlFlowGraph;
import org.graalvm.compiler.nodes.util.GraphUtil;
import org.graalvm.compiler.options.Option;
import org.graalvm.compiler.options.OptionType;
import org.graalvm.compiler.options.OptionValue;
import org.graalvm.compiler.phases.BasePhase;
import org.graalvm.compiler.phases.tiers.PhaseContext;

import jdk.vm.ci.meta.ResolvedJavaMethod;

public class FinalizeProfileNodesPhase extends BasePhase<PhaseContext> {
    private int inlineeInvokeNotificationFreqLog;

    public static class Options {
        @Option(help = "Profile simple methods", type = OptionType.Expert)//
        public static final OptionValue<Boolean> ProfileSimpleMethods = new OptionValue<>(true);
        @Option(help = "Maximum number of nodes in a graph for a simple method", type = OptionType.Expert)//
        public static final OptionValue<Integer> SimpleMethodGraphSize = new OptionValue<>(256);
        @Option(help = "Maximum number of calls in a simple method", type = OptionType.Expert)//
        public static final OptionValue<Integer> SimpleMethodCalls = new OptionValue<>(1);
        @Option(help = "Maximum number of indirect calls in a simple moethod", type = OptionType.Expert)//
        public static final OptionValue<Integer> SimpleMethodIndirectCalls = new OptionValue<>(0);

    }

    public FinalizeProfileNodesPhase(int inlineeInvokeNotificationFreqLog) {
        this.inlineeInvokeNotificationFreqLog = inlineeInvokeNotificationFreqLog;
    }

    private static void removeAllProfilingNodes(StructuredGraph graph) {
        getProfileNodes(graph).forEach((n) -> GraphUtil.removeFixedWithUnusedInputs(n));
    }

    private void assignInlineeInvokeFrequencies(StructuredGraph graph) {
        for (ProfileInvokeNode node : getProfileInvokeNodes(graph)) {
            ResolvedJavaMethod profiledMethod = node.getProfiledMethod();
            if (!profiledMethod.equals(graph.method())) {
                // Some inlinee, reassign the inlinee frequency
                node.setNotificationFreqLog(inlineeInvokeNotificationFreqLog);
            }
        }
    }

    // Hacky heuristic to determine whether we want any profiling in this method.
    // The heuristic is applied after the graph is fully formed and before the first lowering.
    private static boolean simpleMethodHeuristic(StructuredGraph graph) {
        if (Options.ProfileSimpleMethods.getValue()) {
            return false;
        }

        // Check if the graph is smallish..
        if (graph.getNodeCount() > Options.SimpleMethodGraphSize.getValue()) {
            return false;
        }

        // Check if method has loops
        if (graph.hasLoops()) {
            return false;
        }

        // Check if method has calls
        if (graph.getNodes().filter(InvokeNode.class).count() > Options.SimpleMethodCalls.getValue()) {
            return false;
        }

        // Check if method has calls that need profiling
        if (graph.getNodes().filter(InvokeNode.class).filter((n) -> ((InvokeNode) n).getInvokeKind().isIndirect()).count() > Options.SimpleMethodIndirectCalls.getDefaultValue()) {
            return false;
        }

        return true;
    }

    private static void assignRandomSources(StructuredGraph graph) {
        ValueNode seed = graph.unique(new RandomSeedNode());
        ControlFlowGraph cfg = ControlFlowGraph.compute(graph, false, true, false, false);
        Map<LoopBeginNode, ValueNode> loopRandomValueCache = new HashMap<>();

        for (ProfileNode node : getProfileNodes(graph)) {
            ValueNode random;
            Block block = cfg.blockFor(node);
            Loop<Block> loop = block.getLoop();
            // Inject <a href=https://en.wikipedia.org/wiki/Linear_congruential_generator>LCG</a>
            // pseudo-random number generator into the loop
            if (loop != null) {
                LoopBeginNode loopBegin = (LoopBeginNode) loop.getHeader().getBeginNode();
                random = loopRandomValueCache.get(loopBegin);
                if (random == null) {
                    PhiNode phi = graph.addWithoutUnique(new ValuePhiNode(seed.stamp(), loopBegin));
                    phi.addInput(seed);
                    // X_{n+1} = a*X_n + c, using glibc-like constants
                    ValueNode a = ConstantNode.forInt(1103515245, graph);
                    ValueNode c = ConstantNode.forInt(12345, graph);
                    ValueNode next = graph.addOrUniqueWithInputs(new AddNode(c, new MulNode(phi, a)));
                    for (int i = 0; i < loopBegin.getLoopEndCount(); i++) {
                        phi.addInput(next);
                    }
                    random = phi;
                    loopRandomValueCache.put(loopBegin, random);
                }
            } else {
                // Graal doesn't compile methods with irreducible loops. So all profile nodes that
                // are not in a loop are guaranteed to be executed at most once. We feed the seed
                // value to such nodes directly.
                random = seed;
            }
            node.setRandom(random);
        }
    }

    @Override
    protected void run(StructuredGraph graph, PhaseContext context) {
        if (simpleMethodHeuristic(graph)) {
            removeAllProfilingNodes(graph);
            return;
        }

        assignInlineeInvokeFrequencies(graph);
        if (ProfileNode.Options.ProbabilisticProfiling.getValue()) {
            assignRandomSources(graph);
        }
    }

    @Override
    public boolean checkContract() {
        return false;
    }
}
