aboutsummaryrefslogtreecommitdiffstats
path: root/dynamic-layers/clang-layer/recipes-devtools/clang/files/llvm10-basic-block-sections-support.patch
blob: f90a79ae794413aa9432e7e04e625b170353b1ac (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
From d51fdb9f2986747a56c593fa057d531720b39deb Mon Sep 17 00:00:00 2001
From: Sriraman Tallam <tmsriram@google.com>
Date: Fri, 13 Mar 2020 15:58:57 -0700
Subject: [PATCH] Basic Block Sections Support.

This is the first in a series of patches to enable Basic Block Sections
in LLVM.

We introduce a new compiler option, -fbasicblock-sections=, which places every
basic block in a unique ELF text section in the object file along with a
symbol labeling the basic block. The linker can then order the basic block
sections in any arbitrary sequence which when done correctly can encapsulate
block layout, function layout and function splitting optimizations. However,
there are a couple of challenges to be addressed for this to be feasible:

1) The compiler must not allow any implicit fall-through between any two
   adjacent basic blocks as they could be reordered at link time to be
   non-adjacent. In other words, the compiler must make a fall-through
   between adjacent basic blocks explicit by retaining the direct jump
   instruction that jumps to the next basic block. These branches can only
   be removed later by the linker after the blocks have been reordered.
2) All inter-basic block branch targets would now need to be resolved by
   the linker as they cannot be calculated during compile time. This is
   done using static relocations which bloats the size of the object files.
   Further, the compiler tries to use short branch instructions on some ISAs
   for branch offsets that can be accommodated in one byte. This is not
   possible with basic block sections as the offset is not determined at
   compile time, and long branch instructions have to be used everywhere.
3) Each additional section bloats object file sizes by tens of bytes. The
   number of basic blocks can be potentially very large compared to the
   size of functions and can bloat object sizes significantly. Option
   fbasicblock-sections= also takes a file path which can be used to
   specify a subset of basic blocks that needs unique sections to keep
   the bloats small.
4) Debug Info and CFI need special handling and will be presented as
   separate patches.

Basic Block Labels

With -fbasicblock-sections=labels, or when a basic block is placed in a
unique section, it is labelled with a symbol. This allows easy mapping of
virtual addresses from PMU profiles back to the corresponding basic blocks.
Since the number of basic blocks is large, the labeling bloats the symbol
table sizes and the string table sizes significantly. While the binary size
does increase, it does not affect performance as the symbol table is not
loaded in memory during run-time. The string table size bloat is kept very
minimal using a unary naming scheme that uses string suffix compression.
The basic blocks for function foo are named "a.BB.foo", "aa.BB.foo", ...
This turns out to be very good for string table sizes and the bloat in the
string table size for a very large binary is ~8 %. The naming also allows
using the --symbol-ordering-file option in LLD to arbitrarily reorder the
sections.

Differential Revision: https://reviews.llvm.org/D68063

Upstream-Status: Backport [https://github.com/llvm/llvm-project/commit/4dfe92e46542be46d634a7ec24da2f2f889623d0]
Signed-off-by: Anuj Mittal <anuj.mittal@intel.com>
---
 llvm/include/llvm/CodeGen/CommandFlags.inc | 34 ++++++++++++++++++++++
 llvm/include/llvm/Target/TargetMachine.h   | 14 +++++++++
 llvm/include/llvm/Target/TargetOptions.h   | 31 ++++++++++++++++++--
 3 files changed, 76 insertions(+), 3 deletions(-)

diff --git a/llvm/include/llvm/CodeGen/CommandFlags.inc b/llvm/include/llvm/CodeGen/CommandFlags.inc
index 8739b644873d..6475a5b19edb 100644
--- a/llvm/include/llvm/CodeGen/CommandFlags.inc
+++ b/llvm/include/llvm/CodeGen/CommandFlags.inc
@@ -238,6 +238,12 @@ static cl::opt<bool>
                      cl::desc("Emit functions into separate sections"),
                      cl::init(false));
 
+static cl::opt<std::string>
+    BBSections("basicblock-sections",
+               cl::desc("Emit basic blocks into separate sections"),
+               cl::value_desc("all | <function list (file)> | labels | none"),
+               cl::init("none"));
+
 static cl::opt<unsigned> TLSSize("tls-size",
                                  cl::desc("Bit size of immediate TLS offsets"),
                                  cl::init(0));
@@ -251,6 +257,11 @@ static cl::opt<bool>
                        cl::desc("Give unique names to every section"),
                        cl::init(true));
 
+static cl::opt<bool> UniqueBBSectionNames(
+    "unique-bb-section-names",
+    cl::desc("Give unique names to every basic block section"),
+    cl::init(false));
+
 static cl::opt<llvm::EABI>
     EABIVersion("meabi", cl::desc("Set EABI type (default depends on triple):"),
                 cl::init(EABI::Default),
@@ -285,6 +296,27 @@ static cl::opt<bool>
                            cl::desc("Always emit a debug frame section."),
                            cl::init(false));
 
+static llvm::BasicBlockSection
+getBBSectionsMode(llvm::TargetOptions &Options) {
+  if (BBSections == "all")
+    return BasicBlockSection::All;
+  else if (BBSections == "labels")
+    return BasicBlockSection::Labels;
+  else if (BBSections == "none")
+    return BasicBlockSection::None;
+  else {
+    ErrorOr<std::unique_ptr<MemoryBuffer>> MBOrErr =
+        MemoryBuffer::getFile(BBSections);
+    if (!MBOrErr) {
+      errs() << "Error loading basic block sections function list file: "
+             << MBOrErr.getError().message() << "\n";
+    } else {
+      Options.BBSectionsFuncListBuf = std::move(*MBOrErr);
+    }
+    return BasicBlockSection::List;
+  }
+}
+
 // Common utility function tightly tied to the options listed here. Initializes
 // a TargetOptions object with CodeGen flags and returns it.
 static TargetOptions InitTargetOptionsFromCodeGenFlags() {
@@ -308,7 +340,9 @@ static TargetOptions InitTargetOptionsFromCodeGenFlags() {
   Options.RelaxELFRelocations = RelaxELFRelocations;
   Options.DataSections = DataSections;
   Options.FunctionSections = FunctionSections;
+  Options.BBSections = getBBSectionsMode(Options);
   Options.UniqueSectionNames = UniqueSectionNames;
+  Options.UniqueBBSectionNames = UniqueBBSectionNames;
   Options.TLSSize = TLSSize;
   Options.EmulatedTLS = EmulatedTLS;
   Options.ExplicitEmulatedTLS = EmulatedTLS.getNumOccurrences() > 0;
diff --git a/llvm/include/llvm/Target/TargetMachine.h b/llvm/include/llvm/Target/TargetMachine.h
index 176ae39b17a7..4a1f3377f31d 100644
--- a/llvm/include/llvm/Target/TargetMachine.h
+++ b/llvm/include/llvm/Target/TargetMachine.h
@@ -242,6 +242,9 @@ public:
 
   bool getUniqueSectionNames() const { return Options.UniqueSectionNames; }
 
+  /// Return true if unique basic block section names must be generated.
+  bool getUniqueBBSectionNames() const { return Options.UniqueBBSectionNames; }
+
   /// Return true if data objects should be emitted into their own section,
   /// corresponds to -fdata-sections.
   bool getDataSections() const {
@@ -254,6 +257,17 @@ public:
     return Options.FunctionSections;
   }
 
+  /// If basic blocks should be emitted into their own section,
+  /// corresponding to -fbasicblock-sections.
+  llvm::BasicBlockSection getBBSectionsType() const {
+    return Options.BBSections;
+  }
+
+  /// Get the list of functions and basic block ids that need unique sections.
+  const MemoryBuffer *getBBSectionsFuncListBuf() const {
+    return Options.BBSectionsFuncListBuf.get();
+  }
+
   /// Get a \c TargetIRAnalysis appropriate for the target.
   ///
   /// This is used to construct the new pass manager's target IR analysis pass,
diff --git a/llvm/include/llvm/Target/TargetOptions.h b/llvm/include/llvm/Target/TargetOptions.h
index 84c6ee2a6387..d27c7b0178f0 100644
--- a/llvm/include/llvm/Target/TargetOptions.h
+++ b/llvm/include/llvm/Target/TargetOptions.h
@@ -16,8 +16,11 @@
 
 #include "llvm/MC/MCTargetOptions.h"
 
+#include <memory>
+
 namespace llvm {
   class MachineFunction;
+  class MemoryBuffer;
   class Module;
 
   namespace FloatABI {
@@ -63,6 +66,18 @@ namespace llvm {
     };
   }
 
+  enum class BasicBlockSection {
+    All,    // Use Basic Block Sections for all basic blocks.  A section
+            // for every basic block can significantly bloat object file sizes.
+    List,   // Get list of functions & BBs from a file. Selectively enables
+            // basic block sections for a subset of basic blocks which can be
+            // used to control object size bloats from creating sections.
+    Labels, // Do not use Basic Block Sections but label basic blocks.  This
+            // is useful when associating profile counts from virtual addresses
+            // to basic blocks.
+    None    // Do not use Basic Block Sections.
+  };
+
   enum class EABI {
     Unknown,
     Default, // Default means not specified
@@ -114,9 +129,9 @@ namespace llvm {
           EnableFastISel(false), EnableGlobalISel(false), UseInitArray(false),
           DisableIntegratedAS(false), RelaxELFRelocations(false),
           FunctionSections(false), DataSections(false),
-          UniqueSectionNames(true), TrapUnreachable(false),
-          NoTrapAfterNoreturn(false), TLSSize(0), EmulatedTLS(false),
-          ExplicitEmulatedTLS(false), EnableIPRA(false),
+          UniqueSectionNames(true), UniqueBBSectionNames(false),
+          TrapUnreachable(false), NoTrapAfterNoreturn(false), TLSSize(0),
+          EmulatedTLS(false), ExplicitEmulatedTLS(false), EnableIPRA(false),
           EmitStackSizeSection(false), EnableMachineOutliner(false),
           SupportsDefaultOutlining(false), EmitAddrsig(false),
           EnableDebugEntryValues(false), ForceDwarfFrameSection(false) {}
@@ -224,6 +239,9 @@ namespace llvm {
 
     unsigned UniqueSectionNames : 1;
 
+    /// Use unique names for basic block sections.
+    unsigned UniqueBBSectionNames : 1;
+
     /// Emit target-specific trap instruction for 'unreachable' IR instructions.
     unsigned TrapUnreachable : 1;
 
@@ -256,6 +274,13 @@ namespace llvm {
     /// Emit address-significance table.
     unsigned EmitAddrsig : 1;
 
+    /// Emit basic blocks into separate sections.
+    BasicBlockSection BBSections = BasicBlockSection::None;
+
+    /// Memory Buffer that contains information on sampled basic blocks and used
+    /// to selectively generate basic block sections.
+    std::shared_ptr<MemoryBuffer> BBSectionsFuncListBuf;
+
     /// Emit debug info about parameter's entry values.
     unsigned EnableDebugEntryValues : 1;
 
-- 
2.33.1