src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.nodes/src/org/graalvm/compiler/nodes/InliningLog.java
author iveresov
Fri, 02 Feb 2018 17:28:17 -0800
changeset 48861 47f19ff9903c
child 49451 e06f9607f370
permissions -rw-r--r--
8194819: Update Graal Reviewed-by: kvn
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
48861
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
     1
/*
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
     2
 * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
     4
 *
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
     7
 * published by the Free Software Foundation.
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
     8
 *
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
     9
 * This code is distributed in the hope that it will be useful, but WITHOUT
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
    10
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
    11
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
    12
 * version 2 for more details (a copy is included in the LICENSE file that
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
    13
 * accompanied this code).
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
    14
 *
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
    15
 * You should have received a copy of the GNU General Public License version
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
    16
 * 2 along with this work; if not, write to the Free Software Foundation,
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
    17
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
    18
 *
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
    19
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
    20
 * or visit www.oracle.com if you need additional information or have any
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
    21
 * questions.
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
    22
 */
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
    23
package org.graalvm.compiler.nodes;
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
    24
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
    25
import jdk.vm.ci.code.BytecodePosition;
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
    26
import jdk.vm.ci.meta.ResolvedJavaMethod;
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
    27
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
    28
import java.util.ArrayList;
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
    29
import java.util.HashMap;
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
    30
import java.util.List;
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
    31
import java.util.Map;
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
    32
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
    33
/**
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
    34
 * This class contains all inlining decisions performed on a graph during the compilation.
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
    35
 *
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
    36
 * Each inlining decision consists of:
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
    37
 *
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
    38
 * <ul>
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
    39
 * <li>a value indicating whether the decision was positive or negative</li>
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
    40
 * <li>the call target method</li>
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
    41
 * <li>the reason for the inlining decision</li>
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
    42
 * <li>the name of the phase in which the inlining decision took place</li>
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
    43
 * <li>the special {@link BytecodePositionWithId} value that describes the position in the bytecode
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
    44
 * together with the callsite-specific unique identifier</li>
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
    45
 * <li>the inlining log of the inlined graph, or {@code null} if the decision was negative</li>
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
    46
 * </ul>
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
    47
 *
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
    48
 * A phase that does inlining should use the instance of this class contained in the
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
    49
 * {@link StructuredGraph} by calling {@link #addDecision} whenever it decides to inline a method.
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
    50
 * If there are invokes in the graph at the end of the respective phase, then that phase must call
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
    51
 * {@link #addDecision} to log negative decisions.
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
    52
 *
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
    53
 * At the end of the compilation, the contents of the inlining log can be converted into a list of
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
    54
 * decisions by calling {@link #formatAsList} or into an inlining tree, by calling
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
    55
 * {@link #formatAsTree}.
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
    56
 */
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
    57
public class InliningLog {
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
    58
    /**
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
    59
     * A bytecode position with a unique identifier attached.
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
    60
     *
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
    61
     * The purpose of this class is to disambiguate callsites that are duplicated by a
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
    62
     * transformation (such as loop peeling or path duplication).
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
    63
     */
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
    64
    public static final class BytecodePositionWithId extends BytecodePosition implements Comparable<BytecodePositionWithId> {
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
    65
        private final int id;
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
    66
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
    67
        public BytecodePositionWithId(BytecodePositionWithId caller, ResolvedJavaMethod method, int bci, int id) {
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
    68
            super(caller, method, bci);
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
    69
            this.id = id;
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
    70
        }
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
    71
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
    72
        public BytecodePositionWithId addCallerWithId(BytecodePositionWithId caller) {
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
    73
            if (getCaller() == null) {
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
    74
                return new BytecodePositionWithId(caller, getMethod(), getBCI(), id);
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
    75
            } else {
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
    76
                return new BytecodePositionWithId(getCaller().addCallerWithId(caller), getMethod(), getBCI(), id);
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
    77
            }
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
    78
        }
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
    79
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
    80
        public static BytecodePositionWithId create(FrameState state) {
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
    81
            return create(state, true);
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
    82
        }
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
    83
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
    84
        @SuppressWarnings("deprecation")
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
    85
        private static BytecodePositionWithId create(FrameState state, boolean topLevel) {
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
    86
            if (state == null) {
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
    87
                return null;
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
    88
            }
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
    89
            ResolvedJavaMethod method = state.getMethod();
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
    90
            int bci = topLevel ? state.bci - 3 : state.bci;
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
    91
            int id = state.getId();
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
    92
            return new BytecodePositionWithId(create(state.outerFrameState(), false), method, bci, id);
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
    93
        }
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
    94
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
    95
        @Override
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
    96
        public BytecodePositionWithId getCaller() {
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
    97
            return (BytecodePositionWithId) super.getCaller();
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
    98
        }
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
    99
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
   100
        public BytecodePositionWithId withoutCaller() {
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
   101
            return new BytecodePositionWithId(null, getMethod(), getBCI(), id);
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
   102
        }
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
   103
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
   104
        public long getId() {
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
   105
            return id;
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
   106
        }
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
   107
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
   108
        @Override
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
   109
        public boolean equals(Object that) {
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
   110
            return super.equals(that) && this.id == ((BytecodePositionWithId) that).id;
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
   111
        }
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
   112
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
   113
        @Override
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
   114
        public int hashCode() {
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
   115
            return super.hashCode() ^ (id << 16);
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
   116
        }
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
   117
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
   118
        @Override
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
   119
        public int compareTo(BytecodePositionWithId that) {
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
   120
            int diff = this.getBCI() - that.getBCI();
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
   121
            if (diff != 0) {
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
   122
                return diff;
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
   123
            }
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
   124
            diff = (int) (this.getId() - that.getId());
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
   125
            return diff;
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
   126
        }
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
   127
    }
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
   128
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
   129
    public static final class Decision {
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
   130
        private final boolean positive;
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
   131
        private final String reason;
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
   132
        private final String phase;
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
   133
        private final ResolvedJavaMethod target;
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
   134
        private final BytecodePositionWithId position;
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
   135
        private final InliningLog childLog;
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
   136
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
   137
        private Decision(boolean positive, String reason, String phase, ResolvedJavaMethod target, BytecodePositionWithId position, InliningLog childLog) {
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
   138
            assert position != null;
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
   139
            this.positive = positive;
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
   140
            this.reason = reason;
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
   141
            this.phase = phase;
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
   142
            this.target = target;
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
   143
            this.position = position;
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
   144
            this.childLog = childLog;
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
   145
        }
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
   146
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
   147
        public boolean isPositive() {
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
   148
            return positive;
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
   149
        }
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
   150
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
   151
        public String getReason() {
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
   152
            return reason;
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
   153
        }
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
   154
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
   155
        public String getPhase() {
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
   156
            return phase;
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
   157
        }
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
   158
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
   159
        public BytecodePositionWithId getPosition() {
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
   160
            return position;
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
   161
        }
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
   162
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
   163
        public InliningLog getChildLog() {
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
   164
            return childLog;
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
   165
        }
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
   166
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
   167
        public ResolvedJavaMethod getTarget() {
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
   168
            return target;
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
   169
        }
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
   170
    }
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
   171
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
   172
    private static class Callsite {
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
   173
        public final List<String> decisions;
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
   174
        public final Map<BytecodePositionWithId, Callsite> children;
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
   175
        public final BytecodePositionWithId position;
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
   176
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
   177
        Callsite(BytecodePositionWithId position) {
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
   178
            this.children = new HashMap<>();
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
   179
            this.position = position;
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
   180
            this.decisions = new ArrayList<>();
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
   181
        }
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
   182
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
   183
        public Callsite getOrCreateChild(BytecodePositionWithId fromRootPosition) {
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
   184
            Callsite child = children.get(fromRootPosition.withoutCaller());
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
   185
            if (child == null) {
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
   186
                child = new Callsite(fromRootPosition);
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
   187
                children.put(fromRootPosition.withoutCaller(), child);
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
   188
            }
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
   189
            return child;
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
   190
        }
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
   191
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
   192
        public Callsite createCallsite(BytecodePositionWithId fromRootPosition, String decision) {
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
   193
            Callsite parent = getOrCreateCallsite(fromRootPosition.getCaller());
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
   194
            Callsite callsite = parent.getOrCreateChild(fromRootPosition);
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
   195
            callsite.decisions.add(decision);
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
   196
            return null;
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
   197
        }
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
   198
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
   199
        private Callsite getOrCreateCallsite(BytecodePositionWithId fromRootPosition) {
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
   200
            if (fromRootPosition == null) {
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
   201
                return this;
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
   202
            } else {
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
   203
                Callsite parent = getOrCreateCallsite(fromRootPosition.getCaller());
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
   204
                Callsite callsite = parent.getOrCreateChild(fromRootPosition);
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
   205
                return callsite;
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
   206
            }
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
   207
        }
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
   208
    }
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
   209
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
   210
    private final List<Decision> decisions;
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
   211
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
   212
    public InliningLog() {
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
   213
        this.decisions = new ArrayList<>();
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
   214
    }
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
   215
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
   216
    public List<Decision> getDecisions() {
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
   217
        return decisions;
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
   218
    }
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
   219
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
   220
    public void addDecision(boolean positive, String reason, String phase, ResolvedJavaMethod target, BytecodePositionWithId position,
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
   221
                    InliningLog calleeLog) {
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
   222
        Decision decision = new Decision(positive, reason, phase, target, position, calleeLog);
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
   223
        decisions.add(decision);
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
   224
    }
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
   225
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
   226
    public String formatAsList() {
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
   227
        StringBuilder builder = new StringBuilder();
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
   228
        formatAsList("", null, decisions, builder);
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
   229
        return builder.toString();
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
   230
    }
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
   231
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
   232
    private void formatAsList(String phasePrefix, BytecodePositionWithId caller, List<Decision> subDecisions, StringBuilder builder) {
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
   233
        for (Decision decision : subDecisions) {
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
   234
            String phaseStack = phasePrefix.equals("") ? decision.getPhase() : phasePrefix + "-" + decision.getPhase();
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
   235
            String target = decision.getTarget().format("%H.%n(%p)");
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
   236
            String positive = decision.isPositive() ? "inline" : "do not inline";
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
   237
            BytecodePositionWithId absolutePosition = decision.getPosition().addCallerWithId(caller);
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
   238
            String position = "  " + decision.getPosition().toString().replaceAll("\n", "\n  ");
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
   239
            String line = String.format("<%s> %s %s: %s\n%s", phaseStack, positive, target, decision.getReason(), position);
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
   240
            builder.append(line).append(System.lineSeparator());
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
   241
            if (decision.getChildLog() != null) {
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
   242
                formatAsList(phaseStack, absolutePosition, decision.getChildLog().getDecisions(), builder);
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
   243
            }
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
   244
        }
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
   245
    }
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
   246
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
   247
    public String formatAsTree() {
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
   248
        Callsite root = new Callsite(null);
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
   249
        createTree("", null, root, decisions);
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
   250
        StringBuilder builder = new StringBuilder();
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
   251
        formatAsTree(root, "", builder);
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
   252
        return builder.toString();
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
   253
    }
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
   254
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
   255
    private void createTree(String phasePrefix, BytecodePositionWithId caller, Callsite root, List<Decision> subDecisions) {
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
   256
        for (Decision decision : subDecisions) {
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
   257
            String phaseStack = phasePrefix.equals("") ? decision.getPhase() : phasePrefix + "-" + decision.getPhase();
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
   258
            String target = decision.getTarget().format("%H.%n(%p)");
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
   259
            BytecodePositionWithId absolutePosition = decision.getPosition().addCallerWithId(caller);
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
   260
            String line = String.format("<%s> %s: %s", phaseStack, target, decision.getReason());
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
   261
            root.createCallsite(absolutePosition, line);
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
   262
            if (decision.getChildLog() != null) {
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
   263
                createTree(phaseStack, absolutePosition, root, decision.getChildLog().getDecisions());
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
   264
            }
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
   265
        }
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
   266
    }
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
   267
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
   268
    private void formatAsTree(Callsite site, String indent, StringBuilder builder) {
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
   269
        String position = site.position != null ? site.position.withoutCaller().toString() : "<root>";
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
   270
        String decision = String.join("; ", site.decisions);
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
   271
        String line = String.format("%s%s; %s", indent, position, decision);
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
   272
        builder.append(line).append(System.lineSeparator());
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
   273
        String childIndent = indent + "  ";
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
   274
        site.children.entrySet().stream().sorted((x, y) -> x.getKey().compareTo(y.getKey())).forEach(e -> {
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
   275
            formatAsTree(e.getValue(), childIndent, builder);
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
   276
        });
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
   277
    }
47f19ff9903c 8194819: Update Graal
iveresov
parents:
diff changeset
   278
}