Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 18 additions & 18 deletions llvm/docs/MergeFunctions.rst
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@ MergeFunctions pass, how it works
Introduction
============
Sometimes code contains equal functions, or functions that do exactly the same
thing even though they are non-equal on the IR level (e.g.: multiplication on 2
and 'shl 1'). This can happen for several reasons: mainly, the usage of
templates and automatic code generators. Though, sometimes the user itself could
thing even though they are non-equal on the IR level (e.g.,: multiplication on 2
and ``shl 1``). This can happen for several reasons: mainly, the usage of
templates and automatic code generators. However, sometimes the user itself could
write the same thing twice :-)

The main purpose of this pass is to recognize such functions and merge them.
Expand All @@ -20,21 +20,21 @@ describes the algorithm used to compare functions and
explains how we could combine equal functions correctly to keep the module
valid.

Material is brought in a top-down form, so the reader could start to learn pass
The material is presented in a top-down form, so the reader could start to learn pass
from high level ideas and end with low-level algorithm details, thus preparing
him or her for reading the sources.

The main goal is to describe the algorithm and logic here and the concept. If
you *don't want* to read the source code, but want to understand pass
algorithms, this document is good for you. The author tries not to repeat the
source-code and covers only common cases to avoid the cases of needing to
source code and covers only common cases to avoid the cases of needing to
update this document after any minor code changes.


What should I know to be able to follow along with this document?
-----------------------------------------------------------------

The reader should be familiar with common compile-engineering principles and
The reader should be familiar with common compiler-engineering principles and
LLVM code fundamentals. In this article, we assume the reader is familiar with
`Single Static Assignment
<http://en.wikipedia.org/wiki/Static_single_assignment_form>`_
Expand Down Expand Up @@ -99,7 +99,7 @@ and a ``void*`` as equal.
This is just an example; more possible details are described a bit below.

As another example, the reader may imagine two more functions. The first
function performs a multiplication by 2, while the second one performs an
function performs a multiplication by 2, while the second one performs a
logical left shift by 1.

Possible solutions
Expand Down Expand Up @@ -131,7 +131,7 @@ access lookup? The answer is: "yes".
Random-access
"""""""""""""
How can this be done? Just convert each function to a number, and gather
all of them in a special hash-table. Functions with equal hashes are equal.
all of them in a special hash table. Functions with equal hashes are equal.
Good hashing means, that every function part must be taken into account. That
means we have to convert every function part into some number, and then add it
into the hash. The lookup-up time would be small, but such an approach adds some
Expand Down Expand Up @@ -175,7 +175,7 @@ merged with each other. It is defined as:

``std::set<FunctionNode> FnTree;``

Here ``FunctionNode`` is a wrapper for ``llvm::Function`` class, with
Here, ``FunctionNode`` is a wrapper for ``llvm::Function`` class, with an
implemented “<” operator among the functions set (below we explain how it works
exactly; this is a key point in fast functions comparison).

Expand Down Expand Up @@ -207,7 +207,7 @@ from method.
Comparison and logarithmical search
"""""""""""""""""""""""""""""""""""
Let's recall our task: for every function *F* from module *M*, we have to find
equal functions *F`* in the shortest time possible , and merge them into a
equal functions *F`* in the shortest time possible and merge them into a
single function.

Defining total ordering among the functions set allows us to organize
Expand All @@ -225,7 +225,7 @@ possible values:

1, left is *greater* than right.

Of course it means, that we have to maintain
Of course, it means that we have to maintain
*strict and non-strict order relation properties*:

* reflexivity (``a <= a``, ``a == a``, ``a >= a``),
Expand All @@ -235,7 +235,7 @@ Of course it means, that we have to maintain

As mentioned before, the comparison routine consists of
"sub-comparison-routines", with each of them also consisting of
"sub-comparison-routines", and so on. Finally, it ends up with primitive
"sub-comparison-routines", and so on. Finally, it ends up with a primitive
comparison.

Below, we will use the following operations:
Expand Down Expand Up @@ -275,7 +275,7 @@ A brief look at the source code tells us that the comparison starts in the
“``int FunctionComparator::compare(void)``” method.

1. The first parts to be compared are the function's attributes and some
properties that is outside the “attributes” term, but still could make the
properties that are outside the “attributes” term, but still could make the
function different without changing its body. This part of the comparison is
usually done within simple *cmpNumbers* or *cmpFlags* operations (e.g.
``cmpFlags(F1->hasGC(), F2->hasGC())``). Below is a full list of function's
Expand Down Expand Up @@ -365,7 +365,7 @@ comparing them as numbers.
7. Complex types (structures, arrays, etc.). Follow complex objects comparison
technique (see the very first paragraph of this chapter). Both *left* and
*right* are to be expanded and their element types will be checked the same
way. If we get -1 or 1 on some stage, return it. Otherwise return 0.
way. If we get -1 or 1 on some stage, return it. Otherwise, return 0.

8. Steps 1-6 describe all the possible cases, if we passed steps 1-6 and didn't
get any conclusions, then invoke ``llvm_unreachable``, since it's quite an
Expand Down Expand Up @@ -445,7 +445,7 @@ How to implement cmpValues?
but, in general, we need to implement antisymmetric relation. As mentioned
above, to understand what is *less*, we can use order in which we
meet values. If both values have the same order in a function (met at the same
time), we then treat values as *associated*. Otherwise it depends on who was
time), we then treat values as *associated*. Otherwise, it depends on who was
first.

Every time we run the top-level compare method, we initialize two identical
Expand Down Expand Up @@ -623,7 +623,7 @@ to use ``accumulateConstantOffset`` method.
So, if we get constant offset for both left and right *GEPs*, then compare it as
numbers, and return comparison result.

Otherwise treat it like a regular operation (see previous paragraph).
Otherwise, treat it like a regular operation (see previous paragraph).

cmpOperation
------------
Expand Down Expand Up @@ -742,7 +742,7 @@ We call ``writeThunkOrAlias(Function *F, Function *G)``. Here we try to replace
referenced anywhere,
* function should come with external, local or weak linkage.

Otherwise we write thunk: some wrapper that has *G's* interface and calls *F*,
Otherwise, we write thunk: some wrapper that has *G's* interface and calls *F*,
so *G* could be replaced with this wrapper.

*writeAlias*
Expand Down Expand Up @@ -772,7 +772,7 @@ As it written in method comments:
“Replace G with a simple tail call to bitcast(F). Also replace direct uses of G
with bitcast(F). Deletes G.”

In general it does the same as usual when we want to replace callee, except the
In general, it does the same as usual when we want to replace callee, except the
first point:

1. We generate tail call wrapper around *F*, but with an interface that allows using
Expand Down
Loading