Docs question: legality of inspecting other functions in a function pass

Hi,

I'm not planning on doing this, but I noticed that the documentation
in WritingAnLLVMPass.rst doesn't seem to specify whether or not it's
legal for a function pass to inspect (and thus depend upon the
contents of) other functions and I'm curious if this is an oversight
or by design:

    To be explicit, ``FunctionPass`` subclasses are not allowed to:

    #. Modify a ``Function`` other than the one currently being processed.
    ...

Whereas for basic block passes there is an explicit prohibition:

    ``BasicBlockPass``\ es are just like :ref:`FunctionPass's
    <writing-an-llvm-pass-FunctionPass>` , except that they must limit
their scope
    of inspection and modification to a single basic block at a time. As such,
    they are **not** allowed to do any of the following:

    #. Modify or inspect any basic blocks outside of the current one.
    ...

Does anyone know if there's a defined policy about this, either way?
If so, I think it ought to be noted in the docs, for consistency.

Stephen

Once you get your answer, definitely feel free to update the docs.

-- Sean Silva

The prohibition exists, at least in part, because in theory it would be nice to be able to run passes in parallel. It's not a real limitation at the moment because updating instructions in a module is not thread safe (and making it so with the current APIs would probably be somewhat problematic in terms of performance) and so when we do eventually get the ability to run FunctionPasses in parallel they will most likely need new APIs. That said, it's a good idea structurally to view the Function / Block as synchronisation boundaries so that it will be easier to support concurrent execution in the future.

David

I understand the rationale but are you sure that the prohibition
against *inspecting* other functions during a function pass does exist
and is currently followed? If it does I think the docs ought to make
that clear so I want to make sure if the omission is not deliberate.

In theory you could still parallelize function pass execution if they
inspected other functions if they used some kind of read/write locking
and used transactional updates; I would think the main point is that
we want the results to be deterministic and not dependent on the order
in which functions are processed, which applies regardless of what
kind of parallelization and/or synchronization is used.

Stephen

Hi Stephen,

Does anyone know if there's a defined policy about this, either way?
If so, I think it ought to be noted in the docs, for consistency.

The prohibition exists, at least in part, because in theory it would be nice to be able to run passes in parallel. It's not a real limitation at the moment because updating instructions in a module is not thread safe (and making it so with the current APIs would probably be somewhat problematic in terms of performance) and so when we do eventually get the ability to run FunctionPasses in parallel they will most likely need new APIs. That said, it's a good idea structurally to view the Function / Block as synchronisation boundaries so that it will be easier to support concurrent execution in the future.

I understand the rationale but are you sure that the prohibition
against *inspecting* other functions during a function pass does exist
and is currently followed? If it does I think the docs ought to make
that clear so I want to make sure if the omission is not deliberate.

In theory you could still parallelize function pass execution if they
inspected other functions if they used some kind of read/write locking
and used transactional updates; I would think the main point is that
we want the results to be deterministic and not dependent on the order
in which functions are processed, which applies regardless of what
kind of parallelization and/or synchronization is used.

both dragonegg and clang (AFAIK) run some function passes on each function
in turn as they are turned into LLVM IR. If such a function pass tried to
inspect other functions then they won't be able to see all function bodies
because they haven't all been output yet. And which functions do have bodies
available to be inspected depends on the order in which clang decides to
output functions, so the results of running the pass would depend on that
order.

Ciao, Duncan.

both dragonegg and clang (AFAIK) run some function passes on each function
in turn as they are turned into LLVM IR. If such a function pass tried to
inspect other functions then they won't be able to see all function bodies
because they haven't all been output yet. And which functions do have
bodies
available to be inspected depends on the order in which clang decides to
output functions, so the results of running the pass would depend on that
order.

Ciao, Duncan.

OK, so to be clear, the docs are incomplete and need to be updated?
Just trying to get explicit confirmation before I patch this...

Stephen

Hi Stephen,

in my opinion function passes should not be inspecting the bodies of other
functions. I'm happy to review a doc patch that says this.

Ciao, Duncan.

OK, thanks, I submitted a (one-line) patch to llvm-commits:

http://lists.cs.uiuc.edu/pipermail/llvm-commits/Week-of-Mon-20130701/180210.html

I'll commit it in a few days if no one objects.

Stephen