annotate docs/MergeFunctions.rst @ 107:a03ddd01be7e

resolve warnings
author Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
date Sun, 31 Jan 2016 17:34:49 +0900
parents afa8332a0e37
children 1172e4bd9c6f
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
83
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
1 =================================
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
2 MergeFunctions pass, how it works
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
3 =================================
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
4
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
5 .. contents::
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
6 :local:
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
7
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
8 Introduction
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
9 ============
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
10 Sometimes code contains equal functions, or functions that does exactly the same
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
11 thing even though they are non-equal on the IR level (e.g.: multiplication on 2
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
12 and 'shl 1'). It could happen due to several reasons: mainly, the usage of
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
13 templates and automatic code generators. Though, sometimes user itself could
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
14 write the same thing twice :-)
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
15
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
16 The main purpose of this pass is to recognize such functions and merge them.
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
17
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
18 Why would I want to read this document?
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
19 ---------------------------------------
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
20 Document is the extension to pass comments and describes the pass logic. It
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
21 describes algorithm that is used in order to compare functions, it also
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
22 explains how we could combine equal functions correctly, keeping module valid.
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
23
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
24 Material is brought in top-down form, so reader could start learn pass from
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
25 ideas and end up with low-level algorithm details, thus preparing him for
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
26 reading the sources.
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
27
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
28 So main goal is do describe algorithm and logic here; the concept. This document
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
29 is good for you, if you *don't want* to read the source code, but want to
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
30 understand pass algorithms. Author tried not to repeat the source-code and
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
31 cover only common cases, and thus avoid cases when after minor code changes we
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
32 need to update this document.
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
33
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
34
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
35 What should I know to be able to follow along with this document?
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
36 -----------------------------------------------------------------
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
37
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
38 Reader should be familiar with common compile-engineering principles and LLVM
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
39 code fundamentals. In this article we suppose reader is familiar with
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
40 `Single Static Assingment <http://en.wikipedia.org/wiki/Static_single_assignment_form>`_
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
41 concepts. Understanding of
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
42 `IR structure <http://llvm.org/docs/LangRef.html#high-level-structure>`_ is
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
43 also important.
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
44
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
45 We will use such terms as
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
46 "`module <http://llvm.org/docs/LangRef.html#high-level-structure>`_",
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
47 "`function <http://llvm.org/docs/ProgrammersManual.html#the-function-class>`_",
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
48 "`basic block <http://en.wikipedia.org/wiki/Basic_block>`_",
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
49 "`user <http://llvm.org/docs/ProgrammersManual.html#the-user-class>`_",
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
50 "`value <http://llvm.org/docs/ProgrammersManual.html#the-value-class>`_",
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
51 "`instruction <http://llvm.org/docs/ProgrammersManual.html#the-instruction-class>`_".
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
52
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
53 As a good start point, Kaleidoscope tutorial could be used:
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
54
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
55 :doc:`tutorial/index`
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
56
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
57 Especially it's important to understand chapter 3 of tutorial:
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
58
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
59 :doc:`tutorial/LangImpl3`
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
60
95
afa8332a0e37 LLVM 3.8
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents: 83
diff changeset
61 Reader also should know how passes work in LLVM, they could use next article as
afa8332a0e37 LLVM 3.8
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents: 83
diff changeset
62 a reference and start point here:
83
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
63
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
64 :doc:`WritingAnLLVMPass`
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
65
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
66 What else? Well perhaps reader also should have some experience in LLVM pass
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
67 debugging and bug-fixing.
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
68
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
69 What I gain by reading this document?
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
70 -------------------------------------
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
71 Main purpose is to provide reader with comfortable form of algorithms
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
72 description, namely the human reading text. Since it could be hard to
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
73 understand algorithm straight from the source code: pass uses some principles
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
74 that have to be explained first.
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
75
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
76 Author wishes to everybody to avoid case, when you read code from top to bottom
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
77 again and again, and yet you don't understand why we implemented it that way.
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
78
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
79 We hope that after this article reader could easily debug and improve
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
80 MergeFunctions pass and thus help LLVM project.
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
81
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
82 Narrative structure
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
83 -------------------
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
84 Article consists of three parts. First part explains pass functionality on the
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
85 top-level. Second part describes the comparison procedure itself. The third
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
86 part describes the merging process.
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
87
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
88 In every part author also tried to put the contents into the top-down form.
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
89 First, the top-level methods will be described, while the terminal ones will be
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
90 at the end, in the tail of each part. If reader will see the reference to the
95
afa8332a0e37 LLVM 3.8
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents: 83
diff changeset
91 method that wasn't described yet, they will find its description a bit below.
83
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
92
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
93 Basics
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
94 ======
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
95
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
96 How to do it?
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
97 -------------
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
98 Do we need to merge functions? Obvious thing is: yes that's a quite possible
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
99 case, since usually we *do* have duplicates. And it would be good to get rid of
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
100 them. But how to detect such a duplicates? The idea is next: we split functions
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
101 onto small bricks (parts), then we compare "bricks" amount, and if it equal,
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
102 compare "bricks" themselves, and then do our conclusions about functions
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
103 themselves.
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
104
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
105 What the difference it could be? For example, on machine with 64-bit pointers
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
106 (let's assume we have only one address space), one function stores 64-bit
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
107 integer, while another one stores a pointer. So if the target is a machine
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
108 mentioned above, and if functions are identical, except the parameter type (we
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
109 could consider it as a part of function type), then we can treat ``uint64_t``
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
110 and``void*`` as equal.
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
111
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
112 It was just an example; possible details are described a bit below.
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
113
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
114 As another example reader may imagine two more functions. First function
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
115 performs multiplication on 2, while the second one performs arithmetic right
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
116 shift on 1.
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
117
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
118 Possible solutions
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
119 ^^^^^^^^^^^^^^^^^^
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
120 Let's briefly consider possible options about how and what we have to implement
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
121 in order to create full-featured functions merging, and also what it would
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
122 meant for us.
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
123
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
124 Equal functions detection, obviously supposes "detector" method to be
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
125 implemented, latter should answer the question "whether functions are equal".
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
126 This "detector" method consists of tiny "sub-detectors", each of them answers
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
127 exactly the same question, but for function parts.
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
128
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
129 As the second step, we should merge equal functions. So it should be a "merger"
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
130 method. "Merger" accepts two functions *F1* and *F2*, and produces *F1F2*
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
131 function, the result of merging.
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
132
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
133 Having such a routines in our hands, we can process whole module, and merge all
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
134 equal functions.
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
135
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
136 In this case, we have to compare every function with every another function. As
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
137 reader could notice, this way seems to be quite expensive. Of course we could
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
138 introduce hashing and other helpers, but it is still just an optimization, and
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
139 thus the level of O(N*N) complexity.
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
140
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
141 Can we reach another level? Could we introduce logarithmical search, or random
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
142 access lookup? The answer is: "yes".
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
143
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
144 Random-access
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
145 """""""""""""
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
146 How it could be done? Just convert each function to number, and gather all of
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
147 them in special hash-table. Functions with equal hash are equal. Good hashing
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
148 means, that every function part must be taken into account. That means we have
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
149 to convert every function part into some number, and then add it into hash.
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
150 Lookup-up time would be small, but such approach adds some delay due to hashing
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
151 routine.
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
152
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
153 Logarithmical search
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
154 """"""""""""""""""""
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
155 We could introduce total ordering among the functions set, once we had it we
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
156 could then implement a logarithmical search. Lookup time still depends on N,
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
157 but adds a little of delay (*log(N)*).
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
158
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
159 Present state
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
160 """""""""""""
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
161 Both of approaches (random-access and logarithmical) has been implemented and
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
162 tested. And both of them gave a very good improvement. And what was most
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
163 surprising, logarithmical search was faster; sometimes up to 15%. Hashing needs
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
164 some extra CPU time, and it is the main reason why it works slower; in most of
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
165 cases total "hashing" time was greater than total "logarithmical-search" time.
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
166
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
167 So, preference has been granted to the "logarithmical search".
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
168
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
169 Though in the case of need, *logarithmical-search* (read "total-ordering") could
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
170 be used as a milestone on our way to the *random-access* implementation.
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
171
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
172 Every comparison is based either on the numbers or on flags comparison. In
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
173 *random-access* approach we could use the same comparison algorithm. During
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
174 comparison we exit once we find the difference, but here we might have to scan
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
175 whole function body every time (note, it could be slower). Like in
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
176 "total-ordering", we will track every numbers and flags, but instead of
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
177 comparison, we should get numbers sequence and then create the hash number. So,
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
178 once again, *total-ordering* could be considered as a milestone for even faster
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
179 (in theory) random-access approach.
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
180
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
181 MergeFunctions, main fields and runOnModule
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
182 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
183 There are two most important fields in class:
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
184
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
185 ``FnTree`` – the set of all unique functions. It keeps items that couldn't be
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
186 merged with each other. It is defined as:
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
187
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
188 ``std::set<FunctionNode> FnTree;``
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
189
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
190 Here ``FunctionNode`` is a wrapper for ``llvm::Function`` class, with
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
191 implemented “<” operator among the functions set (below we explain how it works
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
192 exactly; this is a key point in fast functions comparison).
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
193
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
194 ``Deferred`` – merging process can affect bodies of functions that are in
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
195 ``FnTree`` already. Obviously such functions should be rechecked again. In this
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
196 case we remove them from ``FnTree``, and mark them as to be rescanned, namely
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
197 put them into ``Deferred`` list.
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
198
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
199 runOnModule
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
200 """""""""""
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
201 The algorithm is pretty simple:
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
202
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
203 1. Put all module's functions into the *worklist*.
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
204
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
205 2. Scan *worklist*'s functions twice: first enumerate only strong functions and
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
206 then only weak ones:
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
207
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
208 2.1. Loop body: take function from *worklist* (call it *FCur*) and try to
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
209 insert it into *FnTree*: check whether *FCur* is equal to one of functions
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
210 in *FnTree*. If there *is* equal function in *FnTree* (call it *FExists*):
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
211 merge function *FCur* with *FExists*. Otherwise add function from *worklist*
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
212 to *FnTree*.
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
213
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
214 3. Once *worklist* scanning and merging operations is complete, check *Deferred*
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
215 list. If it is not empty: refill *worklist* contents with *Deferred* list and
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
216 do step 2 again, if *Deferred* is empty, then exit from method.
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
217
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
218 Comparison and logarithmical search
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
219 """""""""""""""""""""""""""""""""""
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
220 Let's recall our task: for every function *F* from module *M*, we have to find
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
221 equal functions *F`* in shortest time, and merge them into the single function.
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
222
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
223 Defining total ordering among the functions set allows to organize functions
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
224 into the binary tree. The lookup procedure complexity would be estimated as
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
225 O(log(N)) in this case. But how to define *total-ordering*?
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
226
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
227 We have to introduce a single rule applicable to every pair of functions, and
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
228 following this rule then evaluate which of them is greater. What kind of rule
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
229 it could be? Let's declare it as "compare" method, that returns one of 3
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
230 possible values:
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
231
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
232 -1, left is *less* than right,
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
233
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
234 0, left and right are *equal*,
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
235
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
236 1, left is *greater* than right.
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
237
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
238 Of course it means, that we have to maintain
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
239 *strict and non-strict order relation properties*:
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
240
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
241 * reflexivity (``a <= a``, ``a == a``, ``a >= a``),
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
242 * antisymmetry (if ``a <= b`` and ``b <= a`` then ``a == b``),
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
243 * transitivity (``a <= b`` and ``b <= c``, then ``a <= c``)
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
244 * asymmetry (if ``a < b``, then ``a > b`` or ``a == b``).
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
245
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
246 As it was mentioned before, comparison routine consists of
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
247 "sub-comparison-routines", each of them also consists
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
248 "sub-comparison-routines", and so on, finally it ends up with a primitives
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
249 comparison.
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
250
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
251 Below, we will use the next operations:
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
252
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
253 #. ``cmpNumbers(number1, number2)`` is method that returns -1 if left is less
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
254 than right; 0, if left and right are equal; and 1 otherwise.
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
255
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
256 #. ``cmpFlags(flag1, flag2)`` is hypothetical method that compares two flags.
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
257 The logic is the same as in ``cmpNumbers``, where ``true`` is 1, and
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
258 ``false`` is 0.
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
259
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
260 The rest of article is based on *MergeFunctions.cpp* source code
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
261 (*<llvm_dir>/lib/Transforms/IPO/MergeFunctions.cpp*). We would like to ask
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
262 reader to keep this file open nearby, so we could use it as a reference for
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
263 further explanations.
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
264
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
265 Now we're ready to proceed to the next chapter and see how it works.
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
266
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
267 Functions comparison
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
268 ====================
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
269 At first, let's define how exactly we compare complex objects.
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
270
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
271 Complex objects comparison (function, basic-block, etc) is mostly based on its
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
272 sub-objects comparison results. So it is similar to the next "tree" objects
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
273 comparison:
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
274
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
275 #. For two trees *T1* and *T2* we perform *depth-first-traversal* and have
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
276 two sequences as a product: "*T1Items*" and "*T2Items*".
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
277
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
278 #. Then compare chains "*T1Items*" and "*T2Items*" in
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
279 most-significant-item-first order. Result of items comparison would be the
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
280 result of *T1* and *T2* comparison itself.
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
281
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
282 FunctionComparator::compare(void)
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
283 ---------------------------------
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
284 Brief look at the source code tells us, that comparison starts in
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
285 “``int FunctionComparator::compare(void)``” method.
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
286
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
287 1. First parts to be compared are function's attributes and some properties that
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
288 outsides “attributes” term, but still could make function different without
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
289 changing its body. This part of comparison is usually done within simple
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
290 *cmpNumbers* or *cmpFlags* operations (e.g.
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
291 ``cmpFlags(F1->hasGC(), F2->hasGC())``). Below is full list of function's
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
292 properties to be compared on this stage:
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
293
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
294 * *Attributes* (those are returned by ``Function::getAttributes()``
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
295 method).
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
296
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
297 * *GC*, for equivalence, *RHS* and *LHS* should be both either without
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
298 *GC* or with the same one.
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
299
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
300 * *Section*, just like a *GC*: *RHS* and *LHS* should be defined in the
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
301 same section.
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
302
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
303 * *Variable arguments*. *LHS* and *RHS* should be both either with or
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
304 without *var-args*.
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
305
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
306 * *Calling convention* should be the same.
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
307
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
308 2. Function type. Checked by ``FunctionComparator::cmpType(Type*, Type*)``
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
309 method. It checks return type and parameters type; the method itself will be
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
310 described later.
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
311
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
312 3. Associate function formal parameters with each other. Then comparing function
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
313 bodies, if we see the usage of *LHS*'s *i*-th argument in *LHS*'s body, then,
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
314 we want to see usage of *RHS*'s *i*-th argument at the same place in *RHS*'s
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
315 body, otherwise functions are different. On this stage we grant the preference
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
316 to those we met later in function body (value we met first would be *less*).
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
317 This is done by “``FunctionComparator::cmpValues(const Value*, const Value*)``”
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
318 method (will be described a bit later).
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
319
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
320 4. Function body comparison. As it written in method comments:
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
321
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
322 “We do a CFG-ordered walk since the actual ordering of the blocks in the linked
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
323 list is immaterial. Our walk starts at the entry block for both functions, then
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
324 takes each block from each terminator in order. As an artifact, this also means
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
325 that unreachable blocks are ignored.”
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
326
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
327 So, using this walk we get BBs from *left* and *right* in the same order, and
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
328 compare them by “``FunctionComparator::compare(const BasicBlock*, const
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
329 BasicBlock*)``” method.
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
330
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
331 We also associate BBs with each other, like we did it with function formal
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
332 arguments (see ``cmpValues`` method below).
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
333
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
334 FunctionComparator::cmpType
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
335 ---------------------------
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
336 Consider how types comparison works.
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
337
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
338 1. Coerce pointer to integer. If left type is a pointer, try to coerce it to the
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
339 integer type. It could be done if its address space is 0, or if address spaces
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
340 are ignored at all. Do the same thing for the right type.
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
341
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
342 2. If left and right types are equal, return 0. Otherwise we need to give
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
343 preference to one of them. So proceed to the next step.
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
344
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
345 3. If types are of different kind (different type IDs). Return result of type
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
346 IDs comparison, treating them as a numbers (use ``cmpNumbers`` operation).
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
347
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
348 4. If types are vectors or integers, return result of their pointers comparison,
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
349 comparing them as numbers.
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
350
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
351 5. Check whether type ID belongs to the next group (call it equivalent-group):
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
352
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
353 * Void
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
354
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
355 * Float
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
356
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
357 * Double
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
358
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
359 * X86_FP80
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
360
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
361 * FP128
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
362
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
363 * PPC_FP128
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
364
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
365 * Label
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
366
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
367 * Metadata.
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
368
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
369 If ID belongs to group above, return 0. Since it's enough to see that
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
370 types has the same ``TypeID``. No additional information is required.
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
371
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
372 6. Left and right are pointers. Return result of address space comparison
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
373 (numbers comparison).
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
374
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
375 7. Complex types (structures, arrays, etc.). Follow complex objects comparison
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
376 technique (see the very first paragraph of this chapter). Both *left* and
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
377 *right* are to be expanded and their element types will be checked the same
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
378 way. If we get -1 or 1 on some stage, return it. Otherwise return 0.
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
379
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
380 8. Steps 1-6 describe all the possible cases, if we passed steps 1-6 and didn't
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
381 get any conclusions, then invoke ``llvm_unreachable``, since it's quite
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
382 unexpectable case.
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
383
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
384 cmpValues(const Value*, const Value*)
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
385 -------------------------------------
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
386 Method that compares local values.
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
387
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
388 This method gives us an answer on a very curious quesion: whether we could treat
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
389 local values as equal, and which value is greater otherwise. It's better to
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
390 start from example:
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
391
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
392 Consider situation when we're looking at the same place in left function "*FL*"
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
393 and in right function "*FR*". And every part of *left* place is equal to the
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
394 corresponding part of *right* place, and (!) both parts use *Value* instances,
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
395 for example:
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
396
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
397 .. code-block:: llvm
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
398
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
399 instr0 i32 %LV ; left side, function FL
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
400 instr0 i32 %RV ; right side, function FR
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
401
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
402 So, now our conclusion depends on *Value* instances comparison.
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
403
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
404 Main purpose of this method is to determine relation between such values.
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
405
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
406 What we expect from equal functions? At the same place, in functions "*FL*" and
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
407 "*FR*" we expect to see *equal* values, or values *defined* at the same place
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
408 in "*FL*" and "*FR*".
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
409
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
410 Consider small example here:
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
411
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
412 .. code-block:: llvm
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
413
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
414 define void %f(i32 %pf0, i32 %pf1) {
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
415 instr0 i32 %pf0 instr1 i32 %pf1 instr2 i32 123
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
416 }
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
417
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
418 .. code-block:: llvm
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
419
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
420 define void %g(i32 %pg0, i32 %pg1) {
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
421 instr0 i32 %pg0 instr1 i32 %pg0 instr2 i32 123
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
422 }
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
423
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
424 In this example, *pf0* is associated with *pg0*, *pf1* is associated with *pg1*,
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
425 and we also declare that *pf0* < *pf1*, and thus *pg0* < *pf1*.
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
426
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
427 Instructions with opcode "*instr0*" would be *equal*, since their types and
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
428 opcodes are equal, and values are *associated*.
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
429
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
430 Instruction with opcode "*instr1*" from *f* is *greater* than instruction with
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
431 opcode "*instr1*" from *g*; here we have equal types and opcodes, but "*pf1* is
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
432 greater than "*pg0*".
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
433
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
434 And instructions with opcode "*instr2*" are equal, because their opcodes and
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
435 types are equal, and the same constant is used as a value.
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
436
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
437 What we assiciate in cmpValues?
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
438 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
439 * Function arguments. *i*-th argument from left function associated with
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
440 *i*-th argument from right function.
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
441 * BasicBlock instances. In basic-block enumeration loop we associate *i*-th
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
442 BasicBlock from the left function with *i*-th BasicBlock from the right
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
443 function.
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
444 * Instructions.
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
445 * Instruction operands. Note, we can meet *Value* here we have never seen
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
446 before. In this case it is not a function argument, nor *BasicBlock*, nor
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
447 *Instruction*. It is global value. It is constant, since its the only
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
448 supposed global here. Method also compares:
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
449 * Constants that are of the same type.
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
450 * If right constant could be losslessly bit-casted to the left one, then we
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
451 also compare them.
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
452
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
453 How to implement cmpValues?
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
454 ^^^^^^^^^^^^^^^^^^^^^^^^^^^
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
455 *Association* is a case of equality for us. We just treat such values as equal.
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
456 But, in general, we need to implement antisymmetric relation. As it was
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
457 mentioned above, to understand what is *less*, we can use order in which we
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
458 meet values. If both of values has the same order in function (met at the same
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
459 time), then treat values as *associated*. Otherwise – it depends on who was
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
460 first.
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
461
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
462 Every time we run top-level compare method, we initialize two identical maps
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
463 (one for the left side, another one for the right side):
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
464
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
465 ``map<Value, int> sn_mapL, sn_mapR;``
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
466
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
467 The key of the map is the *Value* itself, the *value* – is its order (call it
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
468 *serial number*).
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
469
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
470 To add value *V* we need to perform the next procedure:
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
471
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
472 ``sn_map.insert(std::make_pair(V, sn_map.size()));``
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
473
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
474 For the first *Value*, map will return *0*, for second *Value* map will return
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
475 *1*, and so on.
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
476
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
477 Then we can check whether left and right values met at the same time with simple
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
478 comparison:
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
479
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
480 ``cmpNumbers(sn_mapL[Left], sn_mapR[Right]);``
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
481
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
482 Of course, we can combine insertion and comparison:
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
483
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
484 .. code-block:: c++
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
485
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
486 std::pair<iterator, bool>
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
487 LeftRes = sn_mapL.insert(std::make_pair(Left, sn_mapL.size())), RightRes
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
488 = sn_mapR.insert(std::make_pair(Right, sn_mapR.size()));
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
489 return cmpNumbers(LeftRes.first->second, RightRes.first->second);
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
490
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
491 Let's look, how whole method could be implemented.
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
492
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
493 1. we have to start from the bad news. Consider function self and
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
494 cross-referencing cases:
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
495
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
496 .. code-block:: c++
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
497
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
498 // self-reference unsigned fact0(unsigned n) { return n > 1 ? n
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
499 * fact0(n-1) : 1; } unsigned fact1(unsigned n) { return n > 1 ? n *
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
500 fact1(n-1) : 1; }
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
501
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
502 // cross-reference unsigned ping(unsigned n) { return n!= 0 ? pong(n-1) : 0;
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
503 } unsigned pong(unsigned n) { return n!= 0 ? ping(n-1) : 0; }
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
504
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
505 ..
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
506
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
507 This comparison has been implemented in initial *MergeFunctions* pass
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
508 version. But, unfortunately, it is not transitive. And this is the only case
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
509 we can't convert to less-equal-greater comparison. It is a seldom case, 4-5
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
510 functions of 10000 (checked on test-suite), and, we hope, reader would
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
511 forgive us for such a sacrifice in order to get the O(log(N)) pass time.
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
512
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
513 2. If left/right *Value* is a constant, we have to compare them. Return 0 if it
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
514 is the same constant, or use ``cmpConstants`` method otherwise.
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
515
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
516 3. If left/right is *InlineAsm* instance. Return result of *Value* pointers
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
517 comparison.
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
518
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
519 4. Explicit association of *L* (left value) and *R* (right value). We need to
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
520 find out whether values met at the same time, and thus are *associated*. Or we
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
521 need to put the rule: when we treat *L* < *R*. Now it is easy: just return
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
522 result of numbers comparison:
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
523
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
524 .. code-block:: c++
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
525
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
526 std::pair<iterator, bool>
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
527 LeftRes = sn_mapL.insert(std::make_pair(Left, sn_mapL.size())),
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
528 RightRes = sn_mapR.insert(std::make_pair(Right, sn_mapR.size()));
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
529 if (LeftRes.first->second == RightRes.first->second) return 0;
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
530 if (LeftRes.first->second < RightRes.first->second) return -1;
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
531 return 1;
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
532
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
533 Now when *cmpValues* returns 0, we can proceed comparison procedure. Otherwise,
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
534 if we get (-1 or 1), we need to pass this result to the top level, and finish
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
535 comparison procedure.
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
536
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
537 cmpConstants
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
538 ------------
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
539 Performs constants comparison as follows:
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
540
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
541 1. Compare constant types using ``cmpType`` method. If result is -1 or 1, goto
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
542 step 2, otherwise proceed to step 3.
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
543
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
544 2. If types are different, we still can check whether constants could be
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
545 losslessly bitcasted to each other. The further explanation is modification of
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
546 ``canLosslesslyBitCastTo`` method.
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
547
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
548 2.1 Check whether constants are of the first class types
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
549 (``isFirstClassType`` check):
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
550
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
551 2.1.1. If both constants are *not* of the first class type: return result
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
552 of ``cmpType``.
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
553
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
554 2.1.2. Otherwise, if left type is not of the first class, return -1. If
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
555 right type is not of the first class, return 1.
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
556
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
557 2.1.3. If both types are of the first class type, proceed to the next step
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
558 (2.1.3.1).
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
559
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
560 2.1.3.1. If types are vectors, compare their bitwidth using the
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
561 *cmpNumbers*. If result is not 0, return it.
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
562
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
563 2.1.3.2. Different types, but not a vectors:
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
564
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
565 * if both of them are pointers, good for us, we can proceed to step 3.
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
566 * if one of types is pointer, return result of *isPointer* flags
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
567 comparison (*cmpFlags* operation).
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
568 * otherwise we have no methods to prove bitcastability, and thus return
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
569 result of types comparison (-1 or 1).
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
570
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
571 Steps below are for the case when types are equal, or case when constants are
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
572 bitcastable:
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
573
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
574 3. One of constants is a "*null*" value. Return the result of
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
575 ``cmpFlags(L->isNullValue, R->isNullValue)`` comparison.
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
576
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
577 4. Compare value IDs, and return result if it is not 0:
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
578
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
579 .. code-block:: c++
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
580
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
581 if (int Res = cmpNumbers(L->getValueID(), R->getValueID()))
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
582 return Res;
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
583
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
584 5. Compare the contents of constants. The comparison depends on kind of
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
585 constants, but on this stage it is just a lexicographical comparison. Just see
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
586 how it was described in the beginning of "*Functions comparison*" paragraph.
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
587 Mathematically it is equal to the next case: we encode left constant and right
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
588 constant (with similar way *bitcode-writer* does). Then compare left code
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
589 sequence and right code sequence.
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
590
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
591 compare(const BasicBlock*, const BasicBlock*)
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
592 ---------------------------------------------
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
593 Compares two *BasicBlock* instances.
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
594
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
595 It enumerates instructions from left *BB* and right *BB*.
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
596
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
597 1. It assigns serial numbers to the left and right instructions, using
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
598 ``cmpValues`` method.
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
599
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
600 2. If one of left or right is *GEP* (``GetElementPtr``), then treat *GEP* as
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
601 greater than other instructions, if both instructions are *GEPs* use ``cmpGEP``
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
602 method for comparison. If result is -1 or 1, pass it to the top-level
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
603 comparison (return it).
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
604
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
605 3.1. Compare operations. Call ``cmpOperation`` method. If result is -1 or
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
606 1, return it.
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
607
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
608 3.2. Compare number of operands, if result is -1 or 1, return it.
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
609
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
610 3.3. Compare operands themselves, use ``cmpValues`` method. Return result
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
611 if it is -1 or 1.
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
612
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
613 3.4. Compare type of operands, using ``cmpType`` method. Return result if
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
614 it is -1 or 1.
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
615
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
616 3.5. Proceed to the next instruction.
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
617
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
618 4. We can finish instruction enumeration in 3 cases:
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
619
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
620 4.1. We reached the end of both left and right basic-blocks. We didn't
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
621 exit on steps 1-3, so contents is equal, return 0.
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
622
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
623 4.2. We have reached the end of the left basic-block. Return -1.
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
624
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
625 4.3. Return 1 (the end of the right basic block).
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
626
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
627 cmpGEP
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
628 ------
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
629 Compares two GEPs (``getelementptr`` instructions).
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
630
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
631 It differs from regular operations comparison with the only thing: possibility
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
632 to use ``accumulateConstantOffset`` method.
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
633
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
634 So, if we get constant offset for both left and right *GEPs*, then compare it as
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
635 numbers, and return comparison result.
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
636
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
637 Otherwise treat it like a regular operation (see previous paragraph).
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
638
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
639 cmpOperation
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
640 ------------
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
641 Compares instruction opcodes and some important operation properties.
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
642
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
643 1. Compare opcodes, if it differs return the result.
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
644
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
645 2. Compare number of operands. If it differs – return the result.
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
646
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
647 3. Compare operation types, use *cmpType*. All the same – if types are
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
648 different, return result.
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
649
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
650 4. Compare *subclassOptionalData*, get it with ``getRawSubclassOptionalData``
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
651 method, and compare it like a numbers.
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
652
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
653 5. Compare operand types.
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
654
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
655 6. For some particular instructions check equivalence (relation in our case) of
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
656 some significant attributes. For example we have to compare alignment for
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
657 ``load`` instructions.
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
658
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
659 O(log(N))
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
660 ---------
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
661 Methods described above implement order relationship. And latter, could be used
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
662 for nodes comparison in a binary tree. So we can organize functions set into
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
663 the binary tree and reduce the cost of lookup procedure from
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
664 O(N*N) to O(log(N)).
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
665
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
666 Merging process, mergeTwoFunctions
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
667 ==================================
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
668 Once *MergeFunctions* detected that current function (*G*) is equal to one that
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
669 were analyzed before (function *F*) it calls ``mergeTwoFunctions(Function*,
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
670 Function*)``.
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
671
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
672 Operation affects ``FnTree`` contents with next way: *F* will stay in
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
673 ``FnTree``. *G* being equal to *F* will not be added to ``FnTree``. Calls of
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
674 *G* would be replaced with something else. It changes bodies of callers. So,
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
675 functions that calls *G* would be put into ``Deferred`` set and removed from
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
676 ``FnTree``, and analyzed again.
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
677
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
678 The approach is next:
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
679
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
680 1. Most wished case: when we can use alias and both of *F* and *G* are weak. We
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
681 make both of them with aliases to the third strong function *H*. Actually *H*
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
682 is *F*. See below how it's made (but it's better to look straight into the
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
683 source code). Well, this is a case when we can just replace *G* with *F*
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
684 everywhere, we use ``replaceAllUsesWith`` operation here (*RAUW*).
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
685
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
686 2. *F* could not be overridden, while *G* could. It would be good to do the
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
687 next: after merging the places where overridable function were used, still use
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
688 overridable stub. So try to make *G* alias to *F*, or create overridable tail
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
689 call wrapper around *F* and replace *G* with that call.
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
690
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
691 3. Neither *F* nor *G* could be overridden. We can't use *RAUW*. We can just
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
692 change the callers: call *F* instead of *G*. That's what
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
693 ``replaceDirectCallers`` does.
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
694
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
695 Below is detailed body description.
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
696
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
697 If “F” may be overridden
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
698 ------------------------
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
699 As follows from ``mayBeOverridden`` comments: “whether the definition of this
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
700 global may be replaced by something non-equivalent at link time”. If so, thats
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
701 ok: we can use alias to *F* instead of *G* or change call instructions itself.
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
702
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
703 HasGlobalAliases, removeUsers
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
704 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
705 First consider the case when we have global aliases of one function name to
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
706 another. Our purpose is make both of them with aliases to the third strong
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
707 function. Though if we keep *F* alive and without major changes we can leave it
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
708 in ``FnTree``. Try to combine these two goals.
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
709
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
710 Do stub replacement of *F* itself with an alias to *F*.
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
711
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
712 1. Create stub function *H*, with the same name and attributes like function
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
713 *F*. It takes maximum alignment of *F* and *G*.
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
714
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
715 2. Replace all uses of function *F* with uses of function *H*. It is the two
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
716 steps procedure instead. First of all, we must take into account, all functions
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
717 from whom *F* is called would be changed: since we change the call argument
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
718 (from *F* to *H*). If so we must to review these caller functions again after
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
719 this procedure. We remove callers from ``FnTree``, method with name
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
720 ``removeUsers(F)`` does that (don't confuse with ``replaceAllUsesWith``):
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
721
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
722 2.1. ``Inside removeUsers(Value*
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
723 V)`` we go through the all values that use value *V* (or *F* in our context).
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
724 If value is instruction, we go to function that holds this instruction and
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
725 mark it as to-be-analyzed-again (put to ``Deferred`` set), we also remove
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
726 caller from ``FnTree``.
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
727
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
728 2.2. Now we can do the replacement: call ``F->replaceAllUsesWith(H)``.
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
729
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
730 3. *H* (that now "officially" plays *F*'s role) is replaced with alias to *F*.
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
731 Do the same with *G*: replace it with alias to *F*. So finally everywhere *F*
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
732 was used, we use *H* and it is alias to *F*, and everywhere *G* was used we
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
733 also have alias to *F*.
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
734
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
735 4. Set *F* linkage to private. Make it strong :-)
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
736
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
737 No global aliases, replaceDirectCallers
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
738 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
739 If global aliases are not supported. We call ``replaceDirectCallers`` then. Just
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
740 go through all calls of *G* and replace it with calls of *F*. If you look into
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
741 method you will see that it scans all uses of *G* too, and if use is callee (if
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
742 user is call instruction and *G* is used as what to be called), we replace it
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
743 with use of *F*.
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
744
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
745 If “F” could not be overridden, fix it!
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
746 """""""""""""""""""""""""""""""""""""""
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
747
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
748 We call ``writeThunkOrAlias(Function *F, Function *G)``. Here we try to replace
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
749 *G* with alias to *F* first. Next conditions are essential:
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
750
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
751 * target should support global aliases,
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
752 * the address itself of *G* should be not significant, not named and not
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
753 referenced anywhere,
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
754 * function should come with external, local or weak linkage.
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
755
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
756 Otherwise we write thunk: some wrapper that has *G's* interface and calls *F*,
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
757 so *G* could be replaced with this wrapper.
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
758
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
759 *writeAlias*
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
760
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
761 As follows from *llvm* reference:
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
762
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
763 “Aliases act as *second name* for the aliasee value”. So we just want to create
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
764 second name for *F* and use it instead of *G*:
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
765
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
766 1. create global alias itself (*GA*),
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
767
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
768 2. adjust alignment of *F* so it must be maximum of current and *G's* alignment;
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
769
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
770 3. replace uses of *G*:
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
771
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
772 3.1. first mark all callers of *G* as to-be-analyzed-again, using
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
773 ``removeUsers`` method (see chapter above),
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
774
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
775 3.2. call ``G->replaceAllUsesWith(GA)``.
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
776
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
777 4. Get rid of *G*.
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
778
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
779 *writeThunk*
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
780
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
781 As it written in method comments:
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
782
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
783 “Replace G with a simple tail call to bitcast(F). Also replace direct uses of G
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
784 with bitcast(F). Deletes G.”
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
785
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
786 In general it does the same as usual when we want to replace callee, except the
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
787 first point:
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
788
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
789 1. We generate tail call wrapper around *F*, but with interface that allows use
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
790 it instead of *G*.
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
791
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
792 2. “As-usual”: ``removeUsers`` and ``replaceAllUsesWith`` then.
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
793
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
794 3. Get rid of *G*.
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
795
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
796 That's it.
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
797 ==========
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
798 We have described how to detect equal functions, and how to merge them, and in
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
799 first chapter we have described how it works all-together. Author hopes, reader
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
800 have some picture from now, and it helps him improve and debug ­this pass.
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
801
60c9769439b8 LLVM 3.7
Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
parents:
diff changeset
802 Reader is welcomed to send us any questions and proposals ;-)