This is an archive of the discontinued LLVM Phabricator instance.

Clarify definition of "indirect call" in CallSite
Needs ReviewPublic

Authored by scott.linder on Oct 4 2018, 10:06 AM.

Details

Reviewers
efriedma
sameerds
Summary

Attempt to clarify the definition of "indirect call" in LLVM, and add a function to look through trivial casts in a call instruction.

Rename and invert semantics of "isIndirectCall" to "isConstant". I don't like the new name, but I'm not sure how else to distinguish it from "direct/indirect".

Diff Detail

Event Timeline

scott.linder created this revision.Oct 4 2018, 10:06 AM
sbc100 added inline comments.Oct 4 2018, 10:30 AM
lib/Transforms/InstCombine/InstCombineCalls.cpp
4242

These auto s should probably be replaced with actual types now there is no type on the RHS.

Address feedback

scott.linder marked an inline comment as done.Oct 8 2018, 10:12 AM

Remove update of dyn_cast in WebAssemblyFixFunctionBitcasts which does not use CallSite

efriedma added inline comments.Oct 17 2018, 3:44 PM
include/llvm/IR/CallSite.h
110

Maybe it would be better to avoid "direct" and "indirect"...? Maybe just say "Return the function being called if the callee Value is a Function".

120

This isn't what isIndirectCall actually implements...

120

The new function seems nice.

scott.linder added inline comments.Oct 18 2018, 8:05 AM
include/llvm/IR/CallSite.h
110

One issue is that "direct" and "indirect" are used in similar ways in other places. For example CallGraphSCCPass refers to "devirtualizing" calls which are of the form call bitcast @func because getCalledFunction stops returning nullptr.

I can attempt to find and update all of these comments as well if we think fixing this terminology is useful. I am personally still confused about how these terms are used, and used inconsistently (as you point out below, getCalledFunction and isIndirectCall disagree on the term and they are in the same class).

120

Right, I completely missed that a BitCast is a Constant, and also did not mention the specific check for InlineAsm.

When can getCalledValue return nullptr? And is this definition "correct" for LLVM (e.g. an indirect call is any call which is not one of these cases)?

efriedma added inline comments.Oct 18 2018, 11:27 AM
include/llvm/IR/CallSite.h
120

getCalledValue never returns nullptr.

Assuming you meant getCalledFunction, it only returns non-null if the callee is a Function.

isIndirectCall() isn't really used by anything outside of profiling infrastructure, so the implementation doesn't really affect much.

Maybe it's best to try to avoid defining "direct" and "indirect" calls, and just directly describe what the functions return.

scott.linder added inline comments.Oct 18 2018, 11:54 AM
include/llvm/IR/CallSite.h
120

I meant getCalledValue; the first check in isIndirectCall is:

const Value *V = getCalledValue();
if (!V)
      return false;

Which is redundant if getCalledValue can't return nullptr.

The point of this patch is to clarify the definition, so having a function called isIndirectCall which answers a completely different question doesn't really move anything forward. I don't have a good grip on the right way to define this, though, as the term gets used in a number of places in a way which implies it has multiple definitions. I think ideally "indirect" would actually be defined as it is implemented here, for isIndirectCall, because as far as I know there is no way to introduce a non-constant value into a Constant expression.

efriedma added inline comments.Oct 18 2018, 12:12 PM
include/llvm/IR/CallSite.h
120

Which is redundant if getCalledValue can't return nullptr.

Yes, it's redundant.


isIndirectCall() doesn't really implement what anything in LLVM treats as an indirect call outside of the profiling infrastructure; it should probably be renamed.

scott.linder retitled this revision from Update CallSite docs and add a new function (NFC) to Clarify definition of "indirect call" in CallSite.
scott.linder edited the summary of this revision. (Show Details)

I still think disambiguating "indirect call" in LLVM is worthwhile, so here is another attempt at addressing feedback.

Please rebase on top of https://reviews.llvm.org/D52537 .

Is CallSite being superceded by CallBase? Also, from the linked patch it seems like my assumption that getCalledValue() cannot return null is invalid? Is this true for both CallSite and CallBase?

Is CallSite being superceded by CallBase?

Oh, oops, wasn't looking that closely. Eventually, yes, as part of the terminator cleanup, so we should probably try to make the two agree in the meantime so the transition is straightforward.

Also, from the linked patch it seems like my assumption that getCalledValue() cannot return null is invalid? Is this true for both CallSite and CallBase?

Well, for "valid" IR (that's accepted by the verifier), getCalledValue() is never null. But some passes temporarily null out operands as part of certain algorithms, like erasing dead code, and a small subset of IR APIs work for IR in that state. Not sure getCalledValue()/getCalledFunction() should be in that subset, but it doesn't matter much either way.