Esempio n. 1
0
void InlineContext::Dump(unsigned indent)
{
    // Handle fact that siblings are in reverse order.
    if (m_Sibling != nullptr)
    {
        m_Sibling->Dump(indent);
    }

    // We may not know callee name in some of the failing cases
    Compiler*   compiler   = m_InlineStrategy->GetCompiler();
    const char* calleeName = nullptr;

    if (m_Callee == nullptr)
    {
        assert(!m_Success);
        calleeName = "<unknown>";
    }
    else
    {

#if defined(DEBUG)
        calleeName = compiler->eeGetMethodFullName(m_Callee);
#else
        calleeName         = "callee";
#endif // defined(DEBUG)
    }

    mdMethodDef calleeToken = compiler->info.compCompHnd->getMethodDefFromMethod(m_Callee);

    // Dump this node
    if (m_Parent == nullptr)
    {
        // Root method
        printf("Inlines into %08X %s\n", calleeToken, calleeName);
    }
    else
    {
        // Inline attempt.
        const char* inlineReason = InlGetObservationString(m_Observation);
        const char* inlineResult = m_Success ? "" : "FAILED: ";

        if (m_Offset == BAD_IL_OFFSET)
        {
            printf("%*s[%u IL=???? TR=%06u %08X] [%s%s] %s\n", indent, "", m_Ordinal, m_TreeID, calleeToken,
                   inlineResult, inlineReason, calleeName);
        }
        else
        {
            IL_OFFSET offset = jitGetILoffs(m_Offset);
            printf("%*s[%u IL=%04d TR=%06u %08X] [%s%s] %s\n", indent, "", m_Ordinal, offset, m_TreeID, calleeToken,
                   inlineResult, inlineReason, calleeName);
        }
    }

    // Recurse to first child
    if (m_Child != nullptr)
    {
        m_Child->Dump(indent + 2);
    }
}
Esempio n. 2
0
void InlineContext::DumpXml(FILE* file, unsigned indent)
{
    // Handle fact that siblings are in reverse order.
    if (m_Sibling != nullptr)
    {
        m_Sibling->DumpXml(file, indent);
    }

    Compiler* compiler = m_InlineStrategy->GetCompiler();

    mdMethodDef calleeToken =
        compiler->info.compCompHnd->getMethodDefFromMethod(m_Callee);

    const bool isRoot = m_Parent == nullptr;
    const bool hasChild = m_Child != nullptr;
    const char* inlineType = m_Success ? "Inline" : "FailedInline";
    unsigned newIndent = indent;

    if (!isRoot)
    {
        const char* inlineReason = InlGetObservationString(m_Observation);

        int offset = -1;
        if (m_Offset != BAD_IL_OFFSET)
        {
            offset = (int) jitGetILoffs(m_Offset);
        }

        fprintf(file, "%*s<%s>\n", indent, "", inlineType);
        fprintf(file, "%*s<Token>%u</Token>\n", indent + 2, "", calleeToken);
        fprintf(file, "%*s<Offset>%u</Offset>\n", indent + 2, "", offset);
        fprintf(file, "%*s<Reason>%s</Reason>\n", indent + 2, "", inlineReason);
        newIndent = indent + 2;
    }

    // Handle children

    if (hasChild)
    {
        fprintf(file, "%*s<Inlines>\n", newIndent, "");
        m_Child->DumpXml(file, newIndent + 2);
        fprintf(file, "%*s</Inlines>\n", newIndent, "");
    }
    else
    {
        fprintf(file, "%*s<Inlines />\n", newIndent, "");
    }

    // Close out

    if (!isRoot)
    {
        fprintf(file, "%*s</%s>\n", indent, "", inlineType);
    }
}
Esempio n. 3
0
void InlineContext::Dump(Compiler* compiler, int indent)
{
    // Handle fact that siblings are in reverse order.
    if (m_Sibling != nullptr)
    {
        m_Sibling->Dump(compiler, indent);
    }

    // We may not know callee name in some of the failing cases
    const char* calleeName = nullptr;

    if (m_Callee == nullptr)
    {
        assert(!m_Success);
        calleeName = "<unknown>";
    }
    else
    {
        calleeName = compiler->eeGetMethodFullName(m_Callee);
    }

    // Dump this node
    if (m_Parent == nullptr)
    {
        // Root method
        printf("Inlines into %s\n", calleeName);
    }
    else
    {
        // Inline attempt.
        const char* inlineReason = InlGetObservationString(m_Observation);
        const char* inlineResult = m_Success ? "" : "FAILED: ";

        for (int i = 0; i < indent; i++)
        {
            printf(" ");
        }

        if (m_Offset == BAD_IL_OFFSET)
        {
            printf("[IL=???? TR=%06u] [%s%s] %s\n", m_TreeID, inlineResult, inlineReason, calleeName);
        }
        else
        {
            IL_OFFSET offset = jitGetILoffs(m_Offset);
            printf("[IL=%04d TR=%06u] [%s%s] %s\n", offset, m_TreeID, inlineResult, inlineReason, calleeName);
        }
    }

    // Recurse to first child
    if (m_Child != nullptr)
    {
        m_Child->Dump(compiler, indent + 2);
    }
}
Esempio n. 4
0
void InlineContext::DumpData(unsigned indent)
{
    // Handle fact that siblings are in reverse order.
    if (m_Sibling != nullptr)
    {
        m_Sibling->DumpData(indent);
    }

    Compiler* compiler = m_InlineStrategy->GetCompiler();

#if defined(DEBUG)
    const char* calleeName = compiler->eeGetMethodFullName(m_Callee);
#else
    const char* calleeName = "callee";
#endif // defined(DEBUG)

    if (m_Parent == nullptr)
    {
        // Root method... cons up a policy so we can display the name
        InlinePolicy* policy = InlinePolicy::GetPolicy(compiler, true);
        printf("\nInlines [%u] into \"%s\" [%s]\n",
               m_InlineStrategy->GetInlineCount(),
               calleeName,
               policy->GetName());
    }
    else if (m_Success)
    {
        const char* inlineReason = InlGetObservationString(m_Observation);
        printf("%*s%u,\"%s\",\"%s\"", indent, "", m_Ordinal, inlineReason, calleeName);
        m_Policy->DumpData(stdout);
        printf("\n");
    }

    // Recurse to first child
    if (m_Child != nullptr)
    {
        m_Child->DumpData(indent + 2);
    }
}
Esempio n. 5
0
void InlineResult::Report()
{
    // If we weren't actually inlining, user may have suppressed
    // reporting via setReported(). If so, do nothing.
    if (m_Reported)
    {
        return;
    }

    m_Reported = true;

#ifdef DEBUG
    const char* callee = nullptr;

    // Optionally dump the result
    if (VERBOSE)
    {
        const char* format = "INLINER: during '%s' result '%s' reason '%s' for '%s' calling '%s'\n";
        const char* caller = (m_Caller == nullptr) ? "n/a" : m_RootCompiler->eeGetMethodFullName(m_Caller);

        callee = (m_Callee == nullptr) ? "n/a" : m_RootCompiler->eeGetMethodFullName(m_Callee);

        JITDUMP(format, m_Context, ResultString(), ReasonString(), caller, callee);
    }

    // If the inline failed, leave information on the call so we can
    // later recover what observation lead to the failure.
    if (IsFailure() && (m_Call != nullptr))
    {
        // compiler should have revoked candidacy on the call by now
        assert((m_Call->gtFlags & GTF_CALL_INLINE_CANDIDATE) == 0);

        m_Call->gtInlineObservation = m_Policy->GetObservation();
    }

#endif // DEBUG

    // Was the result NEVER? If so we might want to propagate this to
    // the runtime.

    if (IsNever() && m_Policy->PropagateNeverToRuntime())
    {
        // If we know the callee, and if the observation that got us
        // to this Never inline state is something *other* than
        // IS_NOINLINE, then we've uncovered a reason why this method
        // can't ever be inlined. Update the callee method attributes
        // so that future inline attempts for this callee fail faster.

        InlineObservation obs = m_Policy->GetObservation();

        if ((m_Callee != nullptr) && (obs != InlineObservation::CALLEE_IS_NOINLINE))
        {

#ifdef DEBUG

            if (VERBOSE)
            {
                const char* obsString = InlGetObservationString(obs);
                JITDUMP("\nINLINER: Marking %s as NOINLINE because of %s\n", callee, obsString);
            }

#endif  // DEBUG

            COMP_HANDLE comp = m_RootCompiler->info.compCompHnd;
            comp->setMethodAttribs(m_Callee, CORINFO_FLG_BAD_INLINEE);
        }
    }

    if (IsDecided())
    {
        const char* format = "INLINER: during '%s' result '%s' reason '%s'\n";
        JITLOG_THIS(m_RootCompiler, (LL_INFO100000, format, m_Context, ResultString(), ReasonString()));
        COMP_HANDLE comp = m_RootCompiler->info.compCompHnd;
        comp->reportInliningDecision(m_Caller, m_Callee, Result(), ReasonString());
    }
}